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