KiCad PCB EDA Suite
Loading...
Searching...
No Matches
eda_3d_viewer_settings.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) 2020 Jon Evans <[email protected]>
5 * Copyright (C) 2023 CERN
6 * Copyright (C) 2020-2023 KiCad Developers, see AUTHORS.txt for contributors.
7 *
8 * This program is free software: you can redistribute it and/or modify it
9 * under the terms of the GNU General Public License as published by the
10 * Free Software Foundation, either version 3 of the License, or (at your
11 * option) any later version.
12 *
13 * This program is distributed in the hope that it will be useful, but
14 * WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 * General Public License for more details.
17 *
18 * You should have received a copy of the GNU General Public License along
19 * with this program. If not, see <http://www.gnu.org/licenses/>.
20 */
21
22#include <3d_enums.h>
24#include <settings/parameters.h>
27#include <wx/config.h>
28
30
31using KIGFX::COLOR4D;
32
33using namespace std::placeholders;
34
35
36LAYER_PRESET_3D::LAYER_PRESET_3D( const wxString& aName ) :
37 name( aName )
38{
48
51
53 layers.set( LAYER_FP_TEXT );
54
56
57 // Preload colors vector so we don't have to worry about exceptions using colors.at()
72}
73
74
76 std::vector<LAYER_PRESET_3D>* aPresetList ) :
77 PARAM_LAMBDA<nlohmann::json>( aPath,
78 std::bind( &PARAM_LAYER_PRESET_3D::presetsToJson, this ),
79 std::bind( &PARAM_LAYER_PRESET_3D::jsonToPresets, this, _1 ),
80 {} ),
81 m_presets( aPresetList )
82{
83 wxASSERT( aPresetList );
84}
85
86
88{
89 nlohmann::json ret = nlohmann::json::array();
90
91 for( const LAYER_PRESET_3D& preset : *m_presets )
92 {
93 nlohmann::json js = {
94 { "name", preset.name }
95 };
96
97 nlohmann::json layers = nlohmann::json::array();
98
99 for( int layer = 0; layer < LAYER_3D_END; ++layer )
100 {
101 if( preset.layers.test( layer ) )
102 layers.push_back( layer );
103 }
104
105 js["layers"] = layers;
106
107 nlohmann::json colors = nlohmann::json::array();
108
109 for( const auto& [ layer, color ] : preset.colors )
110 {
111 nlohmann::json layerColor = {
112 { "layer", layer },
113 { "color", color.ToCSSString() }
114 };
115
116 colors.push_back( layerColor );
117 }
118
119 js["colors"] = colors;
120
121 ret.push_back( js );
122 }
123
124 return ret;
125}
126
127
128void PARAM_LAYER_PRESET_3D::jsonToPresets( const nlohmann::json& aJson )
129{
130 if( aJson.empty() || !aJson.is_array() )
131 return;
132
133 m_presets->clear();
134
135 for( const nlohmann::json& preset : aJson )
136 {
137 if( preset.contains( "name" ) )
138 {
139 LAYER_PRESET_3D p( preset.at( "name" ).get<wxString>() );
140
141 if( preset.contains( "layers" ) && preset.at( "layers" ).is_array() )
142 {
143 p.layers.reset();
144
145 for( const nlohmann::json& layer : preset.at( "layers" ) )
146 {
147 if( layer.is_number_integer() )
148 {
149 int layerNum = layer.get<int>();
150
151 if( layerNum >= 0 && layerNum < LAYER_3D_END )
152 p.layers.set( layerNum );
153 }
154 }
155 }
156
157 if( preset.contains( "colors" ) && preset.at( "colors" ).is_array() )
158 {
159 for( const nlohmann::json& layerColor : preset.at( "colors" ) )
160 {
161 if( layerColor.contains( "layer" ) && layerColor.contains( "color" )
162 && layerColor.at( "layer" ).is_number_integer() )
163 {
164 int layerNum = layerColor.at( "layer" ).get<int>();
165 COLOR4D color = layerColor.at( "color" ).get<COLOR4D>();
166 p.colors[ layerNum ] = color;
167 }
168 }
169 }
170
171 m_presets->emplace_back( p );
172 }
173 }
174}
175
176
179
180
183 m_Render(),
184 m_Camera()
185{
186 m_params.emplace_back( new PARAM<bool>( "aui.show_layer_manager",
188
189 m_params.emplace_back( new PARAM<int>( "aui.right_panel_width",
191
192 m_params.emplace_back( new PARAM_ENUM<RENDER_ENGINE>( "render.engine", &m_Render.engine,
193 RENDER_ENGINE::OPENGL,
194 RENDER_ENGINE::OPENGL,
195 RENDER_ENGINE::RAYTRACING ) );
196
197 m_params.emplace_back( new PARAM_ENUM<GRID3D_TYPE>( "render.grid_type", &m_Render.grid_type,
198 GRID3D_TYPE::NONE,
199 GRID3D_TYPE::NONE,
200 GRID3D_TYPE::GRID_10MM ) );
201
202 m_params.emplace_back( new PARAM_ENUM<MATERIAL_MODE>( "render.material_mode",
204 MATERIAL_MODE::NORMAL,
205 MATERIAL_MODE::NORMAL,
206 MATERIAL_MODE::CAD_MODE ) );
207
208 m_params.emplace_back( new PARAM_ENUM<ANTIALIASING_MODE>( "render.opengl_AA_mode",
210 ANTIALIASING_MODE::AA_8X,
211 ANTIALIASING_MODE::AA_NONE,
212 ANTIALIASING_MODE::AA_8X ) );
213
214 m_params.emplace_back( new PARAM<COLOR4D>( "render.opengl_selection_color",
216 COLOR4D( 0.0, 1.0, 0.0, 1.0 ) ) );
217
218 // OpenGL options
219 m_params.emplace_back( new PARAM<bool>( "render.opengl_copper_thickness",
221 m_params.emplace_back( new PARAM<bool>( "render.opengl_show_model_bbox",
222 &m_Render.show_model_bbox, false ) );
223 m_params.emplace_back( new PARAM<bool>( "render.opengl_show_off_board_silk",
224 &m_Render.show_off_board_silk, false ) );
225 m_params.emplace_back( new PARAM<bool>( "render.opengl_highlight_on_rollover",
227 m_params.emplace_back( new PARAM<bool>( "render.opengl_AA_disableOnMove",
229 m_params.emplace_back( new PARAM<bool>( "render.opengl_thickness_disableOnMove",
231 m_params.emplace_back( new PARAM<bool>( "render.opengl_vias_disableOnMove",
233 m_params.emplace_back( new PARAM<bool>( "render.opengl_holes_disableOnMove",
235 m_params.emplace_back( new PARAM<bool>( "render.opengl_render_bbox_only_OnMove",
237
238 // Raytracing options
239 m_params.emplace_back( new PARAM<bool>( "render.raytrace_anti_aliasing",
241 m_params.emplace_back( new PARAM<bool>( "render.raytrace_backfloor",
242 &m_Render.raytrace_backfloor, false ) );
243 m_params.emplace_back( new PARAM<bool>( "render.raytrace_post_processing",
245 m_params.emplace_back( new PARAM<bool>( "render.raytrace_procedural_textures",
247 m_params.emplace_back( new PARAM<bool>( "render.raytrace_reflections",
249 m_params.emplace_back( new PARAM<bool>( "render.raytrace_refractions",
251 m_params.emplace_back( new PARAM<bool>( "render.raytrace_shadows",
252 &m_Render.raytrace_shadows, true ) );
253
254 m_params.emplace_back( new PARAM<int>( "render.raytrace_nrsamples_shadows",
256 m_params.emplace_back( new PARAM<int>( "render.raytrace_nrsamples_reflections",
258 m_params.emplace_back( new PARAM<int>( "render.raytrace_nrsamples_refractions",
260
261 m_params.emplace_back( new PARAM<int>( "render.raytrace_recursivelevel_reflections",
263 m_params.emplace_back( new PARAM<int>( "render.raytrace_recursivelevel_refractions",
265
266 m_params.emplace_back( new PARAM<float>( "render.raytrace_spread_shadows",
268 m_params.emplace_back( new PARAM<float>( "render.raytrace_spread_reflections",
270 m_params.emplace_back( new PARAM<float>( "render.raytrace_spread_refractions",
272
273 m_params.emplace_back( new PARAM<COLOR4D>( "render.raytrace_lightColorCamera",
275 COLOR4D( 0.2, 0.2, 0.2, 1.0 ) ) );
276
277 m_params.emplace_back( new PARAM<COLOR4D>( "render.raytrace_lightColorTop",
279 COLOR4D( 0.247, 0.247, 0.247, 1.0 ) ) );
280
281 m_params.emplace_back( new PARAM<COLOR4D>( "render.raytrace_lightColorBottom",
283 COLOR4D( 0.247, 0.247, 0.247, 1.0 ) ) );
284
285 std::vector<COLOR4D> default_colors =
286 {
287 COLOR4D( 0.168, 0.168, 0.168, 1.0 ),
288 COLOR4D( 0.168, 0.168, 0.168, 1.0 ),
289 COLOR4D( 0.168, 0.168, 0.168, 1.0 ),
290 COLOR4D( 0.168, 0.168, 0.168, 1.0 ),
291 COLOR4D( 0.168, 0.168, 0.168, 1.0 ),
292 COLOR4D( 0.168, 0.168, 0.168, 1.0 ),
293 COLOR4D( 0.168, 0.168, 0.168, 1.0 ),
294 COLOR4D( 0.168, 0.168, 0.168, 1.0 )
295 };
296
297 m_params.emplace_back( new PARAM_LIST<COLOR4D>( "render.raytrace_lightColor",
299 default_colors ) );
300
301 const std::vector<int> default_elevation =
302 {
303 67, 67, 67, 67, -67, -67, -67, -67,
304 };
305
306 m_params.emplace_back( new PARAM_LIST<int>( "render.raytrace_lightElevation",
308 default_elevation ) );
309
310 const std::vector<int> default_azimuth =
311 {
312 45, 135, 225, 315, 45, 135, 225, 315,
313 };
314
315 m_params.emplace_back( new PARAM_LIST<int>( "render.raytrace_lightAzimuth",
317 default_azimuth ) );
318
319 m_params.emplace_back( new PARAM<bool>( "render.show_adhesive",
320 &m_Render.show_adhesive, true ) );
321 m_params.emplace_back( new PARAM<bool>( "render.show_axis",
322 &m_Render.show_axis, true ) );
323 m_params.emplace_back( new PARAM<bool>( "render.show_board_body",
324 &m_Render.show_board_body, true ) );
325 m_params.emplace_back( new PARAM<bool>( "render.show_comments",
326 &m_Render.show_comments, true ) );
327 m_params.emplace_back( new PARAM<bool>( "render.show_drawings",
328 &m_Render.show_drawings, true ) );
329 m_params.emplace_back( new PARAM<bool>( "render.show_eco1",
330 &m_Render.show_eco1, true ) );
331 m_params.emplace_back( new PARAM<bool>( "render.show_eco2",
332 &m_Render.show_eco2, true ) );
333 m_params.emplace_back( new PARAM<bool>( "render.show_footprints_insert",
335 m_params.emplace_back( new PARAM<bool>( "render.show_footprints_normal",
337 m_params.emplace_back( new PARAM<bool>( "render.show_footprints_virtual",
339 m_params.emplace_back( new PARAM<bool>( "render.show_footprints_not_in_posfile",
341 m_params.emplace_back( new PARAM<bool>( "render.show_footprints_dnp",
342 &m_Render.show_footprints_dnp, false ) );
343 m_params.emplace_back( new PARAM<bool>( "render.show_silkscreen_top",
344 &m_Render.show_silkscreen_top, true ) );
345 m_params.emplace_back( new PARAM<bool>( "render.show_silkscreen_bottom",
347 m_params.emplace_back( new PARAM<bool>( "render.show_soldermask_top",
348 &m_Render.show_soldermask_top, true ) );
349 m_params.emplace_back( new PARAM<bool>( "render.show_soldermask_bottom",
351 m_params.emplace_back( new PARAM<bool>( "render.show_solderpaste",
352 &m_Render.show_solderpaste, true ) );
353 m_params.emplace_back( new PARAM<bool>( "render.show_copper_top",
354 &m_Render.show_copper_bottom, true ) );
355 m_params.emplace_back( new PARAM<bool>( "render.show_copper_bottom",
356 &m_Render.show_copper_top, true ) );
357 m_params.emplace_back( new PARAM<bool>( "render.show_zones",
358 &m_Render.show_zones, true ) );
359 m_params.emplace_back( new PARAM<bool>( "render.show_fp_references",
360 &m_Render.show_fp_references, true ) );
361 m_params.emplace_back( new PARAM<bool>( "render.show_fp_values",
362 &m_Render.show_fp_values, true ) );
363 m_params.emplace_back( new PARAM<bool>( "render.show_fp_text",
364 &m_Render.show_fp_text, true ) );
365 m_params.emplace_back( new PARAM<bool>( "render.subtract_mask_from_silk",
367 m_params.emplace_back( new PARAM<bool>( "render.clip_silk_on_via_annulus",
369 m_params.emplace_back( new PARAM<bool>( "render.plated_and_bare_copper",
371 m_params.emplace_back( new PARAM<bool>( "camera.animation_enabled",
372 &m_Camera.animation_enabled, true ) );
373 m_params.emplace_back( new PARAM<int>( "camera.moving_speed_multiplier",
375 m_params.emplace_back( new PARAM<double>( "camera.rotation_increment",
376 &m_Camera.rotation_increment, 10.0 ) );
377 m_params.emplace_back( new PARAM<int>( "camera.projection_mode",
379
380 m_params.emplace_back( new PARAM<bool>( "use_stackup_colors",
381 &m_UseStackupColors, true ) );
382 m_params.emplace_back( new PARAM_LAYER_PRESET_3D( "layer_presets",
383 &m_LayerPresets ) );
384 m_params.emplace_back( new PARAM<wxString>( "current_layer_preset",
386
388
389 registerMigration( 1, 2,
390 [&]() -> bool
391 {
392 Set( "render.opengl_copper_thickness", false );
393 return true;
394 } );
395
396 registerMigration( 2, 3,
397 [&]() -> bool
398 {
399 if( std::optional<bool> optval = Get<bool>( "render.show_copper" ) )
400 {
401 Set( "render.show_copper_top", *optval );
402 Set( "render.show_copper_bottom", *optval );
403 }
404
405 if( std::optional<bool> optval = Get<bool>( "render.show_silkscreen" ) )
406 {
407 Set( "render.show_silkscreen_top", *optval );
408 Set( "render.show_silkscreen_bottom", *optval );
409 }
410
411 if( std::optional<bool> optval = Get<bool>( "render.show_soldermask" ) )
412 {
413 Set( "render.show_soldermask_top", *optval );
414 Set( "render.show_soldermask_bottom", *optval );
415 }
416
417 if( std::optional<bool> optval = Get<bool>( "render.show_comments" ) )
418 Set( "render.show_drawings", *optval );
419
420 if( std::optional<bool> optval = Get<bool>( "render.show_eco" ) )
421 {
422 Set( "render.show_eco1", *optval );
423 Set( "render.show_eco2", *optval );
424 }
425
426 return true;
427 } );
428}
429
430
432{
433 for( LAYER_PRESET_3D& preset : m_LayerPresets )
434 {
435 if( preset.name == aName )
436 return &preset;
437 }
438
439 return nullptr;
440}
441
442
444{
450 try
451 {
452 if( m_internals->contains( "colors" ) )
453 m_internals->erase( "colors" );
454 }
455 catch( ... )
456 {
457 }
458
459 return true;
460}
461
462
464{
465 bool ret = APP_SETTINGS_BASE::MigrateFromLegacy( aCfg );
466
467 ret &= fromLegacy<int>( aCfg, "RenderEngine", "render.engine" );
468 ret &= fromLegacy<int>( aCfg, "ShowGrid3D", "render.grid_type" );
469 ret &= fromLegacy<int>( aCfg, "Render_Material", "render.material_mode" );
470 ret &= fromLegacy<bool>( aCfg, "Render_OGL_ShowCopperThickness", "render.opengl_copper_thickness" );
471 ret &= fromLegacy<bool>( aCfg, "Render_OGL_ShowModelBoudingBoxes", "render.opengl_show_model_bbox" );
472 ret &= fromLegacy<bool>( aCfg, "Render_RAY_AntiAliasing", "render.raytrace_anti_aliasing" );
473 ret &= fromLegacy<bool>( aCfg, "Render_RAY_Backfloor", "render.raytrace_backfloor" );
474 ret &= fromLegacy<bool>( aCfg, "Render_RAY_PostProcess", "render.raytrace_post_processing" );
475 ret &= fromLegacy<bool>( aCfg, "Render_RAY_ProceduralTextures", "render.raytrace_procedural_textures" );
476 ret &= fromLegacy<bool>( aCfg, "Render_RAY_Reflections", "render.raytrace_reflections" );
477 ret &= fromLegacy<bool>( aCfg, "Render_RAY_Refractions", "render.raytrace_refractions" );
478 ret &= fromLegacy<bool>( aCfg, "Render_RAY_Shadows", "render.raytrace_shadows" );
479 ret &= fromLegacy<bool>( aCfg, "ShowRealisticMode", "render.realistic" );
480 ret &= fromLegacy<bool>( aCfg, "ShowAdhesiveLayers", "render.show_adhesive" );
481 ret &= fromLegacy<bool>( aCfg, "ShowAxis", "render.show_axis" );
482 ret &= fromLegacy<bool>( aCfg, "ShowBoardBody", "render.show_board_body" );
483 ret &= fromLegacy<bool>( aCfg, "ShowCommentsLayers", "render.show_comments" );
484 ret &= fromLegacy<bool>( aCfg, "ShowEcoLayers", "render.show_eco" );
485 ret &= fromLegacy<bool>( aCfg, "ShowFootprints_Insert", "render.show_footprints_insert" );
486 ret &= fromLegacy<bool>( aCfg, "ShowFootprints_Normal", "render.show_footprints_normal" );
487 ret &= fromLegacy<bool>( aCfg, "ShowFootprints_Virtual", "render.show_footprints_virtual" );
488 ret &= fromLegacy<bool>( aCfg, "ShowSilkScreenLayers", "render.show_silkscreen" );
489 ret &= fromLegacy<bool>( aCfg, "ShowSolderMasLayers", "render.show_soldermask" );
490 ret &= fromLegacy<bool>( aCfg, "ShowSolderPasteLayers", "render.show_solderpaste" );
491 ret &= fromLegacy<bool>( aCfg, "ShowZones", "render.show_zones" );
492 ret &= fromLegacy<bool>( aCfg, "SubtractMaskFromSilk", "render.subtract_mask_from_silk" );
493
494 auto do_color =
495 [&] ( const std::string& key_r, const std::string& key_g, const std::string& key_b,
496 std::string key_dest, double alpha = 1.0 )
497 {
498 COLOR4D color( 1, 1, 1, alpha );
499
500 if( aCfg->Read( key_r, &color.r )
501 && aCfg->Read( key_g, &color.g )
502 && aCfg->Read( key_b, &color.b ) )
503 {
504 Set( key_dest, color );
505 }
506 };
507
508 do_color( "BgColor_Red", "BgColor_Green", "BgColor_Blue", "colors.background_bottom" );
509 do_color( "BgColor_Red_Top", "BgColor_Green_Top", "BgColor_Blue_Top", "colors.background_top" );
510 do_color( "BoardBodyColor_Red", "BoardBodyColor_Green", "BoardBodyColor_Blue", "colors.board" );
511 do_color( "CopperColor_Red", "CopperColor_Green", "CopperColor_Blue", "colors.copper" );
512 do_color( "SilkColor_Red", "SilkColor_Green", "SilkColor_Blue", "colors.silkscreen_bottom" );
513 do_color( "SilkColor_Red", "SilkColor_Green", "SilkColor_Blue", "colors.silkscreen_top" );
514 do_color( "SMaskColor_Red", "SMaskColor_Green", "SMaskColor_Blue", "colors.soldermask", 0.83 );
515 do_color( "SPasteColor_Red", "SPasteColor_Green", "SPasteColor_Blue", "colors.solderpaste" );
516
517 return ret;
518}
declared enumerations and flags
int color
Definition: DXF_plotter.cpp:58
const char * name
Definition: DXF_plotter.cpp:57
APP_SETTINGS_BASE is a settings class that should be derived for each standalone KiCad application.
Definition: app_settings.h:92
virtual bool MigrateFromLegacy(wxConfigBase *aCfg) override
Migrates from wxConfig to JSON-based configuration.
static KIGFX::COLOR4D g_DefaultComments
static KIGFX::COLOR4D g_DefaultBoardBody
static KIGFX::COLOR4D g_DefaultSolderMask
static KIGFX::COLOR4D g_DefaultECOs
static KIGFX::COLOR4D g_DefaultBackgroundTop
static KIGFX::COLOR4D g_DefaultSurfaceFinish
static KIGFX::COLOR4D g_DefaultSolderPaste
static KIGFX::COLOR4D g_DefaultSilkscreen
static KIGFX::COLOR4D g_DefaultBackgroundBot
virtual bool MigrateFromLegacy(wxConfigBase *aLegacyConfig) override
Migrates from wxConfig to JSON-based configuration.
LAYER_PRESET_3D * FindPreset(const wxString &aName)
std::vector< LAYER_PRESET_3D > m_LayerPresets
void Set(const std::string &aPath, ValueType aVal)
Stores a value into the JSON document Will throw an exception if ValueType isn't something that the l...
std::vector< PARAM_BASE * > m_params
The list of parameters (owned by this object)
void registerMigration(int aOldSchemaVersion, int aNewSchemaVersion, std::function< bool(void)> aMigrator)
Registers a migration from one schema version to another.
std::unique_ptr< JSON_SETTINGS_INTERNALS > m_internals
A color representation with 4 components: red, green, blue, alpha.
Definition: color4d.h:104
Stores an enum as an integer.
Definition: parameters.h:226
Like a normal param, but with custom getter and setter functions.
Definition: parameters.h:293
std::vector< LAYER_PRESET_3D > * m_presets
void jsonToPresets(const nlohmann::json &aJson)
PARAM_LAYER_PRESET_3D(const std::string &aPath, std::vector< LAYER_PRESET_3D > *aPresetList)
const int viewer3dSchemaVersion
! Update the schema version whenever a migration is required
#define LEGACY_PRESET_FLAG
nlohmann::json json
Definition: gerbview.cpp:47
@ LAYER_3D_SOLDERMASK_TOP
Definition: layer_ids.h:458
@ LAYER_3D_ADHESIVE
Definition: layer_ids.h:460
@ LAYER_3D_SMD_MODELS
Definition: layer_ids.h:466
@ LAYER_3D_BACKGROUND_TOP
Definition: layer_ids.h:451
@ LAYER_3D_USER_COMMENTS
Definition: layer_ids.h:461
@ LAYER_3D_SOLDERMASK_BOTTOM
Definition: layer_ids.h:457
@ LAYER_3D_BOARD
Definition: layer_ids.h:452
@ LAYER_3D_USER_ECO1
Definition: layer_ids.h:463
@ LAYER_3D_USER_ECO2
Definition: layer_ids.h:464
@ LAYER_3D_TH_MODELS
Definition: layer_ids.h:465
@ LAYER_3D_SILKSCREEN_TOP
Definition: layer_ids.h:456
@ LAYER_3D_COPPER_TOP
Definition: layer_ids.h:453
@ LAYER_3D_SOLDERPASTE
Definition: layer_ids.h:459
@ LAYER_3D_USER_DRAWINGS
Definition: layer_ids.h:462
@ LAYER_3D_COPPER_BOTTOM
Definition: layer_ids.h:454
@ LAYER_3D_BACKGROUND_BOTTOM
Definition: layer_ids.h:450
@ LAYER_3D_SILKSCREEN_BOTTOM
Definition: layer_ids.h:455
@ LAYER_3D_END
Definition: layer_ids.h:474
@ LAYER_GRID_AXES
Definition: layer_ids.h:210
@ LAYER_FP_REFERENCES
show footprints references (when texts are visible)
Definition: layer_ids.h:215
@ LAYER_FP_TEXT
Definition: layer_ids.h:202
STL namespace.
Declaration of the cogl_att_list class.
std::vector< KIGFX::COLOR4D > raytrace_lightColor
LAYER_PRESET_3D(const wxString &aName=wxEmptyString)
std::bitset< LAYER_3D_END > layers
std::map< int, KIGFX::COLOR4D > colors