KiCad PCB EDA Suite
Loading...
Searching...
No Matches
appearance_controls_3D.cpp
Go to the documentation of this file.
1/*
2 * This program source code file is part of KiCad, a free EDA CAD application.
3 *
4 * Copyright (C) 2023 CERN
5 * Copyright The KiCad Developers, see AUTHORS.txt for contributors.
6 *
7 * This program is free software: you can redistribute it and/or modify it
8 * under the terms of the GNU General Public License as published by the
9 * Free Software Foundation, either version 3 of the License, or (at your
10 * option) any later version.
11 *
12 * This program is distributed in the hope that it will be useful, but
13 * WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * General Public License for more details.
16 *
17 * You should have received a copy of the GNU General Public License along
18 * with this program. If not, see <http://www.gnu.org/licenses/>.
19 */
20
22
23#include <bitmaps.h>
24#include <confirm.h>
25#include <pgm_base.h>
26#include <dpi_scaling_common.h>
27#include <eda_list_dialog.h>
28#include <pcb_display_options.h>
29#include <eda_3d_viewer_frame.h>
30#include <pcbnew_settings.h>
31#include <project.h>
32#include <board.h>
33#include <tool/tool_manager.h>
34#include <tools/pcb_actions.h>
40#include <wx/bmpbuttn.h>
41#include <wx/sizer.h>
42#include <wx/textdlg.h>
43#include <wx/checkbox.h>
44
45#include <../3d_rendering/opengl/render_3d_opengl.h>
46#include <algorithm>
47
49#define RR APPEARANCE_CONTROLS_3D::APPEARANCE_SETTING_3D
50
53
54 // text id tooltip
55 RR( _HKI( "Board Body" ), LAYER_3D_BOARD, _HKI( "Show board body" ) ),
56 RR( _HKI( "Plated Barrels" ),LAYER_3D_PLATED_BARRELS, _HKI( "Show barrels of plated through-holes and vias" ) ),
57 RR( wxS( "F.Cu" ), LAYER_3D_COPPER_TOP, _HKI( "Show front copper / surface finish color" ) ),
58 RR( wxS( "B.Cu" ), LAYER_3D_COPPER_BOTTOM, _HKI( "Show back copper / surface finish color" ) ),
59 RR( _HKI( "Adhesive" ), LAYER_3D_ADHESIVE, _HKI( "Show adhesive" ) ),
60 RR( _HKI( "Solder Paste" ), LAYER_3D_SOLDERPASTE, _HKI( "Show solder paste" ) ),
61 RR( wxS( "F.Silkscreen" ), LAYER_3D_SILKSCREEN_TOP, _HKI( "Show front silkscreen" ) ),
62 RR( wxS( "B.Silkscreen" ), LAYER_3D_SILKSCREEN_BOTTOM, _HKI( "Show back silkscreen" ) ),
63 RR( wxS( "F.Mask" ), LAYER_3D_SOLDERMASK_TOP, _HKI( "Show front solder mask" ) ),
64 RR( wxS( "B.Mask" ), LAYER_3D_SOLDERMASK_BOTTOM, _HKI( "Show back solder mask" ) ),
65 RR( wxS( "User.Drawings" ), LAYER_3D_USER_DRAWINGS, _HKI( "Show user drawings layer" ) ),
66 RR( wxS( "User.Comments" ), LAYER_3D_USER_COMMENTS, _HKI( "Show user comments layer" ) ),
67 RR( wxS( "User.Eco1" ), LAYER_3D_USER_ECO1, _HKI( "Show user ECO1 layer" ) ),
68 RR( wxS( "User.Eco2" ), LAYER_3D_USER_ECO2, _HKI( "Show user ECO2 layer" ) ),
69 RR( wxS( "User.1" ), LAYER_3D_USER_1, _HKI( "Show user defined layer 1" ) ),
70 RR( wxS( "User.2" ), LAYER_3D_USER_2, _HKI( "Show user defined layer 2" ) ),
71 RR( wxS( "User.3" ), LAYER_3D_USER_3, _HKI( "Show user defined layer 3" ) ),
72 RR( wxS( "User.4" ), LAYER_3D_USER_4, _HKI( "Show user defined layer 4" ) ),
73 RR( wxS( "User.5" ), LAYER_3D_USER_5, _HKI( "Show user defined layer 5" ) ),
74 RR( wxS( "User.6" ), LAYER_3D_USER_6, _HKI( "Show user defined layer 6" ) ),
75 RR( wxS( "User.7" ), LAYER_3D_USER_7, _HKI( "Show user defined layer 7" ) ),
76 RR( wxS( "User.8" ), LAYER_3D_USER_8, _HKI( "Show user defined layer 8" ) ),
77 RR( wxS( "User.9" ), LAYER_3D_USER_9, _HKI( "Show user defined layer 9" ) ),
78 RR( wxS( "User.10" ), LAYER_3D_USER_10, _HKI( "Show user defined layer 10" ) ),
79 RR( wxS( "User.11" ), LAYER_3D_USER_11, _HKI( "Show user defined layer 11" ) ),
80 RR( wxS( "User.12" ), LAYER_3D_USER_12, _HKI( "Show user defined layer 12" ) ),
81 RR( wxS( "User.13" ), LAYER_3D_USER_13, _HKI( "Show user defined layer 13" ) ),
82 RR( wxS( "User.14" ), LAYER_3D_USER_14, _HKI( "Show user defined layer 14" ) ),
83 RR( wxS( "User.15" ), LAYER_3D_USER_15, _HKI( "Show user defined layer 15" ) ),
84 RR( wxS( "User.16" ), LAYER_3D_USER_16, _HKI( "Show user defined layer 16" ) ),
85 RR( wxS( "User.17" ), LAYER_3D_USER_17, _HKI( "Show user defined layer 17" ) ),
86 RR( wxS( "User.18" ), LAYER_3D_USER_18, _HKI( "Show user defined layer 18" ) ),
87 RR( wxS( "User.19" ), LAYER_3D_USER_19, _HKI( "Show user defined layer 19" ) ),
88 RR( wxS( "User.20" ), LAYER_3D_USER_20, _HKI( "Show user defined layer 20" ) ),
89 RR( wxS( "User.21" ), LAYER_3D_USER_21, _HKI( "Show user defined layer 21" ) ),
90 RR( wxS( "User.22" ), LAYER_3D_USER_22, _HKI( "Show user defined layer 22" ) ),
91 RR( wxS( "User.23" ), LAYER_3D_USER_23, _HKI( "Show user defined layer 23" ) ),
92 RR( wxS( "User.24" ), LAYER_3D_USER_24, _HKI( "Show user defined layer 24" ) ),
93 RR( wxS( "User.25" ), LAYER_3D_USER_25, _HKI( "Show user defined layer 25" ) ),
94 RR( wxS( "User.26" ), LAYER_3D_USER_26, _HKI( "Show user defined layer 26" ) ),
95 RR( wxS( "User.27" ), LAYER_3D_USER_27, _HKI( "Show user defined layer 27" ) ),
96 RR( wxS( "User.28" ), LAYER_3D_USER_28, _HKI( "Show user defined layer 28" ) ),
97 RR( wxS( "User.29" ), LAYER_3D_USER_29, _HKI( "Show user defined layer 29" ) ),
98 RR( wxS( "User.30" ), LAYER_3D_USER_30, _HKI( "Show user defined layer 30" ) ),
99 RR( wxS( "User.31" ), LAYER_3D_USER_31, _HKI( "Show user defined layer 31" ) ),
100 RR( wxS( "User.32" ), LAYER_3D_USER_32, _HKI( "Show user defined layer 32" ) ),
101 RR( wxS( "User.33" ), LAYER_3D_USER_33, _HKI( "Show user defined layer 33" ) ),
102 RR( wxS( "User.34" ), LAYER_3D_USER_34, _HKI( "Show user defined layer 34" ) ),
103 RR( wxS( "User.35" ), LAYER_3D_USER_35, _HKI( "Show user defined layer 35" ) ),
104 RR( wxS( "User.36" ), LAYER_3D_USER_36, _HKI( "Show user defined layer 36" ) ),
105 RR( wxS( "User.37" ), LAYER_3D_USER_37, _HKI( "Show user defined layer 37" ) ),
106 RR( wxS( "User.38" ), LAYER_3D_USER_38, _HKI( "Show user defined layer 38" ) ),
107 RR( wxS( "User.39" ), LAYER_3D_USER_39, _HKI( "Show user defined layer 39" ) ),
108 RR( wxS( "User.40" ), LAYER_3D_USER_40, _HKI( "Show user defined layer 40" ) ),
109 RR( wxS( "User.41" ), LAYER_3D_USER_41, _HKI( "Show user defined layer 41" ) ),
110 RR( wxS( "User.42" ), LAYER_3D_USER_42, _HKI( "Show user defined layer 42" ) ),
111 RR( wxS( "User.43" ), LAYER_3D_USER_43, _HKI( "Show user defined layer 43" ) ),
112 RR( wxS( "User.44" ), LAYER_3D_USER_44, _HKI( "Show user defined layer 44" ) ),
113 RR( wxS( "User.45" ), LAYER_3D_USER_45, _HKI( "Show user defined layer 45" ) ),
114 RR(),
115 RR( _HKI( "Through-hole Models" ), LAYER_3D_TH_MODELS, EDA_3D_ACTIONS::showTHT ),
119 RR( _HKI( "Models marked DNP" ), LAYER_3D_MODELS_MARKED_DNP, EDA_3D_ACTIONS::showDNP ),
120 RR( _HKI( "Model Bounding Boxes" ), LAYER_3D_BOUNDING_BOXES, EDA_3D_ACTIONS::showBBoxes ),
121 RR(),
122 RR( _HKI( "Values" ), LAYER_FP_VALUES, _HKI( "Show footprint values" ) ),
123 RR( _HKI( "References" ), LAYER_FP_REFERENCES, _HKI( "Show footprint references" ) ),
124 RR( _HKI( "Footprint Text" ), LAYER_FP_TEXT, _HKI( "Show all footprint text" ) ),
125 RR( _HKI( "Off-board Silkscreen" ), LAYER_3D_OFF_BOARD_SILK, _HKI( "Do not clip silk layers to board outline" ) ),
126 RR(),
128 RR( _HKI( "Background Start" ), LAYER_3D_BACKGROUND_TOP, _HKI( "Background gradient start color" ) ),
129 RR( _HKI( "Background End" ), LAYER_3D_BACKGROUND_BOTTOM, _HKI( "Background gradient end color" ) ),
130};
131
132// The list of IDs that can have colors coming from the board stackup, and cannot be
133// modified if use colors from stackup is activated
134static std::vector<int> inStackupColors{ LAYER_3D_BOARD,
139 };
140
143 m_frame( aParent ),
144 m_focusOwner( aFocusOwner ),
145 m_lastSelectedViewport( nullptr )
146{
147 DPI_SCALING_COMMON dpi( nullptr, m_frame );
148
149 int screenHeight = wxSystemSettings::GetMetric( wxSYS_SCREEN_Y );
150 m_pointSize = wxSystemSettings::GetFont( wxSYS_DEFAULT_GUI_FONT ).GetPointSize();
151
152 m_layerPanelColour = m_panelLayers->GetBackgroundColour().ChangeLightness( 110 );
153 SetBorders( true, false, false, false );
154
155 m_layersOuterSizer = new wxBoxSizer( wxVERTICAL );
157 m_windowLayers->SetScrollRate( 0, 5 );
158 m_windowLayers->Bind( wxEVT_SET_FOCUS, &APPEARANCE_CONTROLS_3D::OnSetFocus, this );
159
160 m_envOuterSizer = new wxBoxSizer( wxVERTICAL );
161
162 wxFont infoFont = KIUI::GetInfoFont( this );
163 m_panelLayers->SetFont( infoFont );
164 m_windowLayers->SetFont( infoFont );
165 m_presetsLabel->SetFont( infoFont );
166 m_viewportsLabel->SetFont( infoFont );
167
168 // Create display options
169 m_cbUseBoardStackupColors = new wxCheckBox( m_panelLayers, wxID_ANY,
170 _( "Use board stackup colors" ) );
171 m_cbUseBoardStackupColors->SetFont( infoFont );
172
173 m_cbUseBoardStackupColors->Bind( wxEVT_CHECKBOX,
174 [this]( wxCommandEvent& aEvent )
175 {
177 cfg->m_UseStackupColors = aEvent.IsChecked();
178
180 m_frame->NewDisplay( true );
181 } );
182
183 m_cbUseBoardEditorCopperColors = new wxCheckBox( m_panelLayers, wxID_ANY,
184 _( "Use PCB editor copper colors" ) );
185 m_cbUseBoardEditorCopperColors->SetFont( infoFont );
186 m_cbUseBoardEditorCopperColors->SetToolTip( _( "Use the board editor layer colors for copper "
187 "layers (realtime renderer only)" ) );
188
189 m_cbUseBoardEditorCopperColors->Bind( wxEVT_CHECKBOX,
190 [this]( wxCommandEvent& aEvent )
191 {
193 cfg->m_Render.use_board_editor_copper_colors = aEvent.IsChecked();
194
196 m_frame->NewDisplay( true );
197 } );
198
199 m_panelLayersSizer->Add( m_cbUseBoardStackupColors, 0, wxEXPAND | wxTOP | wxLEFT | wxRIGHT, 5 );
201 wxEXPAND | wxALL, 5 );
202
203 m_cbLayerPresets->SetToolTip( wxString::Format( _( "Save and restore color and visibility combinations.\n"
204 "Use %s+Tab to activate selector.\n"
205 "Successive Tabs while holding %s down will cycle through "
206 "presets in the popup." ),
209
210 m_cbViewports->SetToolTip( wxString::Format( _( "Save and restore camera position and zoom.\n"
211 "Use %s+Tab to activate selector.\n"
212 "Successive Tabs while holding %s down will cycle through "
213 "viewports in the popup." ),
216
217 if( screenHeight <= 900 && m_pointSize >= FromDIP( KIUI::c_IndicatorSizeDIP ) )
218 m_pointSize = m_pointSize * 8 / 10;
219
221
223 KiBitmapBundle( BITMAPS::visibility ), KiBitmapBundle( BITMAPS::visibility_off ) );
224
225 m_frame->Bind( EDA_LANG_CHANGED, &APPEARANCE_CONTROLS_3D::OnLanguageChanged, this );
226}
227
228
230{
231 m_frame->Unbind( EDA_LANG_CHANGED, &APPEARANCE_CONTROLS_3D::OnLanguageChanged, this );
232}
233
234
236{
237 DPI_SCALING_COMMON dpi( nullptr, m_frame );
238 wxSize size( 220 * dpi.GetScaleFactor(), 480 * dpi.GetScaleFactor() );
239 return size;
240}
241
242
243void APPEARANCE_CONTROLS_3D::OnSetFocus( wxFocusEvent& aEvent )
244{
245#ifdef __WXMSW__
246 // In wxMSW, buttons won't process events unless they have focus, so we'll let it take the
247 // focus and give it back to the parent in the button event handler.
248 if( wxBitmapButton* btn = dynamic_cast<wxBitmapButton*>( aEvent.GetEventObject() ) )
249 {
250 wxCommandEvent evt( wxEVT_BUTTON );
251 wxPostEvent( btn, evt );
252 }
253#endif
254
255 passOnFocus();
256 aEvent.Skip();
257}
258
259
260void APPEARANCE_CONTROLS_3D::OnSize( wxSizeEvent& aEvent )
261{
262 aEvent.Skip();
263}
264
265
267{
268 Freeze();
269
271 m_cbUseBoardStackupColors->SetLabel( _( "Use board stackup colors" ) );
274
275 Thaw();
276 Refresh();
277}
278
279
280void APPEARANCE_CONTROLS_3D::OnLanguageChanged( wxCommandEvent& aEvent )
281{
283
284 aEvent.Skip();
285}
286
287
289{
290 // This is essentially a list of hacks because DarkMode isn't yet implemented inside
291 // wxWidgets.
292 //
293 // The individual wxPanels, COLOR_SWATCHes and GRID_CELL_COLOR_RENDERERs should really be
294 // overriding some virtual method or responding to some wxWidgets event so that the parent
295 // doesn't have to know what it contains. But, that's not where we are, so... :shrug:
296
297 m_layerPanelColour = m_panelLayers->GetBackgroundColour().ChangeLightness( 110 );
298
299 m_windowLayers->SetBackgroundColour( m_layerPanelColour );
300
301 for( wxSizerItem* child : m_layersOuterSizer->GetChildren() )
302 {
303 if( child && child->GetWindow() )
304 child->GetWindow()->SetBackgroundColour( m_layerPanelColour );
305 }
306}
307
308
310{
312
314
315 const wxString& currentPreset = m_frame->GetAdapter().m_Cfg->m_CurrentPreset;
316
317 if( currentPreset == FOLLOW_PCB || currentPreset == FOLLOW_PLOT_SETTINGS )
318 updateLayerPresetWidget( currentPreset );
319 else
321}
322
323
324void APPEARANCE_CONTROLS_3D::ApplyLayerPreset( const wxString& aPresetName )
325{
326 doApplyLayerPreset( aPresetName );
327
328 // Move to front of MRU list
329 if( m_presetMRU.Index( aPresetName ) != wxNOT_FOUND )
330 m_presetMRU.Remove( aPresetName );
331
332 m_presetMRU.Insert( aPresetName, 0 );
333
334 updateLayerPresetWidget( aPresetName );
335}
336
337
338std::vector<VIEWPORT3D> APPEARANCE_CONTROLS_3D::GetUserViewports() const
339{
340 std::vector<VIEWPORT3D> ret;
341
342 for( const auto& [name, viewport] : m_viewports )
343 ret.emplace_back( viewport );
344
345 return ret;
346}
347
348
349void APPEARANCE_CONTROLS_3D::SetUserViewports( std::vector<VIEWPORT3D>& aViewportList )
350{
351 m_viewports.clear();
352
353 for( const VIEWPORT3D& viewport : aViewportList )
354 {
355 if( m_viewports.count( viewport.name ) )
356 continue;
357
358 m_viewports[viewport.name] = viewport;
359
360 m_viewportMRU.Add( viewport.name );
361 }
362
364
365 // Now is as good a time as any to initialize the layer presets as well.
367
368 m_presetMRU.Add( FOLLOW_PCB );
370
371 for( const LAYER_PRESET_3D& preset : m_frame->GetAdapter().m_Cfg->m_LayerPresets )
372 m_presetMRU.Add( preset.name );
373}
374
375
376void APPEARANCE_CONTROLS_3D::ApplyViewport( const wxString& aViewportName )
377{
378 int idx = m_cbViewports->FindString( aViewportName );
379
380 if( idx >= 0 && idx < (int)m_cbViewports->GetCount() - 3 /* separator */ )
381 {
382 m_cbViewports->SetSelection( idx );
383 m_lastSelectedViewport = static_cast<VIEWPORT3D*>( m_cbViewports->GetClientData( idx ) );
384 }
385 else
386 {
387 m_cbViewports->SetSelection( m_cbViewports->GetCount() - 3 ); // separator
388 m_lastSelectedViewport = nullptr;
389 }
390
393}
394
395
396void APPEARANCE_CONTROLS_3D::OnLayerVisibilityChanged( int aLayer, bool isVisible )
397{
398 std::bitset<LAYER_3D_END> visibleLayers = m_frame->GetAdapter().GetVisibleLayers();
399 const std::map<int, COLOR4D>& colors = m_frame->GetAdapter().GetLayerColors();
400 bool killFollow = false;
401 bool doFastRefresh = false; // true to just refresh the display
402
403 // Special-case controls
404 switch( aLayer )
405 {
406 case LAYER_FP_TEXT:
407 // Because Footprint Text is a meta-control that also can disable values/references,
408 // drag them along here so that the user is less likely to be confused.
409 if( !isVisible )
410 {
411 visibleLayers.set( LAYER_FP_REFERENCES, false );
412 visibleLayers.set( LAYER_FP_VALUES, false );
413 }
414
415 visibleLayers.set( LAYER_FP_TEXT, isVisible );
416 killFollow = true;
417 break;
418
420 case LAYER_FP_VALUES:
421 // In case that user changes Footprint Value/References when the Footprint Text
422 // meta-control is disabled, we should put it back on.
423 if( isVisible )
424 visibleLayers.set( LAYER_FP_TEXT, true );
425
426 visibleLayers.set( aLayer, isVisible );
427 killFollow = true;
428 break;
429
430 case LAYER_3D_BOARD:
444 visibleLayers.set( aLayer, isVisible );
445 killFollow = true;
446 break;
447
453 doFastRefresh = true;
454 visibleLayers.set( aLayer, isVisible );
455 break;
456
457 default:
458 visibleLayers.set( aLayer, isVisible );
459
460 if( aLayer >= LAYER_3D_USER_1 && aLayer <= LAYER_3D_USER_45 )
461 killFollow = true;
462
463 break;
464 }
465
466 m_frame->GetAdapter().SetVisibleLayers( visibleLayers );
467 m_frame->GetAdapter().SetLayerColors( colors );
468
469 const wxString& currentPreset = m_frame->GetAdapter().m_Cfg->m_CurrentPreset;
470
471 if( ( currentPreset != FOLLOW_PCB && currentPreset != FOLLOW_PLOT_SETTINGS ) || killFollow )
473
475
476 if( doFastRefresh && m_frame->GetAdapter().m_Cfg->m_Render.engine == RENDER_ENGINE::OPENGL )
477 {
478 RENDER_3D_OPENGL* renderer = static_cast<RENDER_3D_OPENGL*>( m_frame->GetCanvas()->GetCurrentRender() );
479 renderer->Load3dModelsIfNeeded();
481 }
482 else
483 {
484 m_frame->NewDisplay( true );
485 }
486}
487
488
490{
491 std::bitset<LAYER_3D_END> visibleLayers = m_frame->GetAdapter().GetVisibleLayers();
492 std::map<int, COLOR4D> colors = m_frame->GetAdapter().GetLayerColors();
493
494 m_frame->GetAdapter().SetVisibleLayers( visibleLayers );
495
496 int layer = aSwatch->GetId();
497 COLOR4D newColor = aSwatch->GetSwatchColor();
498
499 colors[ layer ] = newColor;
500
501 // The internals of the 3D viewer only supports a single color for copper, which must
502 // be applied to all copper layers.
503 COLOR_SWATCH* otherSwatch = nullptr;
504
505 const std::vector<int> copperIndices{
509 };
510
511 // If the changed swatch is one of the copper layers, we need to update the other copper layers
512 if( std::find( copperIndices.begin(), copperIndices.end(), layer ) != copperIndices.end() )
513 {
514 for( int index : copperIndices )
515 {
516 if( layer != index && colors.count( index ) )
517 {
518 colors[index] = newColor;
519 otherSwatch = m_layerSettingsMap[index]->m_Ctl_color;
520 }
521 }
522 }
523
524 if( otherSwatch )
525 {
526 // Don't send an event, because that will cause an event loop
527 otherSwatch->SetSwatchColor( newColor, false );
528 }
529
530
531 m_frame->GetAdapter().SetLayerColors( colors );
532
533 const wxString& currentPreset = m_frame->GetAdapter().m_Cfg->m_CurrentPreset;
534
535 if( currentPreset == FOLLOW_PCB || currentPreset == FOLLOW_PLOT_SETTINGS )
536 updateLayerPresetWidget( currentPreset );
537 else
539
540 m_frame->NewDisplay( true );
541}
542
543
545{
546 int swatchWidth = m_windowLayers->ConvertDialogToPixels( wxSize( 8, 0 ) ).x;
547
548 std::bitset<LAYER_3D_END> visibleLayers = m_frame->GetAdapter().GetVisibleLayers();
549 std::map<int, COLOR4D> colors = m_frame->GetAdapter().GetLayerColors();
550 std::map<int, COLOR4D> defaultColors = m_frame->GetAdapter().GetDefaultColors();
551 LSET enabled = m_frame->GetBoard()->GetEnabledLayers();
552
553 m_layerSettings.clear();
554 m_layersOuterSizer->Clear( true );
555 m_layersOuterSizer->AddSpacer( 5 );
556
557 m_envOuterSizer->Clear( true );
558
559 auto appendLayer =
560 [&]( const std::unique_ptr<APPEARANCE_SETTING_3D>& aSetting )
561 {
562 wxBoxSizer* sizer = new wxBoxSizer( wxHORIZONTAL );
563 int layer = aSetting->m_Id;
564
565 aSetting->m_Visible = visibleLayers.test( layer );
566
567 if( colors.count( layer ) )
568 {
569 COLOR_SWATCH* swatch = new COLOR_SWATCH( m_windowLayers, colors[ layer ], layer,
570 COLOR4D::WHITE, defaultColors[ layer ],
571 SWATCH_SMALL );
572 swatch->SetToolTip( _( "Left double click or middle click to change color" ) );
573
574 swatch->SetReadOnlyCallback(
575 [this]()
576 {
577 WX_INFOBAR* infobar = m_frame->GetInfoBar();
578
579 infobar->RemoveAllButtons();
580 infobar->AddCloseButton();
581
582 infobar->ShowMessageFor( _( "Uncheck 'Use board stackup colors' to "
583 "allow color editing." ),
584 10000, wxICON_INFORMATION );
585 } );
586
587 sizer->Add( swatch, 0, wxALIGN_CENTER_VERTICAL, 0 );
588 aSetting->m_Ctl_color = swatch;
589
590 swatch->Bind( COLOR_SWATCH_CHANGED,
591 [this]( wxCommandEvent& event )
592 {
593 auto swatch = static_cast<COLOR_SWATCH*>( event.GetEventObject() );
594 onColorSwatchChanged( swatch );
595
596 passOnFocus();
597 } );
598 }
599 else
600 {
601 sizer->AddSpacer( swatchWidth );
602 }
603
604 sizer->AddSpacer( 5 );
605
606 wxString layerName = aSetting->GetLabel();
607 PCB_LAYER_ID boardLayer = Map3DLayerToPCBLayer( layer );
608
609 if( boardLayer != UNDEFINED_LAYER )
610 layerName = m_frame->GetBoard()->GetLayerName( boardLayer );
611
612 wxStaticText* label = new wxStaticText( m_windowLayers, layer, layerName );
613 label->Wrap( -1 );
614 label->SetToolTip( aSetting->GetTooltip() );
615
616 if( layer == LAYER_3D_BACKGROUND_TOP || layer == LAYER_3D_BACKGROUND_BOTTOM )
617 {
618 sizer->AddSpacer( swatchWidth );
619 }
620 else
621 {
622 BITMAP_TOGGLE* btn_visible = new BITMAP_TOGGLE( m_windowLayers, layer,
623 KiBitmapBundle( BITMAPS::visibility ),
624 KiBitmapBundle( BITMAPS::visibility_off ),
625 aSetting->m_Visible );
626
627 btn_visible->Bind( TOGGLE_CHANGED,
628 [this]( wxCommandEvent& aEvent )
629 {
630 int id = static_cast<wxWindow*>( aEvent.GetEventObject() )->GetId();
631 bool isVisible = aEvent.GetInt();
632 OnLayerVisibilityChanged( id, isVisible );
633
634 passOnFocus();
635 } );
636
637 wxString tip;
638 tip.Printf( _( "Show or hide %s" ), aSetting->GetLabel().Lower() );
639 btn_visible->SetToolTip( tip );
640
641 aSetting->m_Ctl_visibility = btn_visible;
642 sizer->Add( btn_visible, 0, wxALIGN_CENTER_VERTICAL, 0 );
643 }
644
645 sizer->AddSpacer( 5 );
646 sizer->Add( label, 0, wxALIGN_CENTER_VERTICAL, 0 );
647
648 m_layersOuterSizer->Add( sizer, 0, wxEXPAND | wxLEFT | wxRIGHT, 5 );
649 m_layersOuterSizer->AddSpacer( 2 );
650 };
651
652 for( const APPEARANCE_SETTING_3D& s_setting : s_layerSettings )
653 {
654 m_layerSettings.emplace_back( std::make_unique<APPEARANCE_SETTING_3D>( s_setting ) );
655 std::unique_ptr<APPEARANCE_SETTING_3D>& setting = m_layerSettings.back();
656
657 if( setting->m_Spacer )
658 {
659 m_layersOuterSizer->AddSpacer( m_pointSize );
660 }
661 else if( setting->m_Id >= LAYER_3D_USER_1 && setting->m_Id <= LAYER_3D_USER_45 )
662 {
663 if( enabled.test( Map3DLayerToPCBLayer( setting->m_Id ) ) )
664 appendLayer( setting );
665 }
666 else
667 {
668 appendLayer( setting );
669 }
670
671 m_layerSettingsMap[setting->m_Id] = setting.get();
672 }
673
674 m_sizerOuter->Layout();
675}
676
677
679{
681 std::bitset<LAYER_3D_END> visibleLayers = m_frame->GetAdapter().GetVisibleLayers();
682 std::map<int, COLOR4D> colors = m_frame->GetAdapter().GetLayerColors();
683
684 for( std::unique_ptr<APPEARANCE_SETTING_3D>& setting : m_layerSettings )
685 {
686 if( setting->m_Spacer )
687 continue;
688
689 if( setting->m_Ctl_visibility )
690 setting->m_Ctl_visibility->SetValue( visibleLayers.test( setting->m_Id ) );
691
692 if( setting->m_Ctl_color )
693 {
694 setting->m_Ctl_color->SetSwatchColor( colors[ setting->m_Id ], false );
695
696 // if cfg->m_UseStackupColors is set, board colors cannot be modified locally, but
697 // other colors can be
698 if( alg::contains( inStackupColors, setting->m_Id ) && cfg )
699 setting->m_Ctl_color->SetReadOnly( cfg->m_UseStackupColors );
700 }
701 }
702
703 if( cfg )
704 {
707 }
708}
709
710
712{
713 m_presetsLabel->SetLabel( wxString::Format( _( "Presets (%s+Tab):" ),
715
716 m_cbLayerPresets->Clear();
717
718 // Build the layers preset list.
719
720 m_cbLayerPresets->Append( _( "Follow PCB Editor" ) );
721 m_cbLayerPresets->Append( _( "Follow PCB Plot Settings" ) );
722
723 for( const LAYER_PRESET_3D& preset : m_frame->GetAdapter().m_Cfg->m_LayerPresets )
724 m_cbLayerPresets->Append( preset.name );
725
726 m_cbLayerPresets->Append( wxT( "---" ) );
727 m_cbLayerPresets->Append( _( "Save preset..." ) );
728 m_cbLayerPresets->Append( _( "Delete preset..." ) );
729
731}
732
733
735{
736 m_frame->GetAdapter().m_Cfg->m_CurrentPreset = wxEmptyString;
737
738 std::vector<LAYER_PRESET_3D>& presets = m_frame->GetAdapter().m_Cfg->m_LayerPresets;
739 std::bitset<LAYER_3D_END> visibleLayers = m_frame->GetAdapter().GetVisibleLayers();
740 std::map<int, COLOR4D> colors = m_frame->GetAdapter().GetLayerColors();
741
742 auto it = std::find_if(
743 presets.begin(), presets.end(),
744 [&]( const LAYER_PRESET_3D& aPreset )
745 {
746 if( aPreset.name.Lower() == _( "legacy colors" ) && m_cbUseBoardStackupColors->GetValue() )
747 return false;
748
749 for( int layer = LAYER_3D_BOARD; layer < LAYER_3D_END; ++layer )
750 {
751 if( aPreset.layers.test( layer ) != visibleLayers.test( layer ) )
752 return false;
753 }
754
755 for( int layer : { LAYER_FP_REFERENCES, LAYER_FP_VALUES, LAYER_FP_TEXT } )
756 {
757 if( aPreset.layers.test( layer ) != visibleLayers.test( layer ) )
758 return false;
759 }
760
761 for( int layer = LAYER_3D_START + 1; layer < LAYER_3D_END; ++layer )
762 {
763 auto it1 = aPreset.colors.find( layer );
764 auto it2 = colors.find( layer );
765
766 if( it1 != aPreset.colors.end() && it2 != colors.end() && *it1 != *it2 )
767 return false;
768 }
769
770 return true;
771 } );
772
773 if( it != presets.end() )
774 {
775 m_frame->GetAdapter().m_Cfg->m_CurrentPreset = it->name;
776 m_cbLayerPresets->SetStringSelection( it->name );
777 }
778 else
779 {
780 m_cbLayerPresets->SetSelection( m_cbLayerPresets->GetCount() - 3 ); // separator
781 }
782}
783
784
786{
787 if( aName == FOLLOW_PCB )
788 m_cbLayerPresets->SetSelection( 0 );
789 else if( aName == FOLLOW_PLOT_SETTINGS )
790 m_cbLayerPresets->SetSelection( 1 );
791 else if( !m_cbLayerPresets->SetStringSelection( aName ) )
792 m_cbLayerPresets->SetSelection( m_cbLayerPresets->GetCount() - 3 ); // separator
793}
794
795
797{
799 int count = m_cbLayerPresets->GetCount();
800 int index = m_cbLayerPresets->GetSelection();
801 wxString name;
802
803 auto resetSelection =
804 [&]()
805 {
807 };
808
809 if( index == 0 )
810 {
812 }
813 else if( index == 1 )
814 {
816 }
817 else if( index == count - 3 )
818 {
819 // Separator: reject the selection
820 resetSelection();
821 return;
822 }
823 else if( index == count - 2 )
824 {
825 wxTextEntryDialog dlg( wxGetTopLevelParent( this ), _( "Layer preset name:" ),
826 _( "Save Layer Preset" ) );
827
828 if( dlg.ShowModal() != wxID_OK )
829 {
830 resetSelection();
831 return;
832 }
833
834 std::bitset<LAYER_3D_END> visibleLayers = m_frame->GetAdapter().GetVisibleLayers();
835 std::map<int, COLOR4D> colors = m_frame->GetAdapter().GetLayerColors();
836
837 name = dlg.GetValue();
838
839 if( LAYER_PRESET_3D* preset = cfg->FindPreset( name ) )
840 {
841 if( !IsOK( wxGetTopLevelParent( this ), _( "Overwrite existing preset?" ) ) )
842 {
843 resetSelection();
844 return;
845 }
846
847 preset->layers = visibleLayers;
848 preset->colors = colors;
849 m_cbLayerPresets->SetSelection( m_cbLayerPresets->FindString( name ) );
850 }
851 else
852 {
853 cfg->m_LayerPresets.emplace_back( name, visibleLayers, colors );
854 m_cbLayerPresets->SetSelection( m_cbLayerPresets->Insert( name, index - 1 ) );
855 }
856
857 cfg->m_CurrentPreset = name;
858 m_presetMRU.Insert( name, 0 );
859
860 return;
861 }
862 else if( index == count - 1 )
863 {
864 wxArrayString headers;
865 std::vector<wxArrayString> items;
866
867 headers.Add( _( "Presets" ) );
868
869 for( LAYER_PRESET_3D& preset : cfg->m_LayerPresets )
870 {
871 wxArrayString item;
872 item.Add( preset.name );
873 items.emplace_back( item );
874 }
875
876 EDA_LIST_DIALOG dlg( m_frame, _( "Delete Preset" ), headers, items );
877 dlg.SetListLabel( _( "Select preset:" ) );
878
879 if( dlg.ShowModal() == wxID_OK )
880 {
881 name = dlg.GetTextSelection();
882
883 if( m_cbLayerPresets->FindString( name ) != wxNOT_FOUND )
884 m_cbLayerPresets->Delete( m_cbLayerPresets->FindString( name ) );
885
886 std::erase_if( cfg->m_LayerPresets,
887 [name]( const LAYER_PRESET_3D& preset )
888 {
889 return preset.name == name;
890 } );
891
892 if( cfg->m_CurrentPreset == name )
893 cfg->m_CurrentPreset = wxEmptyString;
894
895 if( m_presetMRU.Index( name ) >= 0 )
896 m_presetMRU.Remove( name );
897 }
898
899 resetSelection();
900 return;
901 }
902 else
903 {
904 doApplyLayerPreset( m_cbLayerPresets->GetStringSelection() );
905 }
906
907 // Move to front of MRU list
908 if( m_presetMRU.Index( name ) != wxNOT_FOUND )
909 m_presetMRU.Remove( name );
910
911 m_presetMRU.Insert( name, 0 );
912
913 passOnFocus();
914}
915
916
917void APPEARANCE_CONTROLS_3D::doApplyLayerPreset( const wxString& aPresetName )
918{
919 BOARD_ADAPTER& adapter = m_frame->GetAdapter();
920
921 if( aPresetName == FOLLOW_PCB || aPresetName == FOLLOW_PLOT_SETTINGS )
922 {
923 adapter.m_Cfg->m_CurrentPreset = aPresetName;
924 adapter.SetVisibleLayers( adapter.GetVisibleLayers() );
925 }
926 else if( LAYER_PRESET_3D* preset = adapter.m_Cfg->FindPreset( aPresetName ) )
927 {
928 adapter.m_Cfg->m_CurrentPreset = aPresetName;
929 adapter.SetVisibleLayers( preset->layers );
930 adapter.SetLayerColors( preset->colors );
931
932 if( preset->name.Lower() == _( "legacy colors" ) )
933 adapter.m_Cfg->m_UseStackupColors = false;
934 }
935 else
936 {
937 return;
938 }
939
941 m_frame->NewDisplay( true );
942}
943
944
946{
947 m_viewportsLabel->SetLabel( wxString::Format( _( "Viewports (%s+Tab):" ),
949
950 m_cbViewports->Clear();
951
952 for( std::pair<const wxString, VIEWPORT3D>& pair : m_viewports )
953 m_cbViewports->Append( pair.first, static_cast<void*>( &pair.second ) );
954
955 m_cbViewports->Append( wxT( "---" ) );
956 m_cbViewports->Append( _( "Save viewport..." ) );
957 m_cbViewports->Append( _( "Delete viewport..." ) );
958
959 m_cbViewports->SetSelection( m_cbViewports->GetCount() - 3 );
960 m_lastSelectedViewport = nullptr;
961}
962
963
964void APPEARANCE_CONTROLS_3D::onViewportChanged( wxCommandEvent& aEvent )
965{
966 int count = m_cbViewports->GetCount();
967 int index = m_cbViewports->GetSelection();
968
969 if( index >= 0 && index < count - 3 )
970 {
971 VIEWPORT3D* viewport = static_cast<VIEWPORT3D*>( m_cbViewports->GetClientData( index ) );
972
973 wxCHECK( viewport, /* void */ );
974
975 doApplyViewport( *viewport );
976
977 if( !viewport->name.IsEmpty() )
978 {
979 if( m_viewportMRU.Index( viewport->name ) != wxNOT_FOUND )
980 m_viewportMRU.Remove( viewport->name );
981
982 m_viewportMRU.Insert( viewport->name, 0 );
983 }
984 }
985 else if( index == count - 2 )
986 {
987 // Save current state to new preset
988 wxString name;
989
990 wxTextEntryDialog dlg( wxGetTopLevelParent( this ), _( "Viewport name:" ),
991 _( "Save Viewport" ), name );
992
993 if( dlg.ShowModal() != wxID_OK )
994 {
996 m_cbViewports->SetStringSelection( m_lastSelectedViewport->name );
997 else
998 m_cbViewports->SetSelection( m_cbViewports->GetCount() - 3 );
999
1000 return;
1001 }
1002
1003 name = dlg.GetValue();
1004 bool exists = m_viewports.count( name );
1005
1006 if( !exists )
1007 {
1009
1010 index = m_cbViewports->Insert( name, index-1, static_cast<void*>( &m_viewports[name] ) );
1011 }
1012 else
1013 {
1015 index = m_cbViewports->FindString( name );
1016
1017 if( m_viewportMRU.Index( name ) != wxNOT_FOUND )
1018 m_viewportMRU.Remove( name );
1019 }
1020
1021 m_cbViewports->SetSelection( index );
1022 m_viewportMRU.Insert( name, 0 );
1023
1024 return;
1025 }
1026 else if( index == count - 1 )
1027 {
1028 // Delete an existing viewport
1029 wxArrayString headers;
1030 std::vector<wxArrayString> items;
1031
1032 headers.Add( _( "Viewports" ) );
1033
1034 for( std::pair<const wxString, VIEWPORT3D>& pair : m_viewports )
1035 {
1036 wxArrayString item;
1037 item.Add( pair.first );
1038 items.emplace_back( item );
1039 }
1040
1041 EDA_LIST_DIALOG dlg( m_frame, _( "Delete Viewport" ), headers, items );
1042 dlg.SetListLabel( _( "Select viewport:" ) );
1043
1044 if( dlg.ShowModal() == wxID_OK )
1045 {
1046 wxString viewportName = dlg.GetTextSelection();
1047 int idx = m_cbViewports->FindString( viewportName );
1048
1049 if( idx != wxNOT_FOUND )
1050 {
1051 m_viewports.erase( viewportName );
1052 m_cbViewports->Delete( idx );
1053 }
1054
1055 if( m_viewportMRU.Index( viewportName ) != wxNOT_FOUND )
1056 m_viewportMRU.Remove( viewportName );
1057 }
1058
1060 m_cbViewports->SetStringSelection( m_lastSelectedViewport->name );
1061 else
1062 m_cbViewports->SetSelection( m_cbViewports->GetCount() - 3 );
1063
1064 return;
1065 }
1066
1067 passOnFocus();
1068}
1069
1070
1071void APPEARANCE_CONTROLS_3D::onUpdateViewportsCb( wxUpdateUIEvent& aEvent )
1072{
1073 int count = m_cbViewports->GetCount();
1074 int index = m_cbViewports->GetSelection();
1075
1076 if( index >= 0 && index < count - 3 )
1077 {
1078 VIEWPORT3D* viewport = static_cast<VIEWPORT3D*>( m_cbViewports->GetClientData( index ) );
1079
1080 wxCHECK( viewport, /* void */ );
1081
1082 if( m_frame->GetCurrentCamera().GetViewMatrix() != viewport->matrix )
1083 m_cbViewports->SetSelection( -1 );
1084 }
1085}
1086
1087
1089{
1091
1092 if( m_frame->GetAdapter().m_Cfg->m_Render.engine == RENDER_ENGINE::OPENGL )
1094 else
1096}
1097
1098
1100{
1101 m_focusOwner->SetFocus();
1102}
const char * name
Definition: DXF_plotter.cpp:62
static std::vector< int > inStackupColors
#define RR
Render Row abbreviation to reduce source width.
wxBitmapBundle KiBitmapBundle(BITMAPS aBitmap, int aMinHeight)
Definition: bitmap.cpp:110
Container for an appearance setting (can control a layer class, object type, etc.)
Class APPEARANCE_CONTROLS_3D_BASE.
void OnLanguageChanged(wxCommandEvent &aEvent)
GRID_BITMAP_TOGGLE_RENDERER * m_toggleGridRenderer
void onLayerPresetChanged(wxCommandEvent &aEvent) override
void updateLayerPresetWidget(const wxString &aName)
std::vector< VIEWPORT3D > GetUserViewports() const
Return a list of viewports created by the user.
void ApplyViewport(const wxString &aPresetName)
void onColorSwatchChanged(COLOR_SWATCH *aSwatch)
APPEARANCE_CONTROLS_3D(EDA_3D_VIEWER_FRAME *aParent, wxWindow *aFocusOwner)
std::vector< std::unique_ptr< APPEARANCE_SETTING_3D > > m_layerSettings
std::map< int, APPEARANCE_SETTING_3D * > m_layerSettingsMap
static const APPEARANCE_SETTING_3D s_layerSettings[]
Template for object appearance settings.
void doApplyLayerPreset(const wxString &aPresetName)
EDA_3D_VIEWER_FRAME * m_frame
void onUpdateViewportsCb(wxUpdateUIEvent &aEvent) override
void OnSetFocus(wxFocusEvent &aEvent) override
void OnLayerVisibilityChanged(int aLayer, bool isVisible)
void OnSize(wxSizeEvent &aEvent) override
void doApplyViewport(const VIEWPORT3D &aViewport)
std::map< wxString, VIEWPORT3D > m_viewports
wxCheckBox * m_cbUseBoardEditorCopperColors
void ApplyLayerPreset(const wxString &aPresetName)
void onViewportChanged(wxCommandEvent &aEvent) override
void SetUserViewports(std::vector< VIEWPORT3D > &aPresetList)
Update the current viewports from those saved in the project file.
A checkbox control except with custom bitmaps for the checked and unchecked states.
Definition: bitmap_toggle.h:45
Helper class to handle information needed to display 3D board.
Definition: board_adapter.h:73
void SetVisibleLayers(const std::bitset< LAYER_3D_END > &aLayers)
std::map< int, COLOR4D > GetLayerColors() const
Build a color list which is used to store colors layers.
std::bitset< LAYER_3D_END > GetVisibleLayers() const
void SetLayerColors(const std::map< int, COLOR4D > &aColors)
EDA_3D_VIEWER_SETTINGS * m_Cfg
std::map< int, COLOR4D > GetDefaultColors() const
const wxString GetLayerName(PCB_LAYER_ID aLayer) const
Return the name of a aLayer.
Definition: board.cpp:680
const LSET & GetEnabledLayers() const
A proxy function that calls the corresponding function in m_BoardSettings.
Definition: board.cpp:907
const glm::mat4 & GetViewMatrix() const
Definition: camera.cpp:510
void SetViewMatrix(glm::mat4 aViewMatrix)
Set the affine matrix to be applied to a transformation camera.
Definition: camera.cpp:516
A simple color swatch of the kind used to set layer colors.
Definition: color_swatch.h:57
void SetSwatchColor(const KIGFX::COLOR4D &aColor, bool aSendEvent)
Set the current swatch color directly.
KIGFX::COLOR4D GetSwatchColor() const
void SetReadOnlyCallback(std::function< void()> aCallback)
Register a handler for when the user tries to interact with a read-only swatch.
Definition: color_swatch.h:126
int ShowModal() override
Class to handle configuration and automatic determination of the DPI scale to use for canvases.
double GetScaleFactor() const override
Get the DPI scale from all known sources in order:
static TOOL_ACTION showNavigator
static TOOL_ACTION showNotInPosFile
static TOOL_ACTION showTHT
static TOOL_ACTION showDNP
static TOOL_ACTION showSMD
static TOOL_ACTION showVirtual
static TOOL_ACTION showBBoxes
RENDER_3D_BASE * GetCurrentRender() const
void RenderRaytracingRequest()
Request to render the current view in Raytracing mode.
void Request_refresh(bool aRedrawImmediately=true)
Schedule a refresh update of the canvas.
Create and handle a window for the 3d viewer connected to a Kiway and a pcbboard.
void NewDisplay(bool aForceImmediateRedraw=false)
Reload and refresh (rebuild) the 3D scene.
EDA_3D_CANVAS * GetCanvas()
BOARD_ADAPTER & GetAdapter()
LAYER_PRESET_3D * FindPreset(const wxString &aName)
std::vector< LAYER_PRESET_3D > m_LayerPresets
WX_INFOBAR * GetInfoBar()
A dialog which shows:
wxString GetTextSelection(int aColumn=0)
Return the selected text from aColumn in the wxListCtrl in the dialog.
void SetListLabel(const wxString &aLabel)
A toggle button renderer for a wxGrid, similar to BITMAP_TOGGLE.
A color representation with 4 components: red, green, blue, alpha.
Definition: color4d.h:104
LSET is a set of PCB_LAYER_IDs.
Definition: lset.h:37
Object to render the board using openGL.
void Load3dModelsIfNeeded()
Load footprint models if they are not already loaded, i.e.
A modified version of the wxInfoBar class that allows us to:
Definition: wx_infobar.h:76
void RemoveAllButtons()
Remove all the buttons that have been added by the user.
Definition: wx_infobar.cpp:371
void ShowMessageFor(const wxString &aMessage, int aTime, int aFlags=wxICON_INFORMATION, MESSAGE_TYPE aType=WX_INFOBAR::MESSAGE_TYPE::GENERIC)
Show the infobar with the provided message and icon for a specific period of time.
Definition: wx_infobar.cpp:142
void AddCloseButton(const wxString &aTooltip=_("Hide this message."))
Add the default close button to the infobar on the right side.
Definition: wx_infobar.cpp:361
void SetBorders(bool aLeft, bool aRight, bool aTop, bool aBottom)
Definition: wx_panel.h:39
@ SWATCH_SMALL
Definition: color_swatch.h:40
bool IsOK(wxWindow *aParent, const wxString &aMessage)
Display a yes/no dialog with aMessage and returns the user response.
Definition: confirm.cpp:251
This file is part of the common library.
#define _HKI(x)
#define _(s)
Declaration of the eda_3d_viewer class.
#define FOLLOW_PLOT_SETTINGS
#define FOLLOW_PCB
#define VIEWPORT_SWITCH_KEY
#define PRESET_SWITCH_KEY
wxString KeyNameFromKeyCode(int aKeycode, bool *aIsFound)
Return the key name from the key code.
PCB_LAYER_ID Map3DLayerToPCBLayer(int aLayer)
Definition: layer_id.cpp:266
@ LAYER_3D_USER_1
Definition: layer_ids.h:555
@ LAYER_3D_SOLDERMASK_TOP
Definition: layer_ids.h:548
@ LAYER_3D_USER_8
Definition: layer_ids.h:562
@ LAYER_3D_USER_22
Definition: layer_ids.h:576
@ LAYER_3D_USER_44
Definition: layer_ids.h:598
@ LAYER_3D_USER_23
Definition: layer_ids.h:577
@ LAYER_3D_NAVIGATOR
Definition: layer_ids.h:605
@ LAYER_3D_USER_28
Definition: layer_ids.h:582
@ LAYER_3D_BOUNDING_BOXES
Definition: layer_ids.h:606
@ LAYER_3D_START
Definition: layer_ids.h:538
@ LAYER_3D_USER_32
Definition: layer_ids.h:586
@ LAYER_3D_USER_19
Definition: layer_ids.h:573
@ LAYER_3D_USER_25
Definition: layer_ids.h:579
@ LAYER_3D_ADHESIVE
Definition: layer_ids.h:550
@ LAYER_3D_USER_3
Definition: layer_ids.h:557
@ LAYER_3D_USER_21
Definition: layer_ids.h:575
@ LAYER_3D_USER_26
Definition: layer_ids.h:580
@ LAYER_3D_SMD_MODELS
Definition: layer_ids.h:601
@ LAYER_3D_USER_24
Definition: layer_ids.h:578
@ LAYER_3D_USER_43
Definition: layer_ids.h:597
@ LAYER_3D_BACKGROUND_TOP
Definition: layer_ids.h:541
@ LAYER_3D_USER_COMMENTS
Definition: layer_ids.h:551
@ LAYER_3D_SOLDERMASK_BOTTOM
Definition: layer_ids.h:547
@ LAYER_3D_USER_11
Definition: layer_ids.h:565
@ LAYER_3D_USER_41
Definition: layer_ids.h:595
@ LAYER_3D_USER_17
Definition: layer_ids.h:571
@ LAYER_3D_BOARD
Definition: layer_ids.h:542
@ LAYER_3D_PLATED_BARRELS
Definition: layer_ids.h:608
@ LAYER_3D_USER_ECO1
Definition: layer_ids.h:553
@ LAYER_3D_USER_20
Definition: layer_ids.h:574
@ LAYER_3D_USER_31
Definition: layer_ids.h:585
@ LAYER_3D_USER_ECO2
Definition: layer_ids.h:554
@ LAYER_3D_TH_MODELS
Definition: layer_ids.h:600
@ LAYER_3D_USER_15
Definition: layer_ids.h:569
@ LAYER_3D_USER_38
Definition: layer_ids.h:592
@ LAYER_3D_USER_13
Definition: layer_ids.h:567
@ LAYER_3D_USER_33
Definition: layer_ids.h:587
@ LAYER_3D_USER_35
Definition: layer_ids.h:589
@ LAYER_3D_USER_29
Definition: layer_ids.h:583
@ LAYER_3D_USER_40
Definition: layer_ids.h:594
@ LAYER_3D_SILKSCREEN_TOP
Definition: layer_ids.h:546
@ LAYER_3D_VIRTUAL_MODELS
Definition: layer_ids.h:602
@ LAYER_3D_MODELS_MARKED_DNP
Definition: layer_ids.h:604
@ LAYER_3D_USER_7
Definition: layer_ids.h:561
@ LAYER_3D_COPPER_TOP
Definition: layer_ids.h:543
@ LAYER_3D_USER_12
Definition: layer_ids.h:566
@ LAYER_3D_SOLDERPASTE
Definition: layer_ids.h:549
@ LAYER_3D_USER_30
Definition: layer_ids.h:584
@ LAYER_3D_USER_36
Definition: layer_ids.h:590
@ LAYER_3D_USER_2
Definition: layer_ids.h:556
@ LAYER_3D_USER_18
Definition: layer_ids.h:572
@ LAYER_3D_OFF_BOARD_SILK
Definition: layer_ids.h:607
@ LAYER_3D_USER_14
Definition: layer_ids.h:568
@ LAYER_3D_USER_5
Definition: layer_ids.h:559
@ LAYER_3D_USER_37
Definition: layer_ids.h:591
@ LAYER_3D_USER_10
Definition: layer_ids.h:564
@ LAYER_3D_MODELS_NOT_IN_POS
Definition: layer_ids.h:603
@ LAYER_3D_USER_42
Definition: layer_ids.h:596
@ LAYER_3D_USER_45
Definition: layer_ids.h:599
@ LAYER_3D_USER_6
Definition: layer_ids.h:560
@ LAYER_3D_USER_4
Definition: layer_ids.h:558
@ LAYER_3D_USER_27
Definition: layer_ids.h:581
@ LAYER_3D_USER_DRAWINGS
Definition: layer_ids.h:552
@ LAYER_3D_COPPER_BOTTOM
Definition: layer_ids.h:544
@ LAYER_3D_USER_39
Definition: layer_ids.h:593
@ LAYER_3D_USER_9
Definition: layer_ids.h:563
@ LAYER_3D_BACKGROUND_BOTTOM
Definition: layer_ids.h:540
@ LAYER_3D_USER_16
Definition: layer_ids.h:570
@ LAYER_3D_SILKSCREEN_BOTTOM
Definition: layer_ids.h:545
@ LAYER_3D_USER_34
Definition: layer_ids.h:588
@ LAYER_3D_END
Definition: layer_ids.h:610
@ LAYER_FP_REFERENCES
Show footprints references (when texts are visible).
Definition: layer_ids.h:265
@ LAYER_FP_TEXT
Definition: layer_ids.h:239
@ LAYER_FP_VALUES
Show footprints values (when texts are visible).
Definition: layer_ids.h:262
PCB_LAYER_ID
A quick note on layer IDs:
Definition: layer_ids.h:60
@ UNDEFINED_LAYER
Definition: layer_ids.h:61
KICOMMON_API wxFont GetInfoFont(wxWindow *aWindow)
Definition: ui_common.cpp:156
const int c_IndicatorSizeDIP
Definition: ui_common.h:52
bool contains(const _Container &__container, _Value __value)
Returns true if the container contains the given value.
Definition: kicad_algo.h:100
void Refresh()
Update the board display after modifying it by a python script (note: it is automatically called by a...
see class PGM_BASE
wxString name
A name for this layer set.