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