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
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
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 {
176 EDA_3D_VIEWER_SETTINGS* cfg = m_frame->GetAdapter().m_Cfg;
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 {
192 EDA_3D_VIEWER_SETTINGS* cfg = m_frame->GetAdapter().m_Cfg;
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
224
225 m_frame->Bind( EDA_LANG_CHANGED, &APPEARANCE_CONTROLS_3D::OnLanguageChanged, this );
226}
227
228
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();
480 m_frame->GetCanvas()->Request_refresh();
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,
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{
680 EDA_3D_VIEWER_SETTINGS* cfg = m_frame->GetAdapter().m_Cfg;
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 if( !m_frame->GetAdapter().m_Cfg->m_LayerPresets.empty() )
724 m_cbLayerPresets->Append( wxT( "---" ) );
725
726 for( const LAYER_PRESET_3D& preset : m_frame->GetAdapter().m_Cfg->m_LayerPresets )
727 m_cbLayerPresets->Append( preset.name );
728
729 m_cbLayerPresets->Append( wxT( "---" ) );
730 m_cbLayerPresets->Append( _( "Save preset..." ) );
731 m_cbLayerPresets->Append( _( "Delete preset..." ) );
732
733 if( aReset )
734 updateLayerPresetWidget( m_frame->GetAdapter().m_Cfg->m_CurrentPreset );
735}
736
737
739{
740 m_frame->GetAdapter().m_Cfg->m_CurrentPreset = wxEmptyString;
741
742 std::vector<LAYER_PRESET_3D>& presets = m_frame->GetAdapter().m_Cfg->m_LayerPresets;
743 std::bitset<LAYER_3D_END> visibleLayers = m_frame->GetAdapter().GetVisibleLayers();
744 std::map<int, COLOR4D> colors = m_frame->GetAdapter().GetLayerColors();
745
746 auto it = std::find_if(
747 presets.begin(), presets.end(),
748 [&]( const LAYER_PRESET_3D& aPreset )
749 {
750 if( aPreset.name.Lower() == _( "legacy colors" ) && m_cbUseBoardStackupColors->GetValue() )
751 return false;
752
753 for( int layer = LAYER_3D_BOARD; layer < LAYER_3D_END; ++layer )
754 {
755 if( aPreset.layers.test( layer ) != visibleLayers.test( layer ) )
756 return false;
757 }
758
759 for( int layer : { LAYER_FP_REFERENCES, LAYER_FP_VALUES, LAYER_FP_TEXT } )
760 {
761 if( aPreset.layers.test( layer ) != visibleLayers.test( layer ) )
762 return false;
763 }
764
765 for( int layer = LAYER_3D_START + 1; layer < LAYER_3D_END; ++layer )
766 {
767 auto it1 = aPreset.colors.find( layer );
768 auto it2 = colors.find( layer );
769
770 if( it1 != aPreset.colors.end() && it2 != colors.end() && *it1 != *it2 )
771 return false;
772 }
773
774 return true;
775 } );
776
777 if( it != presets.end() )
778 {
779 m_frame->GetAdapter().m_Cfg->m_CurrentPreset = it->name;
780 m_cbLayerPresets->SetStringSelection( it->name );
781 }
782 else
783 {
784 m_cbLayerPresets->SetSelection( m_cbLayerPresets->GetCount() - 3 ); // separator
785 }
786}
787
788
790{
791 if( aName == FOLLOW_PCB )
792 m_cbLayerPresets->SetSelection( 0 );
793 else if( aName == FOLLOW_PLOT_SETTINGS )
794 m_cbLayerPresets->SetSelection( 1 );
795 else if( !m_cbLayerPresets->SetStringSelection( aName ) )
796 m_cbLayerPresets->SetSelection( m_cbLayerPresets->GetCount() - 3 ); // separator
797}
798
799
801{
802 EDA_3D_VIEWER_SETTINGS* cfg = m_frame->GetAdapter().m_Cfg;
803 int count = m_cbLayerPresets->GetCount();
804 int index = m_cbLayerPresets->GetSelection();
805 wxString name;
806
807 auto resetSelection =
808 [&]()
809 {
811 };
812
813 if( index == 0 )
814 {
816 }
817 else if( index == 1 )
818 {
820 }
821 else if( index == count - 2 )
822 {
823 wxTextEntryDialog dlg( wxGetTopLevelParent( this ), _( "Layer preset name:" ),
824 _( "Save Layer Preset" ) );
825
826 if( dlg.ShowModal() != wxID_OK )
827 {
828 resetSelection();
829 return;
830 }
831
832 std::bitset<LAYER_3D_END> visibleLayers = m_frame->GetAdapter().GetVisibleLayers();
833 std::map<int, COLOR4D> colors = m_frame->GetAdapter().GetLayerColors();
834
835 name = dlg.GetValue();
836
837 if( LAYER_PRESET_3D* preset = cfg->FindPreset( name ) )
838 {
839 if( !IsOK( wxGetTopLevelParent( this ), _( "Overwrite existing preset?" ) ) )
840 {
841 resetSelection();
842 return;
843 }
844
845 preset->layers = visibleLayers;
846 preset->colors = colors;
847 m_cbLayerPresets->SetSelection( m_cbLayerPresets->FindString( name ) );
848 }
849 else
850 {
851 cfg->m_LayerPresets.emplace_back( name, visibleLayers, colors );
853 m_cbLayerPresets->SetStringSelection( name );
854 }
855
856 cfg->m_CurrentPreset = name;
857 m_presetMRU.Insert( name, 0 );
858
859 return;
860 }
861 else if( index == count - 1 )
862 {
863 wxArrayString headers;
864 std::vector<wxArrayString> items;
865
866 headers.Add( _( "Presets" ) );
867
868 for( LAYER_PRESET_3D& preset : cfg->m_LayerPresets )
869 {
870 wxArrayString item;
871 item.Add( preset.name );
872 items.emplace_back( item );
873 }
874
875 EDA_LIST_DIALOG dlg( m_frame, _( "Delete Preset" ), headers, items );
876 dlg.SetListLabel( _( "Select preset:" ) );
877
878 if( dlg.ShowModal() == wxID_OK )
879 {
880 name = dlg.GetTextSelection();
881
882 if( m_cbLayerPresets->FindString( name ) != wxNOT_FOUND )
883 m_cbLayerPresets->Delete( m_cbLayerPresets->FindString( name ) );
884
885 std::erase_if( cfg->m_LayerPresets,
886 [name]( const LAYER_PRESET_3D& preset )
887 {
888 return preset.name == name;
889 } );
890
891 if( cfg->m_CurrentPreset == name )
892 cfg->m_CurrentPreset = wxEmptyString;
893
894 if( m_presetMRU.Index( name ) >= 0 )
895 m_presetMRU.Remove( name );
896 }
897
898 resetSelection();
899 return;
900 }
901 else if( m_cbLayerPresets->GetString( index ) == wxT( "---" ) )
902 {
903 // Separator: reject the selection
904 resetSelection();
905 return;
906 }
907 else
908 {
909 doApplyLayerPreset( m_cbLayerPresets->GetStringSelection() );
910 }
911
912 // Move to front of MRU list
913 if( m_presetMRU.Index( name ) != wxNOT_FOUND )
914 m_presetMRU.Remove( name );
915
916 m_presetMRU.Insert( name, 0 );
917
918 passOnFocus();
919}
920
921
922void APPEARANCE_CONTROLS_3D::doApplyLayerPreset( const wxString& aPresetName )
923{
924 BOARD_ADAPTER& adapter = m_frame->GetAdapter();
925
926 if( aPresetName == FOLLOW_PCB || aPresetName == FOLLOW_PLOT_SETTINGS )
927 {
928 adapter.m_Cfg->m_CurrentPreset = aPresetName;
929 adapter.SetVisibleLayers( adapter.GetVisibleLayers() );
930 }
931 else if( LAYER_PRESET_3D* preset = adapter.m_Cfg->FindPreset( aPresetName ) )
932 {
933 adapter.m_Cfg->m_CurrentPreset = aPresetName;
934 adapter.SetVisibleLayers( preset->layers );
935 adapter.SetLayerColors( preset->colors );
936
937 if( preset->name.Lower() == _( "legacy colors" ) )
938 adapter.m_Cfg->m_UseStackupColors = false;
939 }
940 else
941 {
942 return;
943 }
944
946 m_frame->NewDisplay( true );
947}
948
949
951{
952 m_viewportsLabel->SetLabel( wxString::Format( _( "Viewports (%s+Tab):" ),
954
955 m_cbViewports->Clear();
956
957 for( std::pair<const wxString, VIEWPORT3D>& pair : m_viewports )
958 m_cbViewports->Append( pair.first, static_cast<void*>( &pair.second ) );
959
960 m_cbViewports->Append( wxT( "---" ) );
961 m_cbViewports->Append( _( "Save viewport..." ) );
962 m_cbViewports->Append( _( "Delete viewport..." ) );
963
964 m_cbViewports->SetSelection( m_cbViewports->GetCount() - 3 );
965 m_lastSelectedViewport = nullptr;
966}
967
968
969void APPEARANCE_CONTROLS_3D::onViewportChanged( wxCommandEvent& aEvent )
970{
971 int count = m_cbViewports->GetCount();
972 int index = m_cbViewports->GetSelection();
973
974 if( index >= 0 && index < count - 3 )
975 {
976 VIEWPORT3D* viewport = static_cast<VIEWPORT3D*>( m_cbViewports->GetClientData( index ) );
977
978 wxCHECK( viewport, /* void */ );
979
980 doApplyViewport( *viewport );
981
982 if( !viewport->name.IsEmpty() )
983 {
984 if( m_viewportMRU.Index( viewport->name ) != wxNOT_FOUND )
985 m_viewportMRU.Remove( viewport->name );
986
987 m_viewportMRU.Insert( viewport->name, 0 );
988 }
989 }
990 else if( index == count - 2 )
991 {
992 // Save current state to new preset
993 wxString name;
994
995 wxTextEntryDialog dlg( wxGetTopLevelParent( this ), _( "Viewport name:" ),
996 _( "Save Viewport" ), name );
997
998 if( dlg.ShowModal() != wxID_OK )
999 {
1001 m_cbViewports->SetStringSelection( m_lastSelectedViewport->name );
1002 else
1003 m_cbViewports->SetSelection( m_cbViewports->GetCount() - 3 );
1004
1005 return;
1006 }
1007
1008 name = dlg.GetValue();
1009 bool exists = m_viewports.count( name );
1010
1011 if( !exists )
1012 {
1013 m_viewports[name] = VIEWPORT3D( name, m_frame->GetCurrentCamera().GetViewMatrix() );
1014
1015 index = m_cbViewports->Insert( name, index-1, static_cast<void*>( &m_viewports[name] ) );
1016 }
1017 else
1018 {
1019 m_viewports[name].matrix = m_frame->GetCurrentCamera().GetViewMatrix();
1020 index = m_cbViewports->FindString( name );
1021
1022 if( m_viewportMRU.Index( name ) != wxNOT_FOUND )
1023 m_viewportMRU.Remove( name );
1024 }
1025
1026 m_cbViewports->SetSelection( index );
1027 m_viewportMRU.Insert( name, 0 );
1028
1029 return;
1030 }
1031 else if( index == count - 1 )
1032 {
1033 // Delete an existing viewport
1034 wxArrayString headers;
1035 std::vector<wxArrayString> items;
1036
1037 headers.Add( _( "Viewports" ) );
1038
1039 for( std::pair<const wxString, VIEWPORT3D>& pair : m_viewports )
1040 {
1041 wxArrayString item;
1042 item.Add( pair.first );
1043 items.emplace_back( item );
1044 }
1045
1046 EDA_LIST_DIALOG dlg( m_frame, _( "Delete Viewport" ), headers, items );
1047 dlg.SetListLabel( _( "Select viewport:" ) );
1048
1049 if( dlg.ShowModal() == wxID_OK )
1050 {
1051 wxString viewportName = dlg.GetTextSelection();
1052 int idx = m_cbViewports->FindString( viewportName );
1053
1054 if( idx != wxNOT_FOUND )
1055 {
1056 m_viewports.erase( viewportName );
1057 m_cbViewports->Delete( idx );
1058 }
1059
1060 if( m_viewportMRU.Index( viewportName ) != wxNOT_FOUND )
1061 m_viewportMRU.Remove( viewportName );
1062 }
1063
1065 m_cbViewports->SetStringSelection( m_lastSelectedViewport->name );
1066 else
1067 m_cbViewports->SetSelection( m_cbViewports->GetCount() - 3 );
1068
1069 return;
1070 }
1071
1072 passOnFocus();
1073}
1074
1075
1076void APPEARANCE_CONTROLS_3D::onUpdateViewportsCb( wxUpdateUIEvent& aEvent )
1077{
1078 int count = m_cbViewports->GetCount();
1079 int index = m_cbViewports->GetSelection();
1080
1081 if( index >= 0 && index < count - 3 )
1082 {
1083 VIEWPORT3D* viewport = static_cast<VIEWPORT3D*>( m_cbViewports->GetClientData( index ) );
1084
1085 wxCHECK( viewport, /* void */ );
1086
1087 if( m_frame->GetCurrentCamera().GetViewMatrix() != viewport->matrix )
1088 m_cbViewports->SetSelection( -1 );
1089 }
1090}
1091
1092
1094{
1095 m_frame->GetCurrentCamera().SetViewMatrix( aViewport.matrix );
1096
1097 if( m_frame->GetAdapter().m_Cfg->m_Render.engine == RENDER_ENGINE::OPENGL )
1098 m_frame->GetCanvas()->Request_refresh();
1099 else
1100 m_frame->GetCanvas()->RenderRaytracingRequest();
1101}
1102
1103
1105{
1106 m_focusOwner->SetFocus();
1107}
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:401
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: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.
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:251
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:266
@ LAYER_3D_USER_1
Definition layer_ids.h:564
@ LAYER_3D_SOLDERMASK_TOP
Definition layer_ids.h:557
@ LAYER_3D_USER_8
Definition layer_ids.h:571
@ LAYER_3D_USER_22
Definition layer_ids.h:585
@ LAYER_3D_USER_44
Definition layer_ids.h:607
@ LAYER_3D_USER_23
Definition layer_ids.h:586
@ LAYER_3D_NAVIGATOR
Definition layer_ids.h:614
@ LAYER_3D_USER_28
Definition layer_ids.h:591
@ LAYER_3D_BOUNDING_BOXES
Definition layer_ids.h:615
@ LAYER_3D_START
Definition layer_ids.h:547
@ LAYER_3D_USER_32
Definition layer_ids.h:595
@ LAYER_3D_USER_19
Definition layer_ids.h:582
@ LAYER_3D_USER_25
Definition layer_ids.h:588
@ LAYER_3D_ADHESIVE
Definition layer_ids.h:559
@ LAYER_3D_USER_3
Definition layer_ids.h:566
@ LAYER_3D_USER_21
Definition layer_ids.h:584
@ LAYER_3D_USER_26
Definition layer_ids.h:589
@ LAYER_3D_SMD_MODELS
Definition layer_ids.h:610
@ LAYER_3D_USER_24
Definition layer_ids.h:587
@ LAYER_3D_USER_43
Definition layer_ids.h:606
@ LAYER_3D_BACKGROUND_TOP
Definition layer_ids.h:550
@ LAYER_3D_USER_COMMENTS
Definition layer_ids.h:560
@ LAYER_3D_SOLDERMASK_BOTTOM
Definition layer_ids.h:556
@ LAYER_3D_USER_11
Definition layer_ids.h:574
@ LAYER_3D_USER_41
Definition layer_ids.h:604
@ LAYER_3D_USER_17
Definition layer_ids.h:580
@ LAYER_3D_BOARD
Definition layer_ids.h:551
@ LAYER_3D_PLATED_BARRELS
Definition layer_ids.h:617
@ LAYER_3D_USER_ECO1
Definition layer_ids.h:562
@ LAYER_3D_USER_20
Definition layer_ids.h:583
@ LAYER_3D_USER_31
Definition layer_ids.h:594
@ LAYER_3D_USER_ECO2
Definition layer_ids.h:563
@ LAYER_3D_TH_MODELS
Definition layer_ids.h:609
@ LAYER_3D_USER_15
Definition layer_ids.h:578
@ LAYER_3D_USER_38
Definition layer_ids.h:601
@ LAYER_3D_USER_13
Definition layer_ids.h:576
@ LAYER_3D_USER_33
Definition layer_ids.h:596
@ LAYER_3D_USER_35
Definition layer_ids.h:598
@ LAYER_3D_USER_29
Definition layer_ids.h:592
@ LAYER_3D_USER_40
Definition layer_ids.h:603
@ LAYER_3D_SILKSCREEN_TOP
Definition layer_ids.h:555
@ LAYER_3D_VIRTUAL_MODELS
Definition layer_ids.h:611
@ LAYER_3D_MODELS_MARKED_DNP
Definition layer_ids.h:613
@ LAYER_3D_USER_7
Definition layer_ids.h:570
@ LAYER_3D_COPPER_TOP
Definition layer_ids.h:552
@ LAYER_3D_USER_12
Definition layer_ids.h:575
@ LAYER_3D_SOLDERPASTE
Definition layer_ids.h:558
@ LAYER_3D_USER_30
Definition layer_ids.h:593
@ LAYER_3D_USER_36
Definition layer_ids.h:599
@ LAYER_3D_USER_2
Definition layer_ids.h:565
@ LAYER_3D_USER_18
Definition layer_ids.h:581
@ LAYER_3D_OFF_BOARD_SILK
Definition layer_ids.h:616
@ LAYER_3D_USER_14
Definition layer_ids.h:577
@ LAYER_3D_USER_5
Definition layer_ids.h:568
@ LAYER_3D_USER_37
Definition layer_ids.h:600
@ LAYER_3D_USER_10
Definition layer_ids.h:573
@ LAYER_3D_MODELS_NOT_IN_POS
Definition layer_ids.h:612
@ LAYER_3D_USER_42
Definition layer_ids.h:605
@ LAYER_3D_USER_45
Definition layer_ids.h:608
@ LAYER_3D_USER_6
Definition layer_ids.h:569
@ LAYER_3D_USER_4
Definition layer_ids.h:567
@ LAYER_3D_USER_27
Definition layer_ids.h:590
@ LAYER_3D_USER_DRAWINGS
Definition layer_ids.h:561
@ LAYER_3D_COPPER_BOTTOM
Definition layer_ids.h:553
@ LAYER_3D_USER_39
Definition layer_ids.h:602
@ LAYER_3D_USER_9
Definition layer_ids.h:572
@ LAYER_3D_BACKGROUND_BOTTOM
Definition layer_ids.h:549
@ LAYER_3D_USER_16
Definition layer_ids.h:579
@ LAYER_3D_SILKSCREEN_BOTTOM
Definition layer_ids.h:554
@ LAYER_3D_USER_34
Definition layer_ids.h:597
@ LAYER_3D_END
Definition layer_ids.h:619
@ 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)
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.