Compare commits

..

233 Commits

Author SHA1 Message Date
Wayne Stambaugh 3f5d3fa0c6 Tag release version 7.0.1. 2023-03-09 16:59:45 -05:00
Seth Hillbrand 51dc2b109e Handle fully-nested zones
The logic to handle divots needs to account for fully nested, same net
zones.  The process of subtracting led to us considering the inner zone
to be a zone knock-out (negative polygon).  To avoid this, we need to
check if the inner, higher priority zone has any connection to the outer
zone.  If it does not, then we can treat it as an isolated zone without
worrying about divots to the outer zone.

(cherry picked from commit 9146e38af4)
2023-03-09 09:25:20 -08:00
mitxela 2358ff6f07 Helper function to allow net.GetNetClassName()
(cherry picked from commit 734d3667a8)
2023-03-09 14:03:02 +00:00
mitxela 11788d2f39 Expose shared_ptr to swig
Possibly not the right way to go about it but technically works


(cherry picked from commit 182abd4652)
2023-03-09 14:02:48 +00:00
mitxela 541f7467c6 Fix python GetAllNetClasses
(cherry picked from commit 716328e511)
2023-03-09 14:02:34 +00:00
jean-pierre charras 411c9707ee specctra export: fix handling of multi-layer zones.
(from master branch)
2023-03-07 15:45:28 +01:00
Jon Evans ee0ba17c03 Improve HiDPI handling of appearance/layer controls
(cherry picked from commit 43d3a18b86)
2023-03-07 08:49:06 -05:00
Jon Evans 64bc850d8f Fix layer widget in HiDPI situations
(cherry picked from commit 89ef6b36f4)
2023-03-07 08:49:06 -05:00
Jeff Young 154f64dae3 Edge connectors shouldn't trigger edge clearance violations.
Fixes https://gitlab.com/kicad/code/kicad/issues/14199

(cherry picked from commit 33e7c78533)
2023-03-07 12:23:56 +00:00
Johannes Maibaum 7fa758358f Don't bracket KICAD_VERSION when using git describe
(Cherry-picked from 75424cb246)
2023-03-07 10:40:28 +00:00
Salvador E. Tropea f135881bd6 Use constants for the names of the built-in colors
- Avoid repetition and errors from typos
- Allow simple changes
- Simpler data type handling, the constants are wxString
2023-03-07 10:32:18 +00:00
Seth Hillbrand 839301f81e Revert "Consolidated ERC fixes"
This reverts commit 2127712115.

Version uses functions only available in the master branch.  Will revert
for 7.0.2 to allow targeted update
2023-03-06 21:22:55 -08:00
Seth Hillbrand 04f4ca9772 Update translations 2023-03-06 16:55:17 -08:00
Rigo Ligo 525328fba1 Translated using Weblate (Chinese (Simplified))
Currently translated at 100.0% (8011 of 8011 strings)

Translation: KiCad EDA/v7
Translate-URL: https://hosted.weblate.org/projects/kicad/v7/zh_Hans/
2023-03-07 01:50:07 +01:00
boonchai k 471c125c1a Translated using Weblate (Thai)
Currently translated at 89.2% (7148 of 8011 strings)

Translation: KiCad EDA/v7
Translate-URL: https://hosted.weblate.org/projects/kicad/v7/th/
2023-03-07 01:50:07 +01:00
Tokita, Hiroshi 8ef99137c6 Translated using Weblate (Japanese)
Currently translated at 100.0% (8011 of 8011 strings)

Translation: KiCad EDA/v7
Translate-URL: https://hosted.weblate.org/projects/kicad/v7/ja/
2023-03-07 01:50:07 +01:00
boonchai k 404cad062a Translated using Weblate (Thai)
Currently translated at 88.6% (7104 of 8011 strings)

Translation: KiCad EDA/v7
Translate-URL: https://hosted.weblate.org/projects/kicad/v7/th/
2023-03-07 01:50:07 +01:00
dsa-t d4be813f2e Translated using Weblate (Russian)
Currently translated at 100.0% (8011 of 8011 strings)

Translation: KiCad EDA/v7
Translate-URL: https://hosted.weblate.org/projects/kicad/v7/ru/
2023-03-07 01:50:06 +01:00
Jonathan Haas ab3c0b2f03 Translated using Weblate (German)
Currently translated at 99.9% (8009 of 8011 strings)

Translation: KiCad EDA/v7
Translate-URL: https://hosted.weblate.org/projects/kicad/v7/de/
2023-03-07 01:50:06 +01:00
CloverGit defcfc2962 Translated using Weblate (Chinese (Simplified))
Currently translated at 100.0% (8011 of 8011 strings)

Translation: KiCad EDA/v7
Translate-URL: https://hosted.weblate.org/projects/kicad/v7/zh_Hans/
2023-03-07 01:50:06 +01:00
Jan Straka 267cfdf54b Translated using Weblate (Czech)
Currently translated at 90.1% (7218 of 8011 strings)

Translation: KiCad EDA/v7
Translate-URL: https://hosted.weblate.org/projects/kicad/v7/cs/
2023-03-07 01:50:06 +01:00
turkce a7b0231b3c Translated using Weblate (Turkish)
Currently translated at 42.1% (3375 of 8011 strings)

Translation: KiCad EDA/v7
Translate-URL: https://hosted.weblate.org/projects/kicad/v7/tr/
2023-03-07 01:50:06 +01:00
turkce 7c19958840 Translated using Weblate (Turkish)
Currently translated at 41.3% (3310 of 8011 strings)

Translation: KiCad EDA/v7
Translate-URL: https://hosted.weblate.org/projects/kicad/v7/tr/
2023-03-07 01:50:06 +01:00
ssantos 34c3bb7d2c Translated using Weblate (Portuguese)
Currently translated at 99.8% (8001 of 8011 strings)

Translation: KiCad EDA/v7
Translate-URL: https://hosted.weblate.org/projects/kicad/v7/pt/
2023-03-07 01:50:06 +01:00
Toni Laiho b37545ee6c Translated using Weblate (Finnish)
Currently translated at 100.0% (8011 of 8011 strings)

Translation: KiCad EDA/v7
Translate-URL: https://hosted.weblate.org/projects/kicad/v7/fi/
2023-03-07 01:50:05 +01:00
Henrik Kauhanen c1e924c894 Translated using Weblate (Swedish)
Currently translated at 99.9% (8007 of 8011 strings)

Translation: KiCad EDA/v7
Translate-URL: https://hosted.weblate.org/projects/kicad/v7/sv/
2023-03-07 01:50:05 +01:00
Tom Niesse 200e9e28ea Translated using Weblate (Dutch)
Currently translated at 82.8% (6638 of 8011 strings)

Translation: KiCad EDA/v7
Translate-URL: https://hosted.weblate.org/projects/kicad/v7/nl/
2023-03-07 01:50:05 +01:00
Henrik Kauhanen b95f958890 Translated using Weblate (Swedish)
Currently translated at 99.9% (8007 of 8011 strings)

Translation: KiCad EDA/v7
Translate-URL: https://hosted.weblate.org/projects/kicad/v7/sv/
2023-03-07 01:50:05 +01:00
김랑기 fe9666bdaf Translated using Weblate (Korean)
Currently translated at 100.0% (8011 of 8011 strings)

Translation: KiCad EDA/v7
Translate-URL: https://hosted.weblate.org/projects/kicad/v7/ko/
2023-03-07 01:50:05 +01:00
Henrik Kauhanen 948de5dc79 Translated using Weblate (Finnish)
Currently translated at 100.0% (8011 of 8011 strings)

Translation: KiCad EDA/v7
Translate-URL: https://hosted.weblate.org/projects/kicad/v7/fi/
2023-03-07 01:50:05 +01:00
Toni Laiho 8800fd8250 Translated using Weblate (Finnish)
Currently translated at 100.0% (8011 of 8011 strings)

Translation: KiCad EDA/v7
Translate-URL: https://hosted.weblate.org/projects/kicad/v7/fi/
2023-03-07 01:50:05 +01:00
Henrik Kauhanen b1e5d8c915 Translated using Weblate (German)
Currently translated at 99.9% (8009 of 8011 strings)

Translation: KiCad EDA/v7
Translate-URL: https://hosted.weblate.org/projects/kicad/v7/de/
2023-03-07 01:50:05 +01:00
Henrik Kauhanen 02aec8b091 Translated using Weblate (Swedish)
Currently translated at 99.9% (8005 of 8011 strings)

Translation: KiCad EDA/v7
Translate-URL: https://hosted.weblate.org/projects/kicad/v7/sv/
2023-03-07 01:50:04 +01:00
김랑기 50517f6aa6 Translated using Weblate (Korean)
Currently translated at 100.0% (8011 of 8011 strings)

Translation: KiCad EDA/v7
Translate-URL: https://hosted.weblate.org/projects/kicad/v7/ko/
2023-03-07 01:50:04 +01:00
Henrik Kauhanen a752473280 Translated using Weblate (Finnish)
Currently translated at 99.9% (8010 of 8011 strings)

Translation: KiCad EDA/v7
Translate-URL: https://hosted.weblate.org/projects/kicad/v7/fi/
2023-03-07 01:50:04 +01:00
Henrik Kauhanen 7e1972d483 Translated using Weblate (German)
Currently translated at 99.9% (8009 of 8011 strings)

Translation: KiCad EDA/v7
Translate-URL: https://hosted.weblate.org/projects/kicad/v7/de/
2023-03-07 01:50:04 +01:00
Henrik Kauhanen de48bf04bc Translated using Weblate (Swedish)
Currently translated at 99.9% (8006 of 8011 strings)

Translation: KiCad EDA/v7
Translate-URL: https://hosted.weblate.org/projects/kicad/v7/sv/
2023-03-07 01:50:04 +01:00
Henrik Kauhanen 228bf66cac Translated using Weblate (Finnish)
Currently translated at 99.9% (8010 of 8011 strings)

Translation: KiCad EDA/v7
Translate-URL: https://hosted.weblate.org/projects/kicad/v7/fi/
2023-03-07 01:50:04 +01:00
Jan Straka c986c1d26a Translated using Weblate (Czech)
Currently translated at 89.7% (7188 of 8011 strings)

Translation: KiCad EDA/v7
Translate-URL: https://hosted.weblate.org/projects/kicad/v7/cs/
2023-03-07 01:50:04 +01:00
Henrik Kauhanen b0f7ea5b16 Translated using Weblate (Swedish)
Currently translated at 99.9% (8006 of 8011 strings)

Translation: KiCad EDA/v7
Translate-URL: https://hosted.weblate.org/projects/kicad/v7/sv/
2023-03-07 01:50:04 +01:00
Jan Sobków 8b2e2ff1f8 Translated using Weblate (Polish)
Currently translated at 100.0% (8011 of 8011 strings)

Translation: KiCad EDA/v7
Translate-URL: https://hosted.weblate.org/projects/kicad/v7/pl/
2023-03-07 01:50:03 +01:00
Toni Laiho d00166223f Translated using Weblate (Finnish)
Currently translated at 100.0% (8011 of 8011 strings)

Translation: KiCad EDA/v7
Translate-URL: https://hosted.weblate.org/projects/kicad/v7/fi/
2023-03-07 01:50:03 +01:00
Toni Laiho 4701b4bfc2 Translated using Weblate (Finnish)
Currently translated at 100.0% (8011 of 8011 strings)

Translation: KiCad EDA/v7
Translate-URL: https://hosted.weblate.org/projects/kicad/v7/fi/
2023-03-07 01:50:03 +01:00
Ivan Chuba e4c74c727f Translated using Weblate (Ukrainian)
Currently translated at 100.0% (8011 of 8011 strings)

Translation: KiCad EDA/v7
Translate-URL: https://hosted.weblate.org/projects/kicad/v7/uk/
2023-03-07 01:50:03 +01:00
Henrik Kauhanen f626ce29c4 Translated using Weblate (Swedish)
Currently translated at 99.9% (8006 of 8011 strings)

Translation: KiCad EDA/v7
Translate-URL: https://hosted.weblate.org/projects/kicad/v7/sv/
2023-03-07 01:50:03 +01:00
Wellington Terumi Uemura 768d8e5811 Translated using Weblate (Portuguese (Brazil))
Currently translated at 100.0% (8011 of 8011 strings)

Translation: KiCad EDA/v7
Translate-URL: https://hosted.weblate.org/projects/kicad/v7/pt_BR/
2023-03-07 01:50:03 +01:00
ZbeeGin 2ac3a4a103 Translated using Weblate (Polish)
Currently translated at 100.0% (8011 of 8011 strings)

Translation: KiCad EDA/v7
Translate-URL: https://hosted.weblate.org/projects/kicad/v7/pl/
2023-03-07 01:50:03 +01:00
Toni Laiho bb512f3fc0 Translated using Weblate (Finnish)
Currently translated at 100.0% (8011 of 8011 strings)

Translation: KiCad EDA/v7
Translate-URL: https://hosted.weblate.org/projects/kicad/v7/fi/
2023-03-07 01:50:03 +01:00
Henrik Kauhanen d6e7a89c97 Translated using Weblate (Finnish)
Currently translated at 100.0% (8011 of 8011 strings)

Translation: KiCad EDA/v7
Translate-URL: https://hosted.weblate.org/projects/kicad/v7/fi/
2023-03-07 01:50:03 +01:00
Ulices a5455da909 Translated using Weblate (Spanish (Mexico))
Currently translated at 100.0% (8011 of 8011 strings)

Translation: KiCad EDA/v7
Translate-URL: https://hosted.weblate.org/projects/kicad/v7/es_MX/
2023-03-07 01:50:02 +01:00
Henrik Kauhanen 8dadc698cc Translated using Weblate (German)
Currently translated at 99.9% (8010 of 8011 strings)

Translation: KiCad EDA/v7
Translate-URL: https://hosted.weblate.org/projects/kicad/v7/de/
2023-03-07 01:50:02 +01:00
James J 2127712115 Consolidated ERC fixes
- Consistent calculation of IsStacked() for pins across ERC checks
 - Correct placement of ERC marker for unresolved field variables
 - Add sheet-specific paths to two ERC check results

(cherry picked from commit 39e56485fc)
2023-03-06 16:38:11 -08:00
Mario Luzeiro d5b635027e 3D-Viewer: sort models and material models when rendering in transparent
Also enables transparency on model preview and small optimizations fixes

Fixes https://gitlab.com/kicad/code/kicad/-/issues/14005

(cherry picked from commit 7bc976f3f4)
2023-03-06 16:24:24 -08:00
Graham Keeth 9b2aeda51e Fix column offset in BOM script
Debugged by @svk28

Fixes https://gitlab.com/kicad/code/kicad/-/issues/14128

(cherry picked from commit cc110399ea)
2023-03-06 16:23:31 -08:00
Seth Hillbrand 5aba9b539f Revert font spacing/tabs to the v6 model
While convoluted, this model matches as best we have found so far, the
alignment with scintilla.  The spacing is character size for N-1 of the
characters in the 4-space tab stops.  The final character is sized for
the actual space character in the stroke font (0.761905)

Fixes https://gitlab.com/kicad/code/kicad/issues/13791

(cherry picked from commit bce402a01c)
2023-03-06 16:23:06 -08:00
JamesJCode b82020722b Eeschema netlist output: Propagate NC across hierarchical schematics
Fixes #12580

Additionally does not export no_connect netlist annotation on pins
which are both connected to another pin and a NC item, unless all
connected pins are stacked at the symbol level.

Adds testing of pin types to netlist QA unit tests.

(cherry picked from commit 9dca70a773)
2023-03-06 16:22:25 -08:00
Seth Hillbrand b62a8fe65a Handle excessively large values when hatching
While unusual, ensure that hatched zones don't break KiCad if they are
close to the integer limit

Fixes https://gitlab.com/kicad/code/kicad/issues/14066

(cherry picked from commit ffcc0e50b7)
2023-03-06 16:21:13 -08:00
Seth Hillbrand a5d85e3281 Bitmaps are not actually copper
We report bitmaps as being 'on' a copper layer because they are
associated with it but they are not actually physical parts so should
not be included in the DRC checks

Additionally, Bitmaps effective shape starts are the top left corner
rather than the center (unclear why that was there in the first place)

Fixes https://gitlab.com/kicad/code/kicad/issues/14065

(cherry picked from commit 1b8b216ac8)
2023-03-06 16:20:44 -08:00
Seth Hillbrand e699bcf5a3 Use Chamfer lines when deflating
Rounded line ends when deflating leads to microscopic jags in the
outline that are not visible but add substantial computation time and
minor error when computing polygon offsets.

Instead, the chamfer deflate method prevents these jagged lines by
clipping angles < 90° by the error level.  This does not impact deflate
calls where we explicitly require the angles to be maintained

(cherry picked from commit af10878954)
2023-03-06 16:18:51 -08:00
Seth Hillbrand 7ef5e079fd Smarten connection width checker looking for splits
Fractured polygons are always fractured along the x-axis, so when
checking to see if a segment is a fracture point, we check if the y
coordinate is equal.  This avoids situations where there are multiple
fracture points between two inflection points

Additionally, we add a second check to ensure we don't hit spurious
blobs (all kinks should be symmetric and therefore be substantial in
each direction)

Fixes https://gitlab.com/kicad/code/kicad/issues/14130

(cherry picked from commit 7653a2bf99)
2023-03-06 16:14:56 -08:00
Jeff Young 4076461347 Make SPICE netlist title explicit.
Fixes https://gitlab.com/kicad/code/kicad/issues/14183

(cherry picked from commit 6838de962b)
2023-03-06 23:09:51 +00:00
qu1ck d610486c1e Add vector3 to swig
Fixes regression in 7.0 making fp 3d model offsets not accessible in
python

Fixes https://gitlab.com/kicad/code/kicad/-/issues/14179

(cherry picked from commit 88062c5fc3)
2023-03-06 11:23:09 -08:00
Christoph Moench-Tegeder 1891e2ad68 CMakeLists.txt: do not use -ffloat-store on clang
According to it's User Manual, clang does not know about -ffloat-store.
This is corrobated by the FreeBSD i386 build (using LLVM 13 and 15,
depending on the base system version) failing early with an error
message complaining about this parameter being unknown.

See
https://pkg-status.freebsd.org/beefy17/data/main-i386-default/pb27279cba1ca_sed03776ca7/logs/kicad-7.0.0,2.log
for an example of the failure, and
https://clang.llvm.org/docs/UsersManual.html#controlling-floating-point-behavior
for the available floating point options on clang.

(Cherry-picked from 46a59aa2c3)
2023-03-06 16:01:55 +00:00
aris-kimi f1e060902b Simulator: Fix RLGC c unit
(Cherry-picked from db2780090c)
2023-03-06 15:59:54 +00:00
Jeff Young 7dbd920912 Don't allow footprint editor pad tools to run outside footprint editor.
(They can get called if a user re-assigns hotkeys to them.)

Fixes https://gitlab.com/kicad/code/kicad/issues/14166
2023-03-06 14:43:20 +00:00
aris-kimi 05ab9e3836 Simulator: Fix diode ibv unit
(Cherry-picked from 5b43dc4e7b)
2023-03-06 14:20:33 +00:00
Jeff Young a4e0f1f7aa Support both wxWidgets APIs for excluded characters.
(Sadly they're mutually incompatible.)

Fixes https://gitlab.com/kicad/code/kicad/issues/14153

(cherry picked from commit b5060d2951)
2023-03-06 14:17:11 +00:00
Jeff Young a8f27d13e6 Use name (even for fallback models) *if* it's specified in dropdown.
Fixes https://gitlab.com/kicad/code/kicad/issues/12425

(cherry picked from commit 7547e550aa)
2023-03-06 11:18:14 +00:00
Jeff Young 05d425ea88 Add 12505 to the regression test suite.
Fixes https://gitlab.com/kicad/code/kicad/issues/12505

(cherry picked from commit d96598c87c)
2023-03-06 10:27:46 +00:00
Jeff Young 3cb12b5a60 Allow others to also process units changed event.
Fixes https://gitlab.com/kicad/code/kicad/issues/14156

(cherry picked from commit 6a5f305684)
2023-03-05 16:07:00 +00:00
Alex 8f1237e629 bom_csv_grouped_extra: use field-specific methods for data.
Fixes https://gitlab.com/kicad/code/kicad/issues/14129


(cherry picked from commit c1f4911d7e)
2023-03-05 00:26:46 +00:00
Wayne Stambaugh 2c7f44f78d Coverity fixes and code cleaning.
(cherry picked from commit 789bf6455a)
2023-03-04 13:14:59 -05:00
Jeff Young a9447aa8c7 Add UNITS_CHANGED handling to 3D preview controls.
Fixes https://gitlab.com/kicad/code/kicad/issues/14156

(cherry picked from commit 915b352d9b)
2023-03-04 12:12:34 +00:00
Jeff Young 9b61b350fe Don't commit changes on paint events or updateUI events.
Also use std::numeric_limits::epsilon for comparing doubles.

Fixes https://gitlab.com/kicad/code/kicad/issues/13851

(cherry picked from commit d714ff8549)
2023-03-04 00:10:39 +00:00
Alex e3cf65fbdf Fix bitmap scaling when reading legacy schematic as well.
(cherry picked from commit bfc3e2d29b)
2023-03-03 22:39:38 +00:00
Jeff Young e51d43568e Prefer Clamp() to std::min( std::max() ).
(cherry picked from commit d545216432)
2023-03-03 21:32:19 +00:00
Jeff Young 1bb6b7acdd Overflow safety.
Potential fix for some or all of
https://gitlab.com/kicad/code/kicad/-/issues/13969

(cherry picked from commit 2f2a00c307)
2023-03-03 21:32:12 +00:00
Seth Hillbrand adc7a3ba4a Correct parent symbol for lib_text
The edited symbol should be pulled from the parent window when there is
not an existing text object

(cherry picked from commit 59fc62e898)
2023-03-03 12:40:56 -08:00
Jeff Young 94ec6cc362 Convert inline models in Sim.Params fields to SPICE syntax.
Fixes https://gitlab.com/kicad/code/kicad/issues/14157

(cherry picked from commit 14f1f3ec79)
2023-03-03 18:18:32 +00:00
Jeff Young bbdb5eb6e3 Use resolved fields when generating LIB_TREE info.
Fixes https://gitlab.com/kicad/code/kicad/issues/13737

(cherry picked from commit 2fb24347ad)
2023-03-03 17:23:13 +00:00
Jeff Young e487ca8bd8 Handle alternate pin definitions when printing.
Fixes https://gitlab.com/kicad/code/kicad/issues/14122

(cherry picked from commit 2973d292d9)
2023-03-03 12:57:03 +00:00
Jeff Young f5b0e20f78 The screen for undo is the screen that *owns* the SCH_SHEET...
... not the screen the SCH_SHEET owns.

Fixes https://gitlab.com/kicad/code/kicad/issues/14099

(cherry picked from commit 5849458476)
2023-03-03 00:23:41 +00:00
Seth Hillbrand 6116eebbad Prevent inf when presented with 0 errormax
acos(1) returns 0, so this implies infinite segements to get to 0 error.
This is not reasonable but might be encountered in bad arcs or circles
that have 0 radius.  Instead of returning infinite or std::max segments,
we limit the error to be at least 1 IU

(cherry picked from commit 1fda68099f)
2023-03-02 10:21:25 -08:00
Jeff Young 8619705e44 Hook up AddField handler to GRID_TRICKS for SCH dialogs.
Fixes https://gitlab.com/kicad/code/kicad/issues/git/14153
2023-03-02 18:16:02 +00:00
Jeff Young c216ed2d1f Make SME prop-grid hack Mac-only.
Fixes https://gitlab.com/kicad/code/kicad/issues/13852

(cherry picked from commit dcba555d44)
2023-03-02 14:59:57 +00:00
Jeff Young e17dc25bba Add support for non-cardianlly-rotated text boxes.
Also fixes a couple of bugs in text boxes in flipped footprints.

Fixes https://gitlab.com/kicad/code/kicad/issues/14112

(cherry picked from commit 7638e23ff1)
2023-03-02 14:58:44 +00:00
Salvador E. Tropea d311915f9d Fix the CONNECTIVITY_DATA::GetNetItems Python API
- The C++ member now uses std::vector<KICAD_T>
- The Python side can use a single value or a list,
  like in v6.

The std::vector translation is based on the v6 KICAD_T[]
translation.
2023-03-01 18:49:12 +00:00
Jeff Young 3a95826b42 Move only-write-model-if-it-contains-overrides up to base class.
It's necessary to keep us from writing out model lines for included
models and fall-backs of included models.

(cherry picked from commit f5edcf82f2)
2023-03-01 13:44:26 +00:00
jean-pierre charras dcc1009162 plotters rework: add plot fct to use TEXT_ATTRIBUTES class to pass text settings
Old PLOTTER::Text is not (yet) removed, but it use negative text size
to mirrored text, which is not really compatible with some plotters (especially PDF).
Using TEXT_ATTRIBUTES is much easy and much better,
so PLOTTER::PlotText() is added.
Note: "old" PLOTTER::Text() is not removed yet.
From master, commit 51d46c0e73
2023-03-01 10:45:23 +01:00
jean-pierre charras d61e01ff4f Plot Gerber format: ensure all attributes are added to polygon items.
Especially, TA.AperFunction,EtchedComponent for net tie footprints using polygons.
From master, commit ece34e1a0c
2023-03-01 09:39:15 +01:00
Seth Hillbrand 51b9d8e7ad Allow for rounding error in connection width checker
We perform checks using squared distance but this loses the integer
rounding in the standard norm.  To correct for this, we allow a single
IU in the restriction, allowing fractionally smaller connection widths
before calculating the squared limit

Fixes https://gitlab.com/kicad/code/kicad/issues/14130

Fixes https://gitlab.com/kicad/code/kicad/issues/14131

(cherry picked from commit a0f99ea8ba)
2023-02-28 15:26:49 -08:00
qu1ck 90eb5e9c31 PCM: auto reload global libs after dialog is run
This adds Reset() method to KIFACE to reload global libs stored in
global static vars.
Also refactors some lib reload code in various frames to have
common MAIL_RELOAD_LIB handler.

Fixes https://gitlab.com/kicad/code/kicad/-/issues/12500

(cherry picked from commit 2975f53647)
2023-02-28 16:48:28 -05:00
Seth Hillbrand 17c34c88dc Avoid forcing all units
When the enduser is not allowed to change the status of "common to all
units", then it should be disabled

Fixes https://gitlab.com/kicad/code/kicad/issues/14084

(cherry picked from commit 3207d1386e)
2023-02-28 13:42:51 -08:00
aris-kimi ff6f658f9d Simulator: Fix some cases with initial conditions
(cherry picked from commit 4a761179d0)
2023-02-28 21:31:45 +00:00
Seth Hillbrand fb798a4150 Export footprint pad holes to STEP regardless
Footprint pad holes form a part of the board outline regardless of
whether the footprint is in the BOM or not

Fixes https://gitlab.com/kicad/code/kicad/issues/14013

(cherry picked from commit daf70f9b6a)
2023-02-28 12:02:40 -08:00
Salvador E. Tropea 4213bb3a62 Fix rounding errors in gerber files
The userToDeviceCoordinates helper returns a VECTOR2D
Converting it to VECTOR2I back and forth generates rounding errors
Also is a waste of time
2023-02-28 19:23:26 +00:00
Jeff Young 8a34f91172 Fix for overwriting non-specified constraints.
Fixes https://gitlab.com/kicad/code/kicad/issues/14070
2023-02-28 18:29:43 +00:00
jean-pierre charras 764ddd4773 Fix compil warnings. 2023-02-28 18:00:22 +01:00
jean-pierre charras ea0dcc8ebd Fixes in build board outlines as polygon and convert_shape_list_to_polygon:
- Ensure Bezier curves have their polygon build before use it.
- When building board outlines as polygon the same chaining epsilon value
for DRC, export step and 3D view (default 0.01mm).
Fixes #14115
https://gitlab.com/kicad/code/kicad/issues/14115
Fixes #14009
https://gitlab.com/kicad/code/kicad/issues/14009
2023-02-28 17:26:28 +01:00
jean-pierre charras 3f5db9f7f9 EXPORTER_STEP: handle sub-layers in dielectric layer.
A dielectric layer (between 2 copper layers) can be made by more than one
layer (composite dielectric).  Not frequent, but possible.
sub-layers where previously ignored.
2023-02-28 17:25:40 +01:00
Jeff Young a6a0bba1b7 Stage group children when staging group.
Many operations such as move, rotate, etc. are applied directly to the
group's children, so it's the children that need staging.

Fixes https://gitlab.com/kicad/code/kicad/issues/13999
2023-02-28 14:21:12 +00:00
Jeff Young 5ec785e2f7 Spacing & font-size issues in 3D model preview dialog.
Fixes https://gitlab.com/kicad/code/kicad/issues/13880

(cherry picked from commit 7bb006c91d)
2023-02-28 14:21:12 +00:00
Graham Keeth f7d9f1f69d Fix SPICE pins for BJTs and MESFETs
- MESFETs don't have a substrate/bulk pin
- BJTs have a substrate pin, and HICUM/VBIC have TJ

Fixes: https://gitlab.com/kicad/code/kicad/-/issues/13848

(cherry picked from commit 6af3dadaee)
2023-02-28 14:21:12 +00:00
Jeff Young 42efd2d005 Make substrate and thermal junction nodes optional.
Fixes https://gitlab.com/kicad/code/kicad/issues/14083

(cherry picked from commit 1fdc81e68d)
2023-02-28 14:21:12 +00:00
Jeff Young d32e13daee Clear model name when switching to internal model.
Also fixes a bug to ensure that a modelLine gets written when using
an internal model.

Fixes https://gitlab.com/kicad/code/kicad/issues/14083

(cherry picked from commit 2e5bf0210a)
2023-02-28 14:21:12 +00:00
Jeff Young e82c21e944 Get rid of m_sortedSymbolPinList in favour of a properly scoped variable.
Fixes https://gitlab.com/kicad/code/kicad/issues/14083

(cherry picked from commit 2a79a453ec)
2023-02-28 14:21:12 +00:00
Johannes Pfister 33f835a437 When importing legacy PCB dimension: Use automatic dimension when Unit couldn't be determined
(cherry picked from commit a87550a2c6)
2023-02-28 14:21:12 +00:00
Jeff Young 59d8110801 Always highlight children when they're selected on their own.
Fixes https://gitlab.com/kicad/code/kicad/issues/13876

(cherry picked from commit a1ceb585c7)
2023-02-28 14:21:11 +00:00
Jeff Young d028b381fa Make SIM_MODEL_SPICE_FALLBACK act more like the model it's a fallback for.
In particular, install/show the parameters, and keep the existing name
field.

Fixes https://gitlab.com/kicad/code/kicad/issues/14102

(cherry picked from commit 281fde71b9)
2023-02-28 14:21:11 +00:00
Roberto Fernandez Bautista a1a3f810f0 Add missing line from commit b03366c9e8
(cherry picked from commit bb8a3a7fdc)
2023-02-27 23:13:44 +00:00
Roberto Fernandez Bautista c96f0f2396 Fix CADSTAR importer memory leaks
We were leaking the xml tree when throwing exceptions


(cherry picked from commit b03366c9e8)
2023-02-27 22:58:41 +00:00
Fabien Corona 46c8985661 sim - switches: open <-> closed in description 2023-02-27 19:04:48 +01:00
jean-pierre charras c588639503 PANEL_COLOR_SETTINGS: swap swatches and texts to avoid annoying truncation.
In some languages, the texts can be long, and create truncation of the left
column. So if the left column shows swatches they are truncated, or not visible
Truncating long texts is less annoying.
Fixes #14052
https://gitlab.com/kicad/code/kicad/issues/14052
2023-02-27 08:37:13 +01:00
Jeff Young b3c6f559b2 Don't eval empty string.
Fixes https://gitlab.com/kicad/code/kicad/issues/13756

(cherry picked from commit 79f13ea9c7)
2023-02-26 23:14:40 +00:00
Marek Roszko 85544d109c Don't destroy the DIALOG_PCM_PROGRESS until after the threads actually terminated
(cherry picked from commit 47cf26f047)
2023-02-26 22:47:14 +00:00
Jeff Young 4aba595b2b Add second instance of "don't mess up user formatting" fix.
Fixes https://gitlab.com/kicad/code/kicad/issues/13989

(cherry picked from commit 4b427b2d0c)
2023-02-26 22:00:20 +00:00
Jeff Young b2241dca72 Adjust stroke font baseline offset to better match 6.0.
Fixes https://gitlab.com/kicad/code/kicad/issues/13886

(cherry picked from commit 4bb508eacf)
2023-02-26 21:59:43 +00:00
Jeff Young 4ffe742b69 Log new undo record at the start of Change Symbols.
Also fixes a bug where the "screen" variable was used with stale
data.

Fixes https://gitlab.com/kicad/code/kicad/issues/14061

(cherry picked from commit 2b96161d0e)
2023-02-26 21:58:57 +00:00
Jeff Young 5979b8e385 Don't allocate all of memory when the coord system turns inside out.
Fixes https://gitlab.com/kicad/code/kicad/issues/14088

(cherry picked from commit fe9370ceea)
2023-02-26 21:58:08 +00:00
Roberto Fernandez Bautista 955bd5a6d1 CADSTAR Sch: Fix loading of graphical arc shapes
Correctly load arc shapes as real arcs instead of approximating now that
v7 supports graphical arcs in the schematic.

Also fix calculation of arc geometry for ccw arcs.

Fixes https://gitlab.com/kicad/code/kicad/-/issues/14101


(cherry picked from commit 698d0b7e92)
2023-02-26 18:47:39 +00:00
qu1ck 1eb8191519 Treat dimensions in fp as text for bbox calculations
(cherry picked from commit 1ff021bb927e9a146f57277554f370f97c07041c)
2023-02-26 17:59:22 +00:00
qu1ck 396bda5611 Sync pcbnew selection with selected items after plugin is run
(cherry picked from commit 9f10c142c4)
2023-02-26 17:58:57 +00:00
Jon Evans cb334be8c4 PNS: Diff pairs can have different hole-to-hole size
Fixes https://gitlab.com/kicad/code/kicad/-/issues/13993


(cherry picked from commit f12f2b8420)
2023-02-26 17:57:47 +00:00
Jon Evans 8845cc0556 PNS: Safety for evaluating item nets for rules
Fixes https://gitlab.com/kicad/code/kicad/-/issues/13993


(cherry picked from commit 459473ccc3)
2023-02-26 17:57:33 +00:00
Jon Evans e34800ad49 Allow shorting copper zones through negative clearance
This brings the zone filler in line with other places where
we use negative clearance rules to disable constraints.

Fixes https://gitlab.com/kicad/code/kicad/-/issues/14069


(cherry picked from commit b176881d49)
2023-02-26 17:45:46 +00:00
qu1ck 5b574901b3 Fix swig mappings for PCB_BITMAP
From Master branch.
2023-02-26 10:28:59 +01:00
Alex 59b68154e1 Reduce some flickering in PCM.
(cherry picked from commit b592017495)
2023-02-26 08:34:49 +00:00
jean-pierre charras 5a501c8e48 kicad manager, OnOpenFileInTextEditor(): do not quote the filename.
It will be quoted later.
Fixes #14086
https://gitlab.com/kicad/code/kicad/issues/14086
2023-02-26 08:36:58 +01:00
Seth Hillbrand f927c15adf Prevent mutex deadlock
The overbar function in outline fonts recursively calls the text
function which already owns the lock.  To avoid this, we have an
unlocked variant that is wrapped by the exposed text function

Fixes https://gitlab.com/kicad/code/kicad/issues/14015


(cherry picked from commit 81256c0fa4)
2023-02-25 13:44:18 +00:00
Jon Evans d08157f7db Re-disable validator for VALUE and add comment explaining it 2023-02-25 08:05:42 -05:00
jean-pierre charras 8a9ac4f01f Pcbnew: optimize netname and num text size and position display on pad.
Sizes where a bit too big. Fix also a difference between Cairo and OpenGL.
Fixes #13872
https://gitlab.com/kicad/code/kicad/issues/13872
2023-02-25 11:08:29 +01:00
Jon Evans 39df5f3b15 Do not invalidate board caches during DRC
Footprints now modify their parent container when destroyed due to
26542796, and a temporary footprint is created during DRC
in some situations.  This can lead to board caches being messed
with during DRC which can cause unpredictable bad effects due to
multithreading.

Fixes https://gitlab.com/kicad/code/kicad/-/issues/13844


(cherry picked from commit 8440d7258b)
2023-02-25 03:56:27 +00:00
Jon Evans 981bf328ae Value field needs to use the normal text control
Fixes https://gitlab.com/kicad/code/kicad/-/issues/14056
2023-02-24 22:18:31 -05:00
Jon Evans 1f8e9727b0 Set copper edge clearance to a more reasonable default
(cherry picked from commit 1215a967e2)
2023-02-25 01:43:55 +00:00
Jeff Young f604bcb557 Only write included models if they have overridden parameters.
Fixes https://gitlab.com/kicad/code/kicad/issues/13953

(cherry picked from commit 5a12e5ee76)
2023-02-24 20:47:22 +00:00
Jeff Young eccf9eb4a4 Change strategy for committing values from SIM_MODEL propGrid.
Note that the PCB editor's propGrid doesn't seem to need this workaround,
but I haven't yet figured out what's different between it and the sim model
propGrid.

Fixes https://gitlab.com/kicad/code/kicad/issues/13852

(cherry picked from commit c188318174)
2023-02-24 20:47:22 +00:00
Jeff Young 39403fa885 Cleanup some dead code, and add a potentially needed fix for non-Mac.
(The Mac bug is fixed in 4e5b1da81fce7cd9ffedaec878ed07bfcfff4fe2 in
our wxWidgets fork.)

(cherry picked from commit 200a06a677)
2023-02-24 20:47:22 +00:00
Jeff Young 5e7cc30564 Don't mess up user formatting if eval'ing didn't actually change value.
Fixes https://gitlab.com/kicad/code/kicad/issues/13989

(cherry picked from commit 8059edff0e)
2023-02-24 20:47:22 +00:00
Jeff Young f942b4c657 Don't allow extra text in Sim.* fields.
(In particular, the field name.)

Fixes https://gitlab.com/kicad/code/kicad/issues/13996

(cherry picked from commit 71df3f9edb)
2023-02-24 20:47:22 +00:00
Jeff Young f5aeb5b068 More dead code removal and a bit of formatting and const& for strings.
(cherry picked from commit a126d961d8)
2023-02-24 20:47:22 +00:00
Jeff Young 7f6cb9b07b Remove most of SIM_VALUE in favour of good old wxString.
This allows us to save the user's intent, including units, formatting,
and crucially variable references.

(cherry picked from commit 68fe146861)
2023-02-24 20:47:22 +00:00
Jeff Young db3657d411 Terminology and more dead code.
(cherry picked from commit 29f21cdde6)
2023-02-24 20:47:22 +00:00
Jeff Young 38e5da724d Remove dead and redundant code.
(cherry picked from commit 90adc26b73)
2023-02-24 20:47:22 +00:00
Marco Ciampa 24a63eb304 Updated Italian translation 2023-02-24 14:12:48 +01:00
jean-pierre charras c1f5ae1c5a Plot footprint texts: add code to plot Knockout texts.
Fixes #14068
https://gitlab.com/kicad/code/kicad/issues/14068
2023-02-24 08:49:56 +01:00
Jon Evans 009211c740 Fix some PCB_SHAPE properties
Hide irrelevant position/start/end properties
for shape classes that don't use them.


(cherry picked from commit 1651b44ab1)
2023-02-24 01:24:41 +00:00
Alex 1a208a1612 Print original netnames properly when reconnecting zones/vias.
Using GetNetname() after SetNet() isn't a good idea to get the original
name when updating PCB from Schematic.


(cherry picked from commit 9d96edc44f)
2023-02-23 20:30:39 +00:00
Alex b867e51c6c pcbnew: Fix pads losing nets after Undo.
Wasn't fixed in all places after being broken in
13f5c78e89


(cherry picked from commit f31e5ea783)
2023-02-23 20:30:20 +00:00
qu1ck 7693b93c50 Fix plugins in pcbnew breaking by opening fp editor
From master branch.
2023-02-23 15:31:00 +01:00
jean-pierre charras c3d7158669 Eeschema plot: honor B&W plot option for bitmap images.
Fixes #14013
https://gitlab.com/kicad/code/kicad/issues/14013
2023-02-23 09:53:35 +01:00
Marek Roszko 9f5e50f25e Fix typo in appearance_controls.cpp
(cherry picked from commit c2a4dd93e8)
2023-02-23 01:36:52 +00:00
Jon Evans a091ab76d7 Disable auto-refill zones
We need a more advanced dirtying system for this to work out for
many users, it turns out.  Right now too many changes cause full
zone refills which interrupt workflow.


(cherry picked from commit d8f4d04093)
2023-02-23 01:16:21 +00:00
jean-pierre charras d5eb242295 Fix incorrect tilt of italic texts when plotting them.
Fixes #14023
https://gitlab.com/kicad/code/kicad/issues/14023
2023-02-22 20:25:25 +01:00
Salvador E. Tropea b21e65fc5f Fix compatibility with wxWidgets 3.0.x
- Use CanonicalName when GetCanonicalWithRegion() isn't available
2023-02-22 19:23:55 +00:00
Jeff Young 1b07e81936 Fix compile error on OSX. 2023-02-22 18:06:32 +00:00
Jeff Young 962b2d45ef Implement default levels for JFETs, MOSFETs and MESFETs.
(cherry picked from commit fe2679d965)
2023-02-22 18:04:23 +00:00
Jeff Young 7894b41277 Don't allow 0 field text size.
Fixes https://gitlab.com/kicad/code/kicad/issues/13987

(cherry picked from commit cb71ea872b)
2023-02-22 18:04:23 +00:00
Jeff Young 51d0b8d2b5 Don't allow SCH_LABEL_LOCATE_ANY_T to steal SCH_LABEL_LOCATE_WIRE_T's items.
Fixes https://gitlab.com/kicad/code/kicad/issues/13936

(cherry picked from commit 5967ab9a4d)
2023-02-22 18:04:23 +00:00
Jeff Young 7b992a1dc4 Correctly netlist a voltage source with both AC and DC values.
Fixes https://gitlab.com/kicad/code/kicad/issues/13912

(cherry picked from commit c618bb7046)
2023-02-22 18:04:21 +00:00
Jeff Young 2f8615c6c4 Don't use the just-in-time model resolver when updating the dialog.
If it changes in the middle it will leave you in a world of hurt.

Also don't update the library after a loss-of-focus unless the path
really changed.

Fixes https://gitlab.com/kicad/code/kicad/issues/13869

Fixes https://gitlab.com/kicad/code/kicad/issues/13854

(cherry picked from commit 64f1808d60)
2023-02-22 17:53:10 +00:00
Salvador E. Tropea aee6d9d01c Create the built-in colors in the constructor
This is needed so Python scripts can get built-in colors using the
SETTINGS_MANAGER.GetColorSettings() member.
Otherwise calling it with a built-in name crashes.
2023-02-22 09:12:22 -03:00
Marek Roszko fd4a0dbedf Fix up handling of font names available in multiple names
ttf fonts can declare multiple language names. Many by default opt to just declare one and not tag it any particular language.
However, there are CJK languages that typically leverage this function the most. They'll tag both a "en" and a cjk lang family name in CJK characters.

To be as user friendly as possible, we need to display said fonts in the CJK languages if KiCad to set to such a locale.

Fixes https://gitlab.com/kicad/code/kicad/-/issues/14011


(cherry picked from commit 39e69a3d29)
2023-02-22 01:27:09 +00:00
Marek Roszko 14381ac68a Catch parsing exceptions of the local repository.json
Fixes KICAD-B9


(cherry picked from commit 6029fae30b)
2023-02-21 12:15:09 +00:00
Fabien Corona c00a98fed4 Revert "sim - Remember the option to save powers"
This reverts commit 74dcc1b9d5.
2023-02-20 20:59:52 +01:00
Mark Roszko aab7581909 Fix symbol contributor link
(cherry picked from commit 365c7be4ed)
2023-02-20 19:44:59 +00:00
Fabien Corona 74dcc1b9d5 sim - Remember the option to save powers
Fixes #13978


(cherry picked from commit 2a3b70b7eb)
2023-02-20 19:38:19 +00:00
Fabien Corona 17241b3543 sim - missing assignment 2023-02-20 18:15:37 +01:00
Fabien Corona a4a859f47b sim - Check FindParam() results before using them 2023-02-20 18:14:48 +01:00
Fabien Corona b66ed8bc41 sim - don't write dc parameter twice 2023-02-20 18:13:44 +01:00
Fabien Corona 754feff5e7 sim - allow sources that are both AC and TRAN 2023-02-20 18:12:36 +01:00
Fabien Corona cd1b425a80 sim: VSIN - allow user to specify a phase
TD is not the same as PHASE.
TD is the delay before the source turns on.
PHASE is ... the phase

If only TD is set, the signal starts later, but the phase is still 0 when compared to the t=0 of the simulation.

(cherry picked from commit 39a1b14a0f)
2023-02-20 08:45:09 +00:00
Marek Roszko 187947e8d8 Fix crash deleting project tree items
Fixes sentry KICAD-C2


(cherry picked from commit 7d25b6de87)
2023-02-19 15:12:07 +00:00
Marek Roszko 6b38927123 Fix crash parsing cadstar
Fixes sentry KICAD-B2
2023-02-19 08:11:33 -05:00
Marek Roszko f46e4049b6 Try to prevent a crash in mpFXY::Plot
Fixes sentry kicad-c0
2023-02-19 08:11:27 -05:00
Marek Roszko 0ea8299fa7 Fix copypasta typo in export pos
Fixes https://gitlab.com/kicad/code/kicad/-/issues/13991


(cherry picked from commit 9b708ce6d1)
2023-02-19 05:24:36 +00:00
Marek Roszko 5d793193e0 Fix crash by using a shared_mutex to read/write lock the nickIndex
Fixes sentry kicad-ax
2023-02-18 13:02:25 -05:00
Mark Roszko 62337f75b8 FT_Face is also not thread, protect getTextAsGlyphs
(cherry picked from commit 7b4abb1f7b)
2023-02-17 15:17:11 +00:00
Marek Roszko 4d4fdfff70 freetype is not thread safe, zone filler can trigger multi-thread access
sentry KICAD-B1

https://freetype.org/freetype2/docs/reference/ft2-base_interface.html
[Since 2.5.6] In multi-threaded applications it is easiest to use one FT_Library object per thread.
In case this is too cumbersome, a single FT_Library object across threads is possible also, as long as a mutex lock is used around FT_New_Face and FT_Done_Face.


(cherry picked from commit 65d5b34da3)
2023-02-17 15:17:02 +00:00
Alex b63d0a3138 Keep image sizes when loading/saving 7.0- schematic file formats.
Previously, images were assumed to have 300 PPI density when loading from
schematic, but not after initial placement.


(cherry picked from commit bd4758e4df)
2023-02-17 01:50:01 +00:00
Alex 7949c09183 Prevent ghost image after canceling bitmap placement.
(cherry picked from commit ecb28ddf1c)
2023-02-17 01:49:47 +00:00
Seth Hillbrand 3f535aca8c Fix Ukrainian language name
Should refer to the language not to a Ukrainian person

(cherry picked from commit 576bef4ba0)
2023-02-16 15:11:14 -08:00
Jon Evans 9f44809164 Revert "Handle another case where schematic view was being cleared"
This reverts commit 245ce7259c.
2023-02-16 16:44:30 -05:00
Jon Evans f7ccb18af5 Revert "Symbol editor: stop removing overlay from view"
This reverts commit f36cd60fdb.
2023-02-16 16:44:20 -05:00
Jon Evans cca9945867 Revert "Fix handling of selection overlay in schematic editor"
This reverts commit e2711a6121.

This ended up being too complex for 7.0
2023-02-16 16:43:57 -05:00
Jeff Young f23c6b0c2f Clear dirty flags after a move.
Fixes https://gitlab.com/kicad/code/kicad/issues/11362

(cherry picked from commit 40e1296a8b)
2023-02-16 18:10:26 +00:00
Jeff Young 6d22b8c6ed Negative clearance means test won't run, not rule won't match.
Fixes https://gitlab.com/kicad/code/kicad/issues/13947
2023-02-16 18:10:26 +00:00
Jon Evans 245ce7259c Handle another case where schematic view was being cleared
Fixes https://gitlab.com/kicad/code/kicad/-/issues/13944


(cherry picked from commit ec2fc161e1)
2023-02-16 13:25:44 +00:00
Jon Evans f36cd60fdb Symbol editor: stop removing overlay from view
Fixes https://gitlab.com/kicad/code/kicad/-/issues/13944


(cherry picked from commit 955a5a13eb)
2023-02-16 13:17:34 +00:00
jean-pierre charras 8467e2d376 Pcbnew: Do not change visibility objects when changing Visibility layers
Fixes #13836
https://gitlab.com/kicad/code/kicad/issues/13836
2023-02-16 12:42:25 +01:00
jean-pierre charras 2529918d5f Pcbnew: fix incorrect rotation of thermal spoke for rotated footprints.
If the footprint rotation is not a multiple of 90°, the thermal spokes
were not correctly rotated.
Fixes #13919
https://gitlab.com/kicad/code/kicad/issues/13919
2023-02-16 12:41:35 +01:00
Jon Evans e2711a6121 Fix handling of selection overlay in schematic editor
We weren't actually using the overlay group at all

Fixes https://gitlab.com/kicad/code/kicad/-/issues/11142


(cherry picked from commit 0f18a36f8f)
2023-02-16 02:17:36 +00:00
Marek Roszko 89d22e5f94 update sentry-native to 0.6.0
primarily interested in windows bug fix to stack unwinding


(cherry picked from commit 041b7b196d)
2023-02-16 02:10:05 +00:00
jean-pierre charras f13fda9be5 Fix a QA test for bitmaps, to work with latest changes in bitmap code.
cherry pick from 05b68413f7
2023-02-15 15:56:12 +01:00
Ian McInerney 49f6a63a06 Fix compatibility with older wx versions
ToInt was only added in wx 3.1.6 apparently, so for now make them long
types. Fixes bug introduced in 1e8cc6855d

(Cherry-picked from 2b1040ae67)
2023-02-15 11:49:38 +00:00
Ian McInerney e078fea846 Relax wxPython version mismatch check to major.minor
The previous version check failed when the version was even slightly
different, including on the revision field. Theoretically the ABI of the
wx minor versions in use should be the same, so this might work. On the
other hand, with wxPython it could break as well. YOLO.

(Cherry-picked from 1e8cc6855d)
2023-02-15 11:49:15 +00:00
Ian McInerney 048c8b1670 Support subrelease field in wxWidgets cmake detection
Sometimes wxWidgets increments the subrelease to a non-zero value, and
since wxPython will report a subrelease, we must ensure we can get the
subrelease from the wx library properly, otherwise configure will fail
thinking the library isn't the same version as that used by wxPython.

Fixes: https://gitlab.com/kicad/code/kicad/-/issues/13887

(Cherry-picked from b536580119)
2023-02-15 11:48:53 +00:00
Marek Roszko 3b5c38d861 CURLINFO_SIZE_DOWNLOAD_T is a enum entry, use the version check instead
(cherry picked from commit c189053ee5)
2023-02-15 04:45:22 +00:00
Marek Roszko 90fb075e34 CURLOPT_XFERINFOFUNCTION is an enum entry not a define, the check is invalid
(cherry picked from commit 94b5ddbb50)
2023-02-15 04:26:51 +00:00
Jon Evans 08c6d9ce96 Set PPI properly in schematic bitmaps, too
(cherry picked from commit e8a88411ea)
2023-02-15 02:37:22 +00:00
Marek Roszko 76ccb8c31f Try and avoid crashing on gl context creation failure in the 3d viewer
Sentry event id 0ad4afa6b86a4a03ad7f8fdbcdb72f86


(cherry picked from commit 5ccf205788)
2023-02-15 02:20:14 +00:00
Jon Evans 3dfc502814 Router: Do not collide items within a net tie footprint
Fixes https://gitlab.com/kicad/code/kicad/-/issues/13909

(cherry picked from commit 2d7c5c5c0f)
2023-02-14 21:10:42 -05:00
Jon Evans df0f626283 Properties: remove assertion that no longer makes sense
(cherry picked from commit e5b376721d)
2023-02-14 21:10:42 -05:00
Jon Evans 1909ce9220 Properties: fix rebuilding when availability changes
(cherry picked from commit 61dd4b7043)
2023-02-14 21:10:42 -05:00
Jon Evans 15bef82e1e Properties: add some validators for PAD
(cherry picked from commit 0b3928d38f)
2023-02-14 21:10:42 -05:00
Jon Evans 60a45241e6 Properties: introduce validators; re-enable zone hatch settings
(cherry picked from commit eb240fda9a)
2023-02-14 21:10:42 -05:00
Jon Evans d403e92315 Properties: introduce method chaining for initialization
(cherry picked from commit 254168c788)
2023-02-14 21:10:42 -05:00
Marek Roszko eed7ede376 Fix step colors some more
Fixes https://gitlab.com/kicad/code/kicad/-/issues/13611

I need to refactor the overall structure and know what to do, but ugh lazy


(cherry picked from commit c6540575b5)
2023-02-15 00:45:17 +00:00
Jon Evans d20f49b58b Fix handling of PPI when loading embedded images
Fixes https://gitlab.com/kicad/code/kicad/-/issues/13884


(cherry picked from commit 473979d686)
2023-02-15 00:42:30 +00:00
Jon Evans 37091df142 Symbol chooser: save UI settings even when canceled
Fixes https://gitlab.com/kicad/code/kicad/-/issues/13903

(cherry picked from commit 29c4482bc8)
2023-02-14 18:27:31 -05:00
Jon Evans 21081cf80f Handle custom columns in symbol tree synchronizing adapter
Fixes https://gitlab.com/kicad/code/kicad/-/issues/13907

(cherry picked from commit 0913552f84)
2023-02-14 18:27:21 -05:00
Mark Roszko c213b37e96 Update 2 files
- /vcpkg-configuration.json
- /vcpkg.json
2023-02-14 23:12:05 +00:00
Seth Hillbrand d1ca84aa43 Don't desaturate the selection shadow
Selection shadows are helpful when showing which elements are selected
and there is no benefit (and some downside) to having their color
removed.

Fixes https://gitlab.com/kicad/code/kicad/issues/13878

(cherry picked from commit 9f8b25a0b0)
2023-02-14 10:22:49 -08:00
Wayne Stambaugh 0f7fbc411a Allow plotting of multiple board layers per plot in Python.
Since the always plot the edge cuts layer  option was deprecate,
the ability to plot multiple board layers was exposed through the
PLOT_CONTROLLER object.

Added the interactive plot information which was overlooked during
version 7 development.

Fixes https://gitlab.com/kicad/code/kicad/-/issues/13841

(cherry picked from commit eb83f76bff)
2023-02-14 09:53:16 -05:00
Jeff Young f4b2b1b03f Workaround wxWidgets enforced min pen width by using transparent pen.
Also fixes some bugs in our shape printing code when a border is not
specified but a fill is.

Fixes https://gitlab.com/kicad/code/kicad/issues/13891

(cherry picked from commit 03484aedbc)
2023-02-14 14:45:24 +00:00
Marek Roszko 0ecc36c4a5 Fix step model colors again
Fixes https://gitlab.com/kicad/code/kicad/-/issues/13882


(cherry picked from commit df022acc11)
2023-02-14 03:23:06 +00:00
Marek Roszko a48eace90a It's not impossible for the font face to fail loading
LoadFont()'s only usage already checked for nullptr to fallback, let's actually return nullptr on a failed load

Fixes sentry KICAD-8Z
Make the cause of sentry KICAD-95


(cherry picked from commit e8e407dfba)
2023-02-14 01:09:56 +00:00
Marek Roszko 7a2a51ad44 Prevent another GAL crash on init due to psuedo-race
Fixes Sentry KICAD-98


(cherry picked from commit 9647a22e50)
2023-02-14 00:11:15 +00:00
Seth Hillbrand f56fcb0a14 Better handling of vertex sorting
Nominally, the zcode of a vertex is unique.  This is not 100% true,
however, as we must interlace two 32-bit numbers into a single 32-bit
number.  Sorting needs to account for the possibility that the zcode
will be the same while other elements of the vertex are different.  This
commit fixes the broken boolean logic to more clearly handle these cases

Fixes https://gitlab.com/kicad/code/kicad/issues/13867

(cherry picked from commit e7fe69b97f)
2023-02-13 11:23:14 -08:00
Jeff Young 7816652078 Account for border when calculating text margin for text boxes.
Also fixes some unnoticed issues with the textbox dialogs (probably
dating from the move to wxWidgets 3.2).

Fixes https://gitlab.com/kicad/code/kicad/issues/13877
2023-02-13 17:07:42 +00:00
Jeff Young 20aacc7026 Don't confuse .OP with .OPTIONS.
Fixes https://gitlab.com/kicad/code/kicad/issues/13849

(cherry picked from commit d6bef19811)
2023-02-13 13:34:40 +00:00
Jeff Young 49938cfd09 Fix layout issue in IBIS fields. 2023-02-13 12:42:42 +00:00
Jeff Young 53a4ed6b24 ReadDataFields must be a separate step from Create.
Create() is done without execption processing, while ReadDataFields
should have exception processing.

(This also fixes a case where exception processing on ReadDataFields
was missing.)

Also fixes a bug where the pinSelect menu wasn't checked for -1 before
fetching.

Fixes https://gitlab.com/kicad/code/kicad/issues/13856
2023-02-13 12:42:42 +00:00
Marek Roszko 534000b49d Ensure gal is initialized before letting DoRepaint blowup spectacularly.
Maybe a fix for KICAD-6B


(cherry picked from commit 58350b4521)
2023-02-13 12:21:44 +00:00
Jeff Young 7e2ccbf909 Prepend correct SPICE prefix when necessary for plotting currents.
Fixes https://gitlab.com/kicad/code/kicad/issues/13850

(cherry picked from commit a22964a977)
2023-02-13 10:59:32 +00:00
Jeff Young b0b6968185 Fix too-narrow text edit control on Mac.
Also makes the yellow error highlight in CvPCB a bit less jarring.

Fixes https://gitlab.com/kicad/code/kicad/issues/13866

(cherry picked from commit 77421c8fb6)
2023-02-13 10:56:55 +00:00
Jeff Young 94963b5b3a Remove DRC exclusions that no longer have items.
Fixes https://gitlab.com/kicad/code/kicad/issues/13802

(cherry picked from commit 13391176ae)
2023-02-13 10:55:07 +00:00
Jeff Young 77fa61e6fc Make sure screen RTrees are updated when changing bounding boxes.
(cherry picked from commit 7bc79c17d4)
2023-02-13 10:54:59 +00:00
Jeff Young 94c450ad16 Bug fixes for LIB_PIN boundbox generation.
(cherry picked from commit 9ce5978c3d)
2023-02-13 10:54:55 +00:00
Jeff Young a292bf7c83 Don't dirty connectivity when moving non-reference SCH_FIELD.
(cherry picked from commit 2e9ed67e05)
2023-02-13 10:54:49 +00:00
Marek Roszko b24ee1c44f Prevent a crash when a spice SW_I lacks two pin net names
Fixes KICAD-5D


(cherry picked from commit 2cc3d8e9bc)
2023-02-13 03:32:07 +00:00
Jon Evans 981b22ba49 Add initial sections to bare template
(cherry picked from commit 12a9ed0208)
2023-02-11 12:04:45 -05:00
Jon Evans e1eedd3bba Attempt to fix GitLab template duplication
(cherry picked from commit 609ef96e42)
2023-02-11 12:04:39 -05:00
Wayne Stambaugh b949fd4d43 Begin 7.0.1 development. 2023-02-11 11:36:50 -05:00
9141 changed files with 1718781 additions and 7845306 deletions
-4
View File
@@ -30,7 +30,3 @@ bitmaps_png/cpp_*/*.cpp generated
# Lemon grammars
common/libeval/grammar.c generated
common/libeval/grammar.h generated
# Scripts
*.sh text eol=lf
*.bat text eol=crlf
+2 -2
View File
@@ -1,2 +1,2 @@
custom: "https://donate.kicad.org"
community_bridge: kicad
community_bridge: kicad
custom: "https://donate.cernandsocietyfoundation.cern/b/my-donation?cid=4&_cv=1"
+5 -11
View File
@@ -1,8 +1,8 @@
.downloads-by-cmake
.gdb_history
boost_root
/Build*
/build*
/Build
/build
/cmake-build-*
common/fp_lib_table_keywords.cpp
common/drc_rules_keywords.cpp
@@ -17,6 +17,8 @@ include/fp_lib_table_lexer.h
include/lib_table_lexer.h
include/netlist_lexer.h
include/page_layout_reader_lexer.h
eeschema/cmp_library_lexer.h
eeschema/cmp_library_keywords.*
eeschema/dialogs/dialog_bom_cfg_keywords.cpp
eeschema/dialogs/dialog_bom_cfg_lexer.h
common/template_fieldnames_keywords.cpp
@@ -25,11 +27,11 @@ eeschema/schematic_keywords.*
pcbnew/pcb_plot_params_keywords.cpp
pcbnew/pcb_plot_params_lexer.h
Makefile
CMakeUserPresets.json
CMakeCache.txt
.cache/
auto_renamed_to_cpp
Testing
version.h
config.h
install_manifest.txt
doxygen/out
@@ -50,7 +52,6 @@ bitmaps_png/tmp
common/pcb_keywords.cpp
include/pcb_lexer.h
fp-info-cache
qa/tests/output/**
# demo project auxiliary files
demos/**/*-bak
@@ -101,9 +102,6 @@ __pycache__
.editorconfig
CMakeSettings.json
.vscode/
compile_commands.json
/vcpkg_installed
CMakePresets.json
# Sublime Text
*.sublime-*
@@ -112,10 +110,6 @@ CMakePresets.json
.kdev4/
*.kdev4
# Qt Creator
CMakeLists.txt.user
*.autosave
# Translations
*.mo
i18n_status.svg
+28 -2
View File
@@ -8,13 +8,39 @@ default:
name: registry.gitlab.com/kicad/kicad-ci/source_containers/master/fedora:36
entrypoint: ["/bin/sh", "-c"]
##########################################################################
# Test the formatting in a merge request using clang-format
##########################################################################
# The variable CI_COMMIT_BEFORE_SHA is not available in normal merge requests
# so we must build the commit hash ourselves, see:
# https://gitlab.com/gitlab-org/gitlab/issues/12850
test_formatting:
stage: test
needs: []
only:
- merge_requests
allow_failure: true
before_script:
# We must manually add the KiCad remote to ensure it is named sensibly
- git remote add product https://gitlab.com/kicad/code/kicad.git
- git remote add source ${CI_MERGE_REQUEST_SOURCE_PROJECT_URL}.git
- git fetch -n product
- git fetch -n source
# Get the SHAs of the commits
- "TARGET_HEAD_SHA=$(git rev-parse product/${CI_MERGE_REQUEST_TARGET_BRANCH_NAME})"
- "SOURCE_HEAD_SHA=$(git rev-parse source/${CI_MERGE_REQUEST_SOURCE_BRANCH_NAME})"
- "MERGE_BASE_SHA=$(git merge-base ${TARGET_HEAD_SHA} ${SOURCE_HEAD_SHA})"
script:
- echo "Testing formatting from commit ${MERGE_BASE_SHA}"
- ./tools/check_coding.sh --diff --ci --commit ${MERGE_BASE_SHA}
include:
- local: '/.gitlab/templates.yml'
- local: '/.gitlab/Fedora-Linux-CI.yml'
- local: '/.gitlab/Ubuntu-20.04-CI.yml'
- local: '/.gitlab/Windows-CI.yml'
- local: '/.gitlab/macOS-CI.yml'
- local: '/.gitlab/coverity.yml'
- local: '/.gitlab/linux-metadata-validate.yml'
- local: '/.gitlab/doxygen.yml'
- local: '/.gitlab/mr_formatting.yml'
+4 -16
View File
@@ -6,7 +6,7 @@
# Don't tag until we have separate CI for MRs
# tags:
# - kicad-fedora
image: registry.gitlab.com/kicad/kicad-ci/source_containers/master/fedora:38
image: registry.gitlab.com/kicad/kicad-ci/source_containers/master/fedora:37
extends: .only_code
interruptible: false
cache:
@@ -25,10 +25,8 @@
-G Ninja
-DCMAKE_BUILD_TYPE=QABUILD
-DKICAD_STDLIB_LIGHT_DEBUG=ON
-DKICAD_SPICE=ON
-DKICAD_BUILD_I18N=ON
-DKICAD_TEST_XML_OUTPUT=ON
-DKICAD_BUILD_PNS_DEBUG_TOOL=ON
-DKICAD_USE_CMAKE_FINDPROTOBUF=ON
../../
- ninja 2>&1 | tee compilation_log.txt
- cd ../../
@@ -40,11 +38,6 @@
when: always
paths:
- build/linux/3d-viewer/
- build/linux/api/libkiapi.so*
- build/linux/common/libkicommon.so*
- build/linux/common/gal/libkigal.so*
- build/linux/eeschema/_eeschema.kiface
- build/linux/kicad/kicad-cli
- build/linux/pcbnew/pcbnew.py
- build/linux/pcbnew/_pcbnew.kiface
- build/linux/pcbnew/_pcbnew.so
@@ -65,8 +58,6 @@ fedora_build_linux_kicad:
fedora_build_linux_public:
extends: .fedora_build_linux_base
tags:
- saas-linux-medium-amd64
except:
variables:
- $CI_PROJECT_ROOT_NAMESPACE == "kicad"
@@ -144,17 +135,14 @@ fedora_report_metrics_public:
# Run the code unit tests.
##########################################################################
.fedora_qa:
image: registry.gitlab.com/kicad/kicad-ci/source_containers/master/fedora:38
image: registry.gitlab.com/kicad/kicad-ci/source_containers/master/fedora:37
extends:
- .unit_test
- .only_code
before_script:
- if [ "$TEST" == "cli" ] || [ "$TEST" == "python" ]; then python3 -m pip install -r qa/tests/requirements.txt; fi
- if [ "$TEST" == "cli" ]; then sudo dnf -y install gerbv; fi
parallel:
matrix:
# The name of the test without the qa_ prefix
- TEST: [python, cli, common, gerbview, pcbnew, pns_regressions, eeschema, kimath, sexpr, kicad2step, spice, api]
- TEST: [python, common, gerbview, pcbnew, eeschema, kimath, sexpr, kicad2step]
fedora_qa_kicad:
extends: .fedora_qa
+2 -1
View File
@@ -32,6 +32,7 @@
-DKICAD_STDLIB_LIGHT_DEBUG=ON
-DKICAD_SCRIPTING_WXPYTHON=ON
-DKICAD_USE_OCC=ON
-DKICAD_SPICE=ON
-DKICAD_BUILD_I18N=ON
-DKICAD_BUILD_PNS_DEBUG_TOOL=ON
../../
@@ -115,4 +116,4 @@
parallel:
matrix:
# The name of the test without the qa_ prefix
- TEST: [python, common, gerbview, pcbnew, eeschema, kimath, sexpr, kicad2step, spice]
- TEST: [python, common, gerbview, pcbnew, eeschema, kimath, sexpr, kicad2step]
+5 -7
View File
@@ -5,22 +5,19 @@ win64_build:
stage: build
tags:
- kicad-windows-1809
extends: .only_code
interruptible: false
image: registry.gitlab.com/kicad/kicad-ci/windows-build-image/win1809-msvc:latest
variables:
VCPKG_BINARY_SOURCES: 'nuget,kicad,readwrite'
# Switch the compressor to fastzip and reduce the compression level
FF_USE_FASTZIP: "true"
CACHE_COMPRESSION_LEVEL: "fast"
cache:
key: win64-vcpkg-"$CI_COMMIT_REF_SLUG"
paths:
- build\windows\vcpkg_installed
- .vcpkgCache
rules:
- if: $CI_PIPELINE_SOURCE == "schedule"
when: never
- if: $CI_PROJECT_ROOT_NAMESPACE == "kicad" && $CI_COMMIT_REF_PROTECTED == "true"
only:
- branches@kicad/code/kicad
- tags@kicad/code/kicad
script:
- C:\builder\build.ps1 -Env -Arch x64
- $vcpkgCache=Join-Path -Path (Get-Location) -ChildPath ".vcpkgCache";$env:VCPKG_DEFAULT_BINARY_CACHE=$vcpkgCache;New-Item -ItemType Directory -Force -Path $vcpkgCache
@@ -34,6 +31,7 @@ win64_build:
-DCMAKE_BUILD_TYPE=Debug `
-DKICAD_SCRIPTING_WXPYTHON=OFF `
-DKICAD_USE_OCC=ON `
-DKICAD_SPICE=ON `
-DKICAD_BUILD_PNS_DEBUG_TOOL=ON `
-DKICAD_USE_3DCONNEXION=ON `
../../
+12 -17
View File
@@ -22,16 +22,13 @@
# These results will be saved for 1 day if the build fails.
.coverity_submit: &coverity_submit |
echo "Creating tar file of scan results"
export COV_INT_FILENAME=cov-int-$(date +"%Y%m%d%H%M").tar.gz
tar cfz $COV_INT_FILENAME cov-int
tar cfz cov-int.tar.gz cov-int
echo "Submitting scan results"
s5cmd/s5cmd cp $COV_INT_FILENAME s3://$KICAD_CI_R2_BUCKET/coverity/
export FILE_URL="$KICAD_CI_R2_PUBLIC_BASE/coverity/$COV_INT_FILENAME"
export KICAD_VERSION=$(sed 's/[()]//g' kicad_build_version.txt)
curl https://scan.coverity.com/builds?project=$COVERITY_SCAN_PROJECT_NAME \
--form token=$COVERITY_SCAN_TOKEN \
--form email=$GITLAB_USER_EMAIL \
--form url="$FILE_URL" \
--form file=@cov-int.tar.gz \
--form version="$KICAD_VERSION" \
--form description="$KICAD_VERSION / $CI_COMMIT_TITLE" 2>&1 \
| tee curl-response.txt
@@ -42,9 +39,12 @@ Coverity:
tags:
- coverity
stage: build
image: registry.gitlab.com/kicad/kicad-ci/source_containers/master/fedora:38
rules:
- if: $CI_PIPELINE_SOURCE == "schedule" && $SCHEDULED_JOB_NAME == "coverity"
image: registry.gitlab.com/kicad/kicad-ci/source_containers/master/fedora:37
only:
refs:
- schedules
variables:
- $SCHEDULED_JOB_NAME == "coverity"
cache:
key: coverity
paths:
@@ -53,23 +53,18 @@ Coverity:
- export COVERITY_SCAN_PROJECT_NAME="kicad"
- test "$(git rev-parse --is-shallow-repository)" = "false" || (git fetch --unshallow)
- git fetch origin
- curl -LO https://github.com/peak/s5cmd/releases/download/v2.0.0/s5cmd_2.0.0_Linux-64bit.tar.gz
- mkdir s5cmd
- tar -xvf ./s5cmd_2.0.0_Linux-64bit.tar.gz -C s5cmd
- export AWS_ACCESS_KEY_ID=$KICAD_CI_R2_KEY_ID
- export AWS_SECRET_ACCESS_KEY=$KICAD_CI_R2_ACCESS_KEY
- export S3_ENDPOINT_URL=$KICAD_CI_R2_ENDPOINT
script:
- *coverity_cache_prep
- cmake
-DCMAKE_BUILD_TYPE=RelWithDebInfo
-DCMAKE_BUILD_TYPE=Debug
-DKICAD_STDLIB_LIGHT_DEBUG=ON
-DKICAD_SCRIPTING_WXPYTHON=ON
- coverity/bin/cov-build --dir cov-int make -j10
-DKICAD_SPICE=ON
- coverity/bin/cov-build --dir cov-int make -j8
- *coverity_submit
artifacts:
expire_in: 1 year
expose_as: 'Coverity log'
name: "coverity_log.txt"
paths:
- cov-int/build-log.txt
- cov-int/build-log.txt
+7 -4
View File
@@ -3,13 +3,16 @@ build_doxygen_docker:
services:
- docker:dind
stage: build
rules:
- if: $CI_PIPELINE_SOURCE == "schedule" && $SCHEDULED_JOB_NAME == "doxygen"
tags:
- gitlab-org-docker
- docker
before_script:
- docker info
- docker login -u gitlab-ci-token -p "$CI_JOB_TOKEN" "$CI_REGISTRY"
- docker login -u gitlab-ci-token -p "$CI_BUILD_TOKEN" "$CI_REGISTRY"
script:
- docker build -t "${CI_REGISTRY_IMAGE}/doxygen:$CI_COMMIT_BRANCH" -f ./doxygen/doxygen.Dockerfile .
- docker push "${CI_REGISTRY_IMAGE}/doxygen:$CI_COMMIT_BRANCH"
only:
refs:
- schedules
variables:
- $SCHEDULED_JOB_NAME == "doxygen"
+15 -9
View File
@@ -6,18 +6,23 @@ validate_linux_metadata:
needs: []
interruptible: false
# This is the only CI image with the utilities needed for this test
image: registry.gitlab.com/kicad/kicad-ci/source_containers/master/fedora:38
image: registry.gitlab.com/kicad/kicad-ci/source_containers/master/fedora:37
# Due to bug https://github.com/hughsie/appstream-glib/issues/381, this doesn't think our description tag
# is localized even though it actually is.
allow_failure: true
rules:
- if: $CI_PIPELINE_SOURCE == "schedule"
when: never
- if: $CI_PIPELINE_SOURCE == "push" || $CI_PIPELINE_SOURCE == "merge_request_event"
changes:
- resources/linux/**/*
- qa/resources/linux/**/*
- translation/**/*
only:
refs:
- master
- branches
- merge_requests
- pushes
changes:
# Only run if the resources, its tests, or the translations are updated
- resources/linux/**/*
- qa/resources/linux/**/*
- translation/**/*
except:
- schedules
# Only build the metadata files in this CI job
script:
- mkdir -p build/linux
@@ -26,6 +31,7 @@ validate_linux_metadata:
-DCMAKE_BUILD_TYPE=Debug
-DKICAD_STDLIB_LIGHT_DEBUG=ON
-DKICAD_SCRIPTING_WXPYTHON=ON
-DKICAD_SPICE=ON
-DKICAD_BUILD_I18N=ON
../../
- make metadata
-29
View File
@@ -1,29 +0,0 @@
##########################################################################
# Build KiCad on Windows and save the results
##########################################################################
macos_build:
stage: build
tags:
- kicad-macos
interruptible: false
rules:
- if: $CI_PIPELINE_SOURCE == "schedule"
when: never
- if: $CI_PROJECT_ROOT_NAMESPACE == "kicad" && $CI_COMMIT_REF_PROTECTED == "true"
script:
- mkdir -p build/macos
- cd build/macos
- cmake
-G Ninja
-DCMAKE_TOOLCHAIN_FILE=/Users/ci/kicad-mac-builder/toolchain/kicad-mac-builder.cmake
../../
- cmake --build . 2>&1 | tee compilation_log.txt
- cd ../../
artifacts:
# Only save the artifacts that are needed for running the tests in the next stage
# and the compilation log. The entire build directory is too large to save as an
# artifact.
expire_in: 2 hrs
when: always
paths:
- build/macos/compilation_log.txt
-27
View File
@@ -1,27 +0,0 @@
##########################################################################
# Test the formatting in a merge request using clang-format
##########################################################################
# The variable CI_COMMIT_BEFORE_SHA is not available in normal merge requests
# so we must build the commit hash ourselves, see:
# https://gitlab.com/gitlab-org/gitlab/-/issues/12850
test_formatting:
stage: test
needs: []
rules:
- if: $CI_PIPELINE_SOURCE == "merge_request_event"
allow_failure: true
before_script:
# We must manually add the KiCad remote to ensure it is named sensibly
- git remote add product https://gitlab.com/kicad/code/kicad.git ||
git remote set-url product https://gitlab.com/kicad/code/kicad.git
- git remote add source ${CI_MERGE_REQUEST_SOURCE_PROJECT_URL}.git ||
git remote set-url source ${CI_MERGE_REQUEST_SOURCE_PROJECT_URL}.git
- git fetch -n product
- git fetch -n source
# Get the SHAs of the commits
- "TARGET_HEAD_SHA=$(git rev-parse product/${CI_MERGE_REQUEST_TARGET_BRANCH_NAME})"
- "SOURCE_HEAD_SHA=$(git rev-parse source/${CI_MERGE_REQUEST_SOURCE_BRANCH_NAME})"
- "MERGE_BASE_SHA=$(git merge-base ${TARGET_HEAD_SHA} ${SOURCE_HEAD_SHA})"
script:
- echo "Testing formatting from commit ${MERGE_BASE_SHA}"
- ./tools/check_coding.sh --diff --ci --commit ${MERGE_BASE_SHA}
+10 -10
View File
@@ -17,21 +17,21 @@
.unit_test:
stage: test
when: on_success
variables:
BOOST_TEST_LOGGER: 'JUNIT,warning,test_results.${TEST}.xml:HRF,message'
CTEST_OUTPUT_ON_FAILURE: 1
# We define this using a before script because GitLab cannot merge variable
# definitions across inheritance (so the variables block from this would disappear)
before_script:
- export BOOST_TEST_LOGGER='JUNIT,all,test_results.${TEST}.xml:HRF,warning'
- export CTEST_OUTPUT_ON_FAILURE=1
script:
- cd build/linux/qa
- ctest -R qa_${TEST}
# GitLab supports displaying the results in the GUI through JUNIT artifacts
# (https://docs.gitlab.com/ee/ci/junit_test_reports.html)
# so we upload the JUNIT results.
# so we upload the JUNIT results. Note that there is a bug with how paths
# are processed in the junit report (https://gitlab.com/gitlab-org/gitlab/issues/23835)
# so we can't use a glob and have to list out each hierarchy separately.
artifacts:
when: always
paths:
- build/linux/qa/**/*.log
- build/linux/qa/**/output/*
- build/linux/qa/**/*.xml
reports:
junit:
- build/linux/qa/**/*.xml
- build/linux/qa/*/*.xml
- build/linux/qa/*/*/*.xml
+61 -1
View File
@@ -61,6 +61,7 @@
#define MASK_3D_CACHE "3D_CACHE"
static std::mutex mutex3D_cache;
static std::mutex mutex3D_cacheManager;
static bool isSHA1Same( const unsigned char* shaA, const unsigned char* shaB ) noexcept
@@ -696,4 +697,63 @@ void S3D_CACHE::CleanCacheDir( int aNumDaysOld )
}
}
}
}
}
void PROJECT::Cleanup3DCache()
{
std::lock_guard<std::mutex> lock( mutex3D_cacheManager );
// Get the existing cache from the project
S3D_CACHE* cache = dynamic_cast<S3D_CACHE*>( GetElem( ELEM_3DCACHE ) );
if( cache )
{
// We'll delete ".3dc" cache files older than this many days
int clearCacheInterval = 0;
if( Pgm().GetCommonSettings() )
clearCacheInterval = Pgm().GetCommonSettings()->m_System.clear_3d_cache_interval;
// An interval of zero means the user doesn't want to ever clear the cache
if( clearCacheInterval > 0 )
cache->CleanCacheDir( clearCacheInterval );
}
}
S3D_CACHE* PROJECT::Get3DCacheManager( bool aUpdateProjDir )
{
std::lock_guard<std::mutex> lock( mutex3D_cacheManager );
// Get the existing cache from the project
S3D_CACHE* cache = dynamic_cast<S3D_CACHE*>( GetElem( ELEM_3DCACHE ) );
if( !cache )
{
// Create a cache if there is not one already
cache = new S3D_CACHE();
wxFileName cfgpath;
cfgpath.AssignDir( SETTINGS_MANAGER::GetUserSettingsPath() );
cfgpath.AppendDir( wxT( "3d" ) );
cache->SetProgramBase( &Pgm() );
cache->Set3DConfigDir( cfgpath.GetFullPath() );
SetElem( ELEM_3DCACHE, cache );
aUpdateProjDir = true;
}
if( aUpdateProjDir )
cache->SetProject( this );
return cache;
}
FILENAME_RESOLVER* PROJECT::Get3DFilenameResolver()
{
return Get3DCacheManager()->GetResolver();
}
+9 -53
View File
@@ -2,7 +2,7 @@
* This program source code file is part of KiCad, a free EDA CAD application.
*
* Copyright (C) 2015-2016 Cirilo Bernardo <cirilo.bernardo@gmail.com>
* Copyright (C) 2020-2023 KiCad Developers, see AUTHORS.txt for contributors.
* Copyright (C) 2020-2022 KiCad Developers, see AUTHORS.txt for contributors.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
@@ -155,47 +155,13 @@ void S3D_PLUGIN_MANAGER::loadPlugins( void )
fn.AssignDir( PATHS::GetStockPlugins3DPath() );
checkPluginPath( std::string( fn.GetPathWithSep().ToUTF8() ), searchpaths );
#else
if( wxGetEnv( wxT( "KICAD_RUN_FROM_BUILD_DIR" ), nullptr ) )
{
// Exe will be at <build_dir>/pcbnew/pcbnew.app/Contents/MacOS/pcbnew for standalone
// Plugin will be at <build_dir>/kicad/KiCad.app/Contents/PlugIns/3d
fn.Assign( wxStandardPaths::Get().GetExecutablePath() );
// Search path on OS X is
// (1) Machine /Library/Application Support/kicad/PlugIns/3d
checkPluginPath( PATHS::GetOSXKicadMachineDataDir() + wxT( "/PlugIns/3d" ), searchpaths );
if( fn.GetName() == wxT( "kicad" ) )
{
fn.AppendDir( wxT( ".." ) ); // Contents
}
else
{
fn.AppendDir( wxT( ".." ) ); // Contents
fn.AppendDir( wxT( ".." ) ); // pcbnew.app
fn.AppendDir( wxT( ".." ) ); // pcbnew
fn.AppendDir( wxT( ".." ) ); // Build root
fn.AppendDir( wxT( "kicad" ) );
fn.AppendDir( wxT( "KiCad.app" ) );
fn.AppendDir( wxT( "Contents" ) );
}
fn.AppendDir( wxT( "PlugIns" ) );
fn.AppendDir( wxT( "3d" ) );
fn.MakeAbsolute();
std::string testpath = std::string( fn.GetPathWithSep().ToUTF8() );
checkPluginPath( testpath, searchpaths );
// Also check when running KiCad manager from build dir
}
else
{
// Search path on OS X is
// (1) Machine /Library/Application Support/kicad/PlugIns/3d
checkPluginPath( PATHS::GetOSXKicadMachineDataDir() + wxT( "/PlugIns/3d" ), searchpaths );
// (2) Bundle kicad.app/Contents/PlugIns/3d
fn.AssignDir( PATHS::GetStockPlugins3DPath() );
checkPluginPath( fn.GetPathWithSep(), searchpaths );
}
// (2) Bundle kicad.app/Contents/PlugIns/3d
fn.AssignDir( PATHS::GetStockPlugins3DPath() );
checkPluginPath( fn.GetPathWithSep(), searchpaths );
#endif
std::list< wxString >::iterator sPL = searchpaths.begin();
@@ -236,7 +202,7 @@ void S3D_PLUGIN_MANAGER::loadPlugins( void )
char const* cp = pp->GetFileFilter( i );
if( cp )
addFilterString( cp );
addFilterString( wxString::FromUTF8Unchecked( cp ) );
}
addExtensionMap( pp );
@@ -328,16 +294,6 @@ void S3D_PLUGIN_MANAGER::checkPluginName( const wxString& aPath,
++bl;
}
// prevent loading non-plugin dlls
if( wxGetEnv( wxT( "KICAD_RUN_FROM_BUILD_DIR" ), nullptr ) )
{
if( !path.GetName().StartsWith( "s3d_plugin" )
&& !path.GetName().StartsWith( "libs3d_plugin" ) )
{
return;
}
}
aPluginList.push_back( wxpath );
wxLogTrace( MASK_3D_PLUGINMGR, wxT( " * [INFO] found 3D plugin '%s'\n" ), wxpath.GetData() );
@@ -416,7 +372,7 @@ void S3D_PLUGIN_MANAGER::addExtensionMap( KICAD_PLUGIN_LDR_3D* aPlugin )
wxString ws;
if( cp )
ws = wxString( cp );
ws = wxString::FromUTF8Unchecked( cp );
if( !ws.empty() )
{
+2 -2
View File
@@ -91,7 +91,7 @@ endif()
unset( S3DSG_VERSION_FILE CACHE )
# Define a flag to expose the appropriate EXPORT macro at build time
target_compile_definitions( kicad_3dsg PRIVATE COMPILE_SGLIB )
target_compile_definitions( kicad_3dsg PRIVATE -DCOMPILE_SGLIB )
target_link_libraries( kicad_3dsg ${wxWidgets_LIBRARIES} )
@@ -108,4 +108,4 @@ install( TARGETS
if( KICAD_WIN32_INSTALL_PDBS )
# Get the PDBs to copy over for MSVC
install(FILES $<TARGET_PDB_FILE:kicad_3dsg> DESTINATION ${KICAD_BIN})
endif()
endif()
+1 -1
View File
@@ -476,7 +476,7 @@ SGVECTOR S3D::CalcTriNorm( const SGPOINT& p1, const SGPOINT& p2, const SGPOINT&
// normal
tri = glm::cross( pts[1] - pts[0], pts[2] - pts[0] );
(void)glm::normalize( tri );
glm::normalize( tri );
return SGVECTOR( tri.x, tri.y, tri.z );
}
+122 -354
View File
@@ -1,9 +1,8 @@
/*
* This program source code file is part of KiCad, a free EDA CAD application.
*
* Copyright (C) 2015-2023 Mario Luzeiro <mrluzeiro@ua.pt>
* Copyright (C) 2023 CERN
* Copyright (C) 1992-2024 KiCad Developers, see AUTHORS.txt for contributors.
* Copyright (C) 2015-2022 Mario Luzeiro <mrluzeiro@ua.pt>
* Copyright (C) 1992-2023 KiCad Developers, see AUTHORS.txt for contributors.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
@@ -23,7 +22,7 @@
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
*/
#include <gal/3d/camera.h>
#include "../3d_rendering/camera.h"
#include "board_adapter.h"
#include <board_design_settings.h>
#include <board_stackup_manager/board_stackup.h>
@@ -37,7 +36,6 @@
#include <pgm_base.h>
#include <settings/settings_manager.h>
#include <wx/log.h>
#include <pcbnew_settings.h>
#include <advanced_config.h>
@@ -50,7 +48,7 @@
#define SOLDERPASTE_LAYER_THICKNESS pcbIUScale.mmToIU( 0.04 )
CUSTOM_COLORS_LIST BOARD_ADAPTER::g_SilkColors;
CUSTOM_COLORS_LIST BOARD_ADAPTER::g_SilkscreenColors;
CUSTOM_COLORS_LIST BOARD_ADAPTER::g_MaskColors;
CUSTOM_COLORS_LIST BOARD_ADAPTER::g_PasteColors;
CUSTOM_COLORS_LIST BOARD_ADAPTER::g_FinishColors;
@@ -63,8 +61,6 @@ KIGFX::COLOR4D BOARD_ADAPTER::g_DefaultSolderMask;
KIGFX::COLOR4D BOARD_ADAPTER::g_DefaultSolderPaste;
KIGFX::COLOR4D BOARD_ADAPTER::g_DefaultSurfaceFinish;
KIGFX::COLOR4D BOARD_ADAPTER::g_DefaultBoardBody;
KIGFX::COLOR4D BOARD_ADAPTER::g_DefaultComments;
KIGFX::COLOR4D BOARD_ADAPTER::g_DefaultECOs;
// To be used in Raytracing render to create bevels on layer items
float g_BevelThickness3DU = 0.0f;
@@ -89,13 +85,15 @@ BOARD_ADAPTER::BOARD_ADAPTER() :
m_IsPreviewer( false ),
m_board( nullptr ),
m_3dModelManager( nullptr ),
m_renderSettings( nullptr ),
m_colors( nullptr ),
m_layerZcoordTop(),
m_layerZcoordBottom()
{
wxLogTrace( m_logTrace, wxT( "BOARD_ADAPTER::BOARD_ADAPTER" ) );
ReloadColorSettings();
if( PgmOrNull() )
m_colors = Pgm().GetSettingsManager().GetColorSettings();
m_boardPos = VECTOR2I();
m_boardSize = VECTOR2I();
@@ -103,9 +101,9 @@ BOARD_ADAPTER::BOARD_ADAPTER() :
m_boardBoundingBox.Reset();
m_TH_IDs.Clear();
m_TH_ODs.Clear();
m_viaAnnuli.Clear();
m_throughHoleIds.Clear();
m_throughHoleOds.Clear();
m_throughHoleAnnularRings.Clear();
m_copperLayersCount = 2;
@@ -132,34 +130,26 @@ BOARD_ADAPTER::BOARD_ADAPTER() :
m_SilkScreenColorTop = SFVEC4F( 0.9, 0.9, 0.9, 1.0 );
m_SilkScreenColorBot = SFVEC4F( 0.9, 0.9, 0.9, 1.0 );
m_CopperColor = SFVEC4F( 0.75, 0.61, 0.23, 1.0 );
m_UserDrawingsColor = SFVEC4F( 0.85, 0.85, 0.85, 1.0 );
m_UserCommentsColor = SFVEC4F( 0.85, 0.85, 0.85, 1.0 );
m_ECO1Color = SFVEC4F( 0.70, 0.10, 0.10, 1.0 );
m_ECO2Color = SFVEC4F( 0.70, 0.10, 0.10, 1.0 );
m_platedPadsFront = nullptr;
m_platedPadsBack = nullptr;
m_offboardPadsFront = nullptr;
m_offboardPadsBack = nullptr;
m_frontPlatedPadAndGraphicPolys = nullptr;
m_backPlatedPadAndGraphicPolys = nullptr;
m_frontPlatedCopperPolys = nullptr;
m_backPlatedCopperPolys = nullptr;
m_frontPlatedPadPolys = nullptr;
m_backPlatedPadPolys = nullptr;
if( !g_ColorsLoaded )
{
#define ADD_COLOR( list, r, g, b, a, name ) \
list.emplace_back( r/255.0, g/255.0, b/255.0, a, name )
ADD_COLOR( g_SilkColors, 245, 245, 245, 1.0, NotSpecifiedPrm() ); // White
ADD_COLOR( g_SilkColors, 20, 51, 36, 1.0, wxT( "Green" ) );
ADD_COLOR( g_SilkColors, 181, 19, 21, 1.0, wxT( "Red" ) );
ADD_COLOR( g_SilkColors, 2, 59, 162, 1.0, wxT( "Blue" ) );
ADD_COLOR( g_SilkColors, 11, 11, 11, 1.0, wxT( "Black" ) );
ADD_COLOR( g_SilkColors, 245, 245, 245, 1.0, wxT( "White" ) );
ADD_COLOR( g_SilkColors, 32, 2, 53, 1.0, wxT( "Purple" ) );
ADD_COLOR( g_SilkColors, 194, 195, 0, 1.0, wxT( "Yellow" ) );
ADD_COLOR( g_SilkscreenColors, 245, 245, 245, 1.0, NotSpecifiedPrm() ); // White
ADD_COLOR( g_SilkscreenColors, 20, 51, 36, 1.0, wxT( "Green" ) );
ADD_COLOR( g_SilkscreenColors, 181, 19, 21, 1.0, wxT( "Red" ) );
ADD_COLOR( g_SilkscreenColors, 2, 59, 162, 1.0, wxT( "Blue" ) );
ADD_COLOR( g_SilkscreenColors, 11, 11, 11, 1.0, wxT( "Black" ) );
ADD_COLOR( g_SilkscreenColors, 245, 245, 245, 1.0, wxT( "White" ) );
ADD_COLOR( g_SilkscreenColors, 32, 2, 53, 1.0, wxT( "Purple" ) );
ADD_COLOR( g_SilkscreenColors, 194, 195, 0, 1.0, wxT( "Yellow" ) );
ADD_COLOR( g_MaskColors, 20, 51, 36, 0.83, NotSpecifiedPrm() ); // Green
ADD_COLOR( g_MaskColors, 20, 51, 36, 0.83, wxT( "Green" ) );
@@ -206,9 +196,6 @@ BOARD_ADAPTER::BOARD_ADAPTER() :
g_DefaultSurfaceFinish = COLOR4D( 0.75, 0.61, 0.23, 1.0 );
g_DefaultBoardBody = COLOR4D( 0.43, 0.45, 0.30, 0.90 );
g_DefaultComments = COLOR4D( 0.85, 0.85, 0.85, 1.0 );
g_DefaultECOs = COLOR4D( 0.70, 0.10, 0.10, 1.0 );
g_ColorsLoaded = true;
}
#undef ADD_COLOR
@@ -221,53 +208,54 @@ BOARD_ADAPTER::~BOARD_ADAPTER()
}
void BOARD_ADAPTER::ReloadColorSettings() noexcept
{
wxCHECK( PgmOrNull(), /* void */ );
PCBNEW_SETTINGS* cfg = nullptr;
try
{
cfg = Pgm().GetSettingsManager().GetAppSettings<PCBNEW_SETTINGS>();
}
catch( const std::runtime_error& e )
{
wxFAIL_MSG( e.what() );
}
if( cfg )
{
m_colors = Pgm().GetSettingsManager().GetColorSettings( cfg->m_ColorTheme );
}
}
bool BOARD_ADAPTER::Is3dLayerEnabled( PCB_LAYER_ID aLayer,
const std::bitset<LAYER_3D_END>& aVisibilityFlags ) const
bool BOARD_ADAPTER::Is3dLayerEnabled( PCB_LAYER_ID aLayer ) const
{
wxASSERT( aLayer < PCB_LAYER_ID_COUNT );
if( m_board && !m_board->IsLayerEnabled( aLayer ) )
return false;
// see if layer needs to be shown
// check the flags
switch( aLayer )
{
case B_Cu: return aVisibilityFlags.test( LAYER_3D_COPPER_BOTTOM );
case F_Cu: return aVisibilityFlags.test( LAYER_3D_COPPER_TOP );
case B_Adhes: return aVisibilityFlags.test( LAYER_3D_ADHESIVE );
case F_Adhes: return aVisibilityFlags.test( LAYER_3D_ADHESIVE );
case B_Paste: return aVisibilityFlags.test( LAYER_3D_SOLDERPASTE );
case F_Paste: return aVisibilityFlags.test( LAYER_3D_SOLDERPASTE );
case B_SilkS: return aVisibilityFlags.test( LAYER_3D_SILKSCREEN_BOTTOM );
case F_SilkS: return aVisibilityFlags.test( LAYER_3D_SILKSCREEN_TOP );
case B_Mask: return aVisibilityFlags.test( LAYER_3D_SOLDERMASK_BOTTOM );
case F_Mask: return aVisibilityFlags.test( LAYER_3D_SOLDERMASK_TOP );
case Dwgs_User: return aVisibilityFlags.test( LAYER_3D_USER_DRAWINGS );
case Cmts_User: return aVisibilityFlags.test( LAYER_3D_USER_COMMENTS );
case Eco1_User: return aVisibilityFlags.test( LAYER_3D_USER_ECO1 );
case Eco2_User: return aVisibilityFlags.test( LAYER_3D_USER_ECO2 );
default: return m_board && m_board->IsLayerVisible( aLayer );
case B_Adhes:
case F_Adhes:
return m_Cfg->m_Render.show_adhesive;
case B_Paste:
case F_Paste:
return m_Cfg->m_Render.show_solderpaste;
case B_SilkS:
case F_SilkS:
return m_Cfg->m_Render.show_silkscreen;
case B_Mask:
case F_Mask:
return m_Cfg->m_Render.show_soldermask;
case Dwgs_User:
case Cmts_User:
return !m_Cfg->m_Render.realistic && m_Cfg->m_Render.show_comments;
case Eco1_User:
case Eco2_User:
return !m_Cfg->m_Render.realistic && m_Cfg->m_Render.show_eco;
case Edge_Cuts:
return !m_Cfg->m_Render.realistic && !m_Cfg->m_Render.show_board_body;
case Margin:
return !m_Cfg->m_Render.realistic;
case B_Cu:
case F_Cu:
return !m_board || m_board->IsLayerVisible( aLayer ) || m_Cfg->m_Render.realistic;
default:
// the layer is an internal copper layer, used the visibility
return m_board && m_board->IsLayerVisible( aLayer );
}
}
@@ -283,12 +271,6 @@ bool BOARD_ADAPTER::IsFootprintShown( FOOTPRINT_ATTR_T aFPAttributes ) const
return false;
}
if( aFPAttributes & FP_DNP )
{
if( !m_Cfg->m_Render.show_footprints_dnp )
return false;
}
if( aFPAttributes & FP_SMD )
return m_Cfg->m_Render.show_footprints_insert;
@@ -344,7 +326,11 @@ void BOARD_ADAPTER::InitSettings( REPORTER* aStatusReporter, REPORTER* aWarningR
BOX2I bbbox;
if( m_board )
bbbox = m_board->ComputeBoundingBox( !m_board->IsFootprintHolder() && haveOutline, false );
{
bbbox = m_board->ComputeBoundingBox( !m_board->IsFootprintHolder()
&& m_Cfg->m_Render.realistic
&& haveOutline );
}
// Gives a non null size to avoid issues in zoom / scale calculations
if( ( bbbox.GetWidth() == 0 ) && ( bbbox.GetHeight() == 0 ) )
@@ -367,10 +353,6 @@ void BOARD_ADAPTER::InitSettings( REPORTER* aStatusReporter, REPORTER* aWarningR
// Calculate the conversion to apply to all positions.
m_biuTo3Dunits = RANGE_SCALE_3D / std::max( m_boardSize.x, m_boardSize.y );
// Hack to keep "home" zoom from being too small.
if( !m_board || !m_board->IsFootprintHolder() )
m_biuTo3Dunits *= 1.6f;
m_boardBodyThickness3DU = DEFAULT_BOARD_THICKNESS * m_biuTo3Dunits;
m_frontCopperThickness3DU = DEFAULT_COPPER_THICKNESS * m_biuTo3Dunits;
m_backCopperThickness3DU = DEFAULT_COPPER_THICKNESS * m_biuTo3Dunits;
@@ -397,18 +379,13 @@ void BOARD_ADAPTER::InitSettings( REPORTER* aStatusReporter, REPORTER* aWarningR
break;
case BS_ITEM_TYPE_COPPER:
{
// The copper thickness must be > 0 to avoid draw issues (divide by 0 for instance)
// We use a minimal arbitrary value = 1 micrometer here:
int copper_thickness = std::max( item->GetThickness(), pcbIUScale.mmToIU( 0.001 ) );
if( item->GetBrdLayerId() == F_Cu )
m_frontCopperThickness3DU = copper_thickness * m_biuTo3Dunits;
m_frontCopperThickness3DU = item->GetThickness() * m_biuTo3Dunits;
else if( item->GetBrdLayerId() == B_Cu )
m_backCopperThickness3DU = copper_thickness * m_biuTo3Dunits;
m_backCopperThickness3DU = item->GetThickness() * m_biuTo3Dunits;
else if( item->IsEnabled() )
thickness += copper_thickness;
}
thickness += item->GetThickness();
break;
default:
@@ -454,7 +431,7 @@ void BOARD_ADAPTER::InitSettings( REPORTER* aStatusReporter, REPORTER* aWarningR
for( ; layer < MAX_CU_LAYERS; layer++ )
{
m_layerZcoordBottom[layer] = -( m_boardBodyThickness3DU / 2.0f );
m_layerZcoordTop[layer] = m_layerZcoordBottom[layer] - m_backCopperThickness3DU;
m_layerZcoordTop[layer] = -( m_boardBodyThickness3DU / 2.0f ) - m_backCopperThickness3DU;
}
// This is the top of the copper layer thickness.
@@ -510,6 +487,7 @@ void BOARD_ADAPTER::InitSettings( REPORTER* aStatusReporter, REPORTER* aWarningR
zposTop = zposBottom + m_nonCopperLayerThickness3DU;
break;
// !TODO: review
default:
zposTop = zpos_copperTop_front + (layer_id - MAX_CU_LAYERS + 3.0f) * zpos_offset;
zposBottom = zposTop - m_nonCopperLayerThickness3DU;
@@ -535,7 +513,7 @@ void BOARD_ADAPTER::InitSettings( REPORTER* aStatusReporter, REPORTER* aWarningR
m_boardBoundingBox = BBOX_3D( boardMin, boardMax );
#ifdef PRINT_STATISTICS_3D_VIEWER
int64_t stats_startCreateBoardPolyTime = GetRunningMicroSecs();
unsigned stats_startCreateBoardPolyTime = GetRunningMicroSecs();
#endif
if( aStatusReporter )
@@ -543,73 +521,22 @@ void BOARD_ADAPTER::InitSettings( REPORTER* aStatusReporter, REPORTER* aWarningR
createLayers( aStatusReporter );
COLOR_SETTINGS* colors = Pgm().GetSettingsManager().GetColorSettings();
auto to_SFVEC4F =
[]( const COLOR4D& src )
{
return SFVEC4F( src.r, src.g, src.b, src.a );
};
std::map<int, COLOR4D> colors = GetLayerColors();
m_BgColorTop = to_SFVEC4F( colors->GetColor( LAYER_3D_BACKGROUND_TOP ) );
m_BgColorBot = to_SFVEC4F( colors->GetColor( LAYER_3D_BACKGROUND_BOTTOM ) );
m_BgColorTop = to_SFVEC4F( colors[ LAYER_3D_BACKGROUND_TOP ] );
m_BgColorBot = to_SFVEC4F( colors[ LAYER_3D_BACKGROUND_BOTTOM ] );
m_SolderPasteColor = to_SFVEC4F( colors[ LAYER_3D_SOLDERPASTE ] );
m_SilkScreenColorBot = to_SFVEC4F( colors[ LAYER_3D_SILKSCREEN_BOTTOM ] );
m_SilkScreenColorTop = to_SFVEC4F( colors[ LAYER_3D_SILKSCREEN_TOP ] );
m_SolderMaskColorBot = to_SFVEC4F( colors[ LAYER_3D_SOLDERMASK_BOTTOM ] );
m_SolderMaskColorTop = to_SFVEC4F( colors[ LAYER_3D_SOLDERMASK_TOP ] );
m_CopperColor = to_SFVEC4F( colors[ LAYER_3D_COPPER_TOP ] );
m_BoardBodyColor = to_SFVEC4F( colors[ LAYER_3D_BOARD ] );
m_UserDrawingsColor = to_SFVEC4F( colors[ LAYER_3D_USER_DRAWINGS ] );
m_UserCommentsColor = to_SFVEC4F( colors[ LAYER_3D_USER_COMMENTS ] );
m_ECO1Color = to_SFVEC4F( colors[ LAYER_3D_USER_ECO1 ] );
m_ECO2Color = to_SFVEC4F( colors[ LAYER_3D_USER_ECO2 ] );
}
m_SolderPasteColor = to_SFVEC4F( colors->GetColor( LAYER_3D_SOLDERPASTE ) );
std::map<int, COLOR4D> BOARD_ADAPTER::GetDefaultColors() const
{
std::map<int, COLOR4D> colors;
colors[ LAYER_3D_BACKGROUND_TOP ] = BOARD_ADAPTER::g_DefaultBackgroundTop;
colors[ LAYER_3D_BACKGROUND_BOTTOM ] = BOARD_ADAPTER::g_DefaultBackgroundBot;
colors[ LAYER_3D_BOARD ] = BOARD_ADAPTER::g_DefaultBoardBody;
colors[ LAYER_3D_COPPER_TOP ] = BOARD_ADAPTER::g_DefaultSurfaceFinish;
colors[ LAYER_3D_COPPER_BOTTOM ] = BOARD_ADAPTER::g_DefaultSurfaceFinish;
colors[ LAYER_3D_SILKSCREEN_TOP ] = BOARD_ADAPTER::g_DefaultSilkscreen;
colors[ LAYER_3D_SILKSCREEN_BOTTOM ] = BOARD_ADAPTER::g_DefaultSilkscreen;
colors[ LAYER_3D_SOLDERMASK_TOP ] = BOARD_ADAPTER::g_DefaultSolderMask;
colors[ LAYER_3D_SOLDERMASK_BOTTOM ] = BOARD_ADAPTER::g_DefaultSolderMask;
colors[ LAYER_3D_SOLDERPASTE ] = BOARD_ADAPTER::g_DefaultSolderPaste;
colors[ LAYER_3D_USER_DRAWINGS ] = BOARD_ADAPTER::g_DefaultComments;
colors[ LAYER_3D_USER_COMMENTS ] = BOARD_ADAPTER::g_DefaultComments;
colors[ LAYER_3D_USER_ECO1 ] = BOARD_ADAPTER::g_DefaultECOs;
colors[ LAYER_3D_USER_ECO2 ] = BOARD_ADAPTER::g_DefaultECOs;
return colors;
}
std::map<int, COLOR4D> BOARD_ADAPTER::GetLayerColors() const
{
std::map<int, COLOR4D> colors;
if( LAYER_PRESET_3D* preset = m_Cfg->FindPreset( m_Cfg->m_CurrentPreset ) )
{
colors = preset->colors;
}
else
{
COLOR_SETTINGS* settings = Pgm().GetSettingsManager().GetColorSettings();
for( const auto& [ layer, defaultColor /* unused */ ] : GetDefaultColors() )
colors[ layer ] = settings->GetColor( layer );
}
if( m_Cfg->m_UseStackupColors && m_board )
if( m_board && colors->GetUseBoardStackupColors() )
{
const BOARD_STACKUP& stackup = m_board->GetDesignSettings().GetStackupDescriptor();
KIGFX::COLOR4D bodyColor( 0, 0, 0, 0 );
auto findColor =
[]( const wxString& aColorName, const CUSTOM_COLORS_LIST& aColorSet )
@@ -630,6 +557,13 @@ std::map<int, COLOR4D> BOARD_ADAPTER::GetLayerColors() const
return KIGFX::COLOR4D();
};
m_SilkScreenColorTop = to_SFVEC4F( g_DefaultSilkscreen );
m_SilkScreenColorBot = to_SFVEC4F( g_DefaultSilkscreen );
m_SolderMaskColorTop = to_SFVEC4F( g_DefaultSolderMask );
m_SolderMaskColorBot = to_SFVEC4F( g_DefaultSolderMask );
KIGFX::COLOR4D bodyColor( 0, 0, 0, 0 );
for( const BOARD_STACKUP_ITEM* stackupItem : stackup.GetList() )
{
wxString colorName = stackupItem->GetColor();
@@ -638,17 +572,16 @@ std::map<int, COLOR4D> BOARD_ADAPTER::GetLayerColors() const
{
case BS_ITEM_TYPE_SILKSCREEN:
if( stackupItem->GetBrdLayerId() == F_SilkS )
colors[ LAYER_3D_SILKSCREEN_TOP ] = findColor( colorName, g_SilkColors );
m_SilkScreenColorTop = to_SFVEC4F( findColor( colorName, g_SilkscreenColors ) );
else
colors[ LAYER_3D_SILKSCREEN_BOTTOM ] = findColor( colorName, g_SilkColors );
m_SilkScreenColorBot = to_SFVEC4F( findColor( colorName, g_SilkscreenColors ) );
break;
case BS_ITEM_TYPE_SOLDERMASK:
if( stackupItem->GetBrdLayerId() == F_Mask )
colors[ LAYER_3D_SOLDERMASK_TOP ] = findColor( colorName, g_MaskColors );
m_SolderMaskColorTop = to_SFVEC4F( findColor( colorName, g_MaskColors ) );
else
colors[ LAYER_3D_SOLDERMASK_BOTTOM ] = findColor( colorName, g_MaskColors );
m_SolderMaskColorBot = to_SFVEC4F( findColor( colorName, g_MaskColors ) );
break;
@@ -671,227 +604,52 @@ std::map<int, COLOR4D> BOARD_ADAPTER::GetLayerColors() const
}
if( bodyColor != COLOR4D( 0, 0, 0, 0 ) )
colors[ LAYER_3D_BOARD ] = bodyColor;
m_BoardBodyColor = to_SFVEC4F( bodyColor );
else
m_BoardBodyColor = to_SFVEC4F( g_DefaultBoardBody );
const wxString& finishName = stackup.m_FinishType;
if( finishName.EndsWith( wxT( "OSP" ) ) )
{
colors[ LAYER_3D_COPPER_TOP ] = findColor( wxT( "Copper" ), g_FinishColors );
m_CopperColor = to_SFVEC4F( findColor( wxT( "Copper" ), g_FinishColors ) );
}
else if( finishName.EndsWith( wxT( "IG" ) )
|| finishName.EndsWith( wxT( "gold" ) ) )
{
colors[ LAYER_3D_COPPER_TOP ] = findColor( wxT( "Gold" ), g_FinishColors );
m_CopperColor = to_SFVEC4F( findColor( wxT( "Gold" ), g_FinishColors ) );
}
else if( finishName.StartsWith( wxT( "HAL" ) )
|| finishName.StartsWith( wxT( "HASL" ) )
|| finishName.EndsWith( wxT( "tin" ) )
|| finishName.EndsWith( wxT( "nickel" ) ) )
{
colors[ LAYER_3D_COPPER_TOP ] = findColor( wxT( "Tin" ), g_FinishColors );
m_CopperColor = to_SFVEC4F( findColor( wxT( "Tin" ), g_FinishColors ) );
}
else if( finishName.EndsWith( wxT( "silver" ) ) )
{
colors[ LAYER_3D_COPPER_TOP ] = findColor( wxT( "Silver" ), g_FinishColors );
m_CopperColor = to_SFVEC4F( findColor( wxT( "Silver" ), g_FinishColors ) );
}
else
{
m_CopperColor = to_SFVEC4F( g_DefaultSurfaceFinish );
}
}
colors[ LAYER_3D_COPPER_BOTTOM ] = colors[ LAYER_3D_COPPER_TOP ];
for( const auto& [layer, val] : m_ColorOverrides )
colors[layer] = val;
return colors;
}
void BOARD_ADAPTER::SetLayerColors( const std::map<int, COLOR4D>& aColors )
{
COLOR_SETTINGS* settings = Pgm().GetSettingsManager().GetColorSettings();
for( const auto& [ layer, color ] : aColors )
settings->SetColor( layer, color );
Pgm().GetSettingsManager().SaveColorSettings( settings, "3d_viewer" );
}
void BOARD_ADAPTER::SetVisibleLayers( const std::bitset<LAYER_3D_END>& aLayers )
{
m_Cfg->m_Render.show_board_body = aLayers.test( LAYER_3D_BOARD );
m_Cfg->m_Render.show_copper_top = aLayers.test( LAYER_3D_COPPER_TOP );
m_Cfg->m_Render.show_copper_bottom = aLayers.test( LAYER_3D_COPPER_BOTTOM );
m_Cfg->m_Render.show_silkscreen_top = aLayers.test( LAYER_3D_SILKSCREEN_TOP );
m_Cfg->m_Render.show_silkscreen_bottom = aLayers.test( LAYER_3D_SILKSCREEN_BOTTOM );
m_Cfg->m_Render.show_soldermask_top = aLayers.test( LAYER_3D_SOLDERMASK_TOP );
m_Cfg->m_Render.show_soldermask_bottom = aLayers.test( LAYER_3D_SOLDERMASK_BOTTOM );
m_Cfg->m_Render.show_solderpaste = aLayers.test( LAYER_3D_SOLDERPASTE );
m_Cfg->m_Render.show_adhesive = aLayers.test( LAYER_3D_ADHESIVE );
m_Cfg->m_Render.show_comments = aLayers.test( LAYER_3D_USER_COMMENTS );
m_Cfg->m_Render.show_drawings = aLayers.test( LAYER_3D_USER_DRAWINGS );
m_Cfg->m_Render.show_eco1 = aLayers.test( LAYER_3D_USER_ECO1 );
m_Cfg->m_Render.show_eco2 = aLayers.test( LAYER_3D_USER_ECO2 );
m_Cfg->m_Render.show_footprints_normal = aLayers.test( LAYER_3D_TH_MODELS );
m_Cfg->m_Render.show_footprints_insert = aLayers.test( LAYER_3D_SMD_MODELS );
m_Cfg->m_Render.show_footprints_virtual = aLayers.test( LAYER_3D_VIRTUAL_MODELS );
m_Cfg->m_Render.show_footprints_not_in_posfile = aLayers.test( LAYER_3D_MODELS_NOT_IN_POS );
m_Cfg->m_Render.show_footprints_dnp = aLayers.test( LAYER_3D_MODELS_MARKED_DNP );
m_Cfg->m_Render.show_fp_references = aLayers.test( LAYER_FP_REFERENCES );
m_Cfg->m_Render.show_fp_values = aLayers.test( LAYER_FP_VALUES );
m_Cfg->m_Render.show_fp_text = aLayers.test( LAYER_FP_TEXT );
m_Cfg->m_Render.show_model_bbox = aLayers.test( LAYER_3D_BOUNDING_BOXES );
m_Cfg->m_Render.show_off_board_silk = aLayers.test( LAYER_3D_OFF_BOARD_SILK );
m_Cfg->m_Render.show_axis = aLayers.test( LAYER_3D_AXES );
}
std::bitset<LAYER_3D_END> BOARD_ADAPTER::GetVisibleLayers() const
{
std::bitset<LAYER_3D_END> ret;
ret.set( LAYER_3D_BOARD, m_Cfg->m_Render.show_board_body );
ret.set( LAYER_3D_COPPER_TOP, m_Cfg->m_Render.show_copper_top );
ret.set( LAYER_3D_COPPER_BOTTOM, m_Cfg->m_Render.show_copper_bottom );
ret.set( LAYER_3D_SILKSCREEN_TOP, m_Cfg->m_Render.show_silkscreen_top );
ret.set( LAYER_3D_SILKSCREEN_BOTTOM, m_Cfg->m_Render.show_silkscreen_bottom );
ret.set( LAYER_3D_SOLDERMASK_TOP, m_Cfg->m_Render.show_soldermask_top );
ret.set( LAYER_3D_SOLDERMASK_BOTTOM, m_Cfg->m_Render.show_soldermask_bottom );
ret.set( LAYER_3D_SOLDERPASTE, m_Cfg->m_Render.show_solderpaste );
ret.set( LAYER_3D_ADHESIVE, m_Cfg->m_Render.show_adhesive );
ret.set( LAYER_3D_USER_COMMENTS, m_Cfg->m_Render.show_comments );
ret.set( LAYER_3D_USER_DRAWINGS, m_Cfg->m_Render.show_drawings );
ret.set( LAYER_3D_USER_ECO1, m_Cfg->m_Render.show_eco1 );
ret.set( LAYER_3D_USER_ECO2, m_Cfg->m_Render.show_eco2 );
ret.set( LAYER_FP_REFERENCES, m_Cfg->m_Render.show_fp_references );
ret.set( LAYER_FP_VALUES, m_Cfg->m_Render.show_fp_values );
ret.set( LAYER_FP_TEXT, m_Cfg->m_Render.show_fp_text );
ret.set( LAYER_3D_TH_MODELS, m_Cfg->m_Render.show_footprints_normal );
ret.set( LAYER_3D_SMD_MODELS, m_Cfg->m_Render.show_footprints_insert );
ret.set( LAYER_3D_VIRTUAL_MODELS, m_Cfg->m_Render.show_footprints_virtual );
ret.set( LAYER_3D_MODELS_NOT_IN_POS, m_Cfg->m_Render.show_footprints_not_in_posfile );
ret.set( LAYER_3D_MODELS_MARKED_DNP, m_Cfg->m_Render.show_footprints_dnp );
ret.set( LAYER_3D_BOUNDING_BOXES, m_Cfg->m_Render.show_model_bbox );
ret.set( LAYER_3D_OFF_BOARD_SILK, m_Cfg->m_Render.show_off_board_silk );
ret.set( LAYER_3D_AXES, m_Cfg->m_Render.show_axis );
if( m_Cfg->m_CurrentPreset == FOLLOW_PCB )
{
if( !m_board )
return ret;
ret.set( LAYER_3D_BOARD, true );
ret.set( LAYER_3D_COPPER_TOP, m_board->IsLayerVisible( F_Cu ) );
ret.set( LAYER_3D_COPPER_BOTTOM, m_board->IsLayerVisible( B_Cu ) );
ret.set( LAYER_3D_SILKSCREEN_TOP, m_board->IsLayerVisible( F_SilkS ) );
ret.set( LAYER_3D_SILKSCREEN_BOTTOM, m_board->IsLayerVisible( B_SilkS ) );
ret.set( LAYER_3D_SOLDERMASK_TOP, m_board->IsLayerVisible( F_Mask ) );
ret.set( LAYER_3D_SOLDERMASK_BOTTOM, m_board->IsLayerVisible( B_Mask ) );
ret.set( LAYER_3D_SOLDERPASTE, m_board->IsLayerVisible( F_Paste ) );
ret.set( LAYER_3D_ADHESIVE, m_board->IsLayerVisible( F_Adhes ) );
ret.set( LAYER_3D_USER_COMMENTS, m_board->IsLayerVisible( Cmts_User ) );
ret.set( LAYER_3D_USER_DRAWINGS, m_board->IsLayerVisible( Dwgs_User ) );
ret.set( LAYER_3D_USER_ECO1, m_board->IsLayerVisible( Eco1_User ) );
ret.set( LAYER_3D_USER_ECO2, m_board->IsLayerVisible( Eco2_User ) );
for( GAL_LAYER_ID layer : { LAYER_FP_REFERENCES, LAYER_FP_VALUES, LAYER_FP_TEXT } )
ret.set( layer, m_board->IsElementVisible( layer ) );
}
else if( m_Cfg->m_CurrentPreset == FOLLOW_PLOT_SETTINGS )
{
if( !m_board )
return ret;
const PCB_PLOT_PARAMS& plotParams = m_board->GetPlotOptions();
LSET layers = plotParams.GetLayerSelection() | plotParams.GetPlotOnAllLayersSelection();
ret.set( LAYER_3D_BOARD, true );
ret.set( LAYER_3D_COPPER_TOP, layers.test( F_Cu ) );
ret.set( LAYER_3D_COPPER_BOTTOM, layers.test( B_Cu ) );
ret.set( LAYER_3D_SILKSCREEN_TOP, layers.test( F_SilkS ) );
ret.set( LAYER_3D_SILKSCREEN_BOTTOM, layers.test( B_SilkS ) );
ret.set( LAYER_3D_SOLDERMASK_TOP, layers.test( F_Mask ) );
ret.set( LAYER_3D_SOLDERMASK_BOTTOM, layers.test( B_Mask ) );
ret.set( LAYER_3D_SOLDERPASTE, layers.test( F_Paste ) );
ret.set( LAYER_3D_ADHESIVE, layers.test( F_Adhes ) );
ret.set( LAYER_3D_USER_COMMENTS, layers.test( Cmts_User ) );
ret.set( LAYER_3D_USER_DRAWINGS, layers.test( Dwgs_User ) );
ret.set( LAYER_3D_USER_ECO1, layers.test( Eco1_User ) );
ret.set( LAYER_3D_USER_ECO2, layers.test( Eco2_User ) );
ret.set( LAYER_FP_REFERENCES, plotParams.GetPlotReference() );
ret.set( LAYER_FP_VALUES, plotParams.GetPlotValue() );
ret.set( LAYER_FP_TEXT, plotParams.GetPlotFPText() );
}
else if( LAYER_PRESET_3D* preset = m_Cfg->FindPreset( m_Cfg->m_CurrentPreset ) )
{
ret = preset->layers;
}
else
{
ret.set( LAYER_3D_BOARD, m_Cfg->m_Render.show_board_body );
ret.set( LAYER_3D_COPPER_TOP, m_Cfg->m_Render.show_copper_top );
ret.set( LAYER_3D_COPPER_BOTTOM, m_Cfg->m_Render.show_copper_bottom );
ret.set( LAYER_3D_SILKSCREEN_TOP, m_Cfg->m_Render.show_silkscreen_top );
ret.set( LAYER_3D_SILKSCREEN_BOTTOM, m_Cfg->m_Render.show_silkscreen_bottom );
ret.set( LAYER_3D_SOLDERMASK_TOP, m_Cfg->m_Render.show_soldermask_top );
ret.set( LAYER_3D_SOLDERMASK_BOTTOM, m_Cfg->m_Render.show_soldermask_bottom );
ret.set( LAYER_3D_SOLDERPASTE, m_Cfg->m_Render.show_solderpaste );
ret.set( LAYER_3D_ADHESIVE, m_Cfg->m_Render.show_adhesive );
ret.set( LAYER_3D_USER_COMMENTS, m_Cfg->m_Render.show_comments );
ret.set( LAYER_3D_USER_DRAWINGS, m_Cfg->m_Render.show_drawings );
ret.set( LAYER_3D_USER_ECO1, m_Cfg->m_Render.show_eco1 );
ret.set( LAYER_3D_USER_ECO2, m_Cfg->m_Render.show_eco2 );
ret.set( LAYER_FP_REFERENCES, m_Cfg->m_Render.show_fp_references );
ret.set( LAYER_FP_VALUES, m_Cfg->m_Render.show_fp_values );
ret.set( LAYER_FP_TEXT, m_Cfg->m_Render.show_fp_text );
m_SilkScreenColorBot = to_SFVEC4F( colors->GetColor( LAYER_3D_SILKSCREEN_BOTTOM ) );
m_SilkScreenColorTop = to_SFVEC4F( colors->GetColor( LAYER_3D_SILKSCREEN_TOP ) );
m_SolderMaskColorBot = to_SFVEC4F( colors->GetColor( LAYER_3D_SOLDERMASK_BOTTOM ) );
m_SolderMaskColorTop = to_SFVEC4F( colors->GetColor( LAYER_3D_SOLDERMASK_TOP ) );
m_CopperColor = to_SFVEC4F( colors->GetColor( LAYER_3D_COPPER ) );
m_BoardBodyColor = to_SFVEC4F( colors->GetColor( LAYER_3D_BOARD ) );
}
return ret;
}
std::bitset<LAYER_3D_END> BOARD_ADAPTER::GetDefaultVisibleLayers() const
{
std::bitset<LAYER_3D_END> ret;
ret.set( LAYER_3D_BOARD, true );
ret.set( LAYER_3D_COPPER_TOP, true );
ret.set( LAYER_3D_COPPER_BOTTOM, true );
ret.set( LAYER_3D_SILKSCREEN_TOP, true );
ret.set( LAYER_3D_SILKSCREEN_BOTTOM, true );
ret.set( LAYER_3D_SOLDERMASK_TOP, true );
ret.set( LAYER_3D_SOLDERMASK_BOTTOM, true );
ret.set( LAYER_3D_SOLDERPASTE, true );
ret.set( LAYER_3D_ADHESIVE, true );
ret.set( LAYER_3D_USER_COMMENTS, false );
ret.set( LAYER_3D_USER_DRAWINGS, false );
ret.set( LAYER_3D_USER_ECO1, false );
ret.set( LAYER_3D_USER_ECO2, false );
ret.set( LAYER_FP_REFERENCES, true );
ret.set( LAYER_FP_VALUES, true );
ret.set( LAYER_FP_TEXT, true );
ret.set( LAYER_3D_TH_MODELS, true );
ret.set( LAYER_3D_SMD_MODELS, true );
ret.set( LAYER_3D_VIRTUAL_MODELS, true );
ret.set( LAYER_3D_MODELS_NOT_IN_POS, false );
ret.set( LAYER_3D_MODELS_MARKED_DNP, false );
ret.set( LAYER_3D_BOUNDING_BOXES, false );
ret.set( LAYER_3D_OFF_BOARD_SILK, false );
ret.set( LAYER_3D_AXES, true );
return ret;
}
extern bool BuildFootprintPolygonOutlines( BOARD* aBoard, SHAPE_POLY_SET& aOutlines,
int aErrorMax, int aChainingEpsilon,
OUTLINE_ERROR_HANDLER* aErrorHandler = nullptr );
bool BOARD_ADAPTER::createBoardPolygon( wxString* aErrorMsg )
@@ -931,7 +689,7 @@ bool BOARD_ADAPTER::createBoardPolygon( wxString* aErrorMsg )
}
else
{
success = m_board->GetBoardPolygonOutlines( m_board_poly, nullptr, false, true );
success = m_board->GetBoardPolygonOutlines( m_board_poly );
if( !success && aErrorMsg )
*aErrorMsg = _( "Board outline is missing or malformed. Run DRC for a full analysis." );
@@ -944,9 +702,19 @@ bool BOARD_ADAPTER::createBoardPolygon( wxString* aErrorMsg )
float BOARD_ADAPTER::GetFootprintZPos( bool aIsFlipped ) const
{
if( aIsFlipped )
return m_layerZcoordBottom[B_Paste];
{
if( m_Cfg->m_Render.show_solderpaste )
return m_layerZcoordBottom[B_SilkS];
else
return m_layerZcoordBottom[B_Paste];
}
else
return m_layerZcoordTop[F_Paste];
{
if( m_Cfg->m_Render.show_solderpaste )
return m_layerZcoordTop[F_SilkS];
else
return m_layerZcoordTop[F_Paste];
}
}
+70 -99
View File
@@ -2,8 +2,7 @@
* This program source code file is part of KiCad, a free EDA CAD application.
*
* Copyright (C) 2015-2016 Mario Luzeiro <mrluzeiro@ua.pt>
* Copyright (C) 2023 CERN
* Copyright (C) 1992-2024 KiCad Developers, see AUTHORS.txt for contributors.
* Copyright (C) 1992-2022 KiCad Developers, see AUTHORS.txt for contributors.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
@@ -31,8 +30,8 @@
#include "../3d_rendering/raytracing/accelerators/container_2d.h"
#include "../3d_rendering/raytracing/accelerators/container_3d.h"
#include "../3d_rendering/raytracing/shapes3D/bbox_3d.h"
#include <gal/3d/camera.h>
#include <3d_enums.h>
#include "../3d_rendering/camera.h"
#include "../3d_enums.h"
#include "../3d_cache/3d_cache.h"
#include "../common_ogl/ogl_attr_list.h"
#include "../3d_viewer/eda_3d_viewer_settings.h"
@@ -42,8 +41,6 @@
#include <pcb_track.h>
#include <pcb_base_frame.h>
#include <pcb_text.h>
#include <pcb_textbox.h>
#include <pcb_table.h>
#include <pcb_shape.h>
#include <pcb_dimension.h>
#include <zone.h>
@@ -52,7 +49,6 @@
#include <dialogs/dialog_color_picker.h>
class COLOR_SETTINGS;
class PCB_TEXTBOX;
/// A type that stores a container of 2d objects for each layer id
typedef std::map<PCB_LAYER_ID, BVH_CONTAINER_2D*> MAP_CONTAINER_2D_BASE;
@@ -89,8 +85,7 @@ public:
*
* @param aLayer layer ID to get status.
*/
bool Is3dLayerEnabled( PCB_LAYER_ID aLayer,
const std::bitset<LAYER_3D_END>& aVisibilityFlags ) const;
bool Is3dLayerEnabled( PCB_LAYER_ID aLayer ) const;
/**
* Test if footprint should be displayed in relation to attributes and the flags.
@@ -105,15 +100,7 @@ public:
void SetBoard( BOARD* aBoard ) noexcept { m_board = aBoard; }
const BOARD* GetBoard() const noexcept { return m_board; }
void ReloadColorSettings() noexcept;
std::map<int, COLOR4D> GetLayerColors() const;
std::map<int, COLOR4D> GetDefaultColors() const;
void SetLayerColors( const std::map<int, COLOR4D>& aColors );
std::bitset<LAYER_3D_END> GetVisibleLayers() const;
std::bitset<LAYER_3D_END> GetDefaultVisibleLayers() const;
void SetVisibleLayers( const std::bitset<LAYER_3D_END>& aLayers );
void SetColorSettings( COLOR_SETTINGS* aSettings ) noexcept { m_colors = aSettings; }
/**
* Function to be called by the render when it need to reload the settings for the board.
@@ -249,12 +236,10 @@ public:
const MAP_CONTAINER_2D_BASE& GetLayerMap() const noexcept { return m_layerMap; }
const BVH_CONTAINER_2D* GetPlatedPadsFront() const noexcept { return m_platedPadsFront; }
const BVH_CONTAINER_2D* GetPlatedPadsBack() const noexcept { return m_platedPadsBack; }
const BVH_CONTAINER_2D* GetOffboardPadsFront() const noexcept { return m_offboardPadsFront; }
const BVH_CONTAINER_2D* GetOffboardPadsBack() const noexcept { return m_offboardPadsBack; }
const MAP_CONTAINER_2D_BASE& GetLayerHoleMap() const noexcept { return m_layerHoleMap; }
const BVH_CONTAINER_2D& GetTH_IDs() const noexcept { return m_TH_IDs; }
const BVH_CONTAINER_2D& GetTH_ODs() const noexcept { return m_TH_ODs; }
const BVH_CONTAINER_2D& GetThroughHoleIds() const noexcept { return m_throughHoleIds; }
const BVH_CONTAINER_2D& GetThroughHoleOds() const noexcept { return m_throughHoleOds; }
/**
* Get through hole outside diameter 2D polygons.
@@ -263,37 +248,37 @@ public:
*
* @return a container with through hold outside diameter 2D polygons.
*/
const SHAPE_POLY_SET& GetTH_ODPolys() const noexcept
const SHAPE_POLY_SET& GetThroughHoleOdPolys() const noexcept
{
return m_TH_ODPolys;
return m_throughHoleOdPolys;
}
const BVH_CONTAINER_2D& GetViaAnnuli() const noexcept
const BVH_CONTAINER_2D& GetThroughHoleAnnularRings() const noexcept
{
return m_viaAnnuli;
return m_throughHoleAnnularRings;
}
const SHAPE_POLY_SET& GetViaAnnuliPolys() const noexcept
const SHAPE_POLY_SET& GetThroughHoleAnnularRingPolys() const noexcept
{
return m_viaAnnuliPolys;
return m_throughHoleAnnularRingPolys;
}
const SHAPE_POLY_SET& GetNPTH_ODPolys() const noexcept
const SHAPE_POLY_SET& GetOuterNonPlatedThroughHolePoly() const noexcept
{
return m_NPTH_ODPolys;
return m_nonPlatedThroughHoleOdPolys;
}
/**
* @return a container with through hole via hole outside diameters.
*/
const BVH_CONTAINER_2D& GetViaTH_ODs() const noexcept
const BVH_CONTAINER_2D& GetThroughHoleViaOds() const noexcept
{
return m_viaTH_ODs;
return m_throughHoleViaOds;
}
const SHAPE_POLY_SET& GetViaTH_ODPolys() const noexcept
const SHAPE_POLY_SET& GetThroughHoleViaOdPolys() const noexcept
{
return m_viaTH_ODPolys;
return m_throughHoleViaOdPolys;
}
unsigned int GetViaCount() const noexcept { return m_viaCount; }
@@ -333,8 +318,8 @@ public:
*/
const MAP_POLY& GetPolyMap() const noexcept { return m_layers_poly; }
const SHAPE_POLY_SET* GetFrontPlatedPadAndGraphicPolys() { return m_frontPlatedPadAndGraphicPolys; }
const SHAPE_POLY_SET* GetBackPlatedPadAndGraphicPolys() { return m_backPlatedPadAndGraphicPolys; }
const SHAPE_POLY_SET* GetFrontPlatedPadPolys() { return m_frontPlatedPadPolys; }
const SHAPE_POLY_SET* GetBackPlatedPadPolys() { return m_backPlatedPadPolys; }
const MAP_POLY& GetHoleIdPolysMap() const noexcept { return m_layerHoleIdPolys; }
const MAP_POLY& GetHoleOdPolysMap() const noexcept { return m_layerHoleOdPolys; }
@@ -349,23 +334,19 @@ private:
void destroyLayers();
// Helper functions to create the board
void createViaWithMargin( const PCB_TRACK* aTrack, CONTAINER_2D_BASE* aDstContainer,
int aMargin );
void createTrack( const PCB_TRACK* aTrack, CONTAINER_2D_BASE* aDstContainer );
void createPadWithMargin( const PAD *aPad, CONTAINER_2D_BASE* aDstContainer,
PCB_LAYER_ID aLayer, const VECTOR2I& aMargin ) const;
void createPadWithHole( const PAD* aPad, CONTAINER_2D_BASE* aDstContainer,
int aInflateValue );
OBJECT_2D* createPadWithDrill( const PAD* aPad, int aInflateValue );
void addPads( const FOOTPRINT* aFootprint, CONTAINER_2D_BASE* aDstContainer,
PCB_LAYER_ID aLayerId, bool aSkipPlatedPads, bool aSkipNonPlatedPads );
PCB_LAYER_ID aLayerId, bool aSkipNPTHPadsWihNoCopper, bool aSkipPlatedPads,
bool aSkipNonPlatedPads );
void addFootprintShapes( const FOOTPRINT* aFootprint, CONTAINER_2D_BASE* aDstContainer,
PCB_LAYER_ID aLayerId,
const std::bitset<LAYER_3D_END>& aVisibilityFlags );
PCB_LAYER_ID aLayerId );
void addText( const EDA_TEXT* aText, CONTAINER_2D_BASE* aDstContainer,
const BOARD_ITEM* aOwner );
@@ -376,23 +357,23 @@ private:
void addShape( const PCB_DIMENSION_BASE* aDimension, CONTAINER_2D_BASE* aDstContainer,
const BOARD_ITEM* aOwner );
void addShape( const PCB_TEXTBOX* aTextBox, CONTAINER_2D_BASE* aContainer,
const BOARD_ITEM* aOwner );
void addTable( const PCB_TABLE* aTable, CONTAINER_2D_BASE* aContainer,
const BOARD_ITEM* aOwner );
void addSolidAreasShapes( const ZONE* aZone, CONTAINER_2D_BASE* aDstContainer,
PCB_LAYER_ID aLayerId );
void createArcSegments( const VECTOR2I& aCentre, const VECTOR2I& aStart,
void transformArcToSegments( const VECTOR2I& aCentre, const VECTOR2I& aStart,
const EDA_ANGLE& aArcAngle, int aCircleToSegmentsCount, int aWidth,
CONTAINER_2D_BASE* aContainer, const BOARD_ITEM& aOwner );
CONTAINER_2D_BASE* aDstContainer, const BOARD_ITEM& aOwner );
void buildPadOutlineAsSegments( const PAD* aPad, CONTAINER_2D_BASE* aDstContainer, int aWidth );
// Helper functions to create poly contours
void buildPadOutlineAsPolygon( const PAD* aPad, SHAPE_POLY_SET& aBuffer, int aWidth) const;
void transformFPShapesToPolySet( const FOOTPRINT* aFootprint, PCB_LAYER_ID aLayer,
SHAPE_POLY_SET& aBuffer ) const;
public:
static CUSTOM_COLORS_LIST g_SilkColors;
static CUSTOM_COLORS_LIST g_SilkscreenColors;
static CUSTOM_COLORS_LIST g_MaskColors;
static CUSTOM_COLORS_LIST g_PasteColors;
static CUSTOM_COLORS_LIST g_FinishColors;
@@ -405,78 +386,68 @@ public:
static KIGFX::COLOR4D g_DefaultSolderPaste;
static KIGFX::COLOR4D g_DefaultSurfaceFinish;
static KIGFX::COLOR4D g_DefaultBoardBody;
static KIGFX::COLOR4D g_DefaultComments;
static KIGFX::COLOR4D g_DefaultECOs;
public:
EDA_3D_VIEWER_SETTINGS* m_Cfg;
bool m_IsBoardView;
bool m_MousewheelPanning;
bool m_IsPreviewer; ///< true if we're in a 3D preview panel, false
///< for the standard 3D viewer
bool m_IsPreviewer; ///< true if the board adaptater is living in a 3D
///< preview panel, false for the standard 3D viewer
SFVEC4F m_BgColorBot; ///< background bottom color
SFVEC4F m_BgColorTop; ///< background top color
SFVEC4F m_BoardBodyColor; ///< in realistic mode: FR4 board color
SFVEC4F m_SolderMaskColorBot; ///< in realistic mode: solder mask color ( bot )
SFVEC4F m_SolderMaskColorTop; ///< in realistic mode: solder mask color ( top )
SFVEC4F m_SolderPasteColor; ///< in realistic mode: solder paste color
SFVEC4F m_SilkScreenColorBot; ///< in realistic mode: SilkScreen color ( bot )
SFVEC4F m_SilkScreenColorTop; ///< in realistic mode: SilkScreen color ( top )
SFVEC4F m_CopperColor; ///< in realistic mode: copper color
SFVEC4F m_UserDrawingsColor;
SFVEC4F m_UserCommentsColor;
SFVEC4F m_ECO1Color;
SFVEC4F m_ECO2Color;
std::map<int, COLOR4D> m_ColorOverrides; ///< allows to override color scheme colors
SFVEC4F m_BgColorBot; ///< background bottom color
SFVEC4F m_BgColorTop; ///< background top color
SFVEC4F m_BoardBodyColor; ///< in realistic mode: FR4 board color
SFVEC4F m_SolderMaskColorBot; ///< in realistic mode: solder mask color ( bot )
SFVEC4F m_SolderMaskColorTop; ///< in realistic mode: solder mask color ( top )
SFVEC4F m_SolderPasteColor; ///< in realistic mode: solder paste color
SFVEC4F m_SilkScreenColorBot; ///< in realistic mode: SilkScreen color ( bot )
SFVEC4F m_SilkScreenColorTop; ///< in realistic mode: SilkScreen color ( top )
SFVEC4F m_CopperColor; ///< in realistic mode: copper color
private:
BOARD* m_board;
S3D_CACHE* m_3dModelManager;
RENDER_SETTINGS* m_renderSettings;
COLOR_SETTINGS* m_colors;
VECTOR2I m_boardPos; ///< Board center position in board internal units.
VECTOR2I m_boardSize; ///< Board size in board internal units.
SFVEC3F m_boardCenter; ///< 3D center position of the board in 3D units.
BBOX_3D m_boardBoundingBox; ///< 3D bounding box of the board in 3D units.
VECTOR2I m_boardPos; ///< Board center position in board internal units.
VECTOR2I m_boardSize; ///< Board size in board internal units.
SFVEC3F m_boardCenter; ///< 3D center position of the board in 3D units.
BBOX_3D m_boardBoundingBox; ///< 3D bounding box of the board in 3D units.
MAP_POLY m_layers_poly; ///< Amalgamated polygon contours for various types
///< of items
MAP_POLY m_layers_poly; ///< Amalgamated polygon contours for various types of
///< items
SHAPE_POLY_SET* m_frontPlatedPadAndGraphicPolys;
SHAPE_POLY_SET* m_backPlatedPadAndGraphicPolys;
SHAPE_POLY_SET* m_frontPlatedCopperPolys;
SHAPE_POLY_SET* m_backPlatedCopperPolys;
SHAPE_POLY_SET* m_frontPlatedPadPolys;
SHAPE_POLY_SET* m_backPlatedPadPolys;
MAP_POLY m_layerHoleOdPolys; ///< Hole outer diameters (per layer)
MAP_POLY m_layerHoleIdPolys; ///< Hole inner diameters (per layer)
MAP_POLY m_layerHoleOdPolys; ///< Hole outer diameters (per layer)
MAP_POLY m_layerHoleIdPolys; ///< Hole inner diameters (per layer)
SHAPE_POLY_SET m_NPTH_ODPolys; ///< NPTH outer diameters
SHAPE_POLY_SET m_TH_ODPolys; ///< PTH outer diameters
SHAPE_POLY_SET m_viaTH_ODPolys; ///< Via hole outer diameters
SHAPE_POLY_SET m_viaAnnuliPolys; ///< Via annular ring outer diameters
SHAPE_POLY_SET m_nonPlatedThroughHoleOdPolys; ///< NPTH outer diameters
SHAPE_POLY_SET m_throughHoleOdPolys; ///< PTH outer diameters
SHAPE_POLY_SET m_throughHoleViaOdPolys; ///< Via hole outer diameters
SHAPE_POLY_SET m_throughHoleAnnularRingPolys; ///< Via annular ring outer diameters
SHAPE_POLY_SET m_board_poly; ///< Board outline polygon.
SHAPE_POLY_SET m_board_poly; ///< Board outline polygon.
MAP_CONTAINER_2D_BASE m_layerMap; ///< 2D elements for each layer.
MAP_CONTAINER_2D_BASE m_layerHoleMap; ///< Holes for each layer.
MAP_CONTAINER_2D_BASE m_layerMap; ///< 2D elements for each layer.
MAP_CONTAINER_2D_BASE m_layerHoleMap; ///< Holes for each layer.
BVH_CONTAINER_2D* m_platedPadsFront;
BVH_CONTAINER_2D* m_platedPadsBack;
BVH_CONTAINER_2D* m_offboardPadsFront;
BVH_CONTAINER_2D* m_offboardPadsBack;
BVH_CONTAINER_2D m_TH_ODs; ///< List of PTH outer diameters
BVH_CONTAINER_2D m_TH_IDs; ///< List of PTH inner diameters
BVH_CONTAINER_2D m_viaAnnuli; ///< List of via annular rings
BVH_CONTAINER_2D m_viaTH_ODs; ///< List of via hole outer diameters
BVH_CONTAINER_2D m_throughHoleOds; ///< List of PTH outer diameters
BVH_CONTAINER_2D m_throughHoleIds; ///< List of PTH inner diameters
BVH_CONTAINER_2D m_throughHoleAnnularRings; ///< List of via annular rings
BVH_CONTAINER_2D m_throughHoleViaOds; ///< List of via hole outer diameters
BVH_CONTAINER_2D m_throughHoleViaIds; ///< List of via hole inner diameters
unsigned int m_copperLayersCount;
double m_biuTo3Dunits; ///< Scale factor to convert board internal units
///< to 3D units normalized between -1.0 and 1.0.
double m_biuTo3Dunits; ///< Scale factor to convert board internal units to
///< 3D units normalized between -1.0 and 1.0.
std::array<float, PCB_LAYER_ID_COUNT> m_layerZcoordTop; ///< Top (End) Z position of each
///< layer in 3D units.
+304 -272
View File
@@ -2,8 +2,7 @@
* This program source code file is part of KiCad, a free EDA CAD application.
*
* Copyright (C) 2015-2016 Mario Luzeiro <mrluzeiro@ua.pt>
* Copyright (C) 2023 CERN
* Copyright (C) 1992-2024 KiCad Developers, see AUTHORS.txt for contributors.
* Copyright (C) 1992-2022 KiCad Developers, see AUTHORS.txt for contributors.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
@@ -24,25 +23,27 @@
*/
/**
* @file create_3Dgraphic_brd_items.cpp
* @file create_graphic_brd_items.cpp
* @brief This file implements the creation of 2D graphic primitives of pcb items:
* pads, tracks, drawsegments, texts....
* It is based on the function found in the files:
* board_items_to_polygon_shape_transform.cpp
*/
#include "../3d_rendering/raytracing/shapes2D/ring_2d.h"
#include "../3d_rendering/raytracing/shapes2D/filled_circle_2d.h"
#include "../3d_rendering/raytracing/shapes2D/round_segment_2d.h"
#include "../3d_rendering/raytracing/shapes2D/triangle_2d.h"
#include "fp_textbox.h"
#include <board_adapter.h>
#include <board.h>
#include <footprint.h>
#include <pad.h>
#include <pcb_text.h>
#include <pcb_textbox.h>
#include <pcb_table.h>
#include <fp_shape.h>
#include <board_design_settings.h>
#include <pcb_painter.h> // for PCB_RENDER_SETTINGS
#include <zone.h>
#include <fp_text.h>
#include <convert_basic_shapes_to_polygon.h>
#include <trigo.h>
#include <geometry/shape_segment.h>
@@ -62,37 +63,6 @@
#define TO_SFVEC2F( vec ) SFVEC2F( TO_3DU( vec.x ), TO_3DU( -vec.y ) )
void addFILLED_CIRCLE_2D( CONTAINER_2D_BASE* aContainer, const SFVEC2F& aCenter, float aRadius,
const BOARD_ITEM& aBoardItem )
{
if( aRadius > 0.0f )
aContainer->Add( new FILLED_CIRCLE_2D( aCenter, aRadius, aBoardItem ) );
}
void addRING_2D( CONTAINER_2D_BASE* aContainer, const SFVEC2F& aCenter, float aInnerRadius,
float aOuterRadius, const BOARD_ITEM& aBoardItem )
{
if( aOuterRadius > aInnerRadius && aInnerRadius > 0.0f )
aContainer->Add( new RING_2D( aCenter, aInnerRadius, aOuterRadius, aBoardItem ) );
}
void addROUND_SEGMENT_2D( CONTAINER_2D_BASE* aContainer, const SFVEC2F& aStart, const SFVEC2F& aEnd,
float aWidth, const BOARD_ITEM& aBoardItem )
{
if( Is_segment_a_circle( aStart, aEnd ) )
{
// Cannot add segments that have the same start and end point
addFILLED_CIRCLE_2D( aContainer, aStart, aWidth / 2, aBoardItem );
return;
}
if( aWidth > 0.0f )
aContainer->Add( new ROUND_SEGMENT_2D( aStart, aEnd, aWidth, aBoardItem ) );
}
void BOARD_ADAPTER::addText( const EDA_TEXT* aText, CONTAINER_2D_BASE* aContainer,
const BOARD_ITEM* aOwner )
{
@@ -106,14 +76,31 @@ void BOARD_ADAPTER::addText( const EDA_TEXT* aText, CONTAINER_2D_BASE* aContaine
if( aOwner && aOwner->IsKnockout() )
{
SHAPE_POLY_SET finalPoly;
const PCB_TEXT* pcbText = static_cast<const PCB_TEXT*>( aOwner );
SHAPE_POLY_SET knockouts;
pcbText->TransformTextToPolySet( finalPoly, 0, m_board->GetDesignSettings().m_MaxError,
ERROR_INSIDE );
CALLBACK_GAL callback_gal( empty_opts,
// Polygon callback
[&]( const SHAPE_LINE_CHAIN& aPoly )
{
knockouts.AddOutline( aPoly );
} );
attrs.m_StrokeWidth = aText->GetEffectiveTextPenWidth();
attrs.m_Angle = aText->GetDrawRotation();
callback_gal.SetIsFill( font->IsOutline() );
callback_gal.SetIsStroke( font->IsStroke() );
callback_gal.SetLineWidth( attrs.m_StrokeWidth );
font->Draw( &callback_gal, aText->GetShownText(), aText->GetDrawPos(), attrs );
SHAPE_POLY_SET finalPoly;
int margin = attrs.m_StrokeWidth * 1.5 +
GetKnockoutTextMargin( attrs.m_Size, attrs.m_StrokeWidth );
aText->TransformBoundingBoxToPolygon( &finalPoly, margin );
finalPoly.BooleanSubtract( knockouts, SHAPE_POLY_SET::PM_FAST );
finalPoly.Fracture( SHAPE_POLY_SET::PM_FAST );
// Do not call finalPoly.Fracture() here: ConvertPolygonToTriangles() call it
// if needed, and Fracture() called twice can create bad results and is useless
ConvertPolygonToTriangles( finalPoly, *aContainer, m_biuTo3Dunits, *aOwner );
}
else
@@ -122,8 +109,24 @@ void BOARD_ADAPTER::addText( const EDA_TEXT* aText, CONTAINER_2D_BASE* aContaine
// Stroke callback
[&]( const VECTOR2I& aPt1, const VECTOR2I& aPt2 )
{
addROUND_SEGMENT_2D( aContainer, TO_SFVEC2F( aPt1 ), TO_SFVEC2F( aPt2 ),
penWidth_3DU, *aOwner );
const SFVEC2F pt1_3DU = TO_SFVEC2F( aPt1 );
const SFVEC2F pt2_3DU = TO_SFVEC2F( aPt2 );
if( penWidth_3DU == 0.0 )
{
// Don't attempt to render degenerate shapes
}
else if( Is_segment_a_circle( pt1_3DU, pt2_3DU ) )
{
// Cannot add segments that have the same start and end point
aContainer->Add( new FILLED_CIRCLE_2D( pt1_3DU, penWidth_3DU / 2,
*aOwner ) );
}
else
{
aContainer->Add( new ROUND_SEGMENT_2D( pt1_3DU, pt2_3DU, penWidth_3DU,
*aOwner ) );
}
},
// Triangulation callback
[&]( const VECTOR2I& aPt1, const VECTOR2I& aPt2, const VECTOR2I& aPt3 )
@@ -134,8 +137,7 @@ void BOARD_ADAPTER::addText( const EDA_TEXT* aText, CONTAINER_2D_BASE* aContaine
attrs.m_Angle = aText->GetDrawRotation();
font->Draw( &callback_gal, aText->GetShownText( true ), aText->GetDrawPos(), attrs,
aOwner->GetFontMetrics() );
font->Draw( &callback_gal, aText->GetShownText(), aText->GetDrawPos(), attrs );
}
}
@@ -143,7 +145,7 @@ void BOARD_ADAPTER::addText( const EDA_TEXT* aText, CONTAINER_2D_BASE* aContaine
void BOARD_ADAPTER::addShape( const PCB_DIMENSION_BASE* aDimension, CONTAINER_2D_BASE* aContainer,
const BOARD_ITEM* aOwner )
{
addText( aDimension, aContainer, aDimension );
addText( &aDimension->Text(), aContainer, aDimension );
const int linewidth = aDimension->GetLineThickness();
@@ -155,19 +157,18 @@ void BOARD_ADAPTER::addShape( const PCB_DIMENSION_BASE* aDimension, CONTAINER_2D
{
const SEG& seg = static_cast<const SHAPE_SEGMENT*>( shape.get() )->GetSeg();
addROUND_SEGMENT_2D( aContainer, TO_SFVEC2F( seg.A ), TO_SFVEC2F( seg.B ),
TO_3DU( linewidth ), *aOwner );
aContainer->Add( new ROUND_SEGMENT_2D( TO_SFVEC2F( seg.A ), TO_SFVEC2F( seg.B ),
TO_3DU( linewidth ), *aOwner ) );
break;
}
case SH_CIRCLE:
{
int radius = static_cast<const SHAPE_CIRCLE*>( shape.get() )->GetRadius();
float innerR3DU = TO_3DU( radius ) - TO_3DU( aDimension->GetLineThickness() ) / 2.0f;
float outerR3DU = TO_3DU( radius ) + TO_3DU( aDimension->GetLineThickness() ) / 2.0f;
addRING_2D( aContainer, TO_SFVEC2F( shape->Centre() ), innerR3DU, outerR3DU, *aOwner );
int delta = aDimension->GetLineThickness() / 2;
aContainer->Add( new RING_2D( TO_SFVEC2F( shape->Centre() ), TO_3DU( radius - delta ),
TO_3DU( radius + delta ), *aOwner ) );
break;
}
@@ -179,74 +180,48 @@ void BOARD_ADAPTER::addShape( const PCB_DIMENSION_BASE* aDimension, CONTAINER_2D
void BOARD_ADAPTER::addFootprintShapes( const FOOTPRINT* aFootprint, CONTAINER_2D_BASE* aContainer,
PCB_LAYER_ID aLayerId,
const std::bitset<LAYER_3D_END>& aVisibilityFlags )
PCB_LAYER_ID aLayerId )
{
KIGFX::GAL_DISPLAY_OPTIONS empty_opts;
for( PCB_FIELD* field : aFootprint->GetFields() )
{
if( field->GetLayer() == aLayerId && field->IsVisible() )
{
if( !aVisibilityFlags.test( LAYER_FP_TEXT ) )
continue;
else if( field->IsReference() && !aVisibilityFlags.test( LAYER_FP_REFERENCES ) )
continue;
else if( field->IsValue() && !aVisibilityFlags.test( LAYER_FP_VALUES ) )
continue;
if( aFootprint->Reference().GetLayer() == aLayerId && aFootprint->Reference().IsVisible() )
addText( &aFootprint->Reference(), aContainer, &aFootprint->Reference() );
addText( field, aContainer, field );
}
}
if( aFootprint->Value().GetLayer() == aLayerId && aFootprint->Value().IsVisible() )
addText( &aFootprint->Value(), aContainer, &aFootprint->Value() );
for( BOARD_ITEM* item : aFootprint->GraphicalItems() )
{
switch( item->Type() )
{
case PCB_TEXT_T:
case PCB_FP_TEXT_T:
{
PCB_TEXT* text = static_cast<PCB_TEXT*>( item );
FP_TEXT* text = static_cast<FP_TEXT*>( item );
if( text->GetLayer() == aLayerId && text->IsVisible() )
{
if( !aVisibilityFlags.test( LAYER_FP_TEXT ) )
continue;
else if( text->GetText() == wxT( "${REFERENCE}" ) && !aVisibilityFlags.test( LAYER_FP_REFERENCES ) )
continue;
else if( text->GetText() == wxT( "${VALUE}" ) && !aVisibilityFlags.test( LAYER_FP_VALUES ) )
continue;
addText( text, aContainer, text );
break;
}
case PCB_FP_TEXTBOX_T:
{
FP_TEXTBOX* textbox = static_cast<FP_TEXTBOX*>( item );
if( textbox->GetLayer() == aLayerId )
{
addShape( textbox, aContainer, aFootprint );
addText( textbox, aContainer, aFootprint );
}
break;
}
case PCB_TEXTBOX_T:
{
PCB_TEXTBOX* textbox = static_cast<PCB_TEXTBOX*>( item );
if( textbox->GetLayer() == aLayerId )
addShape( textbox, aContainer, aFootprint );
break;
}
case PCB_TABLE_T:
{
PCB_TABLE* table = static_cast<PCB_TABLE*>( item );
if( table->GetLayer() == aLayerId )
addTable( table, aContainer, aFootprint );
break;
}
case PCB_DIM_ALIGNED_T:
case PCB_DIM_CENTER_T:
case PCB_DIM_ORTHOGONAL_T:
case PCB_DIM_RADIAL_T:
case PCB_DIM_LEADER_T:
case PCB_FP_DIM_ALIGNED_T:
case PCB_FP_DIM_CENTER_T:
case PCB_FP_DIM_ORTHOGONAL_T:
case PCB_FP_DIM_RADIAL_T:
case PCB_FP_DIM_LEADER_T:
{
PCB_DIMENSION_BASE* dimension = static_cast<PCB_DIMENSION_BASE*>( item );
@@ -256,9 +231,9 @@ void BOARD_ADAPTER::addFootprintShapes( const FOOTPRINT* aFootprint, CONTAINER_2
break;
}
case PCB_SHAPE_T:
case PCB_FP_SHAPE_T:
{
PCB_SHAPE* shape = static_cast<PCB_SHAPE*>( item );
FP_SHAPE* shape = static_cast<FP_SHAPE*>( item );
if( shape->GetLayer() == aLayerId )
addShape( shape, aContainer, aFootprint );
@@ -273,17 +248,6 @@ void BOARD_ADAPTER::addFootprintShapes( const FOOTPRINT* aFootprint, CONTAINER_2
}
void BOARD_ADAPTER::createViaWithMargin( const PCB_TRACK* aTrack, CONTAINER_2D_BASE* aDstContainer,
int aMargin )
{
SFVEC2F start3DU = TO_SFVEC2F( aTrack->GetStart() );
SFVEC2F end3DU = TO_SFVEC2F( aTrack->GetEnd() );
const float radius3DU = TO_3DU( ( aTrack->GetWidth() / 2.0 ) + aMargin );
addFILLED_CIRCLE_2D( aDstContainer, start3DU, radius3DU, *aTrack );
}
void BOARD_ADAPTER::createTrack( const PCB_TRACK* aTrack, CONTAINER_2D_BASE* aDstContainer )
{
SFVEC2F start3DU = TO_SFVEC2F( aTrack->GetStart() );
@@ -292,36 +256,25 @@ void BOARD_ADAPTER::createTrack( const PCB_TRACK* aTrack, CONTAINER_2D_BASE* aDs
switch( aTrack->Type() )
{
case PCB_VIA_T:
addFILLED_CIRCLE_2D( aDstContainer, start3DU, TO_3DU( aTrack->GetWidth() / 2.0 ), *aTrack );
{
const float radius3DU = TO_3DU( aTrack->GetWidth() / 2 );
if( radius3DU > 0.0 )
aDstContainer->Add( new FILLED_CIRCLE_2D( start3DU, radius3DU, *aTrack ) );
break;
}
case PCB_ARC_T:
{
const PCB_ARC* arc = static_cast<const PCB_ARC*>( aTrack );
if( arc->IsDegenerated() )
{
// Draw this very small arc like a track segment (a PCB_TRACE_T)
PCB_TRACK track( arc->GetParent() );
track.SetStart( arc->GetStart() );
track.SetEnd( arc->GetEnd() );
track.SetWidth( arc->GetWidth() );
track.SetLayer( arc->GetLayer() );
createTrack( &track, aDstContainer );
return;
}
VECTOR2I center( arc->GetCenter() );
VECTOR2D center( arc->GetCenter() );
EDA_ANGLE arc_angle = arc->GetAngle();
double radius = arc->GetRadius();
int arcsegcount = GetArcToSegmentCount( KiROUND( radius ), ARC_HIGH_DEF, arc_angle );
int arcsegcount = GetArcToSegmentCount( radius, ARC_HIGH_DEF, arc_angle );
int circlesegcount;
// Avoid arcs that cannot be drawn
if( radius < std::numeric_limits<double>::min() || arc_angle.IsZero() )
break;
// We need a circle to segment count. However, the arc angle can be small, and the
// radius very big. so we calculate a reasonable value for circlesegcount.
if( arcsegcount <= 1 ) // The arc will be approximated by a segment
@@ -331,17 +284,32 @@ void BOARD_ADAPTER::createTrack( const PCB_TRACK* aTrack, CONTAINER_2D_BASE* aDs
else
{
circlesegcount = KiROUND( arcsegcount * 360.0 / std::abs( arc_angle.AsDegrees() ) );
circlesegcount = alg::clamp( 1, circlesegcount, 128 );
circlesegcount = std::max( 1, std::min( circlesegcount, 128 ) );
}
createArcSegments( center, arc->GetStart(), arc_angle, circlesegcount, arc->GetWidth(),
aDstContainer, *arc );
transformArcToSegments( VECTOR2I( center.x, center.y ), arc->GetStart(), arc_angle,
circlesegcount, arc->GetWidth(), aDstContainer, *arc );
break;
}
case PCB_TRACE_T: // Track is a usual straight segment
{
addROUND_SEGMENT_2D( aDstContainer, start3DU, end3DU, TO_3DU( aTrack->GetWidth() ), *aTrack );
if( aTrack->GetWidth() == 0 )
{
// Don't attempt to render degenerate shapes
}
else if( Is_segment_a_circle( start3DU, end3DU ) )
{
// Cannot add segments that have the same start and end point
aDstContainer->Add( new FILLED_CIRCLE_2D( start3DU, TO_3DU( aTrack->GetWidth() / 2 ),
*aTrack ) );
}
else
{
aDstContainer->Add( new ROUND_SEGMENT_2D( start3DU, end3DU, TO_3DU( aTrack->GetWidth() ),
*aTrack ) );
}
break;
}
@@ -374,12 +342,9 @@ void BOARD_ADAPTER::createPadWithMargin( const PAD* aPad, CONTAINER_2D_BASE* aCo
return;
PAD dummy( *aPad );
dummy.SetSize( VECTOR2I( dummySize.x, dummySize.y ) );
dummy.SetSize( wxSize( dummySize.x, dummySize.y ) );
dummy.TransformShapeToPolygon( poly, aLayer, 0, maxError, ERROR_INSIDE );
clearance = { 0, 0 };
// Remove group membership from dummy item before deleting
dummy.SetParentGroup( nullptr );
}
else
{
@@ -393,11 +358,24 @@ void BOARD_ADAPTER::createPadWithMargin( const PAD* aPad, CONTAINER_2D_BASE* aCo
{
const SHAPE_SEGMENT* seg = static_cast<const SHAPE_SEGMENT*>( shape );
addROUND_SEGMENT_2D( aContainer,
TO_SFVEC2F( seg->GetSeg().A ),
TO_SFVEC2F( seg->GetSeg().B ),
TO_3DU( seg->GetWidth() + clearance.x * 2 ),
*aPad );
const SFVEC2F a3DU = TO_SFVEC2F( seg->GetSeg().A );
const SFVEC2F b3DU = TO_SFVEC2F( seg->GetSeg().B );
const double width3DU = TO_3DU( seg->GetWidth() + clearance.x * 2 );
if( width3DU == 0.0 )
{
// Don't attempt to render degenerate shapes
}
else if( Is_segment_a_circle( a3DU, b3DU ) )
{
// Cannot add segments that have the same start and end point
aContainer->Add( new FILLED_CIRCLE_2D( a3DU, width3DU / 2, *aPad ) );
}
else
{
aContainer->Add( new ROUND_SEGMENT_2D( a3DU, b3DU, width3DU, *aPad ) );
}
break;
}
@@ -405,10 +383,13 @@ void BOARD_ADAPTER::createPadWithMargin( const PAD* aPad, CONTAINER_2D_BASE* aCo
{
const SHAPE_CIRCLE* circle = static_cast<const SHAPE_CIRCLE*>( shape );
addFILLED_CIRCLE_2D( aContainer,
TO_SFVEC2F( circle->GetCenter() ),
TO_3DU( circle->GetRadius() + clearance.x ),
*aPad );
const double radius3DU = TO_3DU( circle->GetRadius() + clearance.x );
const SFVEC2F center3DU = TO_SFVEC2F( circle->GetCenter() );
// Don't render zero radius circles
if( radius3DU > 0.0 )
aContainer->Add( new FILLED_CIRCLE_2D( center3DU, radius3DU, *aPad ) );
break;
}
@@ -440,12 +421,23 @@ void BOARD_ADAPTER::createPadWithMargin( const PAD* aPad, CONTAINER_2D_BASE* aCo
for( int i = 0; i < l.SegmentCount(); i++ )
{
SHAPE_SEGMENT seg( l.Segment( i ).A, l.Segment( i ).B, arc->GetWidth() );
const SFVEC2F a3DU = TO_SFVEC2F( seg.GetSeg().A );
const SFVEC2F b3DU = TO_SFVEC2F( seg.GetSeg().B );
const double width3DU = TO_3DU( arc->GetWidth() + clearance.x * 2 );
addROUND_SEGMENT_2D( aContainer,
TO_SFVEC2F( seg.GetSeg().A ),
TO_SFVEC2F( seg.GetSeg().B ),
TO_3DU( arc->GetWidth() + clearance.x * 2 ),
*aPad );
if( width3DU == 0.0 )
{
// Don't attempt to render degenerate shapes
}
else if( Is_segment_a_circle( a3DU, b3DU ) )
{
// Cannot add segments that have the same start and end point
aContainer->Add( new FILLED_CIRCLE_2D( a3DU, width3DU / 2, *aPad ) );
}
else
{
aContainer->Add( new ROUND_SEGMENT_2D( a3DU, b3DU, width3DU, *aPad ) );
}
}
break;
@@ -461,7 +453,7 @@ void BOARD_ADAPTER::createPadWithMargin( const PAD* aPad, CONTAINER_2D_BASE* aCo
if( !poly.IsEmpty() )
{
if( clearance.x )
poly.Inflate( clearance.x, CORNER_STRATEGY::ROUND_ALL_CORNERS, maxError );
poly.Inflate( clearance.x, 32 );
// Add the PAD polygon
ConvertPolygonToTriangles( poly, *aContainer, m_biuTo3Dunits, *aPad );
@@ -469,44 +461,68 @@ void BOARD_ADAPTER::createPadWithMargin( const PAD* aPad, CONTAINER_2D_BASE* aCo
}
void BOARD_ADAPTER::createPadWithHole( const PAD* aPad, CONTAINER_2D_BASE* aDstContainer,
int aInflateValue )
OBJECT_2D* BOARD_ADAPTER::createPadWithDrill( const PAD* aPad, int aInflateValue )
{
if( !aPad->HasHole() )
{
wxLogTrace( m_logTrace, wxT( "BOARD_ADAPTER::createPadWithHole - found an invalid pad" ) );
return;
wxLogTrace( m_logTrace, wxT( "BOARD_ADAPTER::createPadWithDrill - found an invalid pad" ) );
return nullptr;
}
std::shared_ptr<SHAPE_SEGMENT> slot = aPad->GetEffectiveHoleShape();
addROUND_SEGMENT_2D( aDstContainer,
TO_SFVEC2F( slot->GetSeg().A ),
TO_SFVEC2F( slot->GetSeg().B ),
TO_3DU( slot->GetWidth() + aInflateValue * 2 ),
*aPad );
if( slot->GetSeg().A == slot->GetSeg().B )
{
return new FILLED_CIRCLE_2D( TO_SFVEC2F( slot->GetSeg().A ),
TO_3DU( slot->GetWidth() / 2 + aInflateValue ),
*aPad );
}
else
{
return new ROUND_SEGMENT_2D( TO_SFVEC2F( slot->GetSeg().A ),
TO_SFVEC2F( slot->GetSeg().B ),
TO_3DU( slot->GetWidth() + aInflateValue * 2 ),
*aPad );
}
}
void BOARD_ADAPTER::addPads( const FOOTPRINT* aFootprint, CONTAINER_2D_BASE* aContainer,
PCB_LAYER_ID aLayerId, bool aSkipPlatedPads, bool aSkipNonPlatedPads )
PCB_LAYER_ID aLayerId, bool aSkipNPTHPadsWihNoCopper,
bool aSkipPlatedPads, bool aSkipNonPlatedPads )
{
for( PAD* pad : aFootprint->Pads() )
{
if( !pad->IsOnLayer( aLayerId ) )
continue;
if( IsCopperLayer( aLayerId ) )
{
// Skip pad annulus when there isn't one (note: this is more discerning than
// pad->IsOnLayer(), which doesn't check for NPTH pads with holes that consume
// the entire pad).
if( !pad->IsOnCopperLayer() )
continue;
// Skip pad annulus when not connected on this layer (if removing is enabled)
if( !pad->FlashLayer( aLayerId ) && IsCopperLayer( aLayerId ) )
continue;
// Skip pad annulus when not connected on this layer (if removing is enabled)
if( !pad->FlashLayer( aLayerId ) )
continue;
// NPTH pads are not drawn on layers if the shape size and pos is the same as their hole:
if( aSkipNPTHPadsWihNoCopper && ( pad->GetAttribute() == PAD_ATTRIB::NPTH ) )
{
if( pad->GetDrillSize() == pad->GetSize() && pad->GetOffset() == wxPoint( 0, 0 ) )
{
switch( pad->GetShape() )
{
case PAD_SHAPE::CIRCLE:
if( pad->GetDrillShape() == PAD_DRILL_SHAPE_CIRCLE )
continue;
break;
case PAD_SHAPE::OVAL:
if( pad->GetDrillShape() != PAD_DRILL_SHAPE_CIRCLE )
continue;
break;
default:
break;
}
}
}
VECTOR2I margin( 0, 0 );
@@ -553,10 +569,10 @@ void BOARD_ADAPTER::addPads( const FOOTPRINT* aFootprint, CONTAINER_2D_BASE* aCo
// based on TransformArcToPolygon function from
// common/convert_basic_shapes_to_polygon.cpp
void BOARD_ADAPTER::createArcSegments( const VECTOR2I& aCentre, const VECTOR2I& aStart,
const EDA_ANGLE& aArcAngle, int aCircleToSegmentsCount,
int aWidth, CONTAINER_2D_BASE* aContainer,
const BOARD_ITEM& aOwner )
void BOARD_ADAPTER::transformArcToSegments( const VECTOR2I& aCentre, const VECTOR2I& aStart,
const EDA_ANGLE& aArcAngle, int aCircleToSegmentsCount,
int aWidth, CONTAINER_2D_BASE* aContainer,
const BOARD_ITEM& aOwner )
{
// Don't attempt to render degenerate shapes
if( aWidth == 0 )
@@ -586,16 +602,26 @@ void BOARD_ADAPTER::createArcSegments( const VECTOR2I& aCentre, const VECTOR2I&
curr_end = arc_start;
RotatePoint( curr_end, aCentre, -ii );
addROUND_SEGMENT_2D( aContainer, TO_SFVEC2F( curr_start ), TO_SFVEC2F( curr_end ),
TO_3DU( aWidth ), aOwner );
const SFVEC2F start3DU = TO_SFVEC2F( curr_start );
const SFVEC2F end3DU = TO_SFVEC2F( curr_end );
if( Is_segment_a_circle( start3DU, end3DU ) )
aContainer->Add( new FILLED_CIRCLE_2D( start3DU, TO_3DU( aWidth / 2 ), aOwner ) );
else
aContainer->Add( new ROUND_SEGMENT_2D( start3DU, end3DU, TO_3DU( aWidth ), aOwner ) );
curr_start = curr_end;
}
if( curr_end != arc_end )
{
addROUND_SEGMENT_2D( aContainer, TO_SFVEC2F( curr_end ), TO_SFVEC2F( arc_end ),
TO_3DU( aWidth ), aOwner );
const SFVEC2F start3DU = TO_SFVEC2F( curr_end );
const SFVEC2F end3DU = TO_SFVEC2F( arc_end );
if( Is_segment_a_circle( start3DU, end3DU ) )
aContainer->Add( new FILLED_CIRCLE_2D( start3DU, TO_3DU( aWidth / 2 ), aOwner ) );
else
aContainer->Add( new ROUND_SEGMENT_2D( start3DU, end3DU, TO_3DU( aWidth ), aOwner ) );
}
}
@@ -604,28 +630,42 @@ void BOARD_ADAPTER::addShape( const PCB_SHAPE* aShape, CONTAINER_2D_BASE* aConta
const BOARD_ITEM* aOwner )
{
// The full width of the lines to create
const float linewidth3DU = TO_3DU( aShape->GetWidth() );
LINE_STYLE lineStyle = aShape->GetStroke().GetLineStyle();
// The extra 1 protects the inner/outer radius values from degeneracy
const int linewidth = aShape->GetWidth() + 1;
PLOT_DASH_TYPE lineStyle = aShape->GetStroke().GetPlotStyle();
if( lineStyle <= LINE_STYLE::FIRST_TYPE )
if( lineStyle <= PLOT_DASH_TYPE::FIRST_TYPE )
{
switch( aShape->GetShape() )
{
case SHAPE_T::CIRCLE:
{
SFVEC2F center3DU = TO_SFVEC2F( aShape->GetCenter() );
float innerR3DU = TO_3DU( aShape->GetRadius() ) - linewidth3DU / 2.0;
float outerR3DU = TO_3DU( aShape->GetRadius() ) + linewidth3DU / 2.0;
const SFVEC2F center3DU = TO_SFVEC2F( aShape->GetCenter() );
float inner_radius3DU = TO_3DU( aShape->GetRadius() - linewidth / 2 );
float outer_radius3DU = TO_3DU( aShape->GetRadius() + linewidth / 2 );
if( aShape->IsFilled() || innerR3DU <= 0.0 )
addFILLED_CIRCLE_2D( aContainer, center3DU, outerR3DU, *aOwner );
if( inner_radius3DU < 0 )
inner_radius3DU = 0.0;
if( outer_radius3DU == 0.0 )
{
// Don't attempt to render degenerate shapes
}
else if( aShape->IsFilled() )
{
aContainer->Add( new FILLED_CIRCLE_2D( center3DU, outer_radius3DU,
*aOwner ) );
}
else
addRING_2D( aContainer, center3DU, innerR3DU, outerR3DU, *aOwner );
{
aContainer->Add( new RING_2D( center3DU, inner_radius3DU, outer_radius3DU,
*aOwner ) );
}
break;
}
case SHAPE_T::RECTANGLE:
case SHAPE_T::RECT:
if( aShape->IsFilled() )
{
SHAPE_POLY_SET polyList;
@@ -641,14 +681,14 @@ void BOARD_ADAPTER::addShape( const PCB_SHAPE* aShape, CONTAINER_2D_BASE* aConta
{
std::vector<VECTOR2I> pts = aShape->GetRectCorners();
addROUND_SEGMENT_2D( aContainer, TO_SFVEC2F( pts[0] ), TO_SFVEC2F( pts[1] ),
linewidth3DU, *aOwner );
addROUND_SEGMENT_2D( aContainer, TO_SFVEC2F( pts[1] ), TO_SFVEC2F( pts[2] ),
linewidth3DU, *aOwner );
addROUND_SEGMENT_2D( aContainer, TO_SFVEC2F( pts[2] ), TO_SFVEC2F( pts[3] ),
linewidth3DU, *aOwner );
addROUND_SEGMENT_2D( aContainer, TO_SFVEC2F( pts[3] ), TO_SFVEC2F( pts[0] ),
linewidth3DU, *aOwner );
aContainer->Add( new ROUND_SEGMENT_2D( TO_SFVEC2F( pts[0] ), TO_SFVEC2F( pts[1] ),
TO_3DU( linewidth ), *aOwner ) );
aContainer->Add( new ROUND_SEGMENT_2D( TO_SFVEC2F( pts[1] ), TO_SFVEC2F( pts[2] ),
TO_3DU( linewidth ), *aOwner ) );
aContainer->Add( new ROUND_SEGMENT_2D( TO_SFVEC2F( pts[2] ), TO_SFVEC2F( pts[3] ),
TO_3DU( linewidth ), *aOwner ) );
aContainer->Add( new ROUND_SEGMENT_2D( TO_SFVEC2F( pts[3] ), TO_SFVEC2F( pts[0] ),
TO_3DU( linewidth ), *aOwner ) );
}
break;
@@ -656,15 +696,33 @@ void BOARD_ADAPTER::addShape( const PCB_SHAPE* aShape, CONTAINER_2D_BASE* aConta
{
unsigned int segCount = GetCircleSegmentCount( aShape->GetBoundingBox().GetSizeMax() );
createArcSegments( aShape->GetCenter(), aShape->GetStart(), aShape->GetArcAngle(),
segCount, aShape->GetWidth(), aContainer, *aOwner );
transformArcToSegments( aShape->GetCenter(), aShape->GetStart(), aShape->GetArcAngle(),
segCount, linewidth, aContainer, *aOwner );
break;
}
case SHAPE_T::SEGMENT:
addROUND_SEGMENT_2D( aContainer, TO_SFVEC2F( aShape->GetStart() ),
TO_SFVEC2F( aShape->GetEnd() ), linewidth3DU, *aOwner );
{
const SFVEC2F start3DU = TO_SFVEC2F( aShape->GetStart() );
const SFVEC2F end3DU = TO_SFVEC2F( aShape->GetEnd() );
const double linewidth3DU = TO_3DU( linewidth );
if( linewidth3DU == 0.0 )
{
// Don't attempt to render degenerate shapes
}
else if( Is_segment_a_circle( start3DU, end3DU ) )
{
// Cannot add segments that have the same start and end point
aContainer->Add( new FILLED_CIRCLE_2D( start3DU, linewidth3DU / 2, *aOwner ) );
}
else
{
aContainer->Add( new ROUND_SEGMENT_2D( start3DU, end3DU, linewidth3DU, *aOwner ) );
}
break;
}
case SHAPE_T::BEZIER:
case SHAPE_T::POLY:
@@ -674,11 +732,6 @@ void BOARD_ADAPTER::addShape( const PCB_SHAPE* aShape, CONTAINER_2D_BASE* aConta
aShape->TransformShapeToPolygon( polyList, UNDEFINED_LAYER, 0, ARC_HIGH_DEF,
ERROR_INSIDE );
// Some polygons can be a bit complex (especially when coming from a
// picture ot a text converted to a polygon
// So call Simplify before calling ConvertPolygonToTriangles, just in case.
polyList.Simplify( SHAPE_POLY_SET::PM_FAST );
if( polyList.IsEmpty() ) // Just for caution
break;
@@ -692,11 +745,12 @@ void BOARD_ADAPTER::addShape( const PCB_SHAPE* aShape, CONTAINER_2D_BASE* aConta
break;
}
}
else
else if( linewidth > 0 )
{
std::vector<SHAPE*> shapes = aShape->MakeEffectiveShapes( true );
SFVEC2F a3DU;
SFVEC2F b3DU;
double width3DU = TO_3DU( linewidth );
const PCB_PLOT_PARAMS& plotParams = aShape->GetBoard()->GetPlotOptions();
KIGFX::PCB_RENDER_SETTINGS renderSettings;
@@ -706,11 +760,16 @@ void BOARD_ADAPTER::addShape( const PCB_SHAPE* aShape, CONTAINER_2D_BASE* aConta
for( SHAPE* shape : shapes )
{
STROKE_PARAMS::Stroke( shape, lineStyle, aShape->GetWidth(), &renderSettings,
STROKE_PARAMS::Stroke( shape, lineStyle, linewidth, &renderSettings,
[&]( const VECTOR2I& a, const VECTOR2I& b )
{
addROUND_SEGMENT_2D( aContainer, TO_SFVEC2F( a ), TO_SFVEC2F( b ),
linewidth3DU, *aOwner );
a3DU = TO_SFVEC2F( a );
b3DU = TO_SFVEC2F( b );
if( Is_segment_a_circle( a3DU, b3DU ) )
aContainer->Add( new FILLED_CIRCLE_2D( a3DU, width3DU / 2, *aOwner ) );
else
aContainer->Add( new ROUND_SEGMENT_2D( a3DU, b3DU, width3DU, *aOwner ) );
} );
}
@@ -720,51 +779,12 @@ void BOARD_ADAPTER::addShape( const PCB_SHAPE* aShape, CONTAINER_2D_BASE* aConta
}
void BOARD_ADAPTER::addShape( const PCB_TEXTBOX* aTextBox, CONTAINER_2D_BASE* aContainer,
const BOARD_ITEM* aOwner )
{
addText( aTextBox, aContainer, aOwner );
if( !aTextBox->IsBorderEnabled() )
return;
// We cannot use PCB_TEXTBOX::TransformShapeToPolygon because it convert the textbox
// as filled polygon even if there's no background colour.
// So for polygon, we use PCB_SHAPE::TransformShapeToPolygon
if( aTextBox->GetShape() == SHAPE_T::RECTANGLE )
{
addShape( static_cast<const PCB_SHAPE*>( aTextBox ), aContainer, aOwner );
}
else
{
SHAPE_POLY_SET polyList;
aTextBox->PCB_SHAPE::TransformShapeToPolygon( polyList, UNDEFINED_LAYER, 0,
ARC_HIGH_DEF, ERROR_INSIDE );
ConvertPolygonToTriangles( polyList, *aContainer, m_biuTo3Dunits, *aOwner );
}
}
void BOARD_ADAPTER::addTable( const PCB_TABLE* aTable, CONTAINER_2D_BASE* aContainer,
const BOARD_ITEM* aOwner )
{
// JEY TODO: tables
// add borders
for( PCB_TABLECELL* cell : aTable->GetCells() )
addText( cell, aContainer, aOwner );
}
void BOARD_ADAPTER::addSolidAreasShapes( const ZONE* aZone, CONTAINER_2D_BASE* aContainer,
PCB_LAYER_ID aLayerId )
{
// This convert the poly in outline and holes
ConvertPolygonToTriangles( *aZone->GetFilledPolysList( aLayerId ), *aContainer, m_biuTo3Dunits,
*aZone );
ConvertPolygonToTriangles( *aZone->GetFilledPolysList( aLayerId ), *aContainer,
m_biuTo3Dunits, *aZone );
}
@@ -775,23 +795,35 @@ void BOARD_ADAPTER::buildPadOutlineAsSegments( const PAD* aPad, CONTAINER_2D_BAS
{
const SFVEC2F center3DU = TO_SFVEC2F( aPad->ShapePos() );
const int radius = aPad->GetSize().x / 2;
const float inner_radius3DU = TO_3DU( radius - aWidth / 2.0 );
const float outer_radius3DU = TO_3DU( radius + aWidth / 2.0 );
const float inner_radius3DU = TO_3DU( radius - aWidth / 2 );
const float outer_radius3DU = TO_3DU( radius + aWidth / 2 );
addRING_2D( aContainer, center3DU, inner_radius3DU, outer_radius3DU, *aPad );
aContainer->Add( new RING_2D( center3DU, inner_radius3DU, outer_radius3DU, *aPad ) );
return;
}
else
// For other shapes, add outlines as thick segments in polygon buffer
const std::shared_ptr<SHAPE_POLY_SET>& corners = aPad->GetEffectivePolygon();
const SHAPE_LINE_CHAIN& path = corners->COutline( 0 );
for( int j = 0; j < path.PointCount(); j++ )
{
// For other shapes, add outlines as thick segments in polygon buffer
const std::shared_ptr<SHAPE_POLY_SET>& corners = aPad->GetEffectivePolygon( ERROR_INSIDE );
const SHAPE_LINE_CHAIN& path = corners->COutline( 0 );
SFVEC2F start3DU = TO_SFVEC2F( path.CPoint( j ) );
SFVEC2F end3DU = TO_SFVEC2F( path.CPoint( j + 1 ) );
for( int j = 0; j < path.PointCount(); j++ )
if( aWidth == 0 )
{
SFVEC2F start3DU = TO_SFVEC2F( path.CPoint( j ) );
SFVEC2F end3DU = TO_SFVEC2F( path.CPoint( j + 1 ) );
addROUND_SEGMENT_2D( aContainer, start3DU, end3DU, TO_3DU( aWidth ), *aPad );
// Don't attempt to render degenerate shapes
}
else if( Is_segment_a_circle( start3DU, end3DU ) )
{
// Cannot add segments that have the same start and end point
aContainer->Add( new FILLED_CIRCLE_2D( start3DU, TO_3DU( aWidth / 2 ), *aPad ) );
}
else
{
aContainer->Add( new ROUND_SEGMENT_2D( start3DU, end3DU, TO_3DU( aWidth ), *aPad ) );
}
}
}
File diff suppressed because it is too large Load Diff
+89
View File
@@ -0,0 +1,89 @@
/*
* This program source code file is part of KiCad, a free EDA CAD application.
*
* Copyright (C) 2015-2016 Mario Luzeiro <mrluzeiro@ua.pt>
* Copyright (C) 1992-2022 KiCad Developers, see AUTHORS.txt for contributors.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, you may find one here:
* http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
* or you may search the http://www.gnu.org website for the version 2 license,
* or you may write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
*/
/**
* @file create_layer_poly.cpp
* @brief This file implements the creation of the pcb board items in the poly
* contours format.
*/
#include "board_adapter.h"
#include <board_design_settings.h>
#include <convert_basic_shapes_to_polygon.h>
#include <fp_shape.h>
#include <footprint.h>
/*
* This is used to draw pad outlines on silk layers.
*/
void BOARD_ADAPTER::buildPadOutlineAsPolygon( const PAD* aPad, SHAPE_POLY_SET& aBuffer,
int aWidth ) const
{
int maxError = m_board->GetDesignSettings().m_MaxError;
if( aPad->GetShape() == PAD_SHAPE::CIRCLE ) // Draw a ring
{
TransformRingToPolygon( aBuffer, aPad->ShapePos(), aPad->GetSize().x / 2, aWidth, maxError,
ERROR_INSIDE );
return;
}
// For other shapes, add outlines as thick segments in polygon buffer
const std::shared_ptr<SHAPE_POLY_SET>& corners = aPad->GetEffectivePolygon();
const SHAPE_LINE_CHAIN& path = corners->COutline( 0 );
for( int ii = 0; ii < path.PointCount(); ++ii )
{
const VECTOR2I& a = path.CPoint( ii );
const VECTOR2I& b = path.CPoint( ii + 1 );
TransformOvalToPolygon( aBuffer, a, b, aWidth, maxError, ERROR_INSIDE );
}
}
void BOARD_ADAPTER::transformFPShapesToPolySet( const FOOTPRINT* aFootprint, PCB_LAYER_ID aLayer,
SHAPE_POLY_SET& aBuffer ) const
{
int maxError = m_board->GetDesignSettings().m_MaxError;
for( BOARD_ITEM* item : aFootprint->GraphicalItems() )
{
if( item->Type() == PCB_FP_SHAPE_T )
{
FP_SHAPE* shape = static_cast<FP_SHAPE*>( item );
if( shape->GetLayer() == aLayer )
shape->TransformShapeToPolygon( aBuffer, aLayer, 0, maxError, ERROR_INSIDE );
}
else if( BaseType( item->Type() ) == PCB_DIMENSION_T )
{
PCB_DIMENSION_BASE* dimension = static_cast<PCB_DIMENSION_BASE*>( item );
if( dimension->GetLayer() == aLayer )
dimension->TransformShapeToPolygon( aBuffer, aLayer, 0, maxError, ERROR_INSIDE );
}
}
}
+127 -133
View File
@@ -2,7 +2,7 @@
* This program source code file is part of KiCad, a free EDA CAD application.
*
* Copyright (C) 2015-2016 Mario Luzeiro <mrluzeiro@ua.pt>
* Copyright (C) 1992-2024 KiCad Developers, see AUTHORS.txt for contributors.
* Copyright (C) 1992-2023 KiCad Developers, see AUTHORS.txt for contributors.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
@@ -23,23 +23,22 @@
*/
#include <gal/opengl/kiglew.h> // Must be included first
#include <gal/opengl/gl_utils.h>
#include <gl_utils.h>
#include <wx/tokenzr.h>
#include "../common_ogl/ogl_utils.h"
#include "eda_3d_canvas.h"
#include <eda_3d_viewer_frame.h>
#include <3d_rendering/raytracing/render_3d_raytrace_gl.h>
#include <3d_rendering/raytracing/render_3d_raytrace.h>
#include <3d_rendering/opengl/render_3d_opengl.h>
#include <3d_viewer_id.h>
#include <advanced_config.h>
#include <build_version.h>
#include <board.h>
#include <reporter.h>
#include <gal/opengl/gl_context_mgr.h>
#include <core/profile.h> // To use GetRunningMicroSecs or another profiling utility
#include <gl_context_mgr.h>
#include <profile.h> // To use GetRunningMicroSecs or another profiling utility
#include <bitmaps.h>
#include <macros.h>
#include <menus_helpers.h>
#include <pgm_base.h>
#include <settings/settings_manager.h>
#include <tool/tool_dispatcher.h>
@@ -71,12 +70,10 @@ BEGIN_EVENT_TABLE( EDA_3D_CANVAS, HIDPI_GL_3D_CANVAS )
EVT_MIDDLE_DOWN( EDA_3D_CANVAS::OnMiddleDown)
EVT_MOUSEWHEEL( EDA_3D_CANVAS::OnMouseWheel )
EVT_MOTION( EDA_3D_CANVAS::OnMouseMove )
EVT_MAGNIFY( EDA_3D_CANVAS::OnMagnify )
// touch gesture events
EVT_GESTURE_ZOOM( wxID_ANY, EDA_3D_CANVAS::OnZoomGesture )
EVT_GESTURE_PAN( wxID_ANY, EDA_3D_CANVAS::OnPanGesture )
EVT_GESTURE_ROTATE( wxID_ANY, EDA_3D_CANVAS::OnRotateGesture )
#if wxCHECK_VERSION( 3, 1, 0 ) || defined( USE_OSX_MAGNIFY_EVENT )
EVT_MAGNIFY( EDA_3D_CANVAS::OnMagnify )
#endif
// other events
EVT_ERASE_BACKGROUND( EDA_3D_CANVAS::OnEraseBackground )
@@ -87,11 +84,10 @@ BEGIN_EVENT_TABLE( EDA_3D_CANVAS, HIDPI_GL_3D_CANVAS )
END_EVENT_TABLE()
EDA_3D_CANVAS::EDA_3D_CANVAS( wxWindow* aParent, const wxGLAttributes& aGLAttribs,
EDA_3D_CANVAS::EDA_3D_CANVAS( wxWindow* aParent, const int* aAttribList,
BOARD_ADAPTER& aBoardAdapter, CAMERA& aCamera,
S3D_CACHE* a3DCachePointer ) :
HIDPI_GL_3D_CANVAS( EDA_DRAW_PANEL_GAL::GetVcSettings(), aCamera, aParent, aGLAttribs,
wxID_ANY, wxDefaultPosition,
HIDPI_GL_3D_CANVAS( aCamera, aParent, wxID_ANY, aAttribList, wxDefaultPosition,
wxDefaultSize, wxFULL_REPAINT_ON_RESIZE ),
m_eventDispatcher( nullptr ),
m_parentStatusBar( nullptr ),
@@ -125,7 +121,7 @@ EDA_3D_CANVAS::EDA_3D_CANVAS( wxWindow* aParent, const wxGLAttributes& aGLAttrib
m_is_currently_painting.clear();
m_3d_render_raytracing = new RENDER_3D_RAYTRACE_GL( this, m_boardAdapter, m_camera );
m_3d_render_raytracing = new RENDER_3D_RAYTRACE( this, m_boardAdapter, m_camera );
m_3d_render_opengl = new RENDER_3D_OPENGL( this, m_boardAdapter, m_camera );
wxASSERT( m_3d_render_raytracing != nullptr );
@@ -144,15 +140,11 @@ EDA_3D_CANVAS::EDA_3D_CANVAS( wxWindow* aParent, const wxGLAttributes& aGLAttrib
// long calculation time)
m_3d_render = m_3d_render_opengl;
m_boardAdapter.ReloadColorSettings();
m_boardAdapter.SetColorSettings( Pgm().GetSettingsManager().GetColorSettings() );
wxASSERT( a3DCachePointer != nullptr );
m_boardAdapter.Set3dCacheManager( a3DCachePointer );
#ifdef __WXMSW__
EnableTouchEvents( wxTOUCH_ZOOM_GESTURE | wxTOUCH_PAN_GESTURES | wxTOUCH_ROTATE_GESTURE );
#endif
const wxEventType events[] =
{
// Binding both EVT_CHAR and EVT_CHAR_HOOK ensures that all key events,
@@ -163,7 +155,9 @@ EDA_3D_CANVAS::EDA_3D_CANVAS( wxWindow* aParent, const wxGLAttributes& aGLAttrib
wxEVT_RIGHT_UP, wxEVT_RIGHT_DOWN, wxEVT_RIGHT_DCLICK,
wxEVT_MIDDLE_UP, wxEVT_MIDDLE_DOWN, wxEVT_MIDDLE_DCLICK,
wxEVT_MOTION, wxEVT_MOUSEWHEEL, wxEVT_CHAR, wxEVT_CHAR_HOOK,
#if wxCHECK_VERSION( 3, 1, 0 ) || defined( USE_OSX_MAGNIFY_EVENT )
wxEVT_MAGNIFY,
#endif
wxEVT_MENU_OPEN, wxEVT_MENU_CLOSE, wxEVT_MENU_HIGHLIGHT
};
@@ -236,13 +230,10 @@ bool EDA_3D_CANVAS::initializeOpenGL()
else
{
wxLogTrace( m_logTrace, wxT( "EDA_3D_CANVAS::initializeOpenGL Using GLEW version %s" ),
From_UTF8( (char*) glewGetString( GLEW_VERSION ) ) );
FROM_UTF8( (char*) glewGetString( GLEW_VERSION ) ) );
}
SetOpenGLInfo( (const char*) glGetString( GL_VENDOR ), (const char*) glGetString( GL_RENDERER ),
(const char*) glGetString( GL_VERSION ) );
wxString version = From_UTF8( (char *) glGetString( GL_VERSION ) );
wxString version = FROM_UTF8( (char *) glGetString( GL_VERSION ) );
wxLogTrace( m_logTrace, wxT( "EDA_3D_CANVAS::%s OpenGL version string %s." ),
__WXFUNCTION__, version );
@@ -312,7 +303,7 @@ void EDA_3D_CANVAS::ReloadRequest( BOARD* aBoard , S3D_CACHE* aCachePointer )
if( aBoard != nullptr )
m_boardAdapter.SetBoard( aBoard );
m_boardAdapter.ReloadColorSettings();
m_boardAdapter.SetColorSettings( Pgm().GetSettingsManager().GetColorSettings() );
if( m_3d_render )
m_3d_render->ReloadRequest();
@@ -343,9 +334,6 @@ void EDA_3D_CANVAS::DisplayStatus()
msg.Printf( wxT( "dy %3.2f" ), m_camera.GetCameraPos().y );
m_parentStatusBar->SetStatusText( msg, static_cast<int>( EDA_3D_VIEWER_STATUSBAR::Y_POS ) );
msg.Printf( wxT( "zoom %3.2f" ), 1 / m_camera.GetZoom() );
m_parentStatusBar->SetStatusText( msg, static_cast<int>( EDA_3D_VIEWER_STATUSBAR::ZOOM_LEVEL ) );
}
}
@@ -376,13 +364,16 @@ void EDA_3D_CANVAS::DoRePaint()
// therefore with invalid board.
// This is dependent of the platform.
// Especially on OSX, but also on Windows, it frequently happens
if( !GetParent()->GetParent()->IsShownOnScreen() )
if( !GetParent()->GetParent()->IsShown() )
return; // The parent board editor frame is no more alive
wxString err_messages;
wxString err_messages;
// !TODO: implement error reporter
INFOBAR_REPORTER warningReporter( m_parentInfoBar );
STATUSBAR_REPORTER activityReporter( m_parentStatusBar, EDA_3D_VIEWER_STATUSBAR::ACTIVITY );
int64_t start_time = GetRunningMicroSecs();
unsigned strtime = GetRunningMicroSecs();
// "Makes the OpenGL state that is represented by the OpenGL rendering
// context context current, i.e. it will be used by all subsequent OpenGL calls.
@@ -474,7 +465,7 @@ void EDA_3D_CANVAS::DoRePaint()
if( m_camera_is_moving )
{
const int64_t curtime_delta = GetRunningMicroSecs() - m_strtime_camera_movement;
const unsigned curtime_delta = GetRunningMicroSecs() - m_strtime_camera_movement;
curtime_delta_s = (curtime_delta / 1e6) * m_camera_moving_speed;
m_camera.Interpolate( curtime_delta_s );
@@ -540,13 +531,13 @@ void EDA_3D_CANVAS::DoRePaint()
render_pivot( curtime_delta_s, scale );
}
// This will only be enabled by the 3d mouse plugin, so we can leave
// it as a simple if statement
#if defined( KICAD_USE_3DCONNEXION )
if( m_render3dmousePivot )
{
const float scale = glm::min( m_camera.GetZoom(), 1.0f );
render3dmousePivot( scale );
}
#endif
// "Swaps the double-buffer of this window, making the back-buffer the
// front-buffer and vice versa, so that the output of the previous OpenGL
@@ -555,13 +546,16 @@ void EDA_3D_CANVAS::DoRePaint()
GL_CONTEXT_MANAGER::Get().UnlockCtx( m_glRC );
if( m_mouse_was_moved || m_camera_is_moving )
if( !activityReporter.HasMessage() )
{
// Calculation time in milliseconds
const double calculation_time = (double)( GetRunningMicroSecs() - start_time ) / 1e3;
if( m_mouse_was_moved || m_camera_is_moving )
{
// Calculation time in milliseconds
const double calculation_time = (double)( GetRunningMicroSecs() - strtime) / 1e3;
activityReporter.Report( wxString::Format( _( "Last render time %.0f ms" ),
calculation_time ) );
activityReporter.Report( wxString::Format( _( "Last render time %.0f ms" ),
calculation_time ) );
}
}
// This will reset the flag of camera parameters changed
@@ -621,6 +615,7 @@ void EDA_3D_CANVAS::OnMouseWheel( wxMouseEvent& event )
}
#if wxCHECK_VERSION( 3, 1, 0 ) || defined( USE_OSX_MAGNIFY_EVENT )
void EDA_3D_CANVAS::OnMagnify( wxMouseEvent& event )
{
SetFocus();
@@ -638,82 +633,11 @@ void EDA_3D_CANVAS::OnMagnify( wxMouseEvent& event )
DisplayStatus();
Request_refresh();
}
void EDA_3D_CANVAS::OnZoomGesture( wxZoomGestureEvent& aEvent )
{
SetFocus();
if( aEvent.IsGestureStart() )
{
m_gestureLastZoomFactor = 1.0;
m_camera.SetCurMousePosition( aEvent.GetPosition() );
}
if( m_camera_is_moving )
return;
restart_editingTimeOut_Timer();
m_camera.Pan( aEvent.GetPosition() );
m_camera.SetCurMousePosition( aEvent.GetPosition() );
m_camera.Zoom( aEvent.GetZoomFactor() / m_gestureLastZoomFactor );
m_gestureLastZoomFactor = aEvent.GetZoomFactor();
DisplayStatus();
Request_refresh();
}
void EDA_3D_CANVAS::OnPanGesture( wxPanGestureEvent& aEvent )
{
SetFocus();
if( aEvent.IsGestureStart() )
m_camera.SetCurMousePosition( aEvent.GetPosition() );
if( m_camera_is_moving )
return;
m_camera.Pan( aEvent.GetPosition() );
m_camera.SetCurMousePosition( aEvent.GetPosition() );
DisplayStatus();
Request_refresh();
}
void EDA_3D_CANVAS::OnRotateGesture( wxRotateGestureEvent& aEvent )
{
SetFocus();
if( aEvent.IsGestureStart() )
{
m_gestureLastAngle = 0;
m_camera.SetCurMousePosition( aEvent.GetPosition() );
// We don't want to process the first angle
return;
}
if( m_camera_is_moving )
return;
m_camera.RotateScreen( m_gestureLastAngle - aEvent.GetRotationAngle() );
m_gestureLastAngle = aEvent.GetRotationAngle();
DisplayStatus();
Request_refresh();
}
#endif
void EDA_3D_CANVAS::OnMouseMove( wxMouseEvent& event )
{
if( m_3d_render && m_3d_render->IsReloadRequestPending() )
return; // Prevents using invalid m_3d_render_raytracing data
if( m_camera_is_moving )
return;
@@ -920,7 +844,7 @@ void EDA_3D_CANVAS::OnTimerTimeout_Redraw( wxTimerEvent& aEvent )
void EDA_3D_CANVAS::OnRefreshRequest( wxEvent& aEvent )
{
Refresh();
DoRePaint();
}
@@ -993,56 +917,68 @@ void EDA_3D_CANVAS::move_pivot_based_on_cur_mouse_position()
}
bool EDA_3D_CANVAS::SetView3D( VIEW3D_TYPE aRequestedView )
bool EDA_3D_CANVAS::SetView3D( int aKeycode )
{
if( m_camera_is_moving )
return false;
const float delta_move = m_delta_move_step_factor * m_camera.GetZoom();
const float arrow_moving_time_speed = 8.0f;
bool handled = false;
switch( aRequestedView )
switch( aKeycode )
{
case VIEW3D_TYPE::VIEW3D_PIVOT_CENTER:
case WXK_SPACE:
move_pivot_based_on_cur_mouse_position();
return true;
case VIEW3D_TYPE::VIEW3D_PAN_LEFT:
case WXK_LEFT:
m_camera.SetInterpolateMode( CAMERA_INTERPOLATION::LINEAR );
m_camera.SetT0_and_T1_current_T();
m_camera.Pan_T1( SFVEC3F( -delta_move, 0.0f, 0.0f ) );
request_start_moving_camera( arrow_moving_time_speed, false );
return true;
case VIEW3D_TYPE::VIEW3D_PAN_RIGHT:
case WXK_RIGHT:
m_camera.SetInterpolateMode( CAMERA_INTERPOLATION::LINEAR );
m_camera.SetT0_and_T1_current_T();
m_camera.Pan_T1( SFVEC3F( +delta_move, 0.0f, 0.0f ) );
request_start_moving_camera( arrow_moving_time_speed, false );
return true;
case VIEW3D_TYPE::VIEW3D_PAN_UP:
case WXK_UP:
m_camera.SetInterpolateMode( CAMERA_INTERPOLATION::LINEAR );
m_camera.SetT0_and_T1_current_T();
m_camera.Pan_T1( SFVEC3F( 0.0f, +delta_move, 0.0f ) );
request_start_moving_camera( arrow_moving_time_speed, false );
return true;
case VIEW3D_TYPE::VIEW3D_PAN_DOWN:
case WXK_DOWN:
m_camera.SetInterpolateMode( CAMERA_INTERPOLATION::LINEAR );
m_camera.SetT0_and_T1_current_T();
m_camera.Pan_T1( SFVEC3F( 0.0f, -delta_move, 0.0f ) );
request_start_moving_camera( arrow_moving_time_speed, false );
return true;
case VIEW3D_TYPE::VIEW3D_FIT_SCREEN:
case WXK_HOME:
m_camera.SetInterpolateMode( CAMERA_INTERPOLATION::BEZIER );
m_camera.SetT0_and_T1_current_T();
m_camera.Reset_T1();
request_start_moving_camera( glm::min( glm::max( m_camera.GetZoom(), 1 / 1.26f ), 1.26f ) );
return true;
case VIEW3D_TYPE::VIEW3D_ZOOM_IN:
case WXK_END:
break;
case WXK_TAB:
m_camera.SetInterpolateMode( CAMERA_INTERPOLATION::EASING_IN_OUT );
m_camera.SetT0_and_T1_current_T();
m_camera.RotateZ_T1( glm::radians( 45.0f ) );
request_start_moving_camera();
handled = true;
break;
case WXK_F1:
m_camera.SetInterpolateMode( CAMERA_INTERPOLATION::BEZIER );
m_camera.SetT0_and_T1_current_T();
@@ -1051,7 +987,7 @@ bool EDA_3D_CANVAS::SetView3D( VIEW3D_TYPE aRequestedView )
return true;
case VIEW3D_TYPE::VIEW3D_ZOOM_OUT:
case WXK_F2:
m_camera.SetInterpolateMode( CAMERA_INTERPOLATION::BEZIER );
m_camera.SetT0_and_T1_current_T();
@@ -1060,28 +996,86 @@ bool EDA_3D_CANVAS::SetView3D( VIEW3D_TYPE aRequestedView )
return true;
case VIEW3D_TYPE::VIEW3D_RIGHT:
case VIEW3D_TYPE::VIEW3D_LEFT:
case VIEW3D_TYPE::VIEW3D_FRONT:
case VIEW3D_TYPE::VIEW3D_BACK:
case VIEW3D_TYPE::VIEW3D_FLIP:
case ID_VIEW3D_RESET:
m_camera.SetInterpolateMode( CAMERA_INTERPOLATION::BEZIER );
m_camera.SetT0_and_T1_current_T();
m_camera.ViewCommand_T1( aRequestedView );
m_camera.Reset_T1();
request_start_moving_camera( glm::min( glm::max( m_camera.GetZoom(), 0.5f ), 1.125f ) );
return true;
case ID_VIEW3D_RIGHT:
m_camera.SetInterpolateMode( CAMERA_INTERPOLATION::BEZIER );
m_camera.SetT0_and_T1_current_T();
m_camera.Reset_T1();
m_camera.RotateZ_T1( glm::radians( -90.0f ) );
m_camera.RotateX_T1( glm::radians( -90.0f ) );
request_start_moving_camera();
return true;
case VIEW3D_TYPE::VIEW3D_TOP:
case VIEW3D_TYPE::VIEW3D_BOTTOM:
case ID_VIEW3D_LEFT:
m_camera.SetInterpolateMode( CAMERA_INTERPOLATION::BEZIER );
m_camera.SetT0_and_T1_current_T();
m_camera.ViewCommand_T1( aRequestedView );
m_camera.Reset_T1();
m_camera.RotateZ_T1( glm::radians( 90.0f ) );
m_camera.RotateX_T1( glm::radians( -90.0f ) );
request_start_moving_camera();
return true;
case ID_VIEW3D_FRONT:
m_camera.SetInterpolateMode( CAMERA_INTERPOLATION::BEZIER );
m_camera.SetT0_and_T1_current_T();
m_camera.Reset_T1();
m_camera.RotateX_T1( glm::radians( -90.0f ) );
request_start_moving_camera();
return true;
case ID_VIEW3D_BACK:
m_camera.SetInterpolateMode( CAMERA_INTERPOLATION::BEZIER );
m_camera.SetT0_and_T1_current_T();
m_camera.Reset_T1();
m_camera.RotateX_T1( glm::radians( -90.0f ) );
// The rotation angle should be 180.
// We use 179.999 (180 - epsilon) to avoid a full 360 deg rotation when
// using 180 deg if the previous rotated position was already 180 deg
m_camera.RotateZ_T1( glm::radians( 179.999f ) );
request_start_moving_camera();
return true;
case ID_VIEW3D_TOP:
m_camera.SetInterpolateMode( CAMERA_INTERPOLATION::BEZIER );
m_camera.SetT0_and_T1_current_T();
m_camera.Reset_T1();
request_start_moving_camera( glm::min( glm::max( m_camera.GetZoom(), 0.5f ), 1.125f ) );
return true;
case ID_VIEW3D_BOTTOM:
m_camera.SetInterpolateMode( CAMERA_INTERPOLATION::BEZIER );
m_camera.SetT0_and_T1_current_T();
m_camera.Reset_T1();
m_camera.RotateY_T1( glm::radians( 179.999f ) ); // Rotation = 180 - epsilon
request_start_moving_camera( glm::min( glm::max( m_camera.GetZoom(), 0.5f ), 1.125f ) );
return true;
case ID_VIEW3D_FLIP:
m_camera.SetInterpolateMode( CAMERA_INTERPOLATION::BEZIER );
m_camera.SetT0_and_T1_current_T();
m_camera.RotateY_T1( glm::radians( 179.999f ) );
request_start_moving_camera();
return true;
default:
return false;
}
m_mouse_was_moved = true;
restart_editingTimeOut_Timer();
DisplayStatus();
Request_refresh();
return handled;
}
+28 -24
View File
@@ -2,7 +2,7 @@
* This program source code file is part of KiCad, a free EDA CAD application.
*
* Copyright (C) 2015-2016 Mario Luzeiro <mrluzeiro@ua.pt>
* Copyright (C) 1992-2024 KiCad Developers, see AUTHORS.txt for contributors.
* Copyright (C) 1992-2021 KiCad Developers, see AUTHORS.txt for contributors.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
@@ -38,7 +38,7 @@
class WX_INFOBAR;
class wxStatusBar;
class BOARD;
class RENDER_3D_RAYTRACE_GL;
class RENDER_3D_RAYTRACE;
class RENDER_3D_OPENGL;
@@ -52,12 +52,12 @@ public:
* Create a new 3D Canvas with an attribute list.
*
* @param aParent the parent creator of this canvas.
* @param aGLAttribs openGL attributes created by #OGL_ATT_LIST::GetAttributesList.
* @param aAttribList a list of openGL options created by GetOpenGL_AttributesList.
* @param aBoard The board.
* @param aSettings the settings options to be used by this canvas.
*/
EDA_3D_CANVAS( wxWindow* aParent, const wxGLAttributes& aGLAttribs, BOARD_ADAPTER& aSettings,
CAMERA& aCamera, S3D_CACHE* a3DCachePointer );
EDA_3D_CANVAS( wxWindow* aParent, const int* aAttribList,
BOARD_ADAPTER& aSettings, CAMERA& aCamera, S3D_CACHE* a3DCachePointer );
~EDA_3D_CANVAS();
@@ -97,7 +97,7 @@ public:
}
/**
* @return the current render ( a RENDER_3D_RAYTRACE_GL* or a RENDER_3D_OPENGL* render )
* @return the current render ( a RENDER_3D_RAYTRACE* or a RENDER_3D_OPENGL* render )
*/
RENDER_3D_BASE* GetCurrentRender() const { return m_3d_render; }
@@ -114,12 +114,12 @@ public:
void GetScreenshot( wxImage& aDstImage );
/**
* Select a specific 3D view or operation
* Helper function to call view commands.
*
* @param aRequestedView the view to move to
* @return true if the view request was handled, false if no command found for this view.
* @param aKeycode ascii key commands.
* @return true if the key code was handled, false if no command found for this code.
*/
bool SetView3D( VIEW3D_TYPE aRequestedView );
bool SetView3D( int aKeycode );
/**
* Enable or disable camera animation when switching to a pre-defined view.
@@ -178,6 +178,8 @@ public:
*/
void SetRenderPivot( bool aValue ) { m_render_pivot = aValue; }
#if defined( KICAD_USE_3DCONNEXION )
/**
* Get a value indicating whether to render the 3dmouse pivot.
*/
@@ -207,6 +209,13 @@ public:
{
m_3dmousePivotPos = aPos;
}
#endif
private:
/**
* Called by a wxPaintEvent event
*/
void OnPaint( wxPaintEvent& aEvent );
/**
* The actual function to repaint the canvas.
@@ -216,17 +225,16 @@ public:
*/
void DoRePaint();
private:
// The wxPaintEvent event. mainly calls DoRePaint()
void OnPaint( wxPaintEvent& aEvent );
void OnEraseBackground( wxEraseEvent& event );
void OnRefreshRequest( wxEvent& aEvent );
void OnMouseWheel( wxMouseEvent& event );
#if wxCHECK_VERSION( 3, 1, 0 ) || defined( USE_OSX_MAGNIFY_EVENT )
void OnMagnify( wxMouseEvent& event );
#endif
void OnMouseMove( wxMouseEvent& event );
void OnLeftDown( wxMouseEvent& event );
void OnLeftUp( wxMouseEvent& event );
@@ -237,10 +245,6 @@ private:
void OnResize( wxSizeEvent& event );
void OnTimerTimeout_Redraw( wxTimerEvent& event );
void OnZoomGesture( wxZoomGestureEvent& event );
void OnPanGesture( wxPanGestureEvent& event );
void OnRotateGesture( wxRotateGestureEvent& event );
DECLARE_EVENT_TABLE()
/**
@@ -274,12 +278,14 @@ private:
*/
void render_pivot( float t, float aScale );
#if defined( KICAD_USE_3DCONNEXION )
/**
* Render the 3dmouse pivot cursor.
*
* @param aScale scale to apply on the cursor.
*/
void render3dmousePivot( float aScale );
#endif
/**
* @return true if OpenGL initialization succeeded.
@@ -309,13 +315,13 @@ private:
bool m_render_pivot; // Render the pivot while camera moving
float m_camera_moving_speed; // 1.0f will be 1:1
int64_t m_strtime_camera_movement; // Ticktime of camera movement start
unsigned m_strtime_camera_movement; // Ticktime of camera movement start
bool m_animation_enabled; // Camera animation enabled
int m_moving_speed_multiplier; // Camera animation speed multiplier option
BOARD_ADAPTER& m_boardAdapter; // Pre-computed 3D info and settings
RENDER_3D_BASE* m_3d_render;
RENDER_3D_RAYTRACE_GL* m_3d_render_raytracing;
RENDER_3D_RAYTRACE* m_3d_render_raytracing;
RENDER_3D_OPENGL* m_3d_render_opengl;
bool m_opengl_supports_raytracing;
@@ -325,12 +331,10 @@ private:
BOARD_ITEM* m_currentRollOverItem;
#if defined( KICAD_USE_3DCONNEXION )
bool m_render3dmousePivot = false; // Render the 3dmouse pivot
SFVEC3F m_3dmousePivotPos; // The position of the 3dmouse pivot
///< Used to track gesture events.
double m_gestureLastZoomFactor = 1.0;
double m_gestureLastAngle = 0.0;
#endif
/**
* Trace mask used to enable or disable the trace output of this class.
@@ -120,6 +120,7 @@ void EDA_3D_CANVAS::render_pivot( float t, float aScale )
}
#if defined( KICAD_USE_3DCONNEXION )
void EDA_3D_CANVAS::render3dmousePivot( float aScale )
{
wxASSERT( aScale >= 0.0f );
@@ -159,3 +160,4 @@ void EDA_3D_CANVAS::render3dmousePivot( float aScale )
glDisable( GL_BLEND );
glDisable( GL_POINT_SMOOTH );
}
#endif
@@ -74,28 +74,4 @@ enum class MATERIAL_MODE
CAD_MODE = 2 ///< Use a gray shading based on diffuse material
};
enum class VIEW3D_TYPE
{
// Specific directions
VIEW3D_TOP,
VIEW3D_BOTTOM,
VIEW3D_LEFT,
VIEW3D_RIGHT,
VIEW3D_FRONT,
VIEW3D_BACK,
VIEW3D_FLIP,
// Movement commands
VIEW3D_PAN_UP,
VIEW3D_PAN_DOWN,
VIEW3D_PAN_LEFT,
VIEW3D_PAN_RIGHT,
VIEW3D_ZOOM_IN,
VIEW3D_ZOOM_OUT,
VIEW3D_PIVOT_CENTER,
// Specific levels
VIEW3D_FIT_SCREEN
};
#endif // _3D_ENUMS_H_
@@ -2,7 +2,7 @@
* This program source code file is part of KiCad, a free EDA CAD application.
*
* Copyright (C) 2015-2016 Mario Luzeiro <mrluzeiro@ua.pt>
* Copyright (C) 1992-2024 KiCad Developers, see AUTHORS.txt for contributors.
* Copyright (C) 1992-2021 KiCad Developers, see AUTHORS.txt for contributors.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
@@ -35,12 +35,10 @@
#include "../3d_cache/3d_cache.h"
#include <wx/dcclient.h>
#include <base_units.h>
#include <build_version.h>
#include <gal/opengl/gl_context_mgr.h>
#include <gl_context_mgr.h>
#include <settings/common_settings.h>
#include <pgm_base.h>
#include <dpi_scaling_common.h>
#include <class_draw_panel_gal.h>
#include <gal/dpi_scaling.h>
#include <macros.h>
/**
@@ -86,10 +84,9 @@ END_EVENT_TABLE()
#define RANGE_SCALE_3D 8.0f
EDA_3D_MODEL_VIEWER::EDA_3D_MODEL_VIEWER( wxWindow* aParent, const wxGLAttributes& aGLAttribs,
EDA_3D_MODEL_VIEWER::EDA_3D_MODEL_VIEWER( wxWindow* aParent, const int* aAttribList,
S3D_CACHE* aCacheManager ) :
HIDPI_GL_CANVAS( EDA_DRAW_PANEL_GAL::GetVcSettings(), aParent, aGLAttribs, wxID_ANY,
wxDefaultPosition, wxDefaultSize,
HIDPI_GL_CANVAS( aParent, wxID_ANY, aAttribList, wxDefaultPosition, wxDefaultSize,
wxFULL_REPAINT_ON_RESIZE ),
m_trackBallCamera( RANGE_SCALE_3D * 4.0f ),
m_cacheManager( aCacheManager )
@@ -103,6 +100,11 @@ EDA_3D_MODEL_VIEWER::EDA_3D_MODEL_VIEWER( wxWindow* aParent, const wxGLAttribute
m_BiuTo3dUnits = 1.0;
m_glRC = nullptr;
COMMON_SETTINGS* settings = Pgm().GetCommonSettings();
const DPI_SCALING dpi{ settings, this };
SetScaleFactor( dpi.GetScaleFactor() );
}
@@ -193,12 +195,9 @@ void EDA_3D_MODEL_VIEWER::ogl_initialize()
else
{
wxLogTrace( m_logTrace, wxT( "EDA_3D_MODEL_VIEWER::ogl_initialize Using GLEW version %s" ),
From_UTF8( (char*) glewGetString( GLEW_VERSION ) ) );
FROM_UTF8( (char*) glewGetString( GLEW_VERSION ) ) );
}
SetOpenGLInfo( (const char*) glGetString( GL_VENDOR ), (const char*) glGetString( GL_RENDERER ),
(const char*) glGetString( GL_VERSION ) );
glHint( GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST );
glHint( GL_LINE_SMOOTH_HINT, GL_NICEST );
glHint( GL_POLYGON_SMOOTH_HINT, GL_NICEST );
@@ -301,7 +300,7 @@ void EDA_3D_MODEL_VIEWER::OnPaint( wxPaintEvent& event )
// clear color and depth buffers
glEnable( GL_DEPTH_TEST );
glClearColor( 0.0f, 0.0f, 0.0f, 0.0f );
glClearColor( 0.0f, 0.0f, 0.0f, 1.0f );
glClearDepth( 1.0f );
glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT );
@@ -401,16 +400,16 @@ void EDA_3D_MODEL_VIEWER::OnMouseWheel( wxMouseEvent& event )
if( event.ShiftDown() )
{
//if( event.GetWheelRotation() < 0 )
//SetView3D( VIEW_3D_TYPE::VIEW3D_PAN_UP ); // move up
//SetView3D( WXK_UP ); // move up
//else
//SetView3D( VIEW_3D_TYPE::VIEW3D_PAN_DOWN ); // move down
//SetView3D( WXK_DOWN ); // move down
}
else if( event.ControlDown() )
{
//if( event.GetWheelRotation() > 0 )
//SetView3D( VIEW_3D_TYPE::VIEW3D_PAN_RIGHT ); // move right
//SetView3D( WXK_RIGHT ); // move right
//else
//SetView3D( VIEW_3D_TYPE::VIEW3D_PAN_LEFT ); // move left
//SetView3D( WXK_LEFT ); // move left
}
else
{
@@ -23,7 +23,7 @@
*/
/**
* @file eda_3d_model_viewer.h
* @file c3d_model_viewer.h
* @brief Implements a model viewer canvas.
*
* The purpose of model viewer is to render 3d models that come in the original data from
@@ -49,9 +49,9 @@ public:
* Create a new 3D Canvas with a attribute list.
*
* @param aParent the parent creator of this canvas.
* @param aGLAttribs openGL attributes created by #OGL_ATT_LIST::GetAttributesList.
* @param aAttribList a list of openGL options created by #OGL_ATT_LIST::GetAttributesList.
*/
EDA_3D_MODEL_VIEWER( wxWindow* aParent, const wxGLAttributes& aGLAttribs,
EDA_3D_MODEL_VIEWER( wxWindow* aParent, const int* aAttribList = nullptr,
S3D_CACHE* aCacheManager = nullptr );
~EDA_3D_MODEL_VIEWER();
+6
View File
@@ -1,3 +1,4 @@
if( KICAD_USE_3DCONNEXION )
add_library(3d-viewer_navlib STATIC
"nl_3d_viewer_plugin.cpp"
"nl_3d_viewer_plugin_impl.cpp"
@@ -22,4 +23,9 @@
$<TARGET_PROPERTY:3DxWare::Navlib,INTERFACE_LINK_LIBRARIES>
3DxWare::Navlib
)
else()
add_library(3d-viewer_navlib STATIC
"nl_3d_viewer_plugin.cpp"
)
endif(KICAD_USE_3DCONNEXION)
+22 -11
View File
@@ -19,19 +19,14 @@
*/
#include "nl_3d_viewer_plugin.h"
#if defined( KICAD_USE_3DCONNEXION )
#include "nl_3d_viewer_plugin_impl.h"
#include <advanced_config.h>
#include <kiplatform/drivers.h>
NL_3D_VIEWER_PLUGIN::NL_3D_VIEWER_PLUGIN( EDA_3D_CANVAS* aViewport )
: m_impl( nullptr )
NL_3D_VIEWER_PLUGIN::NL_3D_VIEWER_PLUGIN( EDA_3D_CANVAS* aViewport ) :
m_impl( new NL_3D_VIEWER_PLUGIN_IMPL( aViewport ) )
{
if( ADVANCED_CFG::GetCfg().m_Use3DConnexionDriver
&& KIPLATFORM::DRIVERS::Valid3DConnexionDriverVersion() )
{
m_impl = new NL_3D_VIEWER_PLUGIN_IMPL( aViewport );
}
}
@@ -43,6 +38,22 @@ NL_3D_VIEWER_PLUGIN::~NL_3D_VIEWER_PLUGIN()
void NL_3D_VIEWER_PLUGIN::SetFocus( bool focus )
{
if( m_impl )
m_impl->SetFocus( focus );
m_impl->SetFocus( focus );
}
#else
NL_3D_VIEWER_PLUGIN::NL_3D_VIEWER_PLUGIN( EDA_3D_CANVAS* aViewport ) : m_impl( nullptr )
{
}
void NL_3D_VIEWER_PLUGIN::SetFocus( bool focus )
{
}
NL_3D_VIEWER_PLUGIN::~NL_3D_VIEWER_PLUGIN()
{
}
#endif
@@ -73,10 +73,7 @@ bool equals( glm::mat<L, C, T, Q> const& aFirst, glm::mat<L, C, T, Q> const& aSe
NL_3D_VIEWER_PLUGIN_IMPL::NL_3D_VIEWER_PLUGIN_IMPL( EDA_3D_CANVAS* aCanvas ) :
NAV_3D( false, false ),
m_canvas( aCanvas ),
m_capIsMoving( false ),
m_newWidth( 0.0 )
NAV_3D( false, false ), m_canvas( aCanvas ), m_capIsMoving( false )
{
m_camera = dynamic_cast<TRACK_BALL*>( m_canvas->GetCamera() );
@@ -176,7 +173,7 @@ void NL_3D_VIEWER_PLUGIN_IMPL::exportCommandsAndImages()
for( it = actions.begin(); it != actions.end(); ++it )
{
const TOOL_ACTION* action = *it;
std::string label = action->GetMenuLabel().ToStdString();
std::string label = action->GetLabel().ToStdString();
if( label.empty() )
{
@@ -591,7 +588,7 @@ long NL_3D_VIEWER_PLUGIN_IMPL::SetActiveCommand( std::string commandId )
if( runAction )
{
tool_manager->RunAction( *context );
tool_manager->RunAction( *context, true );
m_canvas->Request_refresh();
}
}
+1 -39
View File
@@ -2,7 +2,7 @@
* This program source code file is part of KiCad, a free EDA CAD application.
*
* Copyright (C) 2016 Mario Luzeiro <mrluzeiro@ua.pt>
* Copyright (C) 2016-2024 KiCad Developers, see AUTHORS.txt for contributors.
* Copyright (C) 2016-2020 KiCad Developers, see AUTHORS.txt for contributors.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
@@ -46,19 +46,6 @@ static void dbg_save_rgb_buffer( const wxString& aFileName, unsigned char *aRGBp
}
static void dbg_save_rgb_a_buffer( const wxString& aFileName, unsigned char* aRGBpixelBuffer,
unsigned char* aAlphaBuffer, unsigned int aXSize,
unsigned int aYSize )
{
wxImage image( aXSize, aYSize );
image.SetData( aRGBpixelBuffer );
image.SetAlpha( aAlphaBuffer );
image = image.Mirror( false );
image.SaveFile( aFileName + wxT( ".png" ), wxBITMAP_TYPE_PNG );
image.Destroy();
}
void DBG_SaveBuffer( const wxString& aFileName, const unsigned char *aInBuffer,
unsigned int aXSize, unsigned int aYSize )
{
@@ -123,31 +110,6 @@ void DBG_SaveBuffer( const wxString& aFileName, const SFVEC3F *aInBuffer,
}
void DBG_SaveBuffer( const wxString& aFileName, const SFVEC4F *aInBuffer,
unsigned int aXSize, unsigned int aYSize )
{
const unsigned int wxh = aXSize * aYSize;
unsigned char *pixelbuffer = (unsigned char*) malloc( wxh * 4 );
unsigned char *alphabuffer = (unsigned char*) malloc( wxh );
for( unsigned int i = 0; i < wxh; ++i )
{
const SFVEC4F &v = aInBuffer[i];
const unsigned int ix3 = i * 3;
// Set RGB value with all same values intensities
pixelbuffer[ix3 + 0] = (unsigned char) glm::min( (int) ( v.r * 255.0f ), 255 );
pixelbuffer[ix3 + 1] = (unsigned char) glm::min( (int) ( v.g * 255.0f ), 255 );
pixelbuffer[ix3 + 2] = (unsigned char) glm::min( (int) ( v.b * 255.0f ), 255 );
alphabuffer[i] = (unsigned char) glm::min( (int) ( v.a * 255.0f ), 255 );
}
dbg_save_rgb_a_buffer( aFileName, pixelbuffer, alphabuffer, aXSize, aYSize );
}
void DBG_SaveNormalsBuffer( const wxString& aFileName, const SFVEC3F *aInNormalsBuffer,
unsigned int aXSize, unsigned int aYSize )
{
+1 -4
View File
@@ -2,7 +2,7 @@
* This program source code file is part of KiCad, a free EDA CAD application.
*
* Copyright (C) 2016 Mario Luzeiro <mrluzeiro@ua.pt>
* Copyright (C) 2016-2024 KiCad Developers, see AUTHORS.txt for contributors.
* Copyright (C) 2016-2020 KiCad Developers, see AUTHORS.txt for contributors.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
@@ -42,9 +42,6 @@ void DBG_SaveBuffer( const wxString& aFileName, const float *aInBuffer,
void DBG_SaveBuffer( const wxString& aFileName, const SFVEC3F *aInBuffer,
unsigned int aXSize, unsigned int aYSize );
void DBG_SaveBuffer( const wxString& aFileName, const SFVEC4F *aInBuffer,
unsigned int aXSize, unsigned int aYSize );
void DBG_SaveNormalsBuffer( const wxString& aFileName, const SFVEC3F *aInNormalsBuffer,
unsigned int aXSize, unsigned int aYSize );
@@ -2,7 +2,7 @@
* This program source code file is part of KiCad, a free EDA CAD application.
*
* Copyright (C) 2015-2016 Mario Luzeiro <mrluzeiro@ua.pt>
* Copyright (C) 2015-2024 KiCad Developers, see AUTHORS.txt for contributors.
* Copyright (C) 2015-2020 KiCad Developers, see AUTHORS.txt for contributors.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
@@ -26,10 +26,9 @@
* @file camera.cpp
*/
#include <gal/3d/camera.h>
#include "camera.h"
#include <wx/log.h>
#include <algorithm>
#include <3d_enums.h>
// A helper function to normalize aAngle between -2PI and +2PI
inline void normalise2PI( float& aAngle )
@@ -51,22 +50,15 @@ const float CAMERA::DEFAULT_MIN_ZOOM = 0.020f;
const float CAMERA::DEFAULT_MAX_ZOOM = 2.0f;
CAMERA::CAMERA( float aInitialDistance ) :
CAMERA( SFVEC3F( 0.0f, 0.0f, -aInitialDistance ), SFVEC3F( 0.0f ),
PROJECTION_TYPE::PERSPECTIVE )
{
}
CAMERA::CAMERA( SFVEC3F aInitPos, SFVEC3F aLookat, PROJECTION_TYPE aProjectionType )
CAMERA::CAMERA( float aInitialDistance )
{
wxLogTrace( m_logTrace, wxT( "CAMERA::CAMERA" ) );
m_camera_pos_init = aInitPos;
m_board_lookat_pos_init = aLookat;
m_windowSize = SFVEC2I( 0, 0 );
m_projectionType = aProjectionType;
m_interpolation_mode = CAMERA_INTERPOLATION::BEZIER;
m_camera_pos_init = SFVEC3F( 0.0f, 0.0f, -aInitialDistance );
m_board_lookat_pos_init = SFVEC3F( 0.0f );
m_windowSize = SFVEC2I( 0, 0 );
m_projectionType = PROJECTION_TYPE::PERSPECTIVE;
m_interpolation_mode = CAMERA_INTERPOLATION::BEZIER;
m_minZoom = DEFAULT_MIN_ZOOM;
m_maxZoom = DEFAULT_MAX_ZOOM;
@@ -107,57 +99,6 @@ void CAMERA::Reset()
}
bool CAMERA::ViewCommand_T1( VIEW3D_TYPE aRequestedView )
{
switch( aRequestedView )
{
case VIEW3D_TYPE::VIEW3D_RIGHT:
SetT0_and_T1_current_T();
Reset_T1();
RotateZ_T1( glm::radians( -90.0f ) );
RotateX_T1( glm::radians( -90.0f ) );
return true;
case VIEW3D_TYPE::VIEW3D_LEFT:
Reset_T1();
RotateZ_T1( glm::radians( 90.0f ) );
RotateX_T1( glm::radians( -90.0f ) );
return true;
case VIEW3D_TYPE::VIEW3D_FRONT:
Reset_T1();
RotateX_T1( glm::radians( -90.0f ) );
return true;
case VIEW3D_TYPE::VIEW3D_BACK:
Reset_T1();
RotateX_T1( glm::radians( -90.0f ) );
// The rotation angle should be 180.
// We use 179.999 (180 - epsilon) to avoid a full 360 deg rotation when
// using 180 deg if the previous rotated position was already 180 deg
RotateZ_T1( glm::radians( 179.999f ) );
return true;
case VIEW3D_TYPE::VIEW3D_TOP:
Reset_T1();
return true;
case VIEW3D_TYPE::VIEW3D_BOTTOM:
Reset_T1();
RotateY_T1( glm::radians( 179.999f ) ); // Rotation = 180 - epsilon
return true;
case VIEW3D_TYPE::VIEW3D_FLIP:
RotateY_T1( glm::radians( 179.999f ) );
return true;
default:
return false;
}
}
void CAMERA::Reset_T1()
{
m_camera_pos_t1 = m_camera_pos_init;
@@ -647,14 +588,6 @@ bool CAMERA::Zoom_T1( float aFactor )
}
void CAMERA::RotateScreen( float aAngleInRadians )
{
glm::mat4 matrix = GetRotationMatrix();
SetRotationMatrix( glm::rotate( matrix, aAngleInRadians, GetDir() ) );
updateRotationMatrix();
}
void CAMERA::RotateX( float aAngleInRadians )
{
m_rotate_aux.x += aAngleInRadians;
@@ -2,7 +2,7 @@
* This program source code file is part of KiCad, a free EDA CAD application.
*
* Copyright (C) 2015-2016 Mario Luzeiro <mrluzeiro@ua.pt>
* Copyright (C) 2015-2024 KiCad Developers, see AUTHORS.txt for contributors.
* Copyright (C) 2015-2020 KiCad Developers, see AUTHORS.txt for contributors.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
@@ -30,11 +30,9 @@
#ifndef CAMERA_H
#define CAMERA_H
#include <gal/gal.h>
#include <plugins/3dapi/xv3d_types.h>
#include "../3d_rendering/raytracing/ray.h"
#include <wx/gdicmn.h> // for wxSize
#include <vector>
#include <3d_enums.h>
enum class PROJECTION_TYPE
{
@@ -60,29 +58,6 @@ struct CAMERA_FRUSTUM
SFVEC3F fbr; ///< Far Bottom Right
float nearD, farD, ratio, angle, tang;
float nw, nh, fw, fh;
CAMERA_FRUSTUM() :
nc( { 0.0, 0.0, 0.0 } ),
fc( { 0.0, 0.0, 0.0 } ),
ntl( { 0.0, 0.0, 0.0 } ),
ntr( { 0.0, 0.0, 0.0 } ),
nbl( { 0.0, 0.0, 0.0 } ),
nbr( { 0.0, 0.0, 0.0 } ),
ftl( { 0.0, 0.0, 0.0 } ),
ftr( { 0.0, 0.0, 0.0 } ),
fbl( { 0.0, 0.0, 0.0 } ),
fbr( { 0.0, 0.0, 0.0 } ),
nearD( 0.0 ),
farD( 0.0 ),
ratio( 1.0 ),
angle( 0.0 ),
tang( 0.0 ),
nw( 0.0 ),
nh( 0.0 ),
fw( 0.0 ),
fh( 0.0 )
{
}
};
@@ -99,7 +74,7 @@ enum class CAMERA_INTERPOLATION
*
* It must be derived by other classes to implement a real camera object.
*/
class GAL_API CAMERA
class CAMERA
{
public:
static const float DEFAULT_MIN_ZOOM;
@@ -111,7 +86,6 @@ public:
* @param aInitialDistance Initial Z-distance to the board
*/
explicit CAMERA( float aInitialDistance );
explicit CAMERA( SFVEC3F aInitPos, SFVEC3F aLookat, PROJECTION_TYPE aProjectionType );
virtual ~CAMERA()
{
@@ -234,13 +208,6 @@ public:
zoomChanged();
}
bool ViewCommand_T1( VIEW3D_TYPE aRequestedView );
/**
* Rotates the camera in screen plane.
*/
void RotateScreen( float aAngleInRadians );
void RotateX( float aAngleInRadians );
void RotateY( float aAngleInRadians );
void RotateZ( float aAngleInRadians );
+69
View File
@@ -0,0 +1,69 @@
/*
* This program source code file is part of KiCad, a free EDA CAD application.
*
* Copyright (C) 2015-2016 Mario Luzeiro <mrluzeiro@ua.pt>
* Copyright (C) 2015-2020 KiCad Developers, see AUTHORS.txt for contributors.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, you may find one here:
* http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
* or you may search the http://www.gnu.org website for the version 2 license,
* or you may write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
*/
/**
* @file color_rgb.cpp
*/
#include "color_rgb.h"
COLOR_RGB::COLOR_RGB( const SFVEC3F& aColor )
{
r = (unsigned int) glm::clamp( (int) ( aColor.r * 255 ), 0, 255 );
g = (unsigned int) glm::clamp( (int) ( aColor.g * 255 ), 0, 255 );
b = (unsigned int) glm::clamp( (int) ( aColor.b * 255 ), 0, 255 );
}
COLOR_RGB BlendColor( const COLOR_RGB& aC1, const COLOR_RGB& aC2 )
{
const unsigned int r = aC1.r + aC2.r;
const unsigned int g = aC1.g + aC2.g;
const unsigned int b = aC1.b + aC2.b;
return COLOR_RGB( ( r >> 1 ), ( g >> 1 ), ( b >> 1 ) );
}
COLOR_RGB BlendColor( const COLOR_RGB& aC1, const COLOR_RGB& aC2, const COLOR_RGB& aC3 )
{
const unsigned int r = aC1.r + aC2.r + aC3.r;
const unsigned int g = aC1.g + aC2.g + aC3.g;
const unsigned int b = aC1.b + aC2.b + aC3.b;
return COLOR_RGB( ( r / 3 ), ( g / 3 ), ( b / 3 ) );
}
COLOR_RGB BlendColor( const COLOR_RGB& aC1, const COLOR_RGB& aC2, const COLOR_RGB& aC3,
const COLOR_RGB& aC4 )
{
const unsigned int r = aC1.r + aC2.r + aC3.r + aC4.r;
const unsigned int g = aC1.g + aC2.g + aC3.g + aC4.g;
const unsigned int b = aC1.b + aC2.b + aC3.b + aC4.b;
return COLOR_RGB( ( r >> 2 ), ( g >> 2 ), ( b >> 2 ) );
}
+61
View File
@@ -0,0 +1,61 @@
/*
* This program source code file is part of KiCad, a free EDA CAD application.
*
* Copyright (C) 2015-2016 Mario Luzeiro <mrluzeiro@ua.pt>
* Copyright (C) 2015-2020 KiCad Developers, see AUTHORS.txt for contributors.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, you may find one here:
* http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
* or you may search the http://www.gnu.org website for the version 2 license,
* or you may write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
*/
/**
* @file color_rgb.h
*/
#ifndef COLOR_RGB_H
#define COLOR_RGB_H
#include <plugins/3dapi/xv3d_types.h>
union COLOR_RGB
{
unsigned char c[3];
struct
{
unsigned char r;
unsigned char g;
unsigned char b;
};
COLOR_RGB( const SFVEC3F& aColor );
COLOR_RGB() { r = 0; g = 0; b = 0; }
COLOR_RGB( unsigned char aR, unsigned char aG, unsigned char aB )
{
r = aR;
g = aG;
b = aB;
}
};
COLOR_RGB BlendColor( const COLOR_RGB& aC1, const COLOR_RGB& aC2 );
COLOR_RGB BlendColor( const COLOR_RGB& aC1, const COLOR_RGB& aC2, const COLOR_RGB& aC3 );
COLOR_RGB BlendColor( const COLOR_RGB& aC1, const COLOR_RGB& aC2, const COLOR_RGB& aC3,
const COLOR_RGB& aC4 );
#endif // COLOR_RGB_H
-82
View File
@@ -1,82 +0,0 @@
/*
* This program source code file is part of KiCad, a free EDA CAD application.
*
* Copyright (C) 2015-2016 Mario Luzeiro <mrluzeiro@ua.pt>
* Copyright (C) 2015-2024 KiCad Developers, see AUTHORS.txt for contributors.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, you may find one here:
* http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
* or you may search the http://www.gnu.org website for the version 2 license,
* or you may write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
*/
/**
* @file color_rgba.cpp
*/
#include "color_rgba.h"
COLOR_RGBA::COLOR_RGBA( const SFVEC3F& aColor )
{
r = (unsigned int) glm::clamp( (int) ( aColor.r * 255 ), 0, 255 );
g = (unsigned int) glm::clamp( (int) ( aColor.g * 255 ), 0, 255 );
b = (unsigned int) glm::clamp( (int) ( aColor.b * 255 ), 0, 255 );
a = 255;
}
COLOR_RGBA::COLOR_RGBA( const SFVEC4F& aColor )
{
r = (unsigned int) glm::clamp( (int) ( aColor.r * 255 ), 0, 255 );
g = (unsigned int) glm::clamp( (int) ( aColor.g * 255 ), 0, 255 );
b = (unsigned int) glm::clamp( (int) ( aColor.b * 255 ), 0, 255 );
a = (unsigned int) glm::clamp( (int) ( aColor.a * 255 ), 0, 255 );
}
COLOR_RGBA BlendColor( const COLOR_RGBA& aC1, const COLOR_RGBA& aC2 )
{
const unsigned int r = aC1.r + aC2.r;
const unsigned int g = aC1.g + aC2.g;
const unsigned int b = aC1.b + aC2.b;
const unsigned int a = aC1.a + aC2.a;
return COLOR_RGBA( ( r >> 1 ), ( g >> 1 ), ( b >> 1 ), ( a >> 1 ) );
}
COLOR_RGBA BlendColor( const COLOR_RGBA& aC1, const COLOR_RGBA& aC2, const COLOR_RGBA& aC3 )
{
const unsigned int r = aC1.r + aC2.r + aC3.r;
const unsigned int g = aC1.g + aC2.g + aC3.g;
const unsigned int b = aC1.b + aC2.b + aC3.b;
const unsigned int a = aC1.a + aC2.a + aC3.a;
return COLOR_RGBA( ( r / 3 ), ( g / 3 ), ( b / 3 ), ( a / 3 ) );
}
COLOR_RGBA BlendColor( const COLOR_RGBA& aC1, const COLOR_RGBA& aC2, const COLOR_RGBA& aC3,
const COLOR_RGBA& aC4 )
{
const unsigned int r = aC1.r + aC2.r + aC3.r + aC4.r;
const unsigned int g = aC1.g + aC2.g + aC3.g + aC4.g;
const unsigned int b = aC1.b + aC2.b + aC3.b + aC4.b;
const unsigned int a = aC1.a + aC2.a + aC3.a + aC4.a;
return COLOR_RGBA( ( r >> 2 ), ( g >> 2 ), ( b >> 2 ), ( a >> 2 ) );
}
-71
View File
@@ -1,71 +0,0 @@
/*
* This program source code file is part of KiCad, a free EDA CAD application.
*
* Copyright (C) 2015-2016 Mario Luzeiro <mrluzeiro@ua.pt>
* Copyright (C) 2015-2024 KiCad Developers, see AUTHORS.txt for contributors.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, you may find one here:
* http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
* or you may search the http://www.gnu.org website for the version 2 license,
* or you may write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
*/
/**
* @file color_rgba.h
*/
#ifndef COLOR_RGBA_H
#define COLOR_RGBA_H
#include <plugins/3dapi/xv3d_types.h>
union COLOR_RGBA
{
unsigned char c[4];
struct
{
unsigned char r;
unsigned char g;
unsigned char b;
unsigned char a;
};
COLOR_RGBA( const SFVEC3F& aColor );
COLOR_RGBA( const SFVEC4F& aColor );
COLOR_RGBA() { r = 0; g = 0; b = 0; a = 0; }
COLOR_RGBA( unsigned char aR, unsigned char aG, unsigned char aB )
{
r = aR;
g = aG;
b = aB;
}
COLOR_RGBA( unsigned char aR, unsigned char aG, unsigned char aB, unsigned char aA )
{
r = aR;
g = aG;
b = aB;
a = aA;
}
};
COLOR_RGBA BlendColor( const COLOR_RGBA& aC1, const COLOR_RGBA& aC2 );
COLOR_RGBA BlendColor( const COLOR_RGBA& aC1, const COLOR_RGBA& aC2, const COLOR_RGBA& aC3 );
COLOR_RGBA BlendColor( const COLOR_RGBA& aC1, const COLOR_RGBA& aC2, const COLOR_RGBA& aC3,
const COLOR_RGBA& aC4 );
#endif // COLOR_RGBA_H
+21 -18
View File
@@ -24,7 +24,8 @@
*/
/**
* @file 3d_model.cpp
* @file c_ogl_3dmodel.cpp
* @brief
*/
#include <algorithm>
#include <stdexcept>
@@ -447,7 +448,7 @@ void MODEL_3D::Draw( bool aTransparent, float aOpacity, bool aUseSelectedMateria
glTexEnvfv( GL_TEXTURE_ENV, GL_TEXTURE_ENV_COLOR, (const float*)&param.x );
std::vector<const MODEL_3D::MATERIAL *> materialsToRender;
materialsToRender.reserve( m_materials.size() );
if( aModelWorldMatrix && aCameraWorldPos )
@@ -482,21 +483,23 @@ void MODEL_3D::Draw( bool aTransparent, float aOpacity, bool aUseSelectedMateria
// Sort from back to front
std::sort( materialsSorted.begin(), materialsSorted.end(),
[&]( std::pair<const MODEL_3D::MATERIAL*, float>& a,
std::pair<const MODEL_3D::MATERIAL*, float>& b )
{
bool aInsideB = a.first->m_bbox.Inside( b.first->m_bbox );
bool bInsideA = b.first->m_bbox.Inside( a.first->m_bbox );
[&]( std::pair<const MODEL_3D::MATERIAL*, float>& a,
std::pair<const MODEL_3D::MATERIAL*, float>& b ) {
// If A is inside B, then A is rendered first
if( aInsideB != bInsideA )
return bInsideA;
if( b.first->m_bbox.Inside( a.first->m_bbox ) )
{
return true;
}
else
{
if( a.first->m_bbox.Inside( b.first->m_bbox ) )
{
return false;
}
}
if( a.second != b.second )
return a.second > b.second;
return a.first > b.first; // compare pointers as a last resort
} );
return a.second > b.second;
} );
for( const std::pair<const MODEL_3D::MATERIAL*, float>& mat : materialsSorted )
{
@@ -521,10 +524,10 @@ void MODEL_3D::Draw( bool aTransparent, float aOpacity, bool aUseSelectedMateria
{
continue;
}
materialsToRender.push_back( &mat );
}
}
}
for( const MODEL_3D::MATERIAL* mat : materialsToRender )
{
@@ -603,7 +606,7 @@ void MODEL_3D::DrawBboxes() const
: sizeof( GLuint );
glDrawElements( GL_LINES, bbox_idx_count * m_meshes_bbox.size(), m_bbox_index_buffer_type,
reinterpret_cast<const void*>(
reinterpret_cast<const void*>(
static_cast<uintptr_t>( bbox_idx_count * idx_size ) ) );
}
+2 -2
View File
@@ -3,7 +3,7 @@
*
* Copyright (C) 2020 Oleg Endo <olegendo@gcc.gnu.org>
* Copyright (C) 2015-2016 Mario Luzeiro <mrluzeiro@ua.pt>
* Copyright (C) 2015-2024 KiCad Developers, see AUTHORS.txt for contributors.
* Copyright (C) 2015-2020 KiCad Developers, see AUTHORS.txt for contributors.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
@@ -30,7 +30,7 @@
#include <plugins/3dapi/c3dmodel.h>
#include "../../common_ogl/openGL_includes.h"
#include "../raytracing/shapes3D/bbox_3d.h"
#include <3d_enums.h>
#include "../../3d_enums.h"
#include <wx/chartype.h>
+126 -137
View File
@@ -2,8 +2,7 @@
* This program source code file is part of KiCad, a free EDA CAD application.
*
* Copyright (C) 2015-2016 Mario Luzeiro <mrluzeiro@ua.pt>
* Copyright (C) 2023 CERN
* Copyright (C) 2015-2023 KiCad Developers, see AUTHORS.txt for contributors.
* Copyright (C) 2015-2022 KiCad Developers, see AUTHORS.txt for contributors.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
@@ -24,24 +23,24 @@
*/
#include "render_3d_opengl.h"
#include "opengl_utils.h"
#include <board.h>
#include <footprint.h>
#include "../../3d_math.h"
#include "convert_basic_shapes_to_polygon.h"
#include <trigo.h>
#include <project.h>
#include <core/profile.h> // To use GetRunningMicroSecs or another profiling utility
#include <profile.h> // To use GetRunningMicroSecs or another profiling utility
#include <fp_lib_table.h>
#include <eda_3d_canvas.h>
#include <eda_3d_viewer_frame.h>
#include <project_pcb.h>
void RENDER_3D_OPENGL::addObjectTriangles( const FILLED_CIRCLE_2D* aCircle,
void RENDER_3D_OPENGL::addObjectTriangles( const FILLED_CIRCLE_2D* aFilledCircle,
TRIANGLE_DISPLAY_LIST* aDstLayer, float aZtop,
float aZbot )
{
const SFVEC2F& center = aCircle->GetCenter();
const float radius = aCircle->GetRadius() * 2.0f; // Double because the render triangle
const SFVEC2F& center = aFilledCircle->GetCenter();
const float radius = aFilledCircle->GetRadius() * 2.0f; // Double because the render triangle
// This is a small adjustment to the circle texture
const float texture_factor = ( 8.0f / (float) SIZE_OF_CIRCLE_TEXTURE ) + 1.0f;
@@ -303,7 +302,7 @@ OPENGL_RENDER_LIST* RENDER_3D_OPENGL::generateHoles( const LIST_OBJECT2D& aListH
OPENGL_RENDER_LIST* RENDER_3D_OPENGL::generateLayerList( const BVH_CONTAINER_2D* aContainer,
const SHAPE_POLY_SET* aPolyList,
PCB_LAYER_ID aLayer,
PCB_LAYER_ID aLayerId,
const BVH_CONTAINER_2D* aThroughHoles )
{
if( aContainer == nullptr )
@@ -317,7 +316,7 @@ OPENGL_RENDER_LIST* RENDER_3D_OPENGL::generateLayerList( const BVH_CONTAINER_2D*
float layer_z_bot = 0.0f;
float layer_z_top = 0.0f;
getLayerZPos( aLayer, layer_z_top, layer_z_bot );
getLayerZPos( aLayerId, layer_z_top, layer_z_bot );
// Calculate an estimation for the nr of triangles based on the nr of objects
unsigned int nrTrianglesEstimation = listObject2d.size() * 8;
@@ -376,12 +375,12 @@ OPENGL_RENDER_LIST* RENDER_3D_OPENGL::generateLayerList( const BVH_CONTAINER_2D*
}
OPENGL_RENDER_LIST* RENDER_3D_OPENGL::generateEmptyLayerList( PCB_LAYER_ID aLayer )
OPENGL_RENDER_LIST* RENDER_3D_OPENGL::generateEmptyLayerList( PCB_LAYER_ID aLayerId )
{
float layer_z_bot = 0.0f;
float layer_z_top = 0.0f;
getLayerZPos( aLayer, layer_z_top, layer_z_bot );
getLayerZPos( aLayerId, layer_z_top, layer_z_bot );
TRIANGLE_DISPLAY_LIST* layerTriangles = new TRIANGLE_DISPLAY_LIST( 1 );
@@ -454,7 +453,7 @@ void RENDER_3D_OPENGL::reload( REPORTER* aStatusReporter, REPORTER* aWarningRepo
OBJECT_2D_STATS::Instance().ResetStats();
int64_t stats_startReloadTime = GetRunningMicroSecs();
unsigned stats_startReloadTime = GetRunningMicroSecs();
m_boardAdapter.InitSettings( aStatusReporter, aWarningReporter );
@@ -465,23 +464,28 @@ void RENDER_3D_OPENGL::reload( REPORTER* aStatusReporter, REPORTER* aWarningRepo
aStatusReporter->Report( _( "Load OpenGL: board" ) );
// Create Board
m_board = createBoard( m_boardAdapter.GetBoardPoly(), &m_boardAdapter.GetTH_IDs() );
m_board = createBoard( m_boardAdapter.GetBoardPoly(), &m_boardAdapter.GetThroughHoleIds() );
m_antiBoardPolys.RemoveAllContours();
m_antiBoardPolys.NewOutline();
m_antiBoardPolys.Append( VECTOR2I( -INT_MAX/2, -INT_MAX/2 ) );
m_antiBoardPolys.Append( VECTOR2I( INT_MAX/2, -INT_MAX/2 ) );
m_antiBoardPolys.Append( VECTOR2I( INT_MAX/2, INT_MAX/2 ) );
m_antiBoardPolys.Append( VECTOR2I( -INT_MAX/2, INT_MAX/2 ) );
m_antiBoardPolys.Outline( 0 ).SetClosed( true );
if( m_boardAdapter.m_Cfg->m_Render.realistic )
{
m_antiBoardPolys.RemoveAllContours();
m_antiBoardPolys.NewOutline();
m_antiBoardPolys.Append( VECTOR2I( -INT_MAX/2, -INT_MAX/2 ) );
m_antiBoardPolys.Append( VECTOR2I( INT_MAX/2, -INT_MAX/2 ) );
m_antiBoardPolys.Append( VECTOR2I( INT_MAX/2, INT_MAX/2 ) );
m_antiBoardPolys.Append( VECTOR2I( -INT_MAX/2, INT_MAX/2 ) );
m_antiBoardPolys.Outline( 0 ).SetClosed( true );
m_antiBoardPolys.BooleanSubtract( m_boardAdapter.GetBoardPoly(),
SHAPE_POLY_SET::PM_STRICTLY_SIMPLE );
m_antiBoard = createBoard( m_antiBoardPolys );
m_antiBoardPolys.BooleanSubtract( m_boardAdapter.GetBoardPoly(),
SHAPE_POLY_SET::PM_STRICTLY_SIMPLE );
m_antiBoard = createBoard( m_antiBoardPolys );
}
SHAPE_POLY_SET board_poly_with_holes = m_boardAdapter.GetBoardPoly().CloneDropTriangulation();
board_poly_with_holes.BooleanSubtract( m_boardAdapter.GetTH_ODPolys(), SHAPE_POLY_SET::PM_FAST );
board_poly_with_holes.BooleanSubtract( m_boardAdapter.GetNPTH_ODPolys(), SHAPE_POLY_SET::PM_FAST );
board_poly_with_holes.BooleanSubtract( m_boardAdapter.GetThroughHoleOdPolys(),
SHAPE_POLY_SET::PM_FAST );
board_poly_with_holes.BooleanSubtract( m_boardAdapter.GetOuterNonPlatedThroughHolePoly(),
SHAPE_POLY_SET::PM_FAST );
m_boardWithHoles = createBoard( board_poly_with_holes );
@@ -492,22 +496,28 @@ void RENDER_3D_OPENGL::reload( REPORTER* aStatusReporter, REPORTER* aWarningRepo
if( aStatusReporter )
aStatusReporter->Report( _( "Load OpenGL: holes and vias" ) );
SHAPE_POLY_SET outerPolyTHT = m_boardAdapter.GetTH_ODPolys().CloneDropTriangulation();
SHAPE_POLY_SET outerPolyTHT = m_boardAdapter.GetThroughHoleOdPolys().CloneDropTriangulation();
outerPolyTHT.BooleanIntersection( m_boardAdapter.GetBoardPoly(),
SHAPE_POLY_SET::PM_STRICTLY_SIMPLE );
m_outerThroughHoles = generateHoles( m_boardAdapter.GetTH_ODs().GetList(), outerPolyTHT,
1.0f, 0.0f, false, &m_boardAdapter.GetTH_IDs() );
m_outerViaThroughHoles = generateHoles( m_boardAdapter.GetViaTH_ODs().GetList(),
m_boardAdapter.GetViaTH_ODPolys(), 1.0f, 0.0f, false );
if( m_boardAdapter.m_Cfg->m_Render.clip_silk_on_via_annuli )
if( m_boardAdapter.m_Cfg->m_Render.realistic )
{
m_outerThroughHoleRings = generateHoles( m_boardAdapter.GetViaAnnuli().GetList(),
m_boardAdapter.GetViaAnnuliPolys(),
1.0f, 0.0f, false );
outerPolyTHT.BooleanIntersection( m_boardAdapter.GetBoardPoly(),
SHAPE_POLY_SET::PM_STRICTLY_SIMPLE );
}
m_outerThroughHoles = generateHoles( m_boardAdapter.GetThroughHoleOds().GetList(),
outerPolyTHT, 1.0f, 0.0f, false,
&m_boardAdapter.GetThroughHoleIds() );
m_outerViaThroughHoles = generateHoles(
m_boardAdapter.GetThroughHoleViaOds().GetList(),
m_boardAdapter.GetThroughHoleViaOdPolys(), 1.0f, 0.0f, false );
if( m_boardAdapter.m_Cfg->m_Render.clip_silk_on_via_annulus &&
m_boardAdapter.m_Cfg->m_Render.realistic )
{
m_outerThroughHoleRings = generateHoles(
m_boardAdapter.GetThroughHoleAnnularRings().GetList(),
m_boardAdapter.GetThroughHoleAnnularRingPolys(), 1.0f, 0.0f, false );
}
const MAP_POLY& innerMapHoles = m_boardAdapter.GetHoleIdPolysMap();
@@ -522,20 +532,28 @@ void RENDER_3D_OPENGL::reload( REPORTER* aStatusReporter, REPORTER* aWarningRepo
float layer_z_bot = 0.0f;
float layer_z_top = 0.0f;
for( const auto& [ layer, poly ] : outerMapHoles )
for( const std::pair<const PCB_LAYER_ID, SHAPE_POLY_SET*>& ii : outerMapHoles )
{
getLayerZPos( layer, layer_z_top, layer_z_bot );
const PCB_LAYER_ID layer_id = ii.first;
const SHAPE_POLY_SET* poly = ii.second;
const BVH_CONTAINER_2D* container = map_holes.at( layer_id );
m_outerLayerHoles[layer] = generateHoles( map_holes.at( layer )->GetList(), *poly,
layer_z_top, layer_z_bot, false );
getLayerZPos( layer_id, layer_z_top, layer_z_bot );
m_outerLayerHoles[layer_id] = generateHoles( container->GetList(), *poly,
layer_z_top, layer_z_bot, false );
}
for( const auto& [ layer, poly ] : innerMapHoles )
for( const std::pair<const PCB_LAYER_ID, SHAPE_POLY_SET*>& ii : innerMapHoles )
{
getLayerZPos( layer, layer_z_top, layer_z_bot );
const PCB_LAYER_ID layer_id = ii.first;
const SHAPE_POLY_SET* poly = ii.second;
const BVH_CONTAINER_2D* container = map_holes.at( layer_id );
m_innerLayerHoles[layer] = generateHoles( map_holes.at( layer )->GetList(), *poly,
layer_z_top, layer_z_bot, false );
getLayerZPos( layer_id, layer_z_top, layer_z_bot );
m_innerLayerHoles[layer_id] = generateHoles( container->GetList(), *poly,
layer_z_top, layer_z_bot, false );
}
}
@@ -546,98 +564,107 @@ void RENDER_3D_OPENGL::reload( REPORTER* aStatusReporter, REPORTER* aWarningRepo
if( aStatusReporter )
aStatusReporter->Report( _( "Load OpenGL: layers" ) );
std::bitset<LAYER_3D_END> visibilityFlags = m_boardAdapter.GetVisibleLayers();
const MAP_POLY& map_poly = m_boardAdapter.GetPolyMap();
wxString msg;
const MAP_POLY& map_poly = m_boardAdapter.GetPolyMap();
for( const auto& [ layer, container2d ] : m_boardAdapter.GetLayerMap() )
for( const std::pair<const PCB_LAYER_ID, BVH_CONTAINER_2D*>& ii : m_boardAdapter.GetLayerMap() )
{
if( !m_boardAdapter.Is3dLayerEnabled( layer, visibilityFlags ) )
const PCB_LAYER_ID layer_id = ii.first;
if( !m_boardAdapter.Is3dLayerEnabled( layer_id ) )
continue;
if( aStatusReporter )
{
msg = m_boardAdapter.GetBoard()->GetLayerName( layer );
aStatusReporter->Report( wxString::Format( _( "Load OpenGL layer %s" ), msg ) );
aStatusReporter->Report( wxString::Format( _( "Load OpenGL layer %d" ),
(int) layer_id ) );
}
const BVH_CONTAINER_2D* container2d = ii.second;
SHAPE_POLY_SET polyListSubtracted;
SHAPE_POLY_SET* polyList = nullptr;
// Load the vertical (Z axis) component of shapes
if( m_boardAdapter.m_Cfg->m_Render.opengl_copper_thickness )
if( map_poly.find( layer_id ) != map_poly.end() )
{
if( map_poly.find( layer ) != map_poly.end() )
polyListSubtracted = *map_poly.at( layer_id );;
if( m_boardAdapter.m_Cfg->m_Render.realistic )
{
polyListSubtracted = *map_poly.at( layer );
if( LSET::PhysicalLayersMask().test( layer ) )
{
polyListSubtracted.BooleanIntersection( m_boardAdapter.GetBoardPoly(),
SHAPE_POLY_SET::PM_FAST );
}
if( layer != B_Mask && layer != F_Mask )
{
polyListSubtracted.BooleanSubtract( m_boardAdapter.GetTH_ODPolys(),
polyListSubtracted.BooleanIntersection( m_boardAdapter.GetBoardPoly(),
SHAPE_POLY_SET::PM_FAST );
polyListSubtracted.BooleanSubtract( m_boardAdapter.GetNPTH_ODPolys(),
if( layer_id != B_Mask && layer_id != F_Mask )
{
polyListSubtracted.BooleanSubtract( m_boardAdapter.GetThroughHoleOdPolys(),
SHAPE_POLY_SET::PM_FAST );
polyListSubtracted.BooleanSubtract( m_boardAdapter.GetOuterNonPlatedThroughHolePoly(),
SHAPE_POLY_SET::PM_FAST );
}
if( m_boardAdapter.m_Cfg->m_Render.subtract_mask_from_silk )
{
if( layer == B_SilkS && map_poly.find( B_Mask ) != map_poly.end() )
if( layer_id == B_SilkS && map_poly.find( B_Mask ) != map_poly.end() )
{
polyListSubtracted.BooleanSubtract( *map_poly.at( B_Mask ),
SHAPE_POLY_SET::PM_FAST );
}
else if( layer == F_SilkS && map_poly.find( F_Mask ) != map_poly.end() )
else if( layer_id == F_SilkS && map_poly.find( F_Mask ) != map_poly.end() )
{
polyListSubtracted.BooleanSubtract( *map_poly.at( F_Mask ),
SHAPE_POLY_SET::PM_FAST );
}
}
polyList = &polyListSubtracted;
}
polyList = &polyListSubtracted;
}
OPENGL_RENDER_LIST* oglList = generateLayerList( container2d, polyList, layer,
&m_boardAdapter.GetTH_IDs() );
OPENGL_RENDER_LIST* oglList = generateLayerList( container2d, polyList, layer_id,
&m_boardAdapter.GetThroughHoleIds() );
if( oglList != nullptr )
m_layers[layer] = oglList;
m_layers[layer_id] = oglList;
}
if( m_boardAdapter.m_Cfg->m_Render.differentiate_plated_copper )
if( m_boardAdapter.m_Cfg->m_Render.renderPlatedPadsAsPlated
&& m_boardAdapter.m_Cfg->m_Render.realistic )
{
const SHAPE_POLY_SET* frontPlatedPadAndGraphicPolys = m_boardAdapter.GetFrontPlatedPadAndGraphicPolys();
const SHAPE_POLY_SET* backPlatedPadAndGraphicPolys = m_boardAdapter.GetBackPlatedPadAndGraphicPolys();
const SHAPE_POLY_SET* frontPlatedPadPolys = m_boardAdapter.GetFrontPlatedPadPolys();
const SHAPE_POLY_SET* backPlatedPadPolys = m_boardAdapter.GetBackPlatedPadPolys();
if( frontPlatedPadAndGraphicPolys )
if( frontPlatedPadPolys )
{
SHAPE_POLY_SET poly = frontPlatedPadAndGraphicPolys->CloneDropTriangulation();
poly.BooleanIntersection( m_boardAdapter.GetBoardPoly(), SHAPE_POLY_SET::PM_FAST );
poly.BooleanSubtract( m_boardAdapter.GetTH_ODPolys(), SHAPE_POLY_SET::PM_FAST );
poly.BooleanSubtract( m_boardAdapter.GetNPTH_ODPolys(), SHAPE_POLY_SET::PM_FAST );
SHAPE_POLY_SET polySubtracted = frontPlatedPadPolys->CloneDropTriangulation();
polySubtracted.BooleanIntersection( m_boardAdapter.GetBoardPoly(),
SHAPE_POLY_SET::PM_FAST );
polySubtracted.BooleanSubtract( m_boardAdapter.GetThroughHoleOdPolys(),
SHAPE_POLY_SET::PM_FAST );
polySubtracted.BooleanSubtract( m_boardAdapter.GetOuterNonPlatedThroughHolePoly(),
SHAPE_POLY_SET::PM_FAST );
m_platedPadsFront = generateLayerList( m_boardAdapter.GetPlatedPadsFront(), &poly, F_Cu );
m_platedPadsFront = generateLayerList( m_boardAdapter.GetPlatedPadsFront(),
&polySubtracted, F_Cu );
// An entry for F_Cu must exist in m_layers or we'll never look at m_platedPadsFront
if( m_layers.count( F_Cu ) == 0 )
m_layers[F_Cu] = generateEmptyLayerList( F_Cu );
}
if( backPlatedPadAndGraphicPolys )
if( backPlatedPadPolys )
{
SHAPE_POLY_SET poly = backPlatedPadAndGraphicPolys->CloneDropTriangulation();
poly.BooleanIntersection( m_boardAdapter.GetBoardPoly(), SHAPE_POLY_SET::PM_FAST );
poly.BooleanSubtract( m_boardAdapter.GetTH_ODPolys(), SHAPE_POLY_SET::PM_FAST );
poly.BooleanSubtract( m_boardAdapter.GetNPTH_ODPolys(), SHAPE_POLY_SET::PM_FAST );
SHAPE_POLY_SET polySubtracted = backPlatedPadPolys->CloneDropTriangulation();
polySubtracted.BooleanIntersection( m_boardAdapter.GetBoardPoly(),
SHAPE_POLY_SET::PM_FAST );
polySubtracted.BooleanSubtract( m_boardAdapter.GetThroughHoleOdPolys(),
SHAPE_POLY_SET::PM_FAST );
polySubtracted.BooleanSubtract( m_boardAdapter.GetOuterNonPlatedThroughHolePoly(),
SHAPE_POLY_SET::PM_FAST );
m_platedPadsBack = generateLayerList( m_boardAdapter.GetPlatedPadsBack(), &poly, B_Cu );
m_platedPadsBack = generateLayerList( m_boardAdapter.GetPlatedPadsBack(),
&polySubtracted, B_Cu );
// An entry for B_Cu must exist in m_layers or we'll never look at m_platedPadsBack
if( m_layers.count( B_Cu ) == 0 )
@@ -645,15 +672,6 @@ void RENDER_3D_OPENGL::reload( REPORTER* aStatusReporter, REPORTER* aWarningRepo
}
}
if( m_boardAdapter.m_Cfg->m_Render.show_off_board_silk )
{
if( const BVH_CONTAINER_2D* padsFront = m_boardAdapter.GetOffboardPadsFront() )
m_offboardPadsFront = generateLayerList( padsFront, nullptr, F_Cu );
if( const BVH_CONTAINER_2D* padsBack = m_boardAdapter.GetOffboardPadsBack() )
m_offboardPadsBack = generateLayerList( padsBack, nullptr, B_Cu );
}
// Load 3D models
if( aStatusReporter )
aStatusReporter->Report( _( "Loading 3D models..." ) );
@@ -757,9 +775,6 @@ void RENDER_3D_OPENGL::generateViasAndPads()
{
const PCB_VIA* via = static_cast<const PCB_VIA*>( track );
if( via->GetViaType() == VIATYPE::THROUGH )
continue; // handle with pad holes so castellation is taken into account
const float holediameter = via->GetDrillValue() * m_boardAdapter.BiuTo3dUnits();
const int nrSegments = m_boardAdapter.GetCircleSegmentCount( via->GetDrillValue() );
const float hole_inner_radius = holediameter / 2.0f;
@@ -789,33 +804,14 @@ void RENDER_3D_OPENGL::generateViasAndPads()
}
if( m_boardAdapter.GetHoleCount() > 0 || m_boardAdapter.GetViaCount() > 0 )
if( m_boardAdapter.GetHoleCount() > 0 )
{
SHAPE_POLY_SET tht_outer_holes_poly; // Stores the outer poly of the copper holes
SHAPE_POLY_SET tht_inner_holes_poly; // Stores the inner poly of the copper holes
SHAPE_POLY_SET tht_outer_holes_poly; // Stores the outer poly of the copper holes (the pad)
SHAPE_POLY_SET tht_inner_holes_poly; // Stores the inner poly of the copper holes (the hole)
tht_outer_holes_poly.RemoveAllContours();
tht_inner_holes_poly.RemoveAllContours();
// Insert through-via holes (vertical cylinders)
for( const PCB_TRACK* track : m_boardAdapter.GetBoard()->Tracks() )
{
if( track->Type() == PCB_VIA_T )
{
const PCB_VIA* via = static_cast<const PCB_VIA*>( track );
if( via->GetViaType() == VIATYPE::THROUGH )
{
TransformCircleToPolygon( tht_outer_holes_poly, via->GetPosition(),
via->GetDrill() / 2 + platingThickness,
ARC_HIGH_DEF, ERROR_INSIDE );
TransformCircleToPolygon( tht_inner_holes_poly, via->GetPosition(),
via->GetDrill() / 2, ARC_HIGH_DEF, ERROR_INSIDE );
}
}
}
// Insert pads holes (vertical cylinders)
for( const FOOTPRINT* footprint : m_boardAdapter.GetBoard()->Footprints() )
{
@@ -840,7 +836,8 @@ void RENDER_3D_OPENGL::generateViasAndPads()
// Subtract the holes
tht_outer_holes_poly.BooleanSubtract( tht_inner_holes_poly, SHAPE_POLY_SET::PM_FAST );
tht_outer_holes_poly.BooleanSubtract( m_antiBoardPolys, SHAPE_POLY_SET::PM_FAST );
if( m_boardAdapter.m_Cfg->m_Render.realistic )
tht_outer_holes_poly.BooleanSubtract( m_antiBoardPolys, SHAPE_POLY_SET::PM_FAST );
CONTAINER_2D holesContainer;
@@ -906,9 +903,7 @@ void RENDER_3D_OPENGL::Load3dModelsIfNeeded()
load3dModels( &activityReporter );
}
else
{
load3dModels( nullptr );
}
}
@@ -917,18 +912,12 @@ void RENDER_3D_OPENGL::load3dModels( REPORTER* aStatusReporter )
if( !m_boardAdapter.GetBoard() )
return;
// Building the 3D models late crashes on recent versions of macOS
// Unclear the exact mechanism, but as a workaround, just build them
// all the time. See https://gitlab.com/kicad/code/kicad/-/issues/17198
#ifndef __WXMAC__
if( !m_boardAdapter.m_IsPreviewer
&& !m_boardAdapter.m_Cfg->m_Render.show_footprints_normal
if( !m_boardAdapter.m_Cfg->m_Render.show_footprints_normal
&& !m_boardAdapter.m_Cfg->m_Render.show_footprints_insert
&& !m_boardAdapter.m_Cfg->m_Render.show_footprints_virtual )
{
return;
}
#endif
// Go for all footprints
for( const FOOTPRINT* footprint : m_boardAdapter.GetBoard()->Footprints() )
@@ -942,8 +931,8 @@ void RENDER_3D_OPENGL::load3dModels( REPORTER* aStatusReporter )
{
// FindRow() can throw an exception
const FP_LIB_TABLE_ROW* fpRow =
PROJECT_PCB::PcbFootprintLibs( m_boardAdapter.GetBoard()->GetProject() )
->FindRow( libraryName, false );
m_boardAdapter.GetBoard()->GetProject()->PcbFootprintLibs()->FindRow(
libraryName, false );
if( fpRow )
footprintBasePath = fpRow->GetFullURI( true );
@@ -471,11 +471,38 @@ void OPENGL_RENDER_LIST::DrawAll( bool aDrawMiddle ) const
}
void OPENGL_RENDER_LIST::DrawCulled( bool aDrawMiddle,
const OPENGL_RENDER_LIST* aSubtractList,
const OPENGL_RENDER_LIST* bSubtractList,
const OPENGL_RENDER_LIST* cSubtractList,
const OPENGL_RENDER_LIST* dSubtractList ) const
void OPENGL_RENDER_LIST::DrawAllCameraCulled( float zCameraPos, bool aDrawMiddle ) const
{
zCameraPos = m_haveTransformation
? ( ( zCameraPos - m_zPositionTransformation ) / m_zScaleTransformation )
: zCameraPos;
if( aDrawMiddle )
DrawMiddle();
if( zCameraPos > m_zTop )
{
DrawTop();
}
else
{
if( zCameraPos < m_zBot )
{
DrawBot();
}
else
{
// If camera is in the middle dont draw it.
}
}
}
void OPENGL_RENDER_LIST::DrawAllCameraCulledSubtractLayer( bool aDrawMiddle,
const OPENGL_RENDER_LIST* aLayerToSubtractA,
const OPENGL_RENDER_LIST* aLayerToSubtractB,
const OPENGL_RENDER_LIST* aLayerToSubtractC,
const OPENGL_RENDER_LIST* aLayerToSubtractD ) const
{
glClearStencil( 0x00 );
glClear( GL_STENCIL_BUFFER_BIT );
@@ -490,17 +517,17 @@ void OPENGL_RENDER_LIST::DrawCulled( bool aDrawMiddle,
glStencilFunc( GL_ALWAYS, 1, 0 );
glStencilOp( GL_KEEP, GL_KEEP, GL_REPLACE );
if( aSubtractList )
aSubtractList->DrawBot();
if( aLayerToSubtractA )
aLayerToSubtractA->DrawBot();
if( bSubtractList )
bSubtractList->DrawBot();
if( aLayerToSubtractB )
aLayerToSubtractB->DrawBot();
if( cSubtractList )
cSubtractList->DrawBot();
if( aLayerToSubtractC )
aLayerToSubtractC->DrawBot();
if( dSubtractList )
dSubtractList->DrawBot();
if( aLayerToSubtractD )
aLayerToSubtractD->DrawBot();
glEnable(GL_DEPTH_TEST);
glDepthMask(GL_TRUE);
@@ -517,17 +544,17 @@ void OPENGL_RENDER_LIST::DrawCulled( bool aDrawMiddle,
glStencilFunc( GL_ALWAYS, 2, 0 );
glStencilOp( GL_KEEP, GL_KEEP, GL_REPLACE );
if( aSubtractList )
aSubtractList->DrawTop();
if( aLayerToSubtractA )
aLayerToSubtractA->DrawTop();
if( bSubtractList )
bSubtractList->DrawTop();
if( aLayerToSubtractB )
aLayerToSubtractB->DrawTop();
if( cSubtractList )
cSubtractList->DrawTop();
if( aLayerToSubtractC )
aLayerToSubtractC->DrawTop();
if( dSubtractList )
dSubtractList->DrawTop();
if( aLayerToSubtractD )
aLayerToSubtractD->DrawTop();
glEnable(GL_DEPTH_TEST);
glDepthMask(GL_TRUE);
@@ -548,8 +575,8 @@ void OPENGL_RENDER_LIST::DrawCulled( bool aDrawMiddle,
if( aDrawMiddle )
{
if( aSubtractList )
aSubtractList->DrawMiddle();
if( aLayerToSubtractA )
aLayerToSubtractA->DrawMiddle();
}
glLightModeli( GL_LIGHT_MODEL_TWO_SIDE, GL_FALSE );
@@ -561,7 +588,7 @@ void OPENGL_RENDER_LIST::DrawCulled( bool aDrawMiddle,
void OPENGL_RENDER_LIST::ApplyScalePosition( float aZposition, float aZscale )
{
wxCHECK2( aZscale > FLT_EPSILON, aZscale = FLT_EPSILON + 1 );
wxASSERT( aZscale > FLT_EPSILON );
m_zPositionTransformation = aZposition;
m_zScaleTransformation = aZscale;
@@ -569,12 +596,6 @@ void OPENGL_RENDER_LIST::ApplyScalePosition( float aZposition, float aZscale )
}
void OPENGL_RENDER_LIST::ApplyScalePosition( OPENGL_RENDER_LIST* aOtherList )
{
ApplyScalePosition( aOtherList->GetZBot(), aOtherList->GetZTop() - aOtherList->GetZBot() );
}
void OPENGL_RENDER_LIST::SetItIsTransparent( bool aSetTransparent )
{
m_draw_it_transparent = aSetTransparent;
@@ -194,14 +194,15 @@ public:
*
* @param zCameraPos is the camera z axis position.
*/
void DrawCulled( bool aDrawMiddle,
const OPENGL_RENDER_LIST* aSubtractList = nullptr,
const OPENGL_RENDER_LIST* bSubtractList = nullptr,
const OPENGL_RENDER_LIST* cSubtractList = nullptr,
const OPENGL_RENDER_LIST* dSubtractList = nullptr ) const;
void DrawAllCameraCulled( float zCameraPos, bool aDrawMiddle = true ) const;
void DrawAllCameraCulledSubtractLayer( bool aDrawMiddle,
const OPENGL_RENDER_LIST* aLayerToSubtractA = nullptr,
const OPENGL_RENDER_LIST* aLayerToSubtractB = nullptr,
const OPENGL_RENDER_LIST* aLayerToSubtractC = nullptr,
const OPENGL_RENDER_LIST* aLayerToSubtractD = nullptr ) const;
void ApplyScalePosition( float aZposition, float aZscale );
void ApplyScalePosition( OPENGL_RENDER_LIST* aOtherList );
void ClearScalePosition() { m_haveTransformation = false; }
@@ -27,7 +27,7 @@
#include <trigo.h>
#include <wx/debug.h> // For the wxASSERT
#define RADPERDEG 0.0174533f
#define RADPERDEG 0.0174533
void DrawRoundArrow( SFVEC3F aPosition, SFVEC3F aTargetPos, float aSize )
{
@@ -155,7 +155,7 @@ void DrawHalfOpenCylinder( unsigned int aNrSidesPerCircle )
{
SFVEC2D corner = SFVEC2D( 0.0, radius );
RotatePoint( &corner.x, &corner.y, ii );
glVertex3f( static_cast<GLfloat>( corner.x ), static_cast<GLfloat>( corner.y ), 0.0 );
glVertex3f( corner.x, corner.y, 0.0 );
}
glVertex3d( 0.0, -radius, 0.0 );
@@ -171,7 +171,7 @@ void DrawHalfOpenCylinder( unsigned int aNrSidesPerCircle )
SFVEC2D corner = SFVEC2D( 0.0, radius );
RotatePoint( &corner.x, &corner.y, ii );
glVertex3f( static_cast<GLfloat>( corner.x ), static_cast<GLfloat>( corner.y ), 1.0 );
glVertex3f( corner.x, corner.y, 1.0 );
}
glVertex3f( 0.0, radius, 1.0 );
@@ -185,10 +185,9 @@ void DrawHalfOpenCylinder( unsigned int aNrSidesPerCircle )
SFVEC2D corner = SFVEC2D( 0.0, radius );
RotatePoint( &corner.x, &corner.y, ii );
glNormal3f( static_cast<GLfloat>( corner.x * 2.0f ),
static_cast<GLfloat>( corner.y * 2.0f ), 0.0f );
glVertex3f( static_cast<GLfloat>( corner.x ), static_cast<GLfloat>( corner.y ), 1.0f );
glVertex3f( static_cast<GLfloat>( corner.x ), static_cast<GLfloat>( corner.y ), 0.0f );
glNormal3f( corner.x * 2.0f, corner.y * 2.0f, 0.0f );
glVertex3f( corner.x, corner.y, 1.0 );
glVertex3f( corner.x, corner.y, 0.0 );
}
glNormal3f( 0.0, 1.0f, 0.0f );
File diff suppressed because it is too large Load Diff
@@ -2,7 +2,7 @@
* This program source code file is part of KiCad, a free EDA CAD application.
*
* Copyright (C) 2015-2016 Mario Luzeiro <mrluzeiro@ua.pt>
* Copyright (C) 2015-2024 KiCad Developers, see AUTHORS.txt for contributors.
* Copyright (C) 2015-2021 KiCad Developers, see AUTHORS.txt for contributors.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
@@ -73,15 +73,16 @@ public:
private:
OPENGL_RENDER_LIST* generateHoles( const LIST_OBJECT2D& aListHolesObject2d,
const SHAPE_POLY_SET& aPoly, float aZtop, float aZbot,
bool aInvertFaces,
const SHAPE_POLY_SET& aPoly, float aZtop,
float aZbot, bool aInvertFaces,
const BVH_CONTAINER_2D* aThroughHoles = nullptr );
OPENGL_RENDER_LIST* generateLayerList( const BVH_CONTAINER_2D* aContainer,
const SHAPE_POLY_SET* aPolyList, PCB_LAYER_ID aLayer,
const SHAPE_POLY_SET* aPolyList,
PCB_LAYER_ID aLayerId,
const BVH_CONTAINER_2D* aThroughHoles = nullptr );
OPENGL_RENDER_LIST* generateEmptyLayerList( PCB_LAYER_ID aLayer );
OPENGL_RENDER_LIST* generateEmptyLayerList( PCB_LAYER_ID aLayerId );
void addTopAndBottomTriangles( TRIANGLE_DISPLAY_LIST* aDst, const SFVEC2F& v0,
const SFVEC2F& v1, const SFVEC2F& v2, float top, float bot );
@@ -92,17 +93,17 @@ private:
void addObjectTriangles( const POLYGON_4PT_2D* aPoly, TRIANGLE_DISPLAY_LIST* aDstLayer,
float aZtop, float aZbot );
void addObjectTriangles( const FILLED_CIRCLE_2D* aCircle, TRIANGLE_DISPLAY_LIST* aDstLayer,
float aZtop, float aZbot );
void addObjectTriangles( const FILLED_CIRCLE_2D* aFilledCircle,
TRIANGLE_DISPLAY_LIST* aDstLayer, float aZtop, float aZbot );
void addObjectTriangles( const TRIANGLE_2D* aTri, TRIANGLE_DISPLAY_LIST* aDstLayer,
float aZtop, float aZbot );
void addObjectTriangles( const ROUND_SEGMENT_2D* aSeg, TRIANGLE_DISPLAY_LIST* aDstLayer,
float aZtop, float aZbot );
void addObjectTriangles( const ROUND_SEGMENT_2D* aSeg,
TRIANGLE_DISPLAY_LIST* aDstLayer, float aZtop, float aZbot );
void renderSolderMaskLayer( PCB_LAYER_ID aLayerID, float aZPos, bool aShowThickness,
bool aSkipRenderHoles );
void renderSolderMaskLayer( PCB_LAYER_ID aLayerID, float aZPosition,
bool aDrawMiddleSegments, bool aSkipRenderHoles );
void renderBoardBody( bool aSkipRenderHoles );
@@ -153,12 +154,15 @@ private:
void renderOpaqueModels( const glm::mat4 &aCameraViewMatrix );
void renderTransparentModels( const glm::mat4 &aCameraViewMatrix );
void renderModel( const glm::mat4 &aCameraViewMatrix, const MODELTORENDER &aModelToRender,
const SFVEC3F &aSelColor, const SFVEC3F *aCameraWorldPos );
void renderModel( const glm::mat4 &aCameraViewMatrix,
const MODELTORENDER &aModelToRender,
const SFVEC3F &aSelColor,
const SFVEC3F *aCameraWorldPos );
void get3dModelsSelected( std::list<MODELTORENDER> &aDstRenderList, bool aGetTop, bool aGetBot,
bool aRenderTransparentOnly, bool aRenderSelectedOnly );
void get3dModelsSelected( std::list<MODELTORENDER> &aDstRenderList,
bool aGetTop, bool aGetBot, bool aRenderTransparentOnly,
bool aRenderSelectedOnly );
void get3dModelsFromFootprint( std::list<MODELTORENDER> &aDstRenderList,
const FOOTPRINT* aFootprint, bool aRenderTransparentOnly,
@@ -185,6 +189,7 @@ private:
void unsetDepthOffset();
void setLayerMaterial( PCB_LAYER_ID aLayerID );
SFVEC4F getLayerColor( PCB_LAYER_ID aLayerID );
bool initializeOpenGL();
OPENGL_RENDER_LIST* createBoard( const SHAPE_POLY_SET& aBoardPoly,
@@ -208,13 +213,9 @@ private:
SMATERIAL m_GrayMaterial;
} m_materials;
EDA_3D_CANVAS* m_canvas;
MAP_OGL_DISP_LISTS m_layers;
OPENGL_RENDER_LIST* m_platedPadsFront;
OPENGL_RENDER_LIST* m_platedPadsBack;
OPENGL_RENDER_LIST* m_offboardPadsFront;
OPENGL_RENDER_LIST* m_offboardPadsBack;
MAP_OGL_DISP_LISTS m_outerLayerHoles;
MAP_OGL_DISP_LISTS m_innerLayerHoles;
OPENGL_RENDER_LIST* m_board;
@@ -234,8 +235,8 @@ private:
OPENGL_RENDER_LIST* m_padHoles;
// Caches
std::map<wxString, MODEL_3D*> m_3dModelMap;
std::map<std::vector<float>, glm::mat4> m_3dModelMatrixMap;
std::map< wxString, MODEL_3D* > m_3dModelMap;
std::map< std::vector<float>, glm::mat4 > m_3dModelMatrixMap;
BOARD_ITEM* m_currentRollOverItem;
+6 -6
View File
@@ -2,7 +2,7 @@
* This program source code file is part of KiCad, a free EDA CAD application.
*
* Copyright (C) 2015-2016 Mario Luzeiro <mrluzeiro@ua.pt>
* Copyright (C) 2015-2024 KiCad Developers, see AUTHORS.txt for contributors.
* Copyright (C) 2015-2020 KiCad Developers, see AUTHORS.txt for contributors.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
@@ -63,7 +63,7 @@ void POST_SHADER::UpdateSize( unsigned int xSize, unsigned int ySize )
const unsigned int n_elements = xSize * ySize;
m_normals = new SFVEC3F[n_elements];
m_color = new SFVEC4F[n_elements];
m_color = new SFVEC3F[n_elements];
m_depth = new float[n_elements];
m_wc_hitposition = new SFVEC3F[n_elements];
m_shadow_att_factor = new float[n_elements];
@@ -77,7 +77,7 @@ void POST_SHADER::UpdateSize( const SFVEC2UI& aSize )
void POST_SHADER::SetPixelData( unsigned int x, unsigned int y, const SFVEC3F& aNormal,
const SFVEC4F& aColor, const SFVEC3F& aHitPosition,
const SFVEC3F& aColor, const SFVEC3F& aHitPosition,
float aDepth, float aShadowAttFactor )
{
wxASSERT( x < m_size.x );
@@ -125,7 +125,7 @@ const SFVEC3F& POST_SHADER::GetNormalAt( const SFVEC2F& aPos ) const
}
const SFVEC4F& POST_SHADER::GetColorAt( const SFVEC2F& aPos ) const
const SFVEC3F& POST_SHADER::GetColorAt( const SFVEC2F& aPos ) const
{
return m_color[GetIndex( aPos )];
}
@@ -149,13 +149,13 @@ const SFVEC3F& POST_SHADER::GetNormalAt( const SFVEC2I& aPos ) const
}
const SFVEC4F& POST_SHADER::GetColorAt( const SFVEC2I& aPos ) const
const SFVEC3F& POST_SHADER::GetColorAt( const SFVEC2I& aPos ) const
{
return m_color[GetIndex( aPos )];
}
const SFVEC4F& POST_SHADER::GetColorAtNotProtected( const SFVEC2I& aPos ) const
const SFVEC3F& POST_SHADER::GetColorAtNotProtected( const SFVEC2I& aPos ) const
{
return m_color[ aPos.x + m_size.x * aPos.y ];
}
+8 -8
View File
@@ -2,7 +2,7 @@
* This program source code file is part of KiCad, a free EDA CAD application.
*
* Copyright (C) 2015-2016 Mario Luzeiro <mrluzeiro@ua.pt>
* Copyright (C) 2015-2024 KiCad Developers, see AUTHORS.txt for contributors.
* Copyright (C) 2015-2020 KiCad Developers, see AUTHORS.txt for contributors.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
@@ -30,7 +30,7 @@
#ifndef POST_SHADER_H
#define POST_SHADER_H
#include <gal/3d/camera.h>
#include "camera.h"
class POST_SHADER
{
@@ -46,7 +46,7 @@ public:
* @param aShadeColor The result of the shader.
* @return the result of the shade process
*/
virtual SFVEC4F ApplyShadeColor( const SFVEC2I& aShaderPos, const SFVEC4F& aInputColor,
virtual SFVEC3F ApplyShadeColor( const SFVEC2I& aShaderPos, const SFVEC3F& aInputColor,
const SFVEC3F& aShadeColor ) const = 0;
void UpdateSize( const SFVEC2UI& aSize );
@@ -56,10 +56,10 @@ public:
void InitFrame() { m_tmin = FLT_MAX; m_tmax = 0.0f; }
void SetPixelData( unsigned int x, unsigned int y, const SFVEC3F& aNormal,
const SFVEC4F& aColor, const SFVEC3F& aHitPosition,
const SFVEC3F& aColor, const SFVEC3F& aHitPosition,
float aDepth, float aShadowAttFactor );
const SFVEC4F& GetColorAtNotProtected( const SFVEC2I& aPos ) const;
const SFVEC3F& GetColorAtNotProtected( const SFVEC2I& aPos ) const;
void DebugBuffersOutputAsImages() const;
@@ -88,12 +88,12 @@ public:
protected:
const SFVEC3F& GetNormalAt( const SFVEC2F& aPos ) const;
const SFVEC4F& GetColorAt( const SFVEC2F& aPos ) const;
const SFVEC3F& GetColorAt( const SFVEC2F& aPos ) const;
const SFVEC3F& GetPositionAt( const SFVEC2F& aPos ) const;
float GetDepthAt( const SFVEC2F& aPos ) const;
const SFVEC3F& GetNormalAt( const SFVEC2I& aPos ) const;
const SFVEC4F& GetColorAt( const SFVEC2I& aPos ) const;
const SFVEC3F& GetColorAt( const SFVEC2I& aPos ) const;
const SFVEC3F& GetPositionAt( const SFVEC2I& aPos ) const;
const float& GetShadowFactorAt( const SFVEC2I& aPos ) const;
@@ -109,7 +109,7 @@ protected:
SFVEC2UI m_size;
SFVEC3F* m_normals;
SFVEC4F* m_color;
SFVEC3F* m_color;
SFVEC3F* m_wc_hitposition;
float* m_depth;
float* m_shadow_att_factor;
+13 -27
View File
@@ -2,7 +2,7 @@
* This program source code file is part of KiCad, a free EDA CAD application.
*
* Copyright (C) 2015-2016 Mario Luzeiro <mrluzeiro@ua.pt>
* Copyright (C) 2015-2024 KiCad Developers, see AUTHORS.txt for contributors.
* Copyright (C) 2015-2020 KiCad Developers, see AUTHORS.txt for contributors.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
@@ -187,21 +187,21 @@ SFVEC3F POST_SHADER_SSAO::Shade( const SFVEC2I& aShaderPos ) const
ao += aoFF( aShaderPos, ddiff8, n, shadowAt8, shadowAt0, -npw, ph );
gi += giFF( aShaderPos, ddiff , n, shadowAt1, npw, nph) *
giColorCurveShade( GetColorAt( aShaderPos + SFVEC2I( npw, nph ) ) );
giColorCurve( GetColorAt( aShaderPos + SFVEC2I( npw, nph ) ) );
gi += giFF( aShaderPos, ddiff2, n, shadowAt2, npw, -nph) *
giColorCurveShade( GetColorAt( aShaderPos + SFVEC2I( npw,-nph ) ) );
giColorCurve( GetColorAt( aShaderPos + SFVEC2I( npw,-nph ) ) );
gi += giFF( aShaderPos, ddiff3, n, shadowAt3, -npw, nph) *
giColorCurveShade( GetColorAt( aShaderPos + SFVEC2I( -npw, nph ) ) );
giColorCurve( GetColorAt( aShaderPos + SFVEC2I( -npw, nph ) ) );
gi += giFF( aShaderPos, ddiff4, n, shadowAt4, -npw, -nph) *
giColorCurveShade( GetColorAt( aShaderPos + SFVEC2I( -npw,-nph ) ) );
giColorCurve( GetColorAt( aShaderPos + SFVEC2I( -npw,-nph ) ) );
gi += giFF( aShaderPos, ddiff5, n, shadowAt5 , pw, nph) *
giColorCurveShade( GetColorAt( aShaderPos + SFVEC2I( pw, nph ) ) );
giColorCurve( GetColorAt( aShaderPos + SFVEC2I( pw, nph ) ) );
gi += giFF( aShaderPos, ddiff6, n, shadowAt6, pw,-nph) *
giColorCurveShade( GetColorAt( aShaderPos + SFVEC2I( pw,-nph ) ) );
giColorCurve( GetColorAt( aShaderPos + SFVEC2I( pw,-nph ) ) );
gi += giFF( aShaderPos, ddiff7, n, shadowAt7, npw, ph) *
giColorCurveShade( GetColorAt( aShaderPos + SFVEC2I( npw, ph ) ) );
giColorCurve( GetColorAt( aShaderPos + SFVEC2I( npw, ph ) ) );
gi += giFF( aShaderPos, ddiff8, n, shadowAt8, -npw, ph) *
giColorCurveShade( GetColorAt( aShaderPos + SFVEC2I( -npw, ph ) ) );
giColorCurve( GetColorAt( aShaderPos + SFVEC2I( -npw, ph ) ) );
}
// If it received direct light, it shouldn't consider much AO
@@ -227,20 +227,18 @@ SFVEC3F POST_SHADER_SSAO::Shade( const SFVEC2I& aShaderPos ) const
}
SFVEC4F POST_SHADER_SSAO::ApplyShadeColor( const SFVEC2I& aShaderPos, const SFVEC4F& aInputColor,
SFVEC3F POST_SHADER_SSAO::ApplyShadeColor( const SFVEC2I& aShaderPos, const SFVEC3F& aInputColor,
const SFVEC3F& aShadeColor ) const
{
SFVEC4F outColor;
SFVEC3F inColor( aInputColor );
SFVEC3F outColor;
const SFVEC3F subtracted = inColor - aShadeColor;
const SFVEC3F mixed = glm::mix( inColor, inColor * 0.50f - aShadeColor * 0.05f,
const SFVEC3F subtracted = aInputColor - aShadeColor;
const SFVEC3F mixed = glm::mix( aInputColor, aInputColor * 0.50f - aShadeColor * 0.05f,
glm::min( aShadeColor, 1.0f ) );
outColor.r = ( aShadeColor.r < 0.0f ) ? subtracted.r : mixed.r;
outColor.g = ( aShadeColor.g < 0.0f ) ? subtracted.g : mixed.g;
outColor.b = ( aShadeColor.b < 0.0f ) ? subtracted.b : mixed.b;
outColor.a = std::max( aInputColor.a, ( aShadeColor.r + aShadeColor.g + aShadeColor.b ) / 3 );
return outColor;
}
@@ -258,18 +256,6 @@ SFVEC3F POST_SHADER_SSAO::giColorCurve( const SFVEC3F& aColor ) const
}
SFVEC4F POST_SHADER_SSAO::giColorCurve( const SFVEC4F& aColor ) const
{
return SFVEC4F( giColorCurve( SFVEC3F( aColor ) ), aColor.a );
}
SFVEC3F POST_SHADER_SSAO::giColorCurveShade( const SFVEC4F& aColor ) const
{
return giColorCurve( SFVEC3F( aColor ) );
}
SFVEC3F POST_SHADER_SSAO::Blur( const SFVEC2I& aShaderPos ) const
{
const float dCenter = GetDepthAt( aShaderPos );
+2 -4
View File
@@ -2,7 +2,7 @@
* This program source code file is part of KiCad, a free EDA CAD application.
*
* Copyright (C) 2015-2016 Mario Luzeiro <mrluzeiro@ua.pt>
* Copyright (C) 2015-2024 KiCad Developers, see AUTHORS.txt for contributors.
* Copyright (C) 2015-2020 KiCad Developers, see AUTHORS.txt for contributors.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
@@ -40,7 +40,7 @@ public:
explicit POST_SHADER_SSAO( const CAMERA& aCamera );
SFVEC3F Shade(const SFVEC2I& aShaderPos ) const override;
SFVEC4F ApplyShadeColor( const SFVEC2I& aShaderPos, const SFVEC4F& aInputColor,
SFVEC3F ApplyShadeColor( const SFVEC2I& aShaderPos, const SFVEC3F& aInputColor,
const SFVEC3F& aShadeColor ) const override;
SFVEC3F Blur( const SFVEC2I& aShaderPos ) const;
@@ -77,8 +77,6 @@ private:
* @return transformed color.
*/
SFVEC3F giColorCurve( const SFVEC3F& aColor ) const;
SFVEC4F giColorCurve( const SFVEC4F& aColor ) const;
SFVEC3F giColorCurveShade( const SFVEC4F& aColor ) const;
SFVEC3F* m_shadedBuffer;
@@ -23,7 +23,7 @@
*/
/**
* @file bvh_pbrt.cpp
* @file cbvh_pbrt.cpp
* @brief This BVH implementation is based on the source code implementation
* from the book "Physically Based Rendering" (v2 and v3)
*
@@ -437,7 +437,7 @@ BVHBuildNode *BVH_PBRT::recursiveBuild ( std::vector<BVHPrimitiveInfo>& primitiv
(*totalNodes)++;
// !TODO: implement a memory arena
// !TODO: implement an memory Arena
BVHBuildNode *node = static_cast<BVHBuildNode *>( malloc( sizeof( BVHBuildNode ) ) );
m_nodesToFree.push_back( node );
+117 -114
View File
@@ -2,8 +2,7 @@
* This program source code file is part of KiCad, a free EDA CAD application.
*
* Copyright (C) 2015-2022 Mario Luzeiro <mrluzeiro@ua.pt>
* Copyright (C) 2023 CERN
* Copyright (C) 2015-2024 KiCad Developers, see AUTHORS.txt for contributors.
* Copyright (C) 2015-2022 KiCad Developers, see AUTHORS.txt for contributors.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
@@ -23,7 +22,7 @@
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
*/
#include "render_3d_raytrace_base.h"
#include "render_3d_raytrace.h"
#include "shapes3D/plane_3d.h"
#include "shapes3D/round_segment_3d.h"
#include "shapes3D/layer_item_3d.h"
@@ -42,10 +41,9 @@
#include <footprint.h>
#include <fp_lib_table.h>
#include <eda_3d_viewer_frame.h>
#include <project_pcb.h>
#include <base_units.h>
#include <core/profile.h> // To use GetRunningMicroSecs or another profiling utility
#include <profile.h> // To use GetRunningMicroSecs or another profiling utility
/**
* Perform an interpolation step to easy control the transparency based on the
@@ -72,7 +70,7 @@ static float TransparencyControl( float aGrayColorValue, float aTransparency )
#define UNITS3D_TO_UNITSPCB ( pcbIUScale.IU_PER_MM )
void RENDER_3D_RAYTRACE_BASE::setupMaterials()
void RENDER_3D_RAYTRACE::setupMaterials()
{
MATERIAL::SetDefaultRefractionRayCount( m_boardAdapter.m_Cfg->m_Render.raytrace_nrsamples_refractions );
MATERIAL::SetDefaultReflectionRayCount( m_boardAdapter.m_Cfg->m_Render.raytrace_nrsamples_reflections );
@@ -170,13 +168,13 @@ void RENDER_3D_RAYTRACE_BASE::setupMaterials()
m_materials.m_Floor = BLINN_PHONG_MATERIAL( bgTop * 0.125f, SFVEC3F( 0.0f, 0.0f, 0.0f ),
( SFVEC3F( 1.0f ) - bgTop ) / 3.0f,
0.10f * 128.0f, 1.0f, 0.50f );
0.10f * 128.0f, 0.0f, 0.50f );
m_materials.m_Floor.SetCastShadows( false );
m_materials.m_Floor.SetReflectionRecursionCount( 1 );
}
void RENDER_3D_RAYTRACE_BASE::createObject( CONTAINER_3D& aDstContainer, const OBJECT_2D* aObject2D,
void RENDER_3D_RAYTRACE::createObject( CONTAINER_3D& aDstContainer, const OBJECT_2D* aObject2D,
float aZMin, float aZMax, const MATERIAL* aMaterial,
const SFVEC3F& aObjColor )
{
@@ -227,7 +225,7 @@ void RENDER_3D_RAYTRACE_BASE::createObject( CONTAINER_3D& aDstContainer, const O
}
void RENDER_3D_RAYTRACE_BASE::createItemsFromContainer( const BVH_CONTAINER_2D* aContainer2d,
void RENDER_3D_RAYTRACE::createItemsFromContainer( const BVH_CONTAINER_2D* aContainer2d,
PCB_LAYER_ID aLayer_id,
const MATERIAL* aMaterialLayer,
const SFVEC3F& aLayerColor,
@@ -236,9 +234,7 @@ void RENDER_3D_RAYTRACE_BASE::createItemsFromContainer( const BVH_CONTAINER_2D*
if( aContainer2d == nullptr )
return;
EDA_3D_VIEWER_SETTINGS::RENDER_SETTINGS& cfg = m_boardAdapter.m_Cfg->m_Render;
bool isSilk = aLayer_id == B_SilkS || aLayer_id == F_SilkS;
const LIST_OBJECT2D& listObject2d = aContainer2d->GetList();
const LIST_OBJECT2D& listObject2d = aContainer2d->GetList();
if( listObject2d.size() == 0 )
return;
@@ -277,8 +273,11 @@ void RENDER_3D_RAYTRACE_BASE::createItemsFromContainer( const BVH_CONTAINER_2D*
// layer and the flag is set, then clip the silk at the outer edge of the annular ring,
// rather than the at the outer edge of the copper plating.
const BVH_CONTAINER_2D& throughHoleOuter =
cfg.clip_silk_on_via_annuli && isSilk ? m_boardAdapter.GetViaAnnuli()
: m_boardAdapter.GetTH_ODs();
m_boardAdapter.m_Cfg->m_Render.clip_silk_on_via_annulus
&& m_boardAdapter.m_Cfg->m_Render.realistic
&& ( aLayer_id == B_SilkS || aLayer_id == F_SilkS ) ?
m_boardAdapter.GetThroughHoleAnnularRings() :
m_boardAdapter.GetThroughHoleOds();
if( !throughHoleOuter.GetList().empty() )
{
@@ -304,13 +303,14 @@ void RENDER_3D_RAYTRACE_BASE::createItemsFromContainer( const BVH_CONTAINER_2D*
const MAP_CONTAINER_2D_BASE& mapLayers = m_boardAdapter.GetLayerMap();
if( cfg.subtract_mask_from_silk
if( m_boardAdapter.m_Cfg->m_Render.subtract_mask_from_silk
&& m_boardAdapter.m_Cfg->m_Render.realistic
&& ( ( aLayer_id == B_SilkS && mapLayers.find( B_Mask ) != mapLayers.end() )
|| ( aLayer_id == F_SilkS && mapLayers.find( F_Mask ) != mapLayers.end() ) ) )
{
const PCB_LAYER_ID maskLayer = ( aLayer_id == B_SilkS ) ? B_Mask : F_Mask;
const PCB_LAYER_ID layerMask_id = ( aLayer_id == B_SilkS ) ? B_Mask : F_Mask;
const BVH_CONTAINER_2D* containerMaskLayer2d = mapLayers.at( maskLayer );
const BVH_CONTAINER_2D* containerMaskLayer2d = mapLayers.at( layerMask_id );
CONST_LIST_OBJECT2D intersecting;
@@ -330,8 +330,8 @@ void RENDER_3D_RAYTRACE_BASE::createItemsFromContainer( const BVH_CONTAINER_2D*
if( ( object2d_B == CSGITEM_EMPTY ) && ( object2d_C == CSGITEM_FULL ) )
{
LAYER_ITEM* objPtr = new LAYER_ITEM( object2d_A,
m_boardAdapter.GetLayerBottomZPos( aLayer_id ) - aLayerZOffset,
m_boardAdapter.GetLayerTopZPos( aLayer_id ) + aLayerZOffset );
m_boardAdapter.GetLayerBottomZPos( aLayer_id ) - aLayerZOffset,
m_boardAdapter.GetLayerTopZPos( aLayer_id ) + aLayerZOffset );
objPtr->SetMaterial( aMaterialLayer );
objPtr->SetColor( ConvertSRGBToLinear( aLayerColor ) );
m_objectContainer.Add( objPtr );
@@ -343,8 +343,8 @@ void RENDER_3D_RAYTRACE_BASE::createItemsFromContainer( const BVH_CONTAINER_2D*
m_containerWithObjectsToDelete.Add( itemCSG2d );
LAYER_ITEM* objPtr = new LAYER_ITEM( itemCSG2d,
m_boardAdapter.GetLayerBottomZPos( aLayer_id ) - aLayerZOffset,
m_boardAdapter.GetLayerTopZPos( aLayer_id ) + aLayerZOffset );
m_boardAdapter.GetLayerBottomZPos( aLayer_id ) - aLayerZOffset,
m_boardAdapter.GetLayerTopZPos( aLayer_id ) + aLayerZOffset );
objPtr->SetMaterial( aMaterialLayer );
objPtr->SetColor( ConvertSRGBToLinear( aLayerColor ) );
@@ -358,7 +358,7 @@ void RENDER_3D_RAYTRACE_BASE::createItemsFromContainer( const BVH_CONTAINER_2D*
extern void buildBoardBoundingBoxPoly( const BOARD* aBoard, SHAPE_POLY_SET& aOutline );
void RENDER_3D_RAYTRACE_BASE::Reload( REPORTER* aStatusReporter, REPORTER* aWarningReporter,
void RENDER_3D_RAYTRACE::Reload( REPORTER* aStatusReporter, REPORTER* aWarningReporter,
bool aOnlyLoadCopperAndShapes )
{
m_reloadRequested = false;
@@ -368,7 +368,7 @@ void RENDER_3D_RAYTRACE_BASE::Reload( REPORTER* aStatusReporter, REPORTER* aWarn
OBJECT_2D_STATS::Instance().ResetStats();
OBJECT_3D_STATS::Instance().ResetStats();
int64_t stats_startReloadTime = GetRunningMicroSecs();
unsigned stats_startReloadTime = GetRunningMicroSecs();
if( !aOnlyLoadCopperAndShapes )
{
@@ -393,8 +393,6 @@ void RENDER_3D_RAYTRACE_BASE::Reload( REPORTER* aStatusReporter, REPORTER* aWarn
m_outlineBoard2dObjects = new CONTAINER_2D;
m_antioutlineBoard2dObjects = new BVH_CONTAINER_2D;
std::bitset<LAYER_3D_END> layerFlags = m_boardAdapter.GetVisibleLayers();
if( !aOnlyLoadCopperAndShapes )
{
const int outlineCount = m_boardAdapter.GetBoardPoly().OutlineCount();
@@ -436,7 +434,7 @@ void RENDER_3D_RAYTRACE_BASE::Reload( REPORTER* aStatusReporter, REPORTER* aWarn
*m_boardAdapter.GetBoard(), ii );
}
if( layerFlags.test( LAYER_3D_BOARD ) )
if( m_boardAdapter.m_Cfg->m_Render.show_board_body )
{
const LIST_OBJECT2D& listObjects = m_outlineBoard2dObjects->GetList();
@@ -445,9 +443,9 @@ void RENDER_3D_RAYTRACE_BASE::Reload( REPORTER* aStatusReporter, REPORTER* aWarn
std::vector<const OBJECT_2D*>* object2d_B = new std::vector<const OBJECT_2D*>();
// Check if there are any THT that intersects this outline object part
if( !m_boardAdapter.GetTH_ODs().GetList().empty() )
if( !m_boardAdapter.GetThroughHoleOds().GetList().empty() )
{
const BVH_CONTAINER_2D& throughHoles = m_boardAdapter.GetTH_ODs();
const BVH_CONTAINER_2D& throughHoles = m_boardAdapter.GetThroughHoleOds();
CONST_LIST_OBJECT2D intersecting;
throughHoles.GetIntersectingObjects( object2d_A->GetBBox(), intersecting );
@@ -511,9 +509,9 @@ void RENDER_3D_RAYTRACE_BASE::Reload( REPORTER* aStatusReporter, REPORTER* aWarn
// a polygon or dummy block) it will cut also the render of the hole.
// So this will add a full hole.
// In fact, that is not need if the hole have copper.
if( !m_boardAdapter.GetTH_ODs().GetList().empty() )
if( !m_boardAdapter.GetThroughHoleOds().GetList().empty() )
{
const LIST_OBJECT2D& holeList = m_boardAdapter.GetTH_ODs().GetList();
const LIST_OBJECT2D& holeList = m_boardAdapter.GetThroughHoleOds().GetList();
for( const OBJECT_2D* hole2d : holeList )
{
@@ -588,33 +586,40 @@ void RENDER_3D_RAYTRACE_BASE::Reload( REPORTER* aStatusReporter, REPORTER* aWarn
case B_Paste:
case F_Paste:
materialLayer = &m_materials.m_Paste;
layerColor = m_boardAdapter.m_SolderPasteColor;
if( m_boardAdapter.m_Cfg->m_Render.realistic )
layerColor = m_boardAdapter.m_SolderPasteColor;
else
layerColor = m_boardAdapter.GetLayerColor( layer_id );
break;
case B_SilkS:
materialLayer = &m_materials.m_SilkS;
layerColor = m_boardAdapter.m_SilkScreenColorBot;
if( m_boardAdapter.m_Cfg->m_Render.realistic )
layerColor = m_boardAdapter.m_SilkScreenColorBot;
else
layerColor = m_boardAdapter.GetLayerColor( layer_id );
break;
case F_SilkS:
materialLayer = &m_materials.m_SilkS;
layerColor = m_boardAdapter.m_SilkScreenColorTop;
if( m_boardAdapter.m_Cfg->m_Render.realistic )
layerColor = m_boardAdapter.m_SilkScreenColorTop;
else
layerColor = m_boardAdapter.GetLayerColor( layer_id );
break;
case Dwgs_User:
layerColor = m_boardAdapter.m_UserDrawingsColor;
break;
case Cmts_User:
layerColor = m_boardAdapter.m_UserCommentsColor;
break;
case Eco1_User:
layerColor = m_boardAdapter.m_ECO1Color;
break;
case Eco2_User:
layerColor = m_boardAdapter.m_ECO2Color;
case Edge_Cuts:
case Margin:
break;
case B_CrtYd:
@@ -626,15 +631,22 @@ void RENDER_3D_RAYTRACE_BASE::Reload( REPORTER* aStatusReporter, REPORTER* aWarn
break;
default:
if( m_boardAdapter.m_Cfg->m_Render.differentiate_plated_copper )
if( m_boardAdapter.m_Cfg->m_Render.realistic )
{
layerColor = SFVEC3F( 184.0f / 255.0f, 115.0f / 255.0f, 50.0f / 255.0f );
materialLayer = &m_materials.m_NonPlatedCopper;
if( m_boardAdapter.m_Cfg->m_Render.renderPlatedPadsAsPlated )
{
layerColor = SFVEC3F( 184.0f / 255.0f, 115.0f / 255.0f, 50.0f / 255.0f );
materialLayer = &m_materials.m_NonPlatedCopper;
}
else
{
layerColor = m_boardAdapter.m_CopperColor;
materialLayer = &m_materials.m_Copper;
}
}
else
{
layerColor = m_boardAdapter.m_CopperColor;
materialLayer = &m_materials.m_Copper;
layerColor = m_boardAdapter.GetLayerColor( layer_id );
}
break;
@@ -644,7 +656,8 @@ void RENDER_3D_RAYTRACE_BASE::Reload( REPORTER* aStatusReporter, REPORTER* aWarn
} // for each layer on map
// Create plated copper
if( m_boardAdapter.m_Cfg->m_Render.differentiate_plated_copper )
if( m_boardAdapter.m_Cfg->m_Render.renderPlatedPadsAsPlated
&& m_boardAdapter.m_Cfg->m_Render.realistic )
{
createItemsFromContainer( m_boardAdapter.GetPlatedPadsFront(), F_Cu, &m_materials.m_Copper,
m_boardAdapter.m_CopperColor,
@@ -661,9 +674,8 @@ void RENDER_3D_RAYTRACE_BASE::Reload( REPORTER* aStatusReporter, REPORTER* aWarn
// Solder mask layers are "negative" layers so the elements that we have in the container
// should remove the board outline. We will check for all objects in the outline if it
// intersects any object in the layer container and also any hole.
if( ( layerFlags.test( LAYER_3D_SOLDERMASK_TOP )
|| layerFlags.test( LAYER_3D_SOLDERMASK_BOTTOM ) )
&& !m_outlineBoard2dObjects->GetList().empty() )
if( m_boardAdapter.m_Cfg->m_Render.show_soldermask
&& !m_outlineBoard2dObjects->GetList().empty() )
{
const MATERIAL* materialLayer = &m_materials.m_SolderMask;
@@ -677,22 +689,22 @@ void RENDER_3D_RAYTRACE_BASE::Reload( REPORTER* aStatusReporter, REPORTER* aWarn
continue;
// Only get the Solder mask layers (and only if the board has them)
if( layer_id == F_Mask && !layerFlags.test( LAYER_3D_SOLDERMASK_TOP ) )
continue;
if( layer_id == B_Mask && !layerFlags.test( LAYER_3D_SOLDERMASK_BOTTOM ) )
continue;
// Only Mask layers are processed here because they are negative layers
if( layer_id != F_Mask && layer_id != B_Mask )
if( !( layer_id == B_Mask || layer_id == F_Mask ) )
continue;
SFVEC3F layerColor;
if( layer_id == B_Mask )
layerColor = m_boardAdapter.m_SolderMaskColorBot;
if( m_boardAdapter.m_Cfg->m_Render.realistic )
{
if( layer_id == B_Mask )
layerColor = m_boardAdapter.m_SolderMaskColorBot;
else
layerColor = m_boardAdapter.m_SolderMaskColorTop;
}
else
layerColor = m_boardAdapter.m_SolderMaskColorTop;
{
layerColor = m_boardAdapter.GetLayerColor( layer_id );
}
const float zLayerMin = m_boardAdapter.GetLayerBottomZPos( layer_id );
const float zLayerMax = m_boardAdapter.GetLayerTopZPos( layer_id );
@@ -703,9 +715,9 @@ void RENDER_3D_RAYTRACE_BASE::Reload( REPORTER* aStatusReporter, REPORTER* aWarn
std::vector<const OBJECT_2D*>* object2d_B = new std::vector<const OBJECT_2D*>();
// Check if there are any THT that intersects this outline object part
if( !m_boardAdapter.GetTH_ODs().GetList().empty() )
if( !m_boardAdapter.GetThroughHoleOds().GetList().empty() )
{
const BVH_CONTAINER_2D& throughHoles = m_boardAdapter.GetTH_ODs();
const BVH_CONTAINER_2D& throughHoles = m_boardAdapter.GetThroughHoleOds();
CONST_LIST_OBJECT2D intersecting;
throughHoles.GetIntersectingObjects( object2d_A->GetBBox(), intersecting );
@@ -771,8 +783,8 @@ void RENDER_3D_RAYTRACE_BASE::Reload( REPORTER* aStatusReporter, REPORTER* aWarn
}
#ifdef PRINT_STATISTICS_3D_VIEWER
int64_t stats_endConvertTime = GetRunningMicroSecs();
int64_t stats_startLoad3DmodelsTime = stats_endConvertTime;
unsigned stats_endConvertTime = GetRunningMicroSecs();
unsigned stats_startLoad3DmodelsTime = stats_endConvertTime;
#endif
if( aStatusReporter )
@@ -781,7 +793,7 @@ void RENDER_3D_RAYTRACE_BASE::Reload( REPORTER* aStatusReporter, REPORTER* aWarn
load3DModels( m_objectContainer, aOnlyLoadCopperAndShapes );
#ifdef PRINT_STATISTICS_3D_VIEWER
int64_t stats_endLoad3DmodelsTime = GetRunningMicroSecs();
unsigned stats_endLoad3DmodelsTime = GetRunningMicroSecs();
#endif
if( !aOnlyLoadCopperAndShapes )
@@ -817,7 +829,7 @@ void RENDER_3D_RAYTRACE_BASE::Reload( REPORTER* aStatusReporter, REPORTER* aWarn
const SFVEC3F v2 = SFVEC3F( v1.x, v3.y, v1.z );
const SFVEC3F v4 = SFVEC3F( v3.x, v1.y, v1.z );
SFVEC3F floorColor = ConvertSRGBToLinear( m_boardAdapter.m_BgColorTop );
SFVEC3F backgroundColor = ConvertSRGBToLinear( m_boardAdapter.m_BgColorTop );
TRIANGLE* newTriangle1 = new TRIANGLE( v1, v2, v3 );
TRIANGLE* newTriangle2 = new TRIANGLE( v3, v4, v1 );
@@ -828,8 +840,8 @@ void RENDER_3D_RAYTRACE_BASE::Reload( REPORTER* aStatusReporter, REPORTER* aWarn
newTriangle1->SetMaterial( &m_materials.m_Floor );
newTriangle2->SetMaterial( &m_materials.m_Floor );
newTriangle1->SetColor( floorColor );
newTriangle2->SetColor( floorColor );
newTriangle1->SetColor( backgroundColor );
newTriangle2->SetColor( backgroundColor );
// Ceiling triangles
const float maxZ = glm::max( containerBBox.Max().z, boardBBox.Max().z );
@@ -848,8 +860,8 @@ void RENDER_3D_RAYTRACE_BASE::Reload( REPORTER* aStatusReporter, REPORTER* aWarn
newTriangle3->SetMaterial( &m_materials.m_Floor );
newTriangle4->SetMaterial( &m_materials.m_Floor );
newTriangle3->SetColor( floorColor );
newTriangle4->SetColor( floorColor );
newTriangle3->SetColor( backgroundColor );
newTriangle4->SetColor( backgroundColor );
}
}
}
@@ -919,33 +931,10 @@ void RENDER_3D_RAYTRACE_BASE::Reload( REPORTER* aStatusReporter, REPORTER* aWarn
{
float ratio =
std::max( 1.0f, m_objectContainer.GetBBox().GetMaxDimension() / RANGE_SCALE_3D );
m_camera.SetMaxZoom( CAMERA::DEFAULT_MAX_ZOOM * ratio );
float max_zoom = CAMERA::DEFAULT_MAX_ZOOM * ratio;
float min_zoom = static_cast<float>( MIN_DISTANCE_IU * m_boardAdapter.BiuTo3dUnits()
/ -m_camera.GetCameraInitPos().z );
if( min_zoom > max_zoom )
std::swap( min_zoom, max_zoom );
float zoom_ratio = max_zoom / min_zoom;
// Set the minimum number of zoom 'steps' between max and min.
int steps = 3 * 3;
steps -= static_cast<int>( ceil( log( zoom_ratio ) / log( 1.26f ) ) );
steps = std::max( steps, 0 );
// Resize max and min zoom to accomplish the number of steps.
float increased_zoom = pow( 1.26f, steps / 2 );
max_zoom *= increased_zoom;
min_zoom /= increased_zoom;
if( steps & 1 )
min_zoom /= 1.26f;
min_zoom = std::min( min_zoom, 1.0f );
m_camera.SetMaxZoom( max_zoom );
m_camera.SetMinZoom( min_zoom );
m_camera.SetMinZoom( static_cast<float>( MIN_DISTANCE_IU * m_boardAdapter.BiuTo3dUnits()
/ -m_camera.GetCameraInitPos().z ) );
}
// Create an accelerator
@@ -955,14 +944,14 @@ void RENDER_3D_RAYTRACE_BASE::Reload( REPORTER* aStatusReporter, REPORTER* aWarn
if( aStatusReporter )
{
// Calculation time in seconds
double calculation_time = (double) ( GetRunningMicroSecs() - stats_startReloadTime ) / 1e6;
double calculation_time = (double) GetRunningMicroSecs() - stats_startReloadTime / 1e6;
aStatusReporter->Report( wxString::Format( _( "Reload time %.3f s" ), calculation_time ) );
}
}
void RENDER_3D_RAYTRACE_BASE::insertHole( const PCB_VIA* aVia )
void RENDER_3D_RAYTRACE::insertHole( const PCB_VIA* aVia )
{
PCB_LAYER_ID top_layer, bottom_layer;
int radiusBUI = ( aVia->GetDrillValue() / 2 );
@@ -987,17 +976,31 @@ void RENDER_3D_RAYTRACE_BASE::insertHole( const PCB_VIA* aVia )
LAYER_ITEM* objPtr = new LAYER_ITEM( ring, topZ, botZ );
objPtr->SetMaterial( &m_materials.m_Copper );
objPtr->SetColor( ConvertSRGBToLinear( m_boardAdapter.m_CopperColor ) );
if( m_boardAdapter.m_Cfg->m_Render.realistic )
objPtr->SetColor( ConvertSRGBToLinear( m_boardAdapter.m_CopperColor ) );
else if( aVia->GetViaType() == VIATYPE::MICROVIA )
objPtr->SetColor( ConvertSRGBToLinear( m_boardAdapter.GetItemColor( LAYER_VIA_MICROVIA ) ) );
else if( aVia->GetViaType() == VIATYPE::BLIND_BURIED )
objPtr->SetColor( ConvertSRGBToLinear( m_boardAdapter.GetItemColor( LAYER_VIA_BBLIND ) ) );
else
objPtr->SetColor( ConvertSRGBToLinear( m_boardAdapter.GetItemColor( LAYER_VIAS ) ) );
m_objectContainer.Add( objPtr );
}
void RENDER_3D_RAYTRACE_BASE::insertHole( const PAD* aPad )
void RENDER_3D_RAYTRACE::insertHole( const PAD* aPad )
{
const OBJECT_2D* object2d_A = nullptr;
SFVEC3F objColor = m_boardAdapter.m_CopperColor;
SFVEC3F objColor;
if( m_boardAdapter.m_Cfg->m_Render.realistic )
objColor = m_boardAdapter.m_CopperColor;
else
objColor = m_boardAdapter.GetItemColor( LAYER_PADS_TH );
const VECTOR2I drillsize = aPad->GetDrillSize();
const bool hasHole = drillsize.x && drillsize.y;
@@ -1116,11 +1119,12 @@ void RENDER_3D_RAYTRACE_BASE::insertHole( const PAD* aPad )
// Check if there are any other THT that intersects this hole
// It will use the non inflated holes
if( !m_boardAdapter.GetTH_IDs().GetList().empty() )
if( !m_boardAdapter.GetThroughHoleIds().GetList().empty() )
{
CONST_LIST_OBJECT2D intersecting;
m_boardAdapter.GetTH_IDs().GetIntersectingObjects( object2d_A->GetBBox(), intersecting );
m_boardAdapter.GetThroughHoleIds().GetIntersectingObjects( object2d_A->GetBBox(),
intersecting );
for( const OBJECT_2D* hole2d : intersecting )
{
@@ -1164,7 +1168,7 @@ void RENDER_3D_RAYTRACE_BASE::insertHole( const PAD* aPad )
}
void RENDER_3D_RAYTRACE_BASE::addPadsAndVias()
void RENDER_3D_RAYTRACE::addPadsAndVias()
{
if( !m_boardAdapter.GetBoard() )
return;
@@ -1193,13 +1197,12 @@ void RENDER_3D_RAYTRACE_BASE::addPadsAndVias()
}
void RENDER_3D_RAYTRACE_BASE::load3DModels( CONTAINER_3D& aDstContainer, bool aSkipMaterialInformation )
void RENDER_3D_RAYTRACE::load3DModels( CONTAINER_3D& aDstContainer, bool aSkipMaterialInformation )
{
if( !m_boardAdapter.GetBoard() )
return;
if( !m_boardAdapter.m_IsPreviewer
&& !m_boardAdapter.m_Cfg->m_Render.show_footprints_normal
if( !m_boardAdapter.m_Cfg->m_Render.show_footprints_normal
&& !m_boardAdapter.m_Cfg->m_Render.show_footprints_insert
&& !m_boardAdapter.m_Cfg->m_Render.show_footprints_virtual )
{
@@ -1259,8 +1262,8 @@ void RENDER_3D_RAYTRACE_BASE::load3DModels( CONTAINER_3D& aDstContainer, bool aS
{
// FindRow() can throw an exception
const FP_LIB_TABLE_ROW* fpRow =
PROJECT_PCB::PcbFootprintLibs( m_boardAdapter.GetBoard()->GetProject() )
->FindRow( libraryName, false );
m_boardAdapter.GetBoard()->GetProject()->PcbFootprintLibs()->FindRow(
libraryName, false );
if( fpRow )
footprintBasePath = fpRow->GetFullURI( true );
@@ -1315,7 +1318,7 @@ void RENDER_3D_RAYTRACE_BASE::load3DModels( CONTAINER_3D& aDstContainer, bool aS
}
MODEL_MATERIALS* RENDER_3D_RAYTRACE_BASE::getModelMaterial( const S3DMODEL* a3DModel )
MODEL_MATERIALS* RENDER_3D_RAYTRACE::getModelMaterial( const S3DMODEL* a3DModel )
{
MODEL_MATERIALS* materialVector;
@@ -1418,7 +1421,7 @@ MODEL_MATERIALS* RENDER_3D_RAYTRACE_BASE::getModelMaterial( const S3DMODEL* a3DM
}
void RENDER_3D_RAYTRACE_BASE::addModels( CONTAINER_3D& aDstContainer, const S3DMODEL* a3DModel,
void RENDER_3D_RAYTRACE::addModels( CONTAINER_3D& aDstContainer, const S3DMODEL* a3DModel,
const glm::mat4& aModelMatrix, float aFPOpacity,
bool aSkipMaterialInformation, BOARD_ITEM* aBoardItem )
{
+2 -3
View File
@@ -141,8 +141,8 @@ struct RAYSEG2D
bool IntersectSegment( const SFVEC2F &aStartA, const SFVEC2F &aEnd_minus_startA,
const SFVEC2F &aStartB, const SFVEC2F &aEnd_minus_startB );
/*
#if(GLM_ARCH != GLM_ARCH_PURE)
/*
struct RAY4
{
glm::simdVec4 m_orgX; ///< x coordinate of ray origin
@@ -155,10 +155,9 @@ struct RAY4
glm::simdVec4 m_tnear; ///< Start of ray segment
glm::simdVec4 m_tfar; ///< End of ray segment
};
};*/
#endif
*/
#endif // RAY_H
@@ -27,7 +27,7 @@
#include "ray.h"
#include "frustum.h"
#include <gal/3d/camera.h>
#include "../camera.h"
#define RAYPACKET_DIM (1 << 3)
#define RAYPACKET_MASK (unsigned int) ( ( RAYPACKET_DIM - 1 ) )
File diff suppressed because it is too large Load Diff
@@ -0,0 +1,225 @@
/*
* This program source code file is part of KiCad, a free EDA CAD application.
*
* Copyright (C) 2015-2020 Mario Luzeiro <mrluzeiro@ua.pt>
* Copyright (C) 2015-2021 KiCad Developers, see AUTHORS.txt for contributors.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, you may find one here:
* http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
* or you may search the http://www.gnu.org website for the version 2 license,
* or you may write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
*/
#ifndef RENDER_3D_RAYTRACE_H
#define RENDER_3D_RAYTRACE_H
#include "../../common_ogl/openGL_includes.h"
#include "accelerators/container_3d.h"
#include "accelerators/accelerator_3d.h"
#include "../render_3d_base.h"
#include "light.h"
#include "../post_shader_ssao.h"
#include "material.h"
#include <plugins/3dapi/c3dmodel.h>
#include <map>
/// Vector of materials
typedef std::vector< BLINN_PHONG_MATERIAL > MODEL_MATERIALS;
/// Maps a S3DMODEL pointer with a created BLINN_PHONG_MATERIAL vector
typedef std::map< const S3DMODEL* , MODEL_MATERIALS > MAP_MODEL_MATERIALS;
typedef enum
{
RT_RENDER_STATE_TRACING = 0,
RT_RENDER_STATE_POST_PROCESS_SHADE,
RT_RENDER_STATE_POST_PROCESS_BLUR_AND_FINISH,
RT_RENDER_STATE_FINISH,
RT_RENDER_STATE_MAX
} RT_RENDER_STATE;
class RENDER_3D_RAYTRACE : public RENDER_3D_BASE
{
public:
// TODO: Take into account board thickness so that the camera won't move inside of the board
// when facing it perpendicularly.
static constexpr float MIN_DISTANCE_IU = 4 * PCB_IU_PER_MM;
explicit RENDER_3D_RAYTRACE( EDA_3D_CANVAS* aCanvas, BOARD_ADAPTER& aAdapter, CAMERA& aCamera );
~RENDER_3D_RAYTRACE();
void SetCurWindowSize( const wxSize& aSize ) override;
bool Redraw( bool aIsMoving, REPORTER* aStatusReporter, REPORTER* aWarningReporter ) override;
int GetWaitForEditingTimeOut() override;
void Reload( REPORTER* aStatusReporter, REPORTER* aWarningReporter,
bool aOnlyLoadCopperAndShapes );
BOARD_ITEM *IntersectBoardItem( const RAY& aRay );
private:
bool initializeOpenGL();
void initializeNewWindowSize();
void initPbo();
void deletePbo();
void createItemsFromContainer( const BVH_CONTAINER_2D* aContainer2d, PCB_LAYER_ID aLayer_id,
const MATERIAL* aMaterialLayer, const SFVEC3F& aLayerColor,
float aLayerZOffset );
void restartRenderState();
void renderTracing( GLubyte* ptrPBO, REPORTER* aStatusReporter );
void postProcessShading( GLubyte* ptrPBO, REPORTER* aStatusReporter );
void postProcessBlurFinish( GLubyte* ptrPBO, REPORTER* aStatusReporter );
void renderBlockTracing( GLubyte* ptrPBO , signed int iBlock );
void renderFinalColor( GLubyte* ptrPBO, const SFVEC3F& rgbColor,
bool applyColorSpaceConversion );
void renderRayPackets( const SFVEC3F* bgColorY, const RAY* aRayPkt, HITINFO_PACKET* aHitPacket,
bool is_testShadow, SFVEC3F* aOutHitColor );
void renderAntiAliasPackets( const SFVEC3F* aBgColorY, const HITINFO_PACKET* aHitPck_X0Y0,
const HITINFO_PACKET* aHitPck_AA_X1Y1, const RAY* aRayPck,
SFVEC3F* aOutHitColor );
// Materials
void setupMaterials();
SFVEC3F shadeHit( const SFVEC3F& aBgColor, const RAY& aRay, HITINFO& aHitInfo,
bool aIsInsideObject, unsigned int aRecursiveLevel,
bool is_testShadow ) const;
/**
* Create one or more 3D objects form a 2D object and Z positions.
*
* It tries to optimize some types of objects that will be faster to trace than the
* LAYER_ITEM object.
*/
void createObject( CONTAINER_3D& aDstContainer, const OBJECT_2D* aObject2D, float aZMin,
float aZMax, const MATERIAL* aMaterial, const SFVEC3F& aObjColor );
void addPadsAndVias();
void insertHole( const PCB_VIA* aVia );
void insertHole( const PAD* aPad );
void load3DModels( CONTAINER_3D& aDstContainer, bool aSkipMaterialInformation );
void addModels( CONTAINER_3D& aDstContainer, const S3DMODEL* a3DModel,
const glm::mat4& aModelMatrix, float aFPOpacity,
bool aSkipMaterialInformation, BOARD_ITEM* aBoardItem );
MODEL_MATERIALS* getModelMaterial( const S3DMODEL* a3DModel );
void initializeBlockPositions();
void render( GLubyte* ptrPBO, REPORTER* aStatusReporter );
void renderPreview( GLubyte* ptrPBO );
struct
{
BLINN_PHONG_MATERIAL m_Paste;
BLINN_PHONG_MATERIAL m_SilkS;
BLINN_PHONG_MATERIAL m_SolderMask;
BLINN_PHONG_MATERIAL m_EpoxyBoard;
BLINN_PHONG_MATERIAL m_Copper;
BLINN_PHONG_MATERIAL m_NonPlatedCopper;
BLINN_PHONG_MATERIAL m_Floor;
} m_materials;
BOARD_NORMAL m_boardMaterial;
COPPER_NORMAL m_copperMaterial;
PLATED_COPPER_NORMAL m_platedCopperMaterial;
SOLDER_MASK_NORMAL m_solderMaskMaterial;
PLASTIC_NORMAL m_plasticMaterial;
PLASTIC_SHINE_NORMAL m_shinyPlasticMaterial;
BRUSHED_METAL_NORMAL m_brushedMetalMaterial;
SILK_SCREEN_NORMAL m_silkScreenMaterial;
bool m_isPreview;
/// State used on quality render
RT_RENDER_STATE m_renderState;
/// Time that the render starts
unsigned long int m_renderStartTime;
/// Save the number of blocks progress of the render
size_t m_blockRenderProgressCount;
POST_SHADER_SSAO m_postShaderSsao;
std::list<LIGHT*> m_lights;
DIRECTIONAL_LIGHT* m_cameraLight;
bool m_openglSupportsVertexBufferObjects;
GLuint m_pboId;
GLuint m_pboDataSize;
CONTAINER_3D m_objectContainer;
///< Store the list of created objects special for RT that will be clear in the end.
CONTAINER_2D m_containerWithObjectsToDelete;
CONTAINER_2D* m_outlineBoard2dObjects;
BVH_CONTAINER_2D* m_antioutlineBoard2dObjects;
ACCELERATOR_3D* m_accelerator;
SFVEC3F m_backgroundColorTop;
SFVEC3F m_backgroundColorBottom;
///< Used to see if the windows size changed.
wxSize m_oldWindowsSize;
///< Encode Morton code positions.
std::vector< SFVEC2UI > m_blockPositions;
///< Flag if a position was already processed (cleared each new render).
std::vector< int > m_blockPositionsWasProcessed;
///< Encode the Morton code positions (on fast preview mode).
std::vector< SFVEC2UI > m_blockPositionsFast;
SFVEC2UI m_realBufferSize;
SFVEC2UI m_fastPreviewModeSize;
HITINFO_PACKET* m_firstHitinfo;
SFVEC3F* m_shaderBuffer;
// Display Offset
unsigned int m_xoffset;
unsigned int m_yoffset;
/// Stores materials of the 3D models
MAP_MODEL_MATERIALS m_modelMaterialMap;
// Statistics
unsigned int m_convertedDummyBlockCount;
unsigned int m_converted2dRoundSegmentCount;
};
#define USE_SRGB_SPACE
#ifdef USE_SRGB_SPACE
extern SFVEC3F ConvertSRGBToLinear( const SFVEC3F& aSRGBcolor );
#else
#define ConvertSRGBToLinear( v ) ( v )
#endif
#endif // RENDER_3D_RAYTRACE_H
File diff suppressed because it is too large Load Diff
@@ -1,222 +0,0 @@
/*
* This program source code file is part of KiCad, a free EDA CAD application.
*
* Copyright (C) 2015-2020 Mario Luzeiro <mrluzeiro@ua.pt>
* Copyright (C) 2015-2024 KiCad Developers, see AUTHORS.txt for contributors.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, you may find one here:
* http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
* or you may search the http://www.gnu.org website for the version 2 license,
* or you may write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
*/
#ifndef RENDER_3D_RAYTRACE_BASE_H
#define RENDER_3D_RAYTRACE_BASE_H
#include "accelerators/container_3d.h"
#include "accelerators/accelerator_3d.h"
#include "../render_3d_base.h"
#include "light.h"
#include "../post_shader_ssao.h"
#include "material.h"
#include <plugins/3dapi/c3dmodel.h>
#include <map>
/// Vector of materials
typedef std::vector< BLINN_PHONG_MATERIAL > MODEL_MATERIALS;
/// Maps a S3DMODEL pointer with a created BLINN_PHONG_MATERIAL vector
typedef std::map< const S3DMODEL* , MODEL_MATERIALS > MAP_MODEL_MATERIALS;
typedef enum
{
RT_RENDER_STATE_TRACING = 0,
RT_RENDER_STATE_POST_PROCESS_SHADE,
RT_RENDER_STATE_POST_PROCESS_BLUR_AND_FINISH,
RT_RENDER_STATE_FINISH,
RT_RENDER_STATE_MAX
} RT_RENDER_STATE;
class RENDER_3D_RAYTRACE_BASE : public RENDER_3D_BASE
{
public:
// TODO: Take into account board thickness so that the camera won't move inside of the board
// when facing it perpendicularly.
static constexpr float MIN_DISTANCE_IU = 4 * PCB_IU_PER_MM;
explicit RENDER_3D_RAYTRACE_BASE( BOARD_ADAPTER& aAdapter, CAMERA& aCamera );
~RENDER_3D_RAYTRACE_BASE();
int GetWaitForEditingTimeOut() override;
void Reload( REPORTER* aStatusReporter, REPORTER* aWarningReporter,
bool aOnlyLoadCopperAndShapes );
BOARD_ITEM *IntersectBoardItem( const RAY& aRay );
protected:
virtual void initPbo() = 0;
virtual void deletePbo() = 0;
void createItemsFromContainer( const BVH_CONTAINER_2D* aContainer2d, PCB_LAYER_ID aLayer_id,
const MATERIAL* aMaterialLayer, const SFVEC3F& aLayerColor,
float aLayerZOffset );
void restartRenderState();
void renderTracing( GLubyte* ptrPBO, REPORTER* aStatusReporter );
void postProcessShading( GLubyte* ptrPBO, REPORTER* aStatusReporter );
void postProcessBlurFinish( GLubyte* ptrPBO, REPORTER* aStatusReporter );
void renderBlockTracing( GLubyte* ptrPBO , signed int iBlock );
void renderFinalColor( GLubyte* ptrPBO, const SFVEC4F& rgbColor,
bool applyColorSpaceConversion );
void renderRayPackets( const SFVEC4F* bgColorY, const RAY* aRayPkt, HITINFO_PACKET* aHitPacket,
bool is_testShadow, SFVEC4F* aOutHitColor );
void renderAntiAliasPackets( const SFVEC4F* aBgColorY, const HITINFO_PACKET* aHitPck_X0Y0,
const HITINFO_PACKET* aHitPck_AA_X1Y1, const RAY* aRayPck,
SFVEC4F* aOutHitColor );
// Materials
void setupMaterials();
SFVEC4F shadeHit( const SFVEC4F& aBgColor, const RAY& aRay, HITINFO& aHitInfo,
bool aIsInsideObject, unsigned int aRecursiveLevel,
bool is_testShadow ) const;
/**
* Create one or more 3D objects form a 2D object and Z positions.
*
* It tries to optimize some types of objects that will be faster to trace than the
* LAYER_ITEM object.
*/
void createObject( CONTAINER_3D& aDstContainer, const OBJECT_2D* aObject2D, float aZMin,
float aZMax, const MATERIAL* aMaterial, const SFVEC3F& aObjColor );
void addPadsAndVias();
void insertHole( const PCB_VIA* aVia );
void insertHole( const PAD* aPad );
void load3DModels( CONTAINER_3D& aDstContainer, bool aSkipMaterialInformation );
void addModels( CONTAINER_3D& aDstContainer, const S3DMODEL* a3DModel,
const glm::mat4& aModelMatrix, float aFPOpacity,
bool aSkipMaterialInformation, BOARD_ITEM* aBoardItem );
MODEL_MATERIALS* getModelMaterial( const S3DMODEL* a3DModel );
void initializeBlockPositions();
void render( GLubyte* ptrPBO, REPORTER* aStatusReporter );
void renderPreview( GLubyte* ptrPBO );
static SFVEC4F premultiplyAlpha( const SFVEC4F& aInput );
struct
{
BLINN_PHONG_MATERIAL m_Paste;
BLINN_PHONG_MATERIAL m_SilkS;
BLINN_PHONG_MATERIAL m_SolderMask;
BLINN_PHONG_MATERIAL m_EpoxyBoard;
BLINN_PHONG_MATERIAL m_Copper;
BLINN_PHONG_MATERIAL m_NonPlatedCopper;
BLINN_PHONG_MATERIAL m_Floor;
} m_materials;
BOARD_NORMAL m_boardMaterial;
COPPER_NORMAL m_copperMaterial;
PLATED_COPPER_NORMAL m_platedCopperMaterial;
SOLDER_MASK_NORMAL m_solderMaskMaterial;
PLASTIC_NORMAL m_plasticMaterial;
PLASTIC_SHINE_NORMAL m_shinyPlasticMaterial;
BRUSHED_METAL_NORMAL m_brushedMetalMaterial;
SILK_SCREEN_NORMAL m_silkScreenMaterial;
bool m_is_canvas_initialized;
bool m_isPreview;
/// State used on quality render
RT_RENDER_STATE m_renderState;
/// Time that the render starts
int64_t m_renderStartTime;
/// Save the number of blocks progress of the render
size_t m_blockRenderProgressCount;
POST_SHADER_SSAO m_postShaderSsao;
std::list<LIGHT*> m_lights;
DIRECTIONAL_LIGHT* m_cameraLight;
/*GLuint m_pboId;
GLuint m_pboDataSize;*/
CONTAINER_3D m_objectContainer;
///< Store the list of created objects special for RT that will be clear in the end.
CONTAINER_2D m_containerWithObjectsToDelete;
CONTAINER_2D* m_outlineBoard2dObjects;
BVH_CONTAINER_2D* m_antioutlineBoard2dObjects;
ACCELERATOR_3D* m_accelerator;
SFVEC4F m_backgroundColorTop;
SFVEC4F m_backgroundColorBottom;
///< Used to see if the windows size changed.
wxSize m_oldWindowsSize;
///< Encode Morton code positions.
std::vector< SFVEC2UI > m_blockPositions;
///< Flag if a position was already processed (cleared each new render).
std::vector< int > m_blockPositionsWasProcessed;
///< Encode the Morton code positions (on fast preview mode).
std::vector< SFVEC2UI > m_blockPositionsFast;
SFVEC2UI m_realBufferSize;
SFVEC2UI m_fastPreviewModeSize;
HITINFO_PACKET* m_firstHitinfo;
SFVEC3F* m_shaderBuffer;
// Display Offset
unsigned int m_xoffset;
unsigned int m_yoffset;
/// Stores materials of the 3D models
MAP_MODEL_MATERIALS m_modelMaterialMap;
// Statistics
unsigned int m_convertedDummyBlockCount;
unsigned int m_converted2dRoundSegmentCount;
};
#define USE_SRGB_SPACE
#ifdef USE_SRGB_SPACE
extern SFVEC3F ConvertSRGBToLinear( const SFVEC3F& aSRGBcolor );
extern SFVEC4F ConvertSRGBAToLinear( const SFVEC4F& aSRGBAcolor );
#else
#define ConvertSRGBToLinear( v ) ( v )
#define ConvertSRGBAToLinear( v ) ( v )
#endif
#endif // RENDER_3D_RAYTRACE_BASE_H
@@ -1,243 +0,0 @@
/*
* This program source code file is part of KiCad, a free EDA CAD application.
*
* Copyright (C) 2015-2020 Mario Luzeiro <mrluzeiro@ua.pt>
* Copyright (C) 2024 Alex Shvartzkop <dudesuchamazing@gmail.com>
* Copyright (C) 2015-2024 KiCad Developers, see AUTHORS.txt for contributors.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, you may find one here:
* http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
* or you may search the http://www.gnu.org website for the version 2 license,
* or you may write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
*/
#include <gal/opengl/kiglew.h> // Must be included first
#include <algorithm>
#include <atomic>
#include <chrono>
#include <thread>
#include "render_3d_raytrace_gl.h"
#include "../common_ogl/ogl_utils.h"
#include <core/profile.h> // To use GetRunningMicroSecs or another profiling utility
#include <wx/log.h>
RENDER_3D_RAYTRACE_GL::RENDER_3D_RAYTRACE_GL( EDA_3D_CANVAS* aCanvas, BOARD_ADAPTER& aAdapter, CAMERA& aCamera ) :
RENDER_3D_RAYTRACE_BASE( aAdapter, aCamera )
{
wxLogTrace( m_logTrace, wxT( "RENDER_3D_RAYTRACE_GL::RENDER_3D_RAYTRACE_GL" ) );
m_openglSupportsVertexBufferObjects = false;
m_pboId = GL_NONE;
m_pboDataSize = 0;
}
RENDER_3D_RAYTRACE_GL::~RENDER_3D_RAYTRACE_GL()
{
deletePbo();
}
void RENDER_3D_RAYTRACE_GL::deletePbo()
{
// Delete PBO if it was created
if( m_openglSupportsVertexBufferObjects )
{
if( glIsBufferARB( m_pboId ) )
glDeleteBuffers( 1, &m_pboId );
m_pboId = GL_NONE;
}
}
void RENDER_3D_RAYTRACE_GL::SetCurWindowSize( const wxSize& aSize )
{
if( m_windowSize != aSize )
{
m_windowSize = aSize;
glViewport( 0, 0, m_windowSize.x, m_windowSize.y );
initPbo();
}
}
bool RENDER_3D_RAYTRACE_GL::Redraw( bool aIsMoving, REPORTER* aStatusReporter,
REPORTER* aWarningReporter )
{
bool requestRedraw = false;
// Initialize openGL if need
if( !m_canvasInitialized )
{
m_canvasInitialized = true;
//aIsMoving = true;
requestRedraw = true;
// It will assign the first time the windows size, so it will now
// revert to preview mode the first time the Redraw is called
m_oldWindowsSize = m_windowSize;
initializeBlockPositions();
}
std::unique_ptr<BUSY_INDICATOR> busy = CreateBusyIndicator();
// Reload board if it was requested
if( m_reloadRequested )
{
if( aStatusReporter )
aStatusReporter->Report( _( "Loading..." ) );
//aIsMoving = true;
requestRedraw = true;
Reload( aStatusReporter, aWarningReporter, false );
}
// Recalculate constants if windows size was changed
if( m_windowSize != m_oldWindowsSize )
{
m_oldWindowsSize = m_windowSize;
aIsMoving = true;
requestRedraw = true;
initializeBlockPositions();
}
// Clear buffers
glClearColor( 0.0f, 0.0f, 0.0f, 0.0f );
glClearDepth( 1.0f );
glClearStencil( 0x00 );
glClear( GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT );
// 4-byte pixel alignment
glPixelStorei( GL_UNPACK_ALIGNMENT, 4 );
glDisable( GL_STENCIL_TEST );
glDisable( GL_LIGHTING );
glDisable( GL_COLOR_MATERIAL );
glDisable( GL_DEPTH_TEST );
glDisable( GL_TEXTURE_2D );
glDisable( GL_BLEND );
glDisable( GL_MULTISAMPLE );
const bool was_camera_changed = m_camera.ParametersChanged();
if( requestRedraw || aIsMoving || was_camera_changed )
m_renderState = RT_RENDER_STATE_MAX; // Set to an invalid state,
// so it will restart again latter
// This will only render if need, otherwise it will redraw the PBO on the screen again
if( aIsMoving || was_camera_changed )
{
// Set head light (camera view light) with the opposite direction of the camera
if( m_cameraLight )
m_cameraLight->SetDirection( -m_camera.GetDir() );
OglDrawBackground( premultiplyAlpha( m_boardAdapter.m_BgColorTop ),
premultiplyAlpha( m_boardAdapter.m_BgColorBot ) );
// Bind PBO
glBindBufferARB( GL_PIXEL_UNPACK_BUFFER_ARB, m_pboId );
// Get the PBO pixel pointer to write the data
GLubyte* ptrPBO = (GLubyte *)glMapBufferARB( GL_PIXEL_UNPACK_BUFFER_ARB,
GL_WRITE_ONLY_ARB );
if( ptrPBO )
{
renderPreview( ptrPBO );
// release pointer to mapping buffer, this initialize the coping to PBO
glUnmapBufferARB( GL_PIXEL_UNPACK_BUFFER_ARB );
}
glWindowPos2i( m_xoffset, m_yoffset );
}
else
{
// Bind PBO
glBindBufferARB( GL_PIXEL_UNPACK_BUFFER_ARB, m_pboId );
if( m_renderState != RT_RENDER_STATE_FINISH )
{
// Get the PBO pixel pointer to write the data
GLubyte* ptrPBO = (GLubyte *)glMapBufferARB( GL_PIXEL_UNPACK_BUFFER_ARB,
GL_WRITE_ONLY_ARB );
if( ptrPBO )
{
render( ptrPBO, aStatusReporter );
if( m_renderState != RT_RENDER_STATE_FINISH )
requestRedraw = true;
// release pointer to mapping buffer, this initialize the coping to PBO
glUnmapBufferARB( GL_PIXEL_UNPACK_BUFFER_ARB );
}
}
if( m_renderState == RT_RENDER_STATE_FINISH )
{
glClear( GL_COLOR_BUFFER_BIT );
}
glWindowPos2i( m_xoffset, m_yoffset );
}
// This way it will blend the progress rendering with the last buffer. eg:
// if it was called after a openGL.
glEnable( GL_BLEND );
glBlendFunc( GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA );
glEnable( GL_ALPHA_TEST );
glDrawPixels( m_realBufferSize.x, m_realBufferSize.y, GL_RGBA, GL_UNSIGNED_BYTE, 0 );
glBindBufferARB( GL_PIXEL_UNPACK_BUFFER_ARB, 0 );
return requestRedraw;
}
void RENDER_3D_RAYTRACE_GL::initPbo()
{
if( GLEW_ARB_pixel_buffer_object )
{
m_openglSupportsVertexBufferObjects = true;
// Try to delete vbo if it was already initialized
deletePbo();
// Learn about Pixel buffer objects at:
// http://www.songho.ca/opengl/gl_pbo.html
// http://web.eecs.umich.edu/~sugih/courses/eecs487/lectures/25-PBO+Mipmapping.pdf
// "create 2 pixel buffer objects, you need to delete them when program exits.
// glBufferDataARB with NULL pointer reserves only memory space."
// This sets the number of RGBA pixels
m_pboDataSize = m_realBufferSize.x * m_realBufferSize.y * 4;
glGenBuffersARB( 1, &m_pboId );
glBindBufferARB( GL_PIXEL_UNPACK_BUFFER_ARB, m_pboId );
glBufferDataARB( GL_PIXEL_UNPACK_BUFFER_ARB, m_pboDataSize, 0, GL_STREAM_DRAW_ARB );
glBindBufferARB( GL_PIXEL_UNPACK_BUFFER_ARB, 0 );
wxLogTrace( m_logTrace,
wxT( "RENDER_3D_RAYTRACE_GL:: GLEW_ARB_pixel_buffer_object is supported" ) );
}
}
@@ -1,54 +0,0 @@
/*
* This program source code file is part of KiCad, a free EDA CAD application.
*
* Copyright (C) 2015-2020 Mario Luzeiro <mrluzeiro@ua.pt>
* Copyright (C) 2024 Alex Shvartzkop <dudesuchamazing@gmail.com>
* Copyright (C) 2015-2024 KiCad Developers, see AUTHORS.txt for contributors.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, you may find one here:
* http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
* or you may search the http://www.gnu.org website for the version 2 license,
* or you may write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
*/
#ifndef RENDER_3D_RAYTRACE_GL_H
#define RENDER_3D_RAYTRACE_GL_H
#include "../../common_ogl/openGL_includes.h"
#include "render_3d_raytrace_base.h"
class RENDER_3D_RAYTRACE_GL : public RENDER_3D_RAYTRACE_BASE
{
public:
explicit RENDER_3D_RAYTRACE_GL( EDA_3D_CANVAS* aCanvas, BOARD_ADAPTER& aAdapter,
CAMERA& aCamera );
~RENDER_3D_RAYTRACE_GL();
void SetCurWindowSize( const wxSize& aSize ) override;
bool Redraw( bool aIsMoving, REPORTER* aStatusReporter, REPORTER* aWarningReporter ) override;
protected:
void initPbo() override;
void deletePbo() override;
bool m_openglSupportsVertexBufferObjects;
GLuint m_pboId;
GLuint m_pboDataSize;
};
#endif // RENDER_3D_RAYTRACE_GL_H
@@ -1,159 +0,0 @@
/*
* This program source code file is part of KiCad, a free EDA CAD application.
*
* Copyright (C) 2015-2020 Mario Luzeiro <mrluzeiro@ua.pt>
* Copyright (C) 2024 Alex Shvartzkop <dudesuchamazing@gmail.com>
* Copyright (C) 2015-2024 KiCad Developers, see AUTHORS.txt for contributors.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, you may find one here:
* http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
* or you may search the http://www.gnu.org website for the version 2 license,
* or you may write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
*/
#include "render_3d_raytrace_ram.h"
#include <wx/log.h>
RENDER_3D_RAYTRACE_RAM::RENDER_3D_RAYTRACE_RAM( BOARD_ADAPTER& aAdapter, CAMERA& aCamera ) :
RENDER_3D_RAYTRACE_BASE( aAdapter, aCamera ),
m_outputBuffer( nullptr ),
m_pboDataSize( 0 )
{
}
RENDER_3D_RAYTRACE_RAM::~RENDER_3D_RAYTRACE_RAM()
{
deletePbo();
}
GLubyte* RENDER_3D_RAYTRACE_RAM::GetBuffer()
{
return m_outputBuffer;
}
wxSize RENDER_3D_RAYTRACE_RAM::GetRealBufferSize()
{
return wxSize( m_realBufferSize.x, m_realBufferSize.y );
}
void RENDER_3D_RAYTRACE_RAM::deletePbo()
{
delete[] m_outputBuffer;
m_outputBuffer = nullptr;
}
void RENDER_3D_RAYTRACE_RAM::SetCurWindowSize( const wxSize& aSize )
{
if( m_windowSize != aSize )
{
m_windowSize = aSize;
initPbo();
}
}
bool RENDER_3D_RAYTRACE_RAM::Redraw( bool aIsMoving, REPORTER* aStatusReporter,
REPORTER* aWarningReporter )
{
bool requestRedraw = false;
// Initialize openGL if need
if( !m_canvasInitialized )
{
m_canvasInitialized = true;
//aIsMoving = true;
requestRedraw = true;
// It will assign the first time the windows size, so it will now
// revert to preview mode the first time the Redraw is called
m_oldWindowsSize = m_windowSize;
initializeBlockPositions();
}
std::unique_ptr<BUSY_INDICATOR> busy = CreateBusyIndicator();
// Reload board if it was requested
if( m_reloadRequested )
{
if( aStatusReporter )
aStatusReporter->Report( _( "Loading..." ) );
//aIsMoving = true;
requestRedraw = true;
Reload( aStatusReporter, aWarningReporter, false );
}
// Recalculate constants if windows size was changed
if( m_windowSize != m_oldWindowsSize )
{
m_oldWindowsSize = m_windowSize;
aIsMoving = true;
requestRedraw = true;
initializeBlockPositions();
}
const bool was_camera_changed = m_camera.ParametersChanged();
if( requestRedraw || aIsMoving || was_camera_changed )
m_renderState = RT_RENDER_STATE_MAX; // Set to an invalid state,
// so it will restart again latter
// This will only render if need, otherwise it will redraw the PBO on the screen again
if( aIsMoving || was_camera_changed )
{
// Set head light (camera view light) with the opposite direction of the camera
if( m_cameraLight )
m_cameraLight->SetDirection( -m_camera.GetDir() );
if( m_outputBuffer )
{
renderPreview( m_outputBuffer );
}
}
else
{
if( m_renderState != RT_RENDER_STATE_FINISH )
{
if( m_outputBuffer )
{
render( m_outputBuffer, aStatusReporter );
if( m_renderState != RT_RENDER_STATE_FINISH )
requestRedraw = true;
}
}
}
return requestRedraw;
}
void RENDER_3D_RAYTRACE_RAM::initPbo()
{
deletePbo();
m_pboDataSize = m_realBufferSize.x * m_realBufferSize.y * 4;
m_outputBuffer = new GLubyte[m_pboDataSize]();
}
@@ -1,58 +0,0 @@
/*
* This program source code file is part of KiCad, a free EDA CAD application.
*
* Copyright (C) 2015-2020 Mario Luzeiro <mrluzeiro@ua.pt>
* Copyright (C) 2024 Alex Shvartzkop <dudesuchamazing@gmail.com>
* Copyright (C) 2015-2024 KiCad Developers, see AUTHORS.txt for contributors.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, you may find one here:
* http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
* or you may search the http://www.gnu.org website for the version 2 license,
* or you may write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
*/
#ifndef RENDER_3D_RAYTRACE_RAM_H
#define RENDER_3D_RAYTRACE_RAM_H
#include "render_3d_raytrace_base.h"
class RENDER_3D_RAYTRACE_RAM : public RENDER_3D_RAYTRACE_BASE
{
public:
// TODO: Take into account board thickness so that the camera won't move inside of the board
// when facing it perpendicularly.
static constexpr float MIN_DISTANCE_IU = 4 * PCB_IU_PER_MM;
explicit RENDER_3D_RAYTRACE_RAM( BOARD_ADAPTER& aAdapter, CAMERA& aCamera );
~RENDER_3D_RAYTRACE_RAM();
GLubyte* GetBuffer();
wxSize GetRealBufferSize();
void SetCurWindowSize( const wxSize& aSize ) override;
bool Redraw( bool aIsMoving, REPORTER* aStatusReporter, REPORTER* aWarningReporter ) override;
private:
void initPbo() override;
void deletePbo() override;
GLubyte* m_outputBuffer;
GLuint m_pboDataSize;
};
#endif // RENDER_3D_RAYTRACE_RAM_H
@@ -31,7 +31,6 @@
#include "object_2d.h"
#include "../ray.h"
#include "filled_circle_2d.h"
#include <plugins/3dapi/xv3d_types.h> // SFVEC2F
class BOARD_ITEM;
@@ -31,7 +31,6 @@
#define _BBOX_3D_H_
#include <plugins/3dapi/xv3d_types.h> // SFVEC2F
#include <glm/mat4x4.hpp>
struct RAY;
@@ -23,7 +23,8 @@
*/
/**
* @file cylinder_3d.cpp
* @file ccylinder.cpp
* @brief
*/
#include "3d_fastmath.h"
@@ -23,7 +23,8 @@
*/
/**
* @file object_3d.cpp
* @file cobject.cpp
* @brief
*/
#include "object_3d.h"
@@ -52,7 +52,7 @@ class OBJECT_3D
public:
explicit OBJECT_3D( OBJECT_3D_TYPE aObjType );
void SetBoardItem( BOARD_ITEM* aBoardItem ) { m_boardItem = aBoardItem; }
const void SetBoardItem( BOARD_ITEM* aBoardItem ) { m_boardItem = aBoardItem; }
BOARD_ITEM* GetBoardItem() const { return m_boardItem; }
void SetMaterial( const MATERIAL* aMaterial )
+4 -3
View File
@@ -2,7 +2,7 @@
* This program source code file is part of KiCad, a free EDA CAD application.
*
* Copyright (C) 2015-2016 Mario Luzeiro <mrluzeiro@ua.pt>
* Copyright (C) 1992-2024 KiCad Developers, see AUTHORS.txt for contributors.
* Copyright (C) 1992-2016 KiCad Developers, see AUTHORS.txt for contributors.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
@@ -44,12 +44,13 @@
const wxChar* RENDER_3D_BASE::m_logTrace = wxT( "KI_TRACE_3D_RENDER" );
RENDER_3D_BASE::RENDER_3D_BASE( BOARD_ADAPTER& aBoardAdapter, CAMERA& aCamera ) :
RENDER_3D_BASE::RENDER_3D_BASE( EDA_3D_CANVAS* aCanvas, BOARD_ADAPTER& aBoardAdapter, CAMERA& aCamera ) :
m_boardAdapter( aBoardAdapter ),
m_camera( aCamera )
{
wxLogTrace( m_logTrace, wxT( "RENDER_3D_BASE::RENDER_3D_BASE" ) );
m_canvasInitialized = false;
m_canvas = aCanvas;
m_is_opengl_initialized = false;
m_windowSize = wxSize( -1, -1 );
m_reloadRequested = true;
}
+7 -4
View File
@@ -2,7 +2,7 @@
* This program source code file is part of KiCad, a free EDA CAD application.
*
* Copyright (C) 2015-2016 Mario Luzeiro <mrluzeiro@ua.pt>
* Copyright (C) 1992-2024 KiCad Developers, see AUTHORS.txt for contributors.
* Copyright (C) 1992-2016 KiCad Developers, see AUTHORS.txt for contributors.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
@@ -42,7 +42,7 @@
class RENDER_3D_BASE
{
public:
explicit RENDER_3D_BASE( BOARD_ADAPTER& aBoardAdapter, CAMERA& aCamera );
explicit RENDER_3D_BASE( EDA_3D_CANVAS* aCanvas, BOARD_ADAPTER& aBoardAdapter, CAMERA& aCamera );
virtual ~RENDER_3D_BASE() = 0;
@@ -98,13 +98,16 @@ protected:
*/
std::unique_ptr<BUSY_INDICATOR> CreateBusyIndicator() const;
///< the canvas to display the scene
EDA_3D_CANVAS* m_canvas;
///< Settings reference in use for this render.
BOARD_ADAPTER& m_boardAdapter;
CAMERA& m_camera;
///< Flag if the canvas specific for this render was already initialized.
bool m_canvasInitialized;
///< Flag if the opengl specific for this render was already initialized.
bool m_is_opengl_initialized;
///< @todo This must be reviewed in order to flag change types.
bool m_reloadRequested;
+4 -18
View File
@@ -2,7 +2,7 @@
* This program source code file is part of KiCad, a free EDA CAD application.
*
* Copyright (C) 2015-2016 Mario Luzeiro <mrluzeiro@ua.pt>
* Copyright (C) 2015-2024 KiCad Developers, see AUTHORS.txt for contributors.
* Copyright (C) 2015-2020 KiCad Developers, see AUTHORS.txt for contributors.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
@@ -23,7 +23,7 @@
*/
/**
* @file track_ball.cpp
* @file ctrack_ball.cpp
* @brief Implementation of a track ball camera. A track ball is placed in the
* center of the screen and rotates the camera.
*/
@@ -38,24 +38,11 @@
// stdlib
#include <algorithm>
TRACK_BALL::TRACK_BALL( float aInitialDistance ) : CAMERA( aInitialDistance )
TRACK_BALL::TRACK_BALL( float aInitialDistance ) :
CAMERA( aInitialDistance )
{
wxLogTrace( m_logTrace, wxT( "TRACK_BALL::TRACK_BALL" ) );
initQuat();
}
TRACK_BALL::TRACK_BALL( SFVEC3F aInitPos, SFVEC3F aLookat, PROJECTION_TYPE aProjectionType ) :
CAMERA( aInitPos, aLookat, aProjectionType )
{
wxLogTrace( m_logTrace, wxT( "TRACK_BALL::TRACK_BALL" ) );
initQuat();
}
void TRACK_BALL::initQuat()
{
memset( m_quat_t0, 0, sizeof( m_quat_t0 ) );
memset( m_quat_t1, 0, sizeof( m_quat_t1 ) );
@@ -63,7 +50,6 @@ void TRACK_BALL::initQuat()
trackball( m_quat_t1, 0.0, 0.0, 0.0, 0.0 );
}
void TRACK_BALL::Drag( const wxPoint& aNewMousePosition )
{
m_parametersChanged = true;
+2 -5
View File
@@ -2,7 +2,7 @@
* This program source code file is part of KiCad, a free EDA CAD application.
*
* Copyright (C) 2015-2016 Mario Luzeiro <mrluzeiro@ua.pt>
* Copyright (C) 2015-2024 KiCad Developers, see AUTHORS.txt for contributors.
* Copyright (C) 2015-2020 KiCad Developers, see AUTHORS.txt for contributors.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
@@ -30,14 +30,13 @@
#ifndef TRACK_BALL_H
#define TRACK_BALL_H
#include <gal/3d/camera.h>
#include "camera.h"
class TRACK_BALL : public CAMERA
{
public:
explicit TRACK_BALL( float aInitialDistance );
explicit TRACK_BALL( SFVEC3F aInitPos, SFVEC3F aLookat, PROJECTION_TYPE aProjectionType );
virtual ~TRACK_BALL()
{
@@ -58,8 +57,6 @@ public:
void Interpolate( float t ) override;
private:
void initQuat();
/**
* interpolate quaternions of the trackball
*/
+30 -24
View File
@@ -4,8 +4,7 @@
* Copyright (C) 2016 Mario Luzeiro <mrluzeiro@ua.pt>
* Copyright (C) 2015 Jean-Pierre Charras, jp.charras at wanadoo.fr
* Copyright (C) 2013 Wayne Stambaugh <stambaughw@gmail.com>
* Copyright (C) 2023 CERN
* Copyright (C) 1992-2023 KiCad Developers, see AUTHORS.txt for contributors.
* Copyright (C) 1992-2021 KiCad Developers, see AUTHORS.txt for contributors.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
@@ -28,6 +27,7 @@
#include <bitmaps.h>
#include <tool/conditional_menu.h>
#include <eda_3d_viewer_frame.h>
#include <menus_helpers.h>
#include <3d_viewer_id.h>
#include <3d_viewer/tools/eda_3d_actions.h>
#include <tool/tool_manager.h>
@@ -35,12 +35,11 @@
#include <widgets/wx_menubar.h>
void EDA_3D_VIEWER_FRAME::doReCreateMenuBar()
void EDA_3D_VIEWER_FRAME::CreateMenuBar()
{
wxLogTrace( m_logTrace, wxT( "EDA_3D_VIEWER_FRAME::CreateMenuBar" ) );
COMMON_CONTROL* tool = m_toolManager->GetTool<COMMON_CONTROL>();
wxMenuBar* oldMenuBar = GetMenuBar();
WX_MENUBAR* menuBar = new WX_MENUBAR();
@@ -82,20 +81,6 @@ void EDA_3D_VIEWER_FRAME::doReCreateMenuBar()
viewMenu->Add( ACTIONS::zoomFitScreen );
viewMenu->Add( ACTIONS::zoomRedraw );
// Grid submenu
ACTION_MENU* gridSubmenu = new ACTION_MENU( false, tool );
gridSubmenu->SetTitle( _( "3D Grid" ) );
gridSubmenu->SetIcon( BITMAPS::grid );
gridSubmenu->Add( EDA_3D_ACTIONS::noGrid, ACTION_MENU::CHECK);
gridSubmenu->Add( EDA_3D_ACTIONS::show10mmGrid, ACTION_MENU::CHECK);
gridSubmenu->Add( EDA_3D_ACTIONS::show5mmGrid, ACTION_MENU::CHECK);
gridSubmenu->Add( EDA_3D_ACTIONS::show2_5mmGrid, ACTION_MENU::CHECK);
gridSubmenu->Add( EDA_3D_ACTIONS::show1mmGrid, ACTION_MENU::CHECK);
viewMenu->AppendSeparator();
viewMenu->Add( gridSubmenu );
viewMenu->AppendSeparator();
viewMenu->Add( EDA_3D_ACTIONS::rotateXCW );
viewMenu->Add( EDA_3D_ACTIONS::rotateXCCW );
@@ -114,9 +99,6 @@ void EDA_3D_VIEWER_FRAME::doReCreateMenuBar()
viewMenu->Add( EDA_3D_ACTIONS::moveUp );
viewMenu->Add( EDA_3D_ACTIONS::moveDown );
viewMenu->AppendSeparator();
viewMenu->Add( EDA_3D_ACTIONS::showLayersManager, ACTION_MENU::CHECK );
//-- Preferences menu -----------------------------------------------
//
@@ -127,12 +109,37 @@ void EDA_3D_VIEWER_FRAME::doReCreateMenuBar()
BITMAPS::tools,
ACTION_MENU::CHECK );
prefsMenu->Add( ACTIONS::openPreferences );
prefsMenu->Add( _( "Preferences..." ) + wxT( "\tCtrl+," ),
_( "Show preferences for all open tools" ),
wxID_PREFERENCES,
BITMAPS::preference );
prefsMenu->Add( _( "Reset to Default Settings" ), ID_MENU3D_RESET_DEFAULTS, BITMAPS::tools );
prefsMenu->AppendSeparator();
AddMenuLanguageList( prefsMenu, tool );
prefsMenu->Add( EDA_3D_ACTIONS::showTHT, ACTION_MENU::CHECK );
prefsMenu->Add( EDA_3D_ACTIONS::showSMD, ACTION_MENU::CHECK );
prefsMenu->Add( EDA_3D_ACTIONS::showVirtual, ACTION_MENU::CHECK );
prefsMenu->Add( EDA_3D_ACTIONS::showNotInPosFile, ACTION_MENU::CHECK );
prefsMenu->AppendSeparator();
prefsMenu->Add( EDA_3D_ACTIONS::showAxis, ACTION_MENU::CHECK );
prefsMenu->Add( EDA_3D_ACTIONS::showBBoxes, ACTION_MENU::CHECK );
// Grid submenu
ACTION_MENU* gridSubmenu = new ACTION_MENU( false, tool );
gridSubmenu->SetTitle( _( "3D Grid" ) );
gridSubmenu->SetIcon( BITMAPS::grid );
gridSubmenu->Add( EDA_3D_ACTIONS::noGrid, ACTION_MENU::CHECK);
gridSubmenu->Add( EDA_3D_ACTIONS::show10mmGrid, ACTION_MENU::CHECK);
gridSubmenu->Add( EDA_3D_ACTIONS::show5mmGrid, ACTION_MENU::CHECK);
gridSubmenu->Add( EDA_3D_ACTIONS::show2_5mmGrid, ACTION_MENU::CHECK);
gridSubmenu->Add( EDA_3D_ACTIONS::show1mmGrid, ACTION_MENU::CHECK);
prefsMenu->Add( gridSubmenu );
//-- Menubar -------------------------------------------------------------
//
@@ -143,5 +150,4 @@ void EDA_3D_VIEWER_FRAME::doReCreateMenuBar()
AddStandardHelpMenu( menuBar );
SetMenuBar( menuBar );
delete oldMenuBar;
}
+39 -7
View File
@@ -4,8 +4,7 @@
* Copyright (C) 2016 Mario Luzeiro <mrluzeiro@ua.pt>
* Copyright (C) 2015 Jean-Pierre Charras, jp.charras at wanadoo.fr
* Copyright (C) 2013 Wayne Stambaugh <stambaughw@gmail.com>
* Copyright (C) 2023 CERN
* Copyright (C) 1992-2024 KiCad Developers, see AUTHORS.txt for contributors.
* Copyright (C) 1992-2022 KiCad Developers, see AUTHORS.txt for contributors.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
@@ -31,6 +30,7 @@
#include <bitmaps.h>
#include <dialogs/eda_view_switcher.h>
#include <eda_3d_viewer_frame.h>
#include <menus_helpers.h>
#include <tool/action_toolbar.h>
#include <tools/eda_3d_actions.h>
#include <3d_viewer_id.h>
@@ -52,19 +52,44 @@ void EDA_3D_VIEWER_FRAME::ReCreateMainToolbar()
m_mainToolBar->SetAuiManager( &m_auimgr );
}
// Show the hotkey to open the windows list selector:
wxString keyName = KeyNameFromKeyCode( VIEWPORT_SWITCH_KEY );
m_viewportsLabel = new wxStaticText( m_mainToolBar, wxID_ANY,
wxString::Format( _( "Viewports (%s+Tab):" ), keyName ) );
m_viewportsLabel->Wrap( -1 );
m_cbViewports = new wxChoice( m_mainToolBar, wxID_ANY );
for( std::pair<const wxString, VIEWPORT3D>& pair : m_viewports )
m_cbViewports->Append( pair.first, static_cast<void*>( &pair.second ) );
m_cbViewports->Append( wxT( "---" ) );
m_cbViewports->Append( _( "Save viewport..." ) );
m_cbViewports->Append( _( "Delete viewport..." ) );
m_cbViewports->SetToolTip( wxString::Format( _( "Save and restore view orientation and zoom.\n"
"Use %s+Tab to activate selector.\n"
"Successive Tabs while holding %s down will "
"cycle through viewports in the popup." ),
keyName, keyName ) );
m_cbViewports->SetSelection( m_cbViewports->GetCount() - 3 );
m_lastSelectedViewport = nullptr;
// Set up toolbar
m_mainToolBar->AddTool( ID_RELOAD3D_BOARD, wxEmptyString,
KiBitmapBundle( BITMAPS::import3d ),
_( "Reload board" ) );
KiScaledBitmap( BITMAPS::import3d, this ), _( "Reload board" ) );
m_mainToolBar->AddScaledSeparator( this );
m_mainToolBar->AddTool( ID_TOOL_SCREENCOPY_TOCLIBBOARD, wxEmptyString,
KiBitmapBundle( BITMAPS::copy ),
KiScaledBitmap( BITMAPS::copy, this ),
_( "Copy 3D image to clipboard" ) );
m_mainToolBar->AddScaledSeparator( this );
m_mainToolBar->AddTool( ID_RENDER_CURRENT_VIEW, wxEmptyString,
KiBitmapBundle( BITMAPS::render_mode ),
KiScaledBitmap( BITMAPS::render_mode, this ),
_( "Render current view using Raytracing" ), wxITEM_CHECK );
m_mainToolBar->AddScaledSeparator( this );
@@ -98,7 +123,14 @@ void EDA_3D_VIEWER_FRAME::ReCreateMainToolbar()
m_mainToolBar->Add( EDA_3D_ACTIONS::toggleOrtho, ACTION_TOOLBAR::TOGGLE );
m_mainToolBar->AddScaledSeparator( this );
m_mainToolBar->Add( EDA_3D_ACTIONS::showLayersManager, ACTION_TOOLBAR::TOGGLE );
m_mainToolBar->Add( EDA_3D_ACTIONS::showTHT, ACTION_TOOLBAR::TOGGLE );
m_mainToolBar->Add( EDA_3D_ACTIONS::showSMD, ACTION_TOOLBAR::TOGGLE );
m_mainToolBar->Add( EDA_3D_ACTIONS::showVirtual, ACTION_TOOLBAR::TOGGLE );
m_mainToolBar->Add( EDA_3D_ACTIONS::showNotInPosFile, ACTION_TOOLBAR::TOGGLE );
m_mainToolBar->AddScaledSeparator( this );
m_mainToolBar->AddControl( m_viewportsLabel );
m_mainToolBar->AddControl( m_cbViewports );
m_mainToolBar->KiRealize();
}
+261 -223
View File
@@ -2,8 +2,7 @@
* This program source code file is part of KiCad, a free EDA CAD application.
*
* Copyright (C) 2015-2016 Mario Luzeiro <mrluzeiro@ua.pt>
* Copyright (C) 2023 CERN
* Copyright (C) 1992-2024 KiCad Developers, see AUTHORS.txt for contributors.
* Copyright (C) 1992-2023 KiCad Developers, see AUTHORS.txt for contributors.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
@@ -29,21 +28,21 @@
#include <wx/wupdlock.h>
#include <wx/clipbrd.h>
#include <wx/filedlg.h>
#include <wx/choice.h>
#include <wx/dialog.h>
#include "eda_3d_viewer_frame.h"
#include "dialogs/appearance_controls_3D.h"
#include "eda_list_dialog.h"
#include "wx/generic/textdlgg.h"
#include <dialogs/eda_view_switcher.h>
#include <eda_3d_viewer_settings.h>
#include <3d_viewer_id.h>
#include <3d_viewer/tools/eda_3d_actions.h>
#include <3d_viewer/tools/eda_3d_controller.h>
#include <3d_viewer/tools/eda_3d_conditions.h>
#include <board.h>
#include <advanced_config.h>
#include <bitmaps.h>
#include <board_design_settings.h>
#include <core/arraydim.h>
#include <dpi_scaling_common.h>
#include <gal/dpi_scaling.h>
#include <pgm_base.h>
#include <project.h>
#include <project/project_file.h>
@@ -55,11 +54,11 @@
#include <tool/tool_dispatcher.h>
#include <tool/action_toolbar.h>
#include <widgets/wx_infobar.h>
#include <widgets/wx_aui_utils.h>
#include <wildcards_and_files_ext.h>
#include <project_pcb.h>
#if defined( KICAD_USE_3DCONNEXION )
#include <3d_navlib/nl_3d_viewer_plugin.h>
#endif
/**
* Flag to enable 3D viewer main frame window debug tracing.
@@ -91,11 +90,10 @@ EDA_3D_VIEWER_FRAME::EDA_3D_VIEWER_FRAME( KIWAY* aKiway, PCB_BASE_FRAME* aParent
const wxString& aTitle, long style ) :
KIWAY_PLAYER( aKiway, aParent, FRAME_PCB_DISPLAY3D, aTitle, wxDefaultPosition,
wxDefaultSize, style, QUALIFIED_VIEWER3D_FRAMENAME( aParent ), unityScale ),
m_mainToolBar( nullptr ),
m_canvas( nullptr ),
m_currentCamera( m_trackBallCamera ),
m_trackBallCamera( 2 * RANGE_SCALE_3D ),
m_spaceMouse( nullptr )
m_mainToolBar( nullptr ), m_canvas( nullptr ), m_currentCamera( m_trackBallCamera ),
m_viewportsLabel( nullptr ),
m_cbViewports( nullptr ),
m_trackBallCamera( 2 * RANGE_SCALE_3D ), m_spaceMouse( nullptr )
{
wxLogTrace( m_logTrace, wxT( "EDA_3D_VIEWER_FRAME::EDA_3D_VIEWER_FRAME %s" ), aTitle );
@@ -108,7 +106,7 @@ EDA_3D_VIEWER_FRAME::EDA_3D_VIEWER_FRAME( KIWAY* aKiway, PCB_BASE_FRAME* aParent
SetIcon( icon );
// Create the status line
static const int status_dims[5] = { -1, 170, 130, 130, 130 };
static const int status_dims[4] = { -1, 170, 130, 130 };
wxStatusBar *status_bar = CreateStatusBar( arrayDim( status_dims ) );
SetStatusWidths( arrayDim( status_dims ), status_dims );
@@ -117,16 +115,13 @@ EDA_3D_VIEWER_FRAME::EDA_3D_VIEWER_FRAME( KIWAY* aKiway, PCB_BASE_FRAME* aParent
EDA_3D_VIEWER_SETTINGS* cfg = mgr.GetAppSettings<EDA_3D_VIEWER_SETTINGS>();
ANTIALIASING_MODE aaMode = static_cast<ANTIALIASING_MODE>( cfg->m_Render.opengl_AA_mode );
m_canvas = new EDA_3D_CANVAS( this, OGL_ATT_LIST::GetAttributesList( aaMode, true ),
m_boardAdapter, m_currentCamera,
PROJECT_PCB::Get3DCacheManager( &Prj() ) );
m_appearancePanel = new APPEARANCE_CONTROLS_3D( this, GetCanvas() );
m_canvas = new EDA_3D_CANVAS( this, OGL_ATT_LIST::GetAttributesList( aaMode ),
m_boardAdapter, m_currentCamera, Prj().Get3DCacheManager() );
LoadSettings( cfg );
loadCommonSettings();
m_appearancePanel->SetUserViewports( Prj().GetProjectFile().m_Viewports3D );
SetUserViewports( Prj().GetProjectFile().m_Viewports3D );
// Create the manager
m_toolManager = new TOOL_MANAGER;
@@ -149,30 +144,16 @@ EDA_3D_VIEWER_FRAME::EDA_3D_VIEWER_FRAME( KIWAY* aKiway, PCB_BASE_FRAME* aParent
// Run the viewer control tool, it is supposed to be always active
m_toolManager->InvokeTool( "3DViewer.Control" );
ReCreateMenuBar();
CreateMenuBar();
ReCreateMainToolbar();
m_infoBar = new WX_INFOBAR( this, &m_auimgr );
m_auimgr.SetManagedWindow( this );
m_auimgr.AddPane( m_mainToolBar, EDA_PANE().HToolbar().Name( wxS( "MainToolbar" ) )
.Top().Layer( 6 ) );
m_auimgr.AddPane( m_infoBar, EDA_PANE().InfoBar().Name( wxS( "InfoBar" ) )
.Top().Layer( 1 ) );
m_auimgr.AddPane( m_appearancePanel, EDA_PANE().Name( "LayersManager" )
.Right().Layer( 3 )
.Caption( _( "Appearance" ) ).PaneBorder( false )
.MinSize( 180, -1 ).BestSize( 190, -1 ) );
m_auimgr.AddPane( m_canvas, EDA_PANE().Canvas().Name( wxS( "DrawFrame" ) )
.Center() );
wxAuiPaneInfo& layersManager = m_auimgr.GetPane( "LayersManager" );
if( cfg->m_AuiPanels.right_panel_width > 0 )
SetAuiPaneSize( m_auimgr, layersManager, cfg->m_AuiPanels.right_panel_width, -1 );
layersManager.Show( cfg->m_AuiPanels.show_layer_manager );
m_auimgr.AddPane( m_mainToolBar, EDA_PANE().HToolbar().Name( wxS( "MainToolbar" ) ).Top().Layer( 6 ) );
m_auimgr.AddPane( m_infoBar, EDA_PANE().InfoBar().Name( wxS( "InfoBar" ) ).Top().Layer( 1 ) );
m_auimgr.AddPane( m_canvas, EDA_PANE().Canvas().Name( wxS( "DrawFrame" ) ).Center() );
// Call Update() to fix all pane default sizes, especially the "InfoBar" pane before
// hiding it.
@@ -185,6 +166,7 @@ EDA_3D_VIEWER_FRAME::EDA_3D_VIEWER_FRAME( KIWAY* aKiway, PCB_BASE_FRAME* aParent
m_canvas->SetInfoBar( m_infoBar );
m_canvas->SetStatusBar( status_bar );
#if defined( KICAD_USE_3DCONNEXION )
try
{
m_spaceMouse = new NL_3D_VIEWER_PLUGIN( m_canvas );
@@ -193,19 +175,39 @@ EDA_3D_VIEWER_FRAME::EDA_3D_VIEWER_FRAME( KIWAY* aKiway, PCB_BASE_FRAME* aParent
{
wxLogTrace( wxT( "KI_TRACE_NAVLIB" ), e.what() );
}
#endif
// Fixes bug in Windows (XP and possibly others) where the canvas requires the focus
// in order to receive mouse events. Otherwise, the user has to click somewhere on
// the canvas before it will respond to mouse wheel events.
m_canvas->SetFocus();
m_cbViewports->Connect( wxEVT_COMMAND_CHOICE_SELECTED,
wxCommandEventHandler( EDA_3D_VIEWER_FRAME::onViewportChanged ),
nullptr, this );
m_cbViewports->Connect( wxEVT_UPDATE_UI,
wxUpdateUIEventHandler( EDA_3D_VIEWER_FRAME::onUpdateViewportsCb ),
nullptr, this );
}
EDA_3D_VIEWER_FRAME::~EDA_3D_VIEWER_FRAME()
{
delete m_spaceMouse;
#if defined( KICAD_USE_3DCONNEXION )
if( m_spaceMouse != nullptr )
{
delete m_spaceMouse;
}
#endif
Prj().GetProjectFile().m_Viewports3D = m_appearancePanel->GetUserViewports();
Prj().GetProjectFile().m_Viewports3D = GetUserViewports();
m_cbViewports->Disconnect( wxEVT_COMMAND_CHOICE_SELECTED,
wxCommandEventHandler( EDA_3D_VIEWER_FRAME::onViewportChanged ),
nullptr, this );
m_cbViewports->Disconnect( wxEVT_UPDATE_UI,
wxUpdateUIEventHandler( EDA_3D_VIEWER_FRAME::onUpdateViewportsCb ),
nullptr, this );
m_canvas->SetEventDispatcher( nullptr );
@@ -248,15 +250,10 @@ void EDA_3D_VIEWER_FRAME::setupUIConditions()
{
return m_boardAdapter.m_Cfg->m_Render.show_footprints_not_in_posfile;
};
auto show_DNP =
[this]( const SELECTION& aSel )
{
return m_boardAdapter.m_Cfg->m_Render.show_footprints_dnp;
};
auto showBBoxes =
[this]( const SELECTION& aSel )
{
return m_boardAdapter.m_Cfg->m_Render.show_model_bbox;
return m_boardAdapter.m_Cfg->m_Render.opengl_show_model_bbox;
};
auto showAxes =
[this]( const SELECTION& aSel )
@@ -269,31 +266,23 @@ void EDA_3D_VIEWER_FRAME::setupUIConditions()
return m_currentCamera.GetProjection() == PROJECTION_TYPE::ORTHO;
};
auto appearances =
[this]( const SELECTION& aSel )
{
return m_boardAdapter.m_Cfg->m_AuiPanels.show_layer_manager;
};
RegisterUIUpdateHandler( ID_RENDER_CURRENT_VIEW, ACTION_CONDITIONS().Check( raytracing ) );
RegisterUIUpdateHandler( ID_RENDER_CURRENT_VIEW, ACTION_CONDITIONS().Check( raytracing ) );
mgr->SetConditions( EDA_3D_ACTIONS::showTHT, ACTION_CONDITIONS().Check( showTH ) );
mgr->SetConditions( EDA_3D_ACTIONS::showSMD, ACTION_CONDITIONS().Check( showSMD ) );
mgr->SetConditions( EDA_3D_ACTIONS::showVirtual, ACTION_CONDITIONS().Check( showVirtual ) );
mgr->SetConditions( EDA_3D_ACTIONS::showNotInPosFile, ACTION_CONDITIONS().Check( show_NotInPosfile ) );
mgr->SetConditions( EDA_3D_ACTIONS::showTHT, ACTION_CONDITIONS().Check( showTH ) );
mgr->SetConditions( EDA_3D_ACTIONS::showSMD, ACTION_CONDITIONS().Check( showSMD ) );
mgr->SetConditions( EDA_3D_ACTIONS::showVirtual, ACTION_CONDITIONS().Check( showVirtual ) );
mgr->SetConditions( EDA_3D_ACTIONS::showNotInPosFile, ACTION_CONDITIONS().Check( show_NotInPosfile ) );
mgr->SetConditions( EDA_3D_ACTIONS::showDNP, ACTION_CONDITIONS().Check( show_DNP ) );
mgr->SetConditions( EDA_3D_ACTIONS::showBBoxes, ACTION_CONDITIONS().Check( showBBoxes ) );
mgr->SetConditions( EDA_3D_ACTIONS::showAxis, ACTION_CONDITIONS().Check( showAxes ) );
mgr->SetConditions( EDA_3D_ACTIONS::showBBoxes, ACTION_CONDITIONS().Check( showBBoxes ) );
mgr->SetConditions( EDA_3D_ACTIONS::showAxis, ACTION_CONDITIONS().Check( showAxes ) );
mgr->SetConditions( EDA_3D_ACTIONS::noGrid, GridSizeCheck( GRID3D_TYPE::NONE ) );
mgr->SetConditions( EDA_3D_ACTIONS::show10mmGrid, GridSizeCheck( GRID3D_TYPE::GRID_10MM ) );
mgr->SetConditions( EDA_3D_ACTIONS::show5mmGrid, GridSizeCheck( GRID3D_TYPE::GRID_5MM ) );
mgr->SetConditions( EDA_3D_ACTIONS::show2_5mmGrid, GridSizeCheck( GRID3D_TYPE::GRID_2P5MM ) );
mgr->SetConditions( EDA_3D_ACTIONS::show1mmGrid, GridSizeCheck( GRID3D_TYPE::GRID_1MM ) );
mgr->SetConditions( EDA_3D_ACTIONS::toggleOrtho, ACTION_CONDITIONS().Check( ortho ) );
mgr->SetConditions( EDA_3D_ACTIONS::showLayersManager, ACTION_CONDITIONS().Check( appearances ) );
mgr->SetConditions( EDA_3D_ACTIONS::noGrid, GridSizeCheck( GRID3D_TYPE::NONE ) );
mgr->SetConditions( EDA_3D_ACTIONS::show10mmGrid, GridSizeCheck( GRID3D_TYPE::GRID_10MM ) );
mgr->SetConditions( EDA_3D_ACTIONS::show5mmGrid, GridSizeCheck( GRID3D_TYPE::GRID_5MM ) );
mgr->SetConditions( EDA_3D_ACTIONS::show2_5mmGrid, GridSizeCheck( GRID3D_TYPE::GRID_2P5MM ) );
mgr->SetConditions( EDA_3D_ACTIONS::show1mmGrid, GridSizeCheck( GRID3D_TYPE::GRID_1MM ) );
mgr->SetConditions( EDA_3D_ACTIONS::toggleOrtho, ACTION_CONDITIONS().Check( ortho ) );
#undef GridSizeCheck
}
@@ -301,7 +290,6 @@ void EDA_3D_VIEWER_FRAME::setupUIConditions()
bool EDA_3D_VIEWER_FRAME::TryBefore( wxEvent& aEvent )
{
static bool s_presetSwitcherShown = false;
static bool s_viewportSwitcherShown = false;
// wxWidgets generates no key events for the tab key when the ctrl key is held down. One
@@ -315,49 +303,13 @@ bool EDA_3D_VIEWER_FRAME::TryBefore( wxEvent& aEvent )
&& static_cast<wxKeyEvent&>( aEvent ).GetKeyCode() == WXK_TAB )
#endif
{
if( !s_presetSwitcherShown && wxGetKeyState( PRESET_SWITCH_KEY ) )
{
if( m_appearancePanel && this->IsActive() )
{
wxArrayString mru = m_appearancePanel->GetLayerPresetsMRU();
if( mru.size() > 0 )
{
for( wxString& str : mru )
{
if( str == FOLLOW_PCB )
str = _( "Follow PCB Editor" );
else if( str == FOLLOW_PLOT_SETTINGS )
str = _( "Follow PCB Plot Settings" );
}
EDA_VIEW_SWITCHER switcher( this, mru, PRESET_SWITCH_KEY );
s_presetSwitcherShown = true;
switcher.ShowModal();
s_presetSwitcherShown = false;
int idx = switcher.GetSelection();
if( idx >= 0 && idx < (int) mru.size() )
{
wxString internalName = m_appearancePanel->GetLayerPresetsMRU()[idx];
m_appearancePanel->ApplyLayerPreset( internalName );
}
return true;
}
}
}
else if( !s_viewportSwitcherShown && wxGetKeyState( VIEWPORT_SWITCH_KEY ) )
if( !s_viewportSwitcherShown && wxGetKeyState( VIEWPORT_SWITCH_KEY ) )
{
if( this->IsActive() )
{
const wxArrayString& viewportMRU = m_appearancePanel->GetViewportsMRU();
if( viewportMRU.size() > 0 )
if( m_viewportMRU.size() > 0 )
{
EDA_VIEW_SWITCHER switcher( this, viewportMRU, VIEWPORT_SWITCH_KEY );
EDA_VIEW_SWITCHER switcher( this, m_viewportMRU, VIEWPORT_SWITCH_KEY );
s_viewportSwitcherShown = true;
switcher.ShowModal();
@@ -365,8 +317,8 @@ bool EDA_3D_VIEWER_FRAME::TryBefore( wxEvent& aEvent )
int idx = switcher.GetSelection();
if( idx >= 0 && idx < (int) viewportMRU.size() )
m_appearancePanel->ApplyViewport( viewportMRU[idx] );
if( idx >= 0 && idx < (int) m_viewportMRU.size() )
applyViewport( m_viewportMRU[idx] );
return true;
}
@@ -382,31 +334,30 @@ void EDA_3D_VIEWER_FRAME::handleIconizeEvent( wxIconizeEvent& aEvent )
{
KIWAY_PLAYER::handleIconizeEvent( aEvent );
if( m_spaceMouse && aEvent.IsIconized() )
#if defined( KICAD_USE_3DCONNEXION )
if( m_spaceMouse != nullptr && aEvent.IsIconized() )
{
m_spaceMouse->SetFocus( false );
}
#endif
}
void EDA_3D_VIEWER_FRAME::ReloadRequest()
{
// This will schedule a request to load later
// ReloadRequest also updates the board pointer so always call it first
if( m_canvas )
m_canvas->ReloadRequest( GetBoard(), PROJECT_PCB::Get3DCacheManager( &Prj() ) );
if( m_appearancePanel )
m_appearancePanel->UpdateLayerCtls();
m_canvas->ReloadRequest( GetBoard(), Prj().Get3DCacheManager() );
}
void EDA_3D_VIEWER_FRAME::NewDisplay( bool aForceImmediateRedraw )
{
if( m_canvas )
m_canvas->ReloadRequest( GetBoard(), PROJECT_PCB::Get3DCacheManager( &Prj() ) );
ReloadRequest();
// After the ReloadRequest call, the refresh often takes a bit of time,
// and it is made here only on request.
if( m_canvas && aForceImmediateRedraw )
if( aForceImmediateRedraw )
m_canvas->Refresh();
}
@@ -440,11 +391,6 @@ void EDA_3D_VIEWER_FRAME::OnCloseWindow( wxCloseEvent &event )
{
wxLogTrace( m_logTrace, wxT( "EDA_3D_VIEWER_FRAME::OnCloseWindow" ) );
// Do not show the layer manager during closing to avoid flicker on some platforms (Windows)
// that generate useless redraw of items in the Layer Manager
if( m_auimgr.GetPane( wxS( "LayersManager" ) ).IsShown() )
m_auimgr.GetPane( wxS( "LayersManager" ) ).Show( false );
if( m_canvas )
m_canvas->Close();
@@ -498,6 +444,174 @@ void EDA_3D_VIEWER_FRAME::Process_Special_Functions( wxCommandEvent &event )
}
std::vector<VIEWPORT3D> EDA_3D_VIEWER_FRAME::GetUserViewports() const
{
std::vector<VIEWPORT3D> ret;
for( const std::pair<const wxString, VIEWPORT3D>& pair : m_viewports )
ret.emplace_back( pair.second );
return ret;
}
void EDA_3D_VIEWER_FRAME::SetUserViewports( std::vector<VIEWPORT3D>& aViewportList )
{
m_viewports.clear();
for( const VIEWPORT3D& viewport : aViewportList )
{
if( m_viewports.count( viewport.name ) )
continue;
m_viewports[viewport.name] = viewport;
m_viewportMRU.Add( viewport.name );
}
}
void EDA_3D_VIEWER_FRAME::applyViewport( const wxString& aViewportName )
{
int idx = m_cbViewports->FindString( aViewportName );
if( idx >= 0 && idx < m_cbViewports->GetCount() - 3 /* separator */ )
{
m_cbViewports->SetSelection( idx );
m_lastSelectedViewport = static_cast<VIEWPORT3D*>( m_cbViewports->GetClientData( idx ) );
m_currentCamera.SetViewMatrix( m_lastSelectedViewport->matrix );
if( m_boardAdapter.m_Cfg->m_Render.engine == RENDER_ENGINE::OPENGL )
m_canvas->Request_refresh();
else
m_canvas->RenderRaytracingRequest();
if( !m_lastSelectedViewport->name.IsEmpty() )
{
m_viewportMRU.Remove( m_lastSelectedViewport->name );
m_viewportMRU.Insert( m_lastSelectedViewport->name, 0 );
}
}
else
{
m_cbViewports->SetSelection( -1 ); // separator
m_lastSelectedViewport = nullptr;
}
}
void EDA_3D_VIEWER_FRAME::onViewportChanged( wxCommandEvent& aEvent )
{
int count = m_cbViewports->GetCount();
int index = m_cbViewports->GetSelection();
if( index >= 0 && index < count - 3 /* separator */ )
{
VIEWPORT3D* viewport = static_cast<VIEWPORT3D*>( m_cbViewports->GetClientData( index ) );
wxCHECK( viewport, /* void */ );
applyViewport( viewport->name );
}
else if( index == count - 2 )
{
// Save current state to new preset
wxString name;
wxTextEntryDialog dlg( this, _( "Viewport name:" ), _( "Save Viewport" ), name );
if( dlg.ShowModal() != wxID_OK )
{
if( m_lastSelectedViewport )
m_cbViewports->SetStringSelection( m_lastSelectedViewport->name );
else
m_cbViewports->SetSelection( -1 );
return;
}
name = dlg.GetValue();
bool exists = m_viewports.count( name );
if( !exists )
{
m_viewports[name] = VIEWPORT3D( name, m_currentCamera.GetViewMatrix() );
index = m_cbViewports->Insert( name, index-1, static_cast<void*>( &m_viewports[name] ) );
}
else
{
index = m_cbViewports->FindString( name );
m_viewports[name].matrix = m_currentCamera.GetViewMatrix();
m_viewportMRU.Remove( name );
}
m_cbViewports->SetSelection( index );
m_viewportMRU.Insert( name, 0 );
return;
}
else if( index == count - 1 )
{
// Delete an existing viewport
wxArrayString headers;
std::vector<wxArrayString> items;
headers.Add( _( "Viewports" ) );
for( std::pair<const wxString, VIEWPORT3D>& pair : m_viewports )
{
wxArrayString item;
item.Add( pair.first );
items.emplace_back( item );
}
EDA_LIST_DIALOG dlg( this, _( "Delete Viewport" ), headers, items );
dlg.SetListLabel( _( "Select viewport:" ) );
if( dlg.ShowModal() == wxID_OK )
{
wxString viewportName = dlg.GetTextSelection();
int idx = m_cbViewports->FindString( viewportName );
if( idx != wxNOT_FOUND )
{
m_viewports.erase( viewportName );
m_cbViewports->Delete( idx );
m_viewportMRU.Remove( viewportName );
}
}
if( m_lastSelectedViewport )
m_cbViewports->SetStringSelection( m_lastSelectedViewport->name );
else
m_cbViewports->SetSelection( -1 );
return;
}
passOnFocus();
}
void EDA_3D_VIEWER_FRAME::onUpdateViewportsCb( wxUpdateUIEvent& aEvent )
{
int count = m_cbViewports->GetCount();
int index = m_cbViewports->GetSelection();
if( index >= 0 && index < count - 3 )
{
VIEWPORT3D* viewport = static_cast<VIEWPORT3D*>( m_cbViewports->GetClientData( index ) );
wxCHECK( viewport, /* void */ );
if( m_currentCamera.GetViewMatrix() != viewport->matrix )
m_cbViewports->SetSelection( -1 );
}
}
void EDA_3D_VIEWER_FRAME::onRenderEngineSelection( wxCommandEvent &event )
{
RENDER_ENGINE& engine = m_boardAdapter.m_Cfg->m_Render.engine;
@@ -541,8 +655,12 @@ void EDA_3D_VIEWER_FRAME::OnActivate( wxActivateEvent &aEvent )
m_canvas->SetFocus();
}
if( m_spaceMouse )
#if defined( KICAD_USE_3DCONNEXION )
if( m_spaceMouse != nullptr )
{
m_spaceMouse->SetFocus( aEvent.GetActive() );
}
#endif
aEvent.Skip(); // required under wxMAC
}
@@ -558,6 +676,13 @@ void EDA_3D_VIEWER_FRAME::OnSetFocus( wxFocusEvent& aEvent )
}
void EDA_3D_VIEWER_FRAME::passOnFocus()
{
if( m_canvas )
m_canvas->SetFocus();
}
void EDA_3D_VIEWER_FRAME::LoadSettings( APP_SETTINGS_BASE *aCfg )
{
EDA_BASE_FRAME::LoadSettings( aCfg );
@@ -569,35 +694,16 @@ void EDA_3D_VIEWER_FRAME::LoadSettings( APP_SETTINGS_BASE *aCfg )
if( cfg )
{
applySettings( cfg );
m_boardAdapter.SetBoard( GetBoard() );
m_boardAdapter.m_Cfg = cfg;
// When opening the 3D viewer, we use the OpenGL mode, never the ray tracing engine
// because the ray tracing is very time consuming, and can be seen as not working
// (freeze window) with large boards.
m_boardAdapter.m_Cfg->m_Render.engine = RENDER_ENGINE::OPENGL;
if( cfg->m_CurrentPreset == LEGACY_PRESET_FLAG )
{
wxString legacyColorsPresetName = _( "legacy colors" );
cfg->m_UseStackupColors = false;
if( !cfg->FindPreset( legacyColorsPresetName ) )
{
cfg->m_LayerPresets.emplace_back( legacyColorsPresetName,
GetAdapter().GetDefaultVisibleLayers(),
GetAdapter().GetDefaultColors() );
}
cfg->m_CurrentPreset = wxEmptyString;
}
m_boardAdapter.InitSettings( nullptr, nullptr );
if( m_appearancePanel )
m_appearancePanel->CommonSettingsChanged();
m_canvas->SetAnimationEnabled( cfg->m_Camera.animation_enabled );
m_canvas->SetMovingSpeedMultiplier( cfg->m_Camera.moving_speed_multiplier );
m_canvas->SetProjectionMode( cfg->m_Camera.projection_mode );
}
}
@@ -617,8 +723,6 @@ void EDA_3D_VIEWER_FRAME::SaveSettings( APP_SETTINGS_BASE *aCfg )
if( cfg )
{
cfg->m_AuiPanels.right_panel_width = m_appearancePanel->GetSize().x;
cfg->m_Camera.animation_enabled = m_canvas->GetAnimationEnabled();
cfg->m_Camera.moving_speed_multiplier = m_canvas->GetMovingSpeedMultiplier();
cfg->m_Camera.projection_mode = m_canvas->GetProjectionMode();
@@ -640,62 +744,12 @@ void EDA_3D_VIEWER_FRAME::CommonSettingsChanged( bool aEnvVarsChanged, bool aTex
ReCreateMainToolbar();
loadCommonSettings();
applySettings( Pgm().GetSettingsManager().GetAppSettings<EDA_3D_VIEWER_SETTINGS>() );
m_appearancePanel->CommonSettingsChanged();
LoadSettings( Pgm().GetSettingsManager().GetAppSettings<EDA_3D_VIEWER_SETTINGS>() );
NewDisplay( true );
}
void EDA_3D_VIEWER_FRAME::ShowChangedLanguage()
{
EDA_BASE_FRAME::ShowChangedLanguage();
SetTitle( _( "3D Viewer" ) );
ReCreateMainToolbar();
if( m_appearancePanel )
{
wxAuiPaneInfo& lm_pane_info = m_auimgr.GetPane( m_appearancePanel );
lm_pane_info.Caption( _( "Appearance" ) );
}
SetStatusText( wxEmptyString, ACTIVITY );
SetStatusText( wxEmptyString, HOVERED_ITEM );
}
void EDA_3D_VIEWER_FRAME::ToggleAppearanceManager()
{
SETTINGS_MANAGER& mgr = Pgm().GetSettingsManager();
EDA_3D_VIEWER_SETTINGS* cfg = mgr.GetAppSettings<EDA_3D_VIEWER_SETTINGS>();
wxAuiPaneInfo& layersManager = m_auimgr.GetPane( "LayersManager" );
// show auxiliary Vertical layers and visibility manager toolbar
cfg->m_AuiPanels.show_layer_manager = !cfg->m_AuiPanels.show_layer_manager;
layersManager.Show( cfg->m_AuiPanels.show_layer_manager );
if( cfg->m_AuiPanels.show_layer_manager )
{
SetAuiPaneSize( m_auimgr, layersManager, cfg->m_AuiPanels.right_panel_width, -1 );
}
else
{
cfg->m_AuiPanels.right_panel_width = m_appearancePanel->GetSize().x;
m_auimgr.Update();
}
}
void EDA_3D_VIEWER_FRAME::OnDarkModeToggle()
{
if( m_appearancePanel )
m_appearancePanel->OnDarkModeToggle();
}
void EDA_3D_VIEWER_FRAME::takeScreenshot( wxCommandEvent& event )
{
wxString fullFileName;
@@ -707,8 +761,8 @@ void EDA_3D_VIEWER_FRAME::takeScreenshot( wxCommandEvent& event )
if( event.GetId() != ID_TOOL_SCREENCOPY_TOCLIBBOARD )
{
// Remember path between saves during this session only.
const wxString wildcard = fmt_is_jpeg ? FILEEXT::JpegFileWildcard() : FILEEXT::PngFileWildcard();
const wxString ext = fmt_is_jpeg ? FILEEXT::JpegFileExtension : FILEEXT::PngFileExtension;
const wxString wildcard = fmt_is_jpeg ? JpegFileWildcard() : PngFileWildcard();
const wxString ext = fmt_is_jpeg ? JpegFileExtension : PngFileExtension;
// First time path is set to the project path.
if( !m_defaultSaveScreenshotFileName.IsOk() )
@@ -749,13 +803,8 @@ void EDA_3D_VIEWER_FRAME::takeScreenshot( wxCommandEvent& event )
}
// Be sure we have the latest 3D view (remember 3D view is buffered)
// Also ensure any highlighted item is not highlighted when creating screen shot
EDA_3D_VIEWER_SETTINGS::RENDER_SETTINGS& cfg = m_boardAdapter.m_Cfg->m_Render;
bool allow_highlight = cfg.highlight_on_rollover;
cfg.highlight_on_rollover = false;
m_canvas->DoRePaint(); // init first buffer
m_canvas->DoRePaint(); // init second buffer
m_canvas->Request_refresh( true );
wxYield();
// Build image from the 3D buffer
wxWindowUpdateLocker noUpdates( this );
@@ -765,8 +814,6 @@ void EDA_3D_VIEWER_FRAME::takeScreenshot( wxCommandEvent& event )
if( m_canvas )
m_canvas->GetScreenshot( screenshotImage );
cfg.highlight_on_rollover = allow_highlight;
if( event.GetId() == ID_TOOL_SCREENCOPY_TOCLIBBOARD )
{
wxBitmap bitmap( screenshotImage );
@@ -811,18 +858,9 @@ void EDA_3D_VIEWER_FRAME::loadCommonSettings()
COMMON_SETTINGS* settings = Pgm().GetCommonSettings();
const DPI_SCALING dpi{ settings, this };
m_canvas->SetScaleFactor( dpi.GetScaleFactor() );
// TODO(JE) use all control options
m_boardAdapter.m_MousewheelPanning = settings->m_Input.scroll_modifier_zoom != 0;
}
void EDA_3D_VIEWER_FRAME::applySettings( EDA_3D_VIEWER_SETTINGS* cfg )
{
m_boardAdapter.m_Cfg = cfg;
m_canvas->SetAnimationEnabled( cfg->m_Camera.animation_enabled );
m_canvas->SetMovingSpeedMultiplier( cfg->m_Camera.moving_speed_multiplier );
m_canvas->SetProjectionMode( cfg->m_Camera.projection_mode );
m_canvas->SetVcSettings( EDA_DRAW_PANEL_GAL::GetVcSettings() );
}
+26 -16
View File
@@ -4,8 +4,7 @@
* Copyright (C) 2015-2016 Mario Luzeiro <mrluzeiro@ua.pt>
* Copyright (C) 2014 Jean-Pierre Charras, jp.charras at wanadoo.fr
* Copyright (C) 2011 Wayne Stambaugh <stambaughw@gmail.com>
* Copyright (C) 2023 CERN
* Copyright (C) 1992-2024 KiCad Developers, see AUTHORS.txt for contributors.
* Copyright (C) 1992-2022 KiCad Developers, see AUTHORS.txt for contributors.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
@@ -26,7 +25,7 @@
*/
/**
* @file eda_3d_viewer_frame.h
* @file eda_3d_viewer.h
* @brief Declaration of the eda_3d_viewer class
*/
@@ -41,12 +40,15 @@
#include <dialogs/dialog_color_picker.h> // for CUSTOM_COLORS_LIST definition
/// A variable name whose value holds the path of 3D shape files.
/// Currently an environment variable, eventually a project variable.
#define KICAD7_3DMODEL_DIR wxT( "KICAD7_3DMODEL_DIR" )
#define KICAD_DEFAULT_3D_DRAWFRAME_STYLE (wxDEFAULT_FRAME_STYLE | wxWANTS_CHARS)
// Forward declarations
class NL_3D_VIEWER_PLUGIN;
class APPEARANCE_CONTROLS_3D;
enum EDA_3D_VIEWER_STATUSBAR
{
@@ -54,7 +56,6 @@ enum EDA_3D_VIEWER_STATUSBAR
HOVERED_ITEM,
X_POS,
Y_POS,
ZOOM_LEVEL,
};
/**
@@ -105,6 +106,9 @@ public:
EDA_3D_CANVAS* GetCanvas() { return m_canvas; }
std::vector<VIEWPORT3D> GetUserViewports() const;
void SetUserViewports( std::vector<VIEWPORT3D>& aViewportList );
void SaveSettings( APP_SETTINGS_BASE* aCfg ) override;
void LoadSettings( APP_SETTINGS_BASE* aCfg ) override;
@@ -115,19 +119,18 @@ public:
* from the PCB frame because the 3D viewer isn't updated via the #KIWAY.
*/
void CommonSettingsChanged( bool aEnvVarsChanged, bool aTextVarsChanged ) override;
void ShowChangedLanguage() override;
APPEARANCE_CONTROLS_3D* GetAppearanceManager() { return m_appearancePanel; }
void ToggleAppearanceManager();
void OnDarkModeToggle();
protected:
void setupUIConditions() override;
void handleIconizeEvent( wxIconizeEvent& aEvent ) override;
/**
* switch to a given predefined 3D viewport
* @param aViewportName is the name of the viewport to switch on
*/
void applyViewport( const wxString& aViewportName );
private:
/// Called when user press the File->Exit
void Exit3DFrame( wxCommandEvent& event );
@@ -140,11 +143,14 @@ private:
void onRenderEngineSelection( wxCommandEvent& event );
void onDisableRayTracing( wxCommandEvent& aEvent );
void onViewportChanged( wxCommandEvent& aEvent );
void onUpdateViewportsCb( wxUpdateUIEvent& aEvent );
void OnActivate( wxActivateEvent& event );
void OnSetFocus( wxFocusEvent& event );
void passOnFocus();
void doReCreateMenuBar() override;
void CreateMenuBar();
void ReCreateMainToolbar();
/**
@@ -167,12 +173,12 @@ private:
*/
void loadCommonSettings();
void applySettings( EDA_3D_VIEWER_SETTINGS* aSettings );
private:
wxFileName m_defaultSaveScreenshotFileName;
ACTION_TOOLBAR* m_mainToolBar;
wxStaticText* m_viewportsLabel;
wxChoice* m_cbViewports;
EDA_3D_CANVAS* m_canvas;
BOARD_ADAPTER m_boardAdapter;
CAMERA& m_currentCamera;
@@ -182,6 +188,10 @@ private:
NL_3D_VIEWER_PLUGIN* m_spaceMouse;
std::map<wxString, VIEWPORT3D> m_viewports;
VIEWPORT3D* m_lastSelectedViewport;
wxArrayString m_viewportMRU;
/**
* Trace mask used to enable or disable the trace output of this class.
* The debug output can be turned on by setting the WXTRACE environment variable to
+18 -242
View File
@@ -2,8 +2,7 @@
* This program source code file is part of KiCad, a free EDA CAD application.
*
* Copyright (C) 2020 Jon Evans <jon@craftyjon.com>
* Copyright (C) 2023 CERN
* Copyright (C) 2020-2023 KiCad Developers, see AUTHORS.txt for contributors.
* Copyright (C) 2020-2022 KiCad Developers, see AUTHORS.txt for contributors.
*
* This program is free software: you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the
@@ -23,172 +22,21 @@
#include <common_ogl/ogl_attr_list.h>
#include <settings/parameters.h>
#include <settings/json_settings_internals.h>
#include <3d_canvas/board_adapter.h>
#include <wx/config.h>
#include "eda_3d_viewer_settings.h"
using KIGFX::COLOR4D;
using namespace std::placeholders;
LAYER_PRESET_3D::LAYER_PRESET_3D( const wxString& aName ) :
name( aName )
{
layers.set( LAYER_3D_BOARD );
layers.set( LAYER_3D_COPPER_TOP );
layers.set( LAYER_3D_COPPER_BOTTOM );
layers.set( LAYER_3D_SILKSCREEN_TOP );
layers.set( LAYER_3D_SILKSCREEN_BOTTOM );
layers.set( LAYER_3D_SOLDERMASK_TOP );
layers.set( LAYER_3D_SOLDERMASK_BOTTOM );
layers.set( LAYER_3D_SOLDERPASTE );
layers.set( LAYER_3D_ADHESIVE );
layers.set( LAYER_3D_TH_MODELS );
layers.set( LAYER_3D_SMD_MODELS );
layers.set( LAYER_FP_REFERENCES );
layers.set( LAYER_FP_TEXT );
layers.set( LAYER_GRID_AXES );
// Preload colors vector so we don't have to worry about exceptions using colors.at()
colors[ LAYER_3D_BACKGROUND_TOP ] = BOARD_ADAPTER::g_DefaultBackgroundTop;
colors[ LAYER_3D_BACKGROUND_BOTTOM ] = BOARD_ADAPTER::g_DefaultBackgroundBot;
colors[ LAYER_3D_BOARD ] = BOARD_ADAPTER::g_DefaultBoardBody;
colors[ LAYER_3D_COPPER_TOP ] = BOARD_ADAPTER::g_DefaultSurfaceFinish;
colors[ LAYER_3D_COPPER_BOTTOM ] = BOARD_ADAPTER::g_DefaultSurfaceFinish;
colors[ LAYER_3D_SILKSCREEN_TOP ] = BOARD_ADAPTER::g_DefaultSilkscreen;
colors[ LAYER_3D_SILKSCREEN_BOTTOM ] = BOARD_ADAPTER::g_DefaultSilkscreen;
colors[ LAYER_3D_SOLDERMASK_TOP ] = BOARD_ADAPTER::g_DefaultSolderMask;
colors[ LAYER_3D_SOLDERMASK_BOTTOM ] = BOARD_ADAPTER::g_DefaultSolderMask;
colors[ LAYER_3D_SOLDERPASTE ] = BOARD_ADAPTER::g_DefaultSolderPaste;
colors[ LAYER_3D_USER_DRAWINGS ] = BOARD_ADAPTER::g_DefaultComments;
colors[ LAYER_3D_USER_COMMENTS ] = BOARD_ADAPTER::g_DefaultComments;
colors[ LAYER_3D_USER_ECO1 ] = BOARD_ADAPTER::g_DefaultECOs;
colors[ LAYER_3D_USER_ECO2 ] = BOARD_ADAPTER::g_DefaultECOs;
}
PARAM_LAYER_PRESET_3D::PARAM_LAYER_PRESET_3D( const std::string& aPath,
std::vector<LAYER_PRESET_3D>* aPresetList ) :
PARAM_LAMBDA<nlohmann::json>( aPath,
std::bind( &PARAM_LAYER_PRESET_3D::presetsToJson, this ),
std::bind( &PARAM_LAYER_PRESET_3D::jsonToPresets, this, _1 ),
{} ),
m_presets( aPresetList )
{
wxASSERT( aPresetList );
}
nlohmann::json PARAM_LAYER_PRESET_3D::presetsToJson()
{
nlohmann::json ret = nlohmann::json::array();
for( const LAYER_PRESET_3D& preset : *m_presets )
{
nlohmann::json js = {
{ "name", preset.name }
};
nlohmann::json layers = nlohmann::json::array();
for( int layer = 0; layer < LAYER_3D_END; ++layer )
{
if( preset.layers.test( layer ) )
layers.push_back( layer );
}
js["layers"] = layers;
nlohmann::json colors = nlohmann::json::array();
for( const auto& [ layer, color ] : preset.colors )
{
nlohmann::json layerColor = {
{ "layer", layer },
{ "color", color.ToCSSString() }
};
colors.push_back( layerColor );
}
js["colors"] = colors;
ret.push_back( js );
}
return ret;
}
void PARAM_LAYER_PRESET_3D::jsonToPresets( const nlohmann::json& aJson )
{
if( aJson.empty() || !aJson.is_array() )
return;
m_presets->clear();
for( const nlohmann::json& preset : aJson )
{
if( preset.contains( "name" ) )
{
LAYER_PRESET_3D p( preset.at( "name" ).get<wxString>() );
if( preset.contains( "layers" ) && preset.at( "layers" ).is_array() )
{
p.layers.reset();
for( const nlohmann::json& layer : preset.at( "layers" ) )
{
if( layer.is_number_integer() )
{
int layerNum = layer.get<int>();
if( layerNum >= 0 && layerNum < LAYER_3D_END )
p.layers.set( layerNum );
}
}
}
if( preset.contains( "colors" ) && preset.at( "colors" ).is_array() )
{
for( const nlohmann::json& layerColor : preset.at( "colors" ) )
{
if( layerColor.contains( "layer" ) && layerColor.contains( "color" )
&& layerColor.at( "layer" ).is_number_integer() )
{
int layerNum = layerColor.at( "layer" ).get<int>();
COLOR4D color = layerColor.at( "color" ).get<COLOR4D>();
p.colors[ layerNum ] = color;
}
}
}
m_presets->emplace_back( p );
}
}
}
///! Update the schema version whenever a migration is required
const int viewer3dSchemaVersion = 3;
const int viewer3dSchemaVersion = 2;
EDA_3D_VIEWER_SETTINGS::EDA_3D_VIEWER_SETTINGS() :
APP_SETTINGS_BASE( "3d_viewer", viewer3dSchemaVersion ),
m_Render(),
m_Camera()
EDA_3D_VIEWER_SETTINGS::EDA_3D_VIEWER_SETTINGS()
: APP_SETTINGS_BASE( "3d_viewer", viewer3dSchemaVersion ),
m_Render(),
m_Camera()
{
m_params.emplace_back( new PARAM<bool>( "aui.show_layer_manager",
&m_AuiPanels.show_layer_manager, true ) );
m_params.emplace_back( new PARAM<int>( "aui.right_panel_width",
&m_AuiPanels.right_panel_width, -1 ) );
m_params.emplace_back( new PARAM_ENUM<RENDER_ENGINE>( "render.engine", &m_Render.engine,
RENDER_ENGINE::OPENGL,
RENDER_ENGINE::OPENGL,
@@ -219,11 +67,9 @@ EDA_3D_VIEWER_SETTINGS::EDA_3D_VIEWER_SETTINGS() :
m_params.emplace_back( new PARAM<bool>( "render.opengl_copper_thickness",
&m_Render.opengl_copper_thickness, false ) );
m_params.emplace_back( new PARAM<bool>( "render.opengl_show_model_bbox",
&m_Render.show_model_bbox, false ) );
m_params.emplace_back( new PARAM<bool>( "render.opengl_show_off_board_silk",
&m_Render.show_off_board_silk, false ) );
&m_Render.opengl_show_model_bbox, false ) );
m_params.emplace_back( new PARAM<bool>( "render.opengl_highlight_on_rollover",
&m_Render.highlight_on_rollover, true ) );
&m_Render.opengl_highlight_on_rollover, true ) );
m_params.emplace_back( new PARAM<bool>( "render.opengl_AA_disableOnMove",
&m_Render.opengl_AA_disableOnMove, false ) );
m_params.emplace_back( new PARAM<bool>( "render.opengl_thickness_disableOnMove",
@@ -316,6 +162,8 @@ EDA_3D_VIEWER_SETTINGS::EDA_3D_VIEWER_SETTINGS() :
&m_Render.raytrace_lightAzimuth,
default_azimuth ) );
m_params.emplace_back( new PARAM<bool>( "render.realistic",
&m_Render.realistic, true ) );
m_params.emplace_back( new PARAM<bool>( "render.show_adhesive",
&m_Render.show_adhesive, true ) );
m_params.emplace_back( new PARAM<bool>( "render.show_axis",
@@ -324,12 +172,8 @@ EDA_3D_VIEWER_SETTINGS::EDA_3D_VIEWER_SETTINGS() :
&m_Render.show_board_body, true ) );
m_params.emplace_back( new PARAM<bool>( "render.show_comments",
&m_Render.show_comments, true ) );
m_params.emplace_back( new PARAM<bool>( "render.show_drawings",
&m_Render.show_drawings, true ) );
m_params.emplace_back( new PARAM<bool>( "render.show_eco1",
&m_Render.show_eco1, true ) );
m_params.emplace_back( new PARAM<bool>( "render.show_eco2",
&m_Render.show_eco2, true ) );
m_params.emplace_back( new PARAM<bool>( "render.show_eco",
&m_Render.show_eco, true ) );
m_params.emplace_back( new PARAM<bool>( "render.show_footprints_insert",
&m_Render.show_footprints_insert, true ) );
m_params.emplace_back( new PARAM<bool>( "render.show_footprints_normal",
@@ -338,36 +182,20 @@ EDA_3D_VIEWER_SETTINGS::EDA_3D_VIEWER_SETTINGS() :
&m_Render.show_footprints_virtual, true ) );
m_params.emplace_back( new PARAM<bool>( "render.show_footprints_not_in_posfile",
&m_Render.show_footprints_not_in_posfile, true ) );
m_params.emplace_back( new PARAM<bool>( "render.show_footprints_dnp",
&m_Render.show_footprints_dnp, false ) );
m_params.emplace_back( new PARAM<bool>( "render.show_silkscreen_top",
&m_Render.show_silkscreen_top, true ) );
m_params.emplace_back( new PARAM<bool>( "render.show_silkscreen_bottom",
&m_Render.show_silkscreen_bottom, true ) );
m_params.emplace_back( new PARAM<bool>( "render.show_soldermask_top",
&m_Render.show_soldermask_top, true ) );
m_params.emplace_back( new PARAM<bool>( "render.show_soldermask_bottom",
&m_Render.show_soldermask_bottom, true ) );
m_params.emplace_back( new PARAM<bool>( "render.show_silkscreen",
&m_Render.show_silkscreen, true ) );
m_params.emplace_back( new PARAM<bool>( "render.show_soldermask",
&m_Render.show_soldermask, true ) );
m_params.emplace_back( new PARAM<bool>( "render.show_solderpaste",
&m_Render.show_solderpaste, true ) );
m_params.emplace_back( new PARAM<bool>( "render.show_copper_top",
&m_Render.show_copper_bottom, true ) );
m_params.emplace_back( new PARAM<bool>( "render.show_copper_bottom",
&m_Render.show_copper_top, true ) );
m_params.emplace_back( new PARAM<bool>( "render.show_zones",
&m_Render.show_zones, true ) );
m_params.emplace_back( new PARAM<bool>( "render.show_fp_references",
&m_Render.show_fp_references, true ) );
m_params.emplace_back( new PARAM<bool>( "render.show_fp_values",
&m_Render.show_fp_values, true ) );
m_params.emplace_back( new PARAM<bool>( "render.show_fp_text",
&m_Render.show_fp_text, true ) );
m_params.emplace_back( new PARAM<bool>( "render.subtract_mask_from_silk",
&m_Render.subtract_mask_from_silk, false ) );
m_params.emplace_back( new PARAM<bool>( "render.clip_silk_on_via_annulus",
&m_Render.clip_silk_on_via_annuli, false ) );
&m_Render.clip_silk_on_via_annulus, false ) );
m_params.emplace_back( new PARAM<bool>( "render.plated_and_bare_copper",
&m_Render.differentiate_plated_copper, false ) );
&m_Render.renderPlatedPadsAsPlated, false ) );
m_params.emplace_back( new PARAM<bool>( "camera.animation_enabled",
&m_Camera.animation_enabled, true ) );
m_params.emplace_back( new PARAM<int>( "camera.moving_speed_multiplier",
@@ -377,13 +205,6 @@ EDA_3D_VIEWER_SETTINGS::EDA_3D_VIEWER_SETTINGS() :
m_params.emplace_back( new PARAM<int>( "camera.projection_mode",
&m_Camera.projection_mode, 1 ) );
m_params.emplace_back( new PARAM<bool>( "use_stackup_colors",
&m_UseStackupColors, true ) );
m_params.emplace_back( new PARAM_LAYER_PRESET_3D( "layer_presets",
&m_LayerPresets ) );
m_params.emplace_back( new PARAM<wxString>( "current_layer_preset",
&m_CurrentPreset, FOLLOW_PLOT_SETTINGS ) );
registerMigration( 0, 1, std::bind( &EDA_3D_VIEWER_SETTINGS::migrateSchema0to1, this ) );
registerMigration( 1, 2,
@@ -392,51 +213,6 @@ EDA_3D_VIEWER_SETTINGS::EDA_3D_VIEWER_SETTINGS() :
Set( "render.opengl_copper_thickness", false );
return true;
} );
registerMigration( 2, 3,
[&]() -> bool
{
if( std::optional<bool> optval = Get<bool>( "render.show_copper" ) )
{
Set( "render.show_copper_top", *optval );
Set( "render.show_copper_bottom", *optval );
}
if( std::optional<bool> optval = Get<bool>( "render.show_silkscreen" ) )
{
Set( "render.show_silkscreen_top", *optval );
Set( "render.show_silkscreen_bottom", *optval );
}
if( std::optional<bool> optval = Get<bool>( "render.show_soldermask" ) )
{
Set( "render.show_soldermask_top", *optval );
Set( "render.show_soldermask_bottom", *optval );
}
if( std::optional<bool> optval = Get<bool>( "render.show_comments" ) )
Set( "render.show_drawings", *optval );
if( std::optional<bool> optval = Get<bool>( "render.show_eco" ) )
{
Set( "render.show_eco1", *optval );
Set( "render.show_eco2", *optval );
}
return true;
} );
}
LAYER_PRESET_3D* EDA_3D_VIEWER_SETTINGS::FindPreset( const wxString& aName )
{
for( LAYER_PRESET_3D& preset : m_LayerPresets )
{
if( preset.name == aName )
return &preset;
}
return nullptr;
}
+10 -74
View File
@@ -2,8 +2,7 @@
* This program source code file is part of KiCad, a free EDA CAD application.
*
* Copyright (C) 2020 Jon Evans <jon@craftyjon.com>
* Copyright (C) 2023 CERN
* Copyright (C) 2020-2024 KiCad Developers, see AUTHORS.txt for contributors.
* Copyright (C) 2020-2022 KiCad Developers, see AUTHORS.txt for contributors.
*
* This program is free software: you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the
@@ -23,60 +22,15 @@
#define EDA_3D_VIEWER_SETTINGS_H_
#include <3d_enums.h>
#include <common_ogl/ogl_attr_list.h>
#include <plugins/3dapi/xv3d_types.h>
#include <settings/app_settings.h>
#include <settings/parameters.h>
#include <project/board_project_settings.h>
#include "render_settings.h"
#define FOLLOW_PCB wxT( "follow_pcb_editor" )
#define FOLLOW_PLOT_SETTINGS wxT( "follow_plot_settings" )
#define LEGACY_PRESET_FLAG wxT( "legacy_preset_flag" )
enum class ANTIALIASING_MODE;
struct LAYER_PRESET_3D
{
LAYER_PRESET_3D( const wxString& aName = wxEmptyString );
LAYER_PRESET_3D( const wxString& aName, const std::bitset<LAYER_3D_END>& aLayers,
const std::map<int, KIGFX::COLOR4D>& aColors ) :
name( aName ),
layers( aLayers ),
colors( aColors )
{
}
wxString name; ///< A name for this layer set
std::bitset<LAYER_3D_END> layers;
std::map<int, KIGFX::COLOR4D> colors;
};
class PARAM_LAYER_PRESET_3D : public PARAM_LAMBDA<nlohmann::json>
{
public:
PARAM_LAYER_PRESET_3D( const std::string& aPath, std::vector<LAYER_PRESET_3D>* aPresetList );
private:
nlohmann::json presetsToJson();
void jsonToPresets( const nlohmann::json& aJson );
std::vector<LAYER_PRESET_3D>* m_presets;
};
class EDA_3D_VIEWER_SETTINGS : public APP_SETTINGS_BASE
{
public:
struct AUI_PANELS
{
int right_panel_width;
bool show_layer_manager;
};
struct RENDER_SETTINGS
{
RENDER_ENGINE engine;
@@ -90,9 +44,8 @@ public:
bool opengl_holes_disableOnMove;
bool opengl_render_bbox_only_OnMove;
bool opengl_copper_thickness;
bool show_model_bbox;
bool show_off_board_silk;
bool highlight_on_rollover;
bool opengl_show_model_bbox;
bool opengl_highlight_on_rollover;
KIGFX::COLOR4D opengl_selection_color;
bool raytrace_anti_aliasing;
@@ -121,32 +74,23 @@ public:
std::vector<int> raytrace_lightElevation; // -90 .. 90
std::vector<int> raytrace_lightAzimuth; // 0 .. 359
bool realistic;
bool show_adhesive;
bool show_axis;
bool show_board_body;
bool show_comments;
bool show_drawings;
bool show_eco1;
bool show_eco2;
bool show_eco;
bool show_footprints_insert;
bool show_footprints_normal;
bool show_footprints_virtual;
bool show_footprints_not_in_posfile;
bool show_footprints_dnp;
bool show_silkscreen_top;
bool show_silkscreen_bottom;
bool show_soldermask_top;
bool show_soldermask_bottom;
bool show_silkscreen;
bool show_soldermask;
bool show_solderpaste;
bool show_copper_top;
bool show_copper_bottom;
bool show_zones;
bool show_fp_references;
bool show_fp_values;
bool show_fp_text;
bool subtract_mask_from_silk;
bool clip_silk_on_via_annuli;
bool differentiate_plated_copper;
bool clip_silk_on_via_annulus;
bool renderPlatedPadsAsPlated;
};
struct CAMERA_SETTINGS
@@ -161,19 +105,11 @@ public:
virtual ~EDA_3D_VIEWER_SETTINGS() {}
LAYER_PRESET_3D* FindPreset( const wxString& aName );
virtual bool MigrateFromLegacy( wxConfigBase* aLegacyConfig ) override;
public:
AUI_PANELS m_AuiPanels;
RENDER_SETTINGS m_Render;
CAMERA_SETTINGS m_Camera;
bool m_UseStackupColors;
std::vector<LAYER_PRESET_3D> m_LayerPresets;
wxString m_CurrentPreset;
protected:
virtual std::string getLegacyFrameName() const override { return "Viewer3DFrameName"; }
+206 -271
View File
@@ -2,8 +2,7 @@
* This program source code file is part of KiCad, a free EDA CAD application.
*
* Copyright (C) 2017 Jon Evans <jon@craftyjon.com>
* Copyright (C) 2023 CERN
* Copyright (C) 2017-2023 KiCad Developers, see AUTHORS.txt for contributors.
* Copyright (C) 2017-2020 KiCad Developers, see AUTHORS.txt for contributors.
*
* This program is free software: you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the
@@ -24,7 +23,6 @@
#include <3d_viewer_id.h>
#include <3d_enums.h>
#include "eda_3d_actions.h"
#include "tool/tool_action.h"
// Actions, being statically-defined, require specialized I18N handling. We continue to
@@ -34,308 +32,245 @@
#undef _
#define _(s) s
// No description, it is not supposed to be shown anywhere
TOOL_ACTION EDA_3D_ACTIONS::controlActivate( TOOL_ACTION_ARGS()
.Name( "3DViewer.Control" )
.Scope( AS_GLOBAL )
.Flags( AF_ACTIVATE ) );
TOOL_ACTION EDA_3D_ACTIONS::pivotCenter( TOOL_ACTION_ARGS()
.Name( "3DViewer.Control.pivotCenter" )
.Scope( AS_ACTIVE )
.DefaultHotkey( ' ' )
.FriendlyName( _( "Set Pivot" ) )
.Tooltip( _( "Place point around which the board will be rotated (middle mouse click)" ) )
.Flags( AF_NONE )
.Parameter( VIEW3D_TYPE::VIEW3D_PIVOT_CENTER ) );
TOOL_ACTION EDA_3D_ACTIONS::controlActivate( "3DViewer.Control", AS_GLOBAL,
0, "", "", "",
BITMAPS::INVALID_BITMAP, AF_ACTIVATE ); // No description, it is not supposed to be shown anywhere
TOOL_ACTION EDA_3D_ACTIONS::rotateXCW( TOOL_ACTION_ARGS()
.Name( "3DViewer.Control.rotateXclockwise" )
.Scope( AS_GLOBAL )
.FriendlyName( _( "Rotate X Clockwise" ) )
.Icon( BITMAPS::rotate_cw_x )
.Flags( AF_NONE )
.Parameter( ROTATION_DIR::X_CW ) );
TOOL_ACTION EDA_3D_ACTIONS::pivotCenter( "3DViewer.Control.pivotCenter",
AS_ACTIVE,
' ', "",
_( "Center pivot rotation" ), _( "Center pivot rotation (middle mouse click)" ),
BITMAPS::INVALID_BITMAP, AF_NONE, (void*) WXK_SPACE );
TOOL_ACTION EDA_3D_ACTIONS::rotateXCCW( TOOL_ACTION_ARGS()
.Name( "3DViewer.Control.rotateXcounterclockwise" )
.Scope( AS_GLOBAL )
.FriendlyName( _( "Rotate X Counterclockwise" ) )
.Icon( BITMAPS::rotate_ccw_x )
.Flags( AF_NONE )
.Parameter( ROTATION_DIR::X_CCW ) );
TOOL_ACTION EDA_3D_ACTIONS::rotateXCW( "3DViewer.Control.rotateXclockwise",
AS_GLOBAL, 0, "",
_( "Rotate X Clockwise" ), _( "Rotate X Clockwise" ),
BITMAPS::rotate_cw_x, AF_NONE, (void*) ROTATION_DIR::X_CW );
TOOL_ACTION EDA_3D_ACTIONS::rotateYCW( TOOL_ACTION_ARGS()
.Name( "3DViewer.Control.rotateYclockwise" )
.Scope( AS_GLOBAL )
.FriendlyName( _( "Rotate Y Clockwise" ) )
.Icon( BITMAPS::rotate_cw_y )
.Flags( AF_NONE )
.Parameter( ROTATION_DIR::Y_CW ) );
TOOL_ACTION EDA_3D_ACTIONS::rotateXCCW( "3DViewer.Control.rotateXcounterclockwise",
AS_GLOBAL, 0, "",
_( "Rotate X Counterclockwise" ), _( "Rotate X Counterclockwise" ),
BITMAPS::rotate_ccw_x, AF_NONE, (void*) ROTATION_DIR::X_CCW );
TOOL_ACTION EDA_3D_ACTIONS::rotateYCCW( TOOL_ACTION_ARGS()
.Name( "3DViewer.Control.rotateYcounterclockwise" )
.Scope( AS_GLOBAL )
.FriendlyName( _( "Rotate Y Counterclockwise" ) )
.Icon( BITMAPS::rotate_ccw_y )
.Flags( AF_NONE )
.Parameter( ROTATION_DIR::Y_CCW ) );
TOOL_ACTION EDA_3D_ACTIONS::rotateYCW( "3DViewer.Control.rotateYclockwise",
AS_GLOBAL, 0, "",
_( "Rotate Y Clockwise" ), _( "Rotate Y Clockwise" ),
BITMAPS::rotate_cw_y, AF_NONE, (void*) ROTATION_DIR::Y_CW );
TOOL_ACTION EDA_3D_ACTIONS::rotateZCW( TOOL_ACTION_ARGS()
.Name( "3DViewer.Control.rotateZclockwise" )
.Scope( AS_GLOBAL )
.FriendlyName( _( "Rotate Z Clockwise" ) )
.Icon( BITMAPS::rotate_cw_z )
.Flags( AF_NONE )
.Parameter( ROTATION_DIR::Z_CW ) );
TOOL_ACTION EDA_3D_ACTIONS::rotateYCCW( "3DViewer.Control.rotateYcounterclockwise",
AS_GLOBAL, 0, "",
_( "Rotate Y Counterclockwise" ), _( "Rotate Y Counterclockwise" ),
BITMAPS::rotate_ccw_y, AF_NONE, (void*) ROTATION_DIR::Y_CCW );
TOOL_ACTION EDA_3D_ACTIONS::rotateZCCW( TOOL_ACTION_ARGS()
.Name( "3DViewer.Control.rotateZcounterclockwise" )
.Scope( AS_GLOBAL )
.FriendlyName( _( "Rotate Z Counterclockwise" ) )
.Icon( BITMAPS::rotate_ccw_z )
.Flags( AF_NONE )
.Parameter( ROTATION_DIR::Z_CCW ) );
TOOL_ACTION EDA_3D_ACTIONS::rotateZCW( "3DViewer.Control.rotateZclockwise",
AS_GLOBAL, 0, "",
_( "Rotate Z Clockwise" ), _( "Rotate Z Clockwise" ),
BITMAPS::rotate_cw_z, AF_NONE, (void*) ROTATION_DIR::Z_CW );
TOOL_ACTION EDA_3D_ACTIONS::moveLeft( TOOL_ACTION_ARGS()
.Name( "3DViewer.Control.moveLeft" )
.Scope( AS_ACTIVE )
.DefaultHotkey( WXK_LEFT )
.FriendlyName( _( "Move Board Left" ) )
.Icon( BITMAPS::left )
.Flags( AF_NONE )
.Parameter( CURSOR_LEFT ) );
TOOL_ACTION EDA_3D_ACTIONS::rotateZCCW( "3DViewer.Control.rotateZcounterclockwise",
AS_GLOBAL, 0, "",
_( "Rotate Z Counterclockwise" ), _( "Rotate Z Counterclockwise" ),
BITMAPS::rotate_ccw_z, AF_NONE, (void*) ROTATION_DIR::Z_CCW );
TOOL_ACTION EDA_3D_ACTIONS::moveRight( TOOL_ACTION_ARGS()
.Name( "3DViewer.Control.moveRight" )
.Scope( AS_ACTIVE )
.DefaultHotkey( WXK_RIGHT )
.FriendlyName( _( "Move Board Right" ) )
.Icon( BITMAPS::right )
.Flags( AF_NONE )
.Parameter( CURSOR_RIGHT ) );
TOOL_ACTION EDA_3D_ACTIONS::moveLeft( "3DViewer.Control.moveLeft",
AS_ACTIVE,
WXK_LEFT, "",
_( "Move board Left" ), _( "Move board Left" ),
BITMAPS::left, AF_NONE, (void*) CURSOR_LEFT );
TOOL_ACTION EDA_3D_ACTIONS::moveUp( TOOL_ACTION_ARGS()
.Name( "3DViewer.Control.moveUp" )
.Scope( AS_ACTIVE )
.DefaultHotkey( WXK_UP )
.FriendlyName( _( "Move Board Up" ) )
.Icon( BITMAPS::up )
.Flags( AF_NONE )
.Parameter( CURSOR_UP ) );
TOOL_ACTION EDA_3D_ACTIONS::moveRight( "3DViewer.Control.moveRight",
AS_ACTIVE,
WXK_RIGHT, "",
_( "Move board Right" ), _( "Move board Right" ),
BITMAPS::right, AF_NONE, (void*) CURSOR_RIGHT );
TOOL_ACTION EDA_3D_ACTIONS::moveDown( TOOL_ACTION_ARGS()
.Name( "3DViewer.Control.moveDown" )
.Scope( AS_ACTIVE )
.DefaultHotkey( WXK_DOWN )
.FriendlyName( _( "Move Board Down" ) )
.Icon( BITMAPS::down )
.Flags( AF_NONE )
.Parameter( CURSOR_DOWN ) );
TOOL_ACTION EDA_3D_ACTIONS::moveUp( "3DViewer.Control.moveUp",
AS_ACTIVE,
WXK_UP, "",
_( "Move board Up" ), _( "Move board Up" ),
BITMAPS::up, AF_NONE, (void*) CURSOR_UP );
TOOL_ACTION EDA_3D_ACTIONS::homeView( TOOL_ACTION_ARGS()
.Name( "3DViewer.Control.homeView" )
.Scope( AS_ACTIVE )
.DefaultHotkey( WXK_HOME )
.FriendlyName ( _( "Home View" ) )
.Tooltip( _( "Redraw at the home position and zoom" ) )
.Flags( AF_NONE )
.Parameter( VIEW3D_TYPE::VIEW3D_FIT_SCREEN ) );
TOOL_ACTION EDA_3D_ACTIONS::moveDown( "3DViewer.Control.moveDown",
AS_ACTIVE,
WXK_DOWN, "",
_( "Move board Down" ), _( "Move board Down" ),
BITMAPS::down, AF_NONE, (void*) CURSOR_DOWN );
TOOL_ACTION EDA_3D_ACTIONS::flipView( TOOL_ACTION_ARGS()
.Name( "3DViewer.Control.flipView" )
.Scope( AS_ACTIVE )
.DefaultHotkey( 'F' )
.FriendlyName( _( "Flip Board" ) )
.Tooltip( _( "Flip the board view" ) )
.Icon( BITMAPS::flip_board )
.Flags( AF_NONE )
.Parameter( VIEW3D_TYPE::VIEW3D_FLIP ) );
TOOL_ACTION EDA_3D_ACTIONS::homeView( "3DViewer.Control.homeView",
AS_ACTIVE,
WXK_HOME, "",
_( "Home view" ), _( "Home view" ),
BITMAPS::INVALID_BITMAP, AF_NONE, (void*) WXK_HOME );
TOOL_ACTION EDA_3D_ACTIONS::toggleOrtho( TOOL_ACTION_ARGS()
.Name( "3DViewer.Control.toggleOrtho" )
.Scope( AS_GLOBAL )
.FriendlyName( _( "Toggle Orthographic Projection" ) )
.Tooltip( _( "Enable/disable orthographic projection" ) )
.Icon( BITMAPS::ortho ) );
TOOL_ACTION EDA_3D_ACTIONS::resetView( "3DViewer.Control.resetView",
AS_ACTIVE,
'R', "",
_( "Reset view" ), _( "Reset view" ),
BITMAPS::INVALID_BITMAP, AF_NONE, (void*) ID_VIEW3D_RESET );
TOOL_ACTION EDA_3D_ACTIONS::viewFront( TOOL_ACTION_ARGS()
.Name( "3DViewer.Control.viewFront" )
.Scope( AS_ACTIVE )
.DefaultHotkey( 'Y' )
.FriendlyName( _( "View Front" ) )
.Icon( BITMAPS::axis3d_front )
.Flags( AF_NONE )
.Parameter( VIEW3D_TYPE::VIEW3D_FRONT ) );
TOOL_ACTION EDA_3D_ACTIONS::flipView( "3DViewer.Control.flipView",
AS_ACTIVE,
'F', "",
_( "Flip Board" ), _( "Flip the board view" ),
BITMAPS::flip_board, AF_NONE, (void*) ID_VIEW3D_FLIP );
TOOL_ACTION EDA_3D_ACTIONS::viewBack( TOOL_ACTION_ARGS()
.Name( "3DViewer.Control.viewBack" )
.Scope( AS_ACTIVE )
.DefaultHotkey( MD_SHIFT + 'Y' )
.FriendlyName( _( "View Back" ) )
.Icon( BITMAPS::axis3d_back )
.Flags( AF_NONE )
.Parameter( VIEW3D_TYPE::VIEW3D_BACK ) );
TOOL_ACTION EDA_3D_ACTIONS::toggleOrtho( "3DViewer.Control.toggleOrtho",
AS_GLOBAL, 0, "",
_( "Toggle orthographic projection" ), _( "Enable/disable orthographic projection" ),
BITMAPS::ortho );
TOOL_ACTION EDA_3D_ACTIONS::viewLeft( TOOL_ACTION_ARGS()
.Name( "3DViewer.Control.viewLeft" )
.Scope( AS_ACTIVE )
.DefaultHotkey( MD_SHIFT + 'X' )
.FriendlyName( _( "View Left" ) )
.Icon( BITMAPS::axis3d_left )
.Flags( AF_NONE )
.Parameter( VIEW3D_TYPE::VIEW3D_LEFT ) );
TOOL_ACTION EDA_3D_ACTIONS::viewFront( "3DViewer.Control.viewFront",
AS_ACTIVE,
'Y', "",
_( "View Front" ), _( "View Front" ),
BITMAPS::axis3d_front, AF_NONE, (void*) ID_VIEW3D_FRONT );
TOOL_ACTION EDA_3D_ACTIONS::viewRight( TOOL_ACTION_ARGS()
.Name( "3DViewer.Control.viewRight" )
.Scope( AS_ACTIVE )
.DefaultHotkey( 'X' )
.FriendlyName( _( "View Right" ) )
.Icon( BITMAPS::axis3d_right )
.Flags( AF_NONE )
.Parameter( VIEW3D_TYPE::VIEW3D_RIGHT ) );
TOOL_ACTION EDA_3D_ACTIONS::viewBack( "3DViewer.Control.viewBack",
AS_ACTIVE,
MD_SHIFT + 'Y', "",
_( "View Back" ), _( "View Back" ),
BITMAPS::axis3d_back, AF_NONE, (void*) ID_VIEW3D_BACK );
TOOL_ACTION EDA_3D_ACTIONS::viewTop( TOOL_ACTION_ARGS()
.Name( "3DViewer.Control.viewTop" )
.Scope( AS_ACTIVE )
.DefaultHotkey( 'Z' )
.FriendlyName( _( "View Top" ) )
.Icon( BITMAPS::axis3d_top )
.Flags( AF_NONE )
.Parameter( VIEW3D_TYPE::VIEW3D_TOP ) );
TOOL_ACTION EDA_3D_ACTIONS::viewLeft( "3DViewer.Control.viewLeft",
AS_ACTIVE,
MD_SHIFT + 'X', "",
_( "View Left" ), _( "View Left" ),
BITMAPS::axis3d_left, AF_NONE, (void*) ID_VIEW3D_LEFT );
TOOL_ACTION EDA_3D_ACTIONS::viewBottom( TOOL_ACTION_ARGS()
.Name( "3DViewer.Control.viewBottom" )
.Scope( AS_ACTIVE )
.DefaultHotkey( MD_SHIFT + 'Z' )
.FriendlyName( _( "View Bottom" ) )
.Icon( BITMAPS::axis3d_bottom )
.Flags( AF_NONE )
.Parameter( VIEW3D_TYPE::VIEW3D_BOTTOM ) );
TOOL_ACTION EDA_3D_ACTIONS::viewRight( "3DViewer.Control.viewRight",
AS_ACTIVE,
'X', "",
_( "View Right" ), _( "View Right" ),
BITMAPS::axis3d_right, AF_NONE, (void*) ID_VIEW3D_RIGHT );
TOOL_ACTION EDA_3D_ACTIONS::noGrid( TOOL_ACTION_ARGS()
.Name( "3DViewer.Control.noGrid" )
.Scope( AS_GLOBAL )
.FriendlyName( _( "No 3D Grid" ) )
.Flags( AF_NONE )
.Parameter( GRID3D_TYPE::NONE ) );
TOOL_ACTION EDA_3D_ACTIONS::viewTop( "3DViewer.Control.viewTop",
AS_ACTIVE,
'Z', "",
_( "View Top" ), _( "View Top" ),
BITMAPS::axis3d_top, AF_NONE, (void*) ID_VIEW3D_TOP );
TOOL_ACTION EDA_3D_ACTIONS::show10mmGrid( TOOL_ACTION_ARGS()
.Name( "3DViewer.Control.show10mmGrid" )
.Scope( AS_GLOBAL )
.FriendlyName( _( "3D Grid 10mm" ) )
.Flags( AF_NONE )
.Parameter( GRID3D_TYPE::GRID_10MM ) );
TOOL_ACTION EDA_3D_ACTIONS::viewBottom( "3DViewer.Control.viewBottom",
AS_ACTIVE,
MD_SHIFT + 'Z', "",
_( "View Bottom" ), _( "View Bottom" ),
BITMAPS::axis3d_bottom, AF_NONE, (void*) ID_VIEW3D_BOTTOM );
TOOL_ACTION EDA_3D_ACTIONS::show5mmGrid( TOOL_ACTION_ARGS()
.Name( "3DViewer.Control.show5mmGrid" )
.Scope( AS_GLOBAL )
.FriendlyName( _( "3D Grid 5mm" ) )
.Flags( AF_NONE )
.Parameter( GRID3D_TYPE::GRID_5MM ) );
TOOL_ACTION EDA_3D_ACTIONS::noGrid( "3DViewer.Control.noGrid",
AS_GLOBAL, 0, "",
_( "No 3D Grid" ), _( "No 3D Grid" ),
BITMAPS::INVALID_BITMAP, AF_NONE, (void*) GRID3D_TYPE::NONE );
TOOL_ACTION EDA_3D_ACTIONS::show2_5mmGrid( TOOL_ACTION_ARGS()
.Name( "3DViewer.Control.show2_5mmGrid" )
.Scope( AS_GLOBAL )
.FriendlyName( _( "3D Grid 2.5mm" ) )
.Flags( AF_NONE )
.Parameter( GRID3D_TYPE::GRID_2P5MM ) );
TOOL_ACTION EDA_3D_ACTIONS::show10mmGrid( "3DViewer.Control.show10mmGrid",
AS_GLOBAL, 0, "",
_( "3D Grid 10mm" ), _( "3D Grid 10mm" ),
BITMAPS::INVALID_BITMAP, AF_NONE, (void*) GRID3D_TYPE::GRID_10MM );
TOOL_ACTION EDA_3D_ACTIONS::show1mmGrid( TOOL_ACTION_ARGS()
.Name( "3DViewer.Control.show1mmGrid" )
.Scope( AS_GLOBAL )
.FriendlyName( _( "3D Grid 1mm" ) )
.Flags( AF_NONE )
.Parameter( GRID3D_TYPE::GRID_1MM ) );
TOOL_ACTION EDA_3D_ACTIONS::show5mmGrid( "3DViewer.Control.show5mmGrid",
AS_GLOBAL, 0, "",
_( "3D Grid 5mm" ), _( "3D Grid 5mm" ),
BITMAPS::INVALID_BITMAP, AF_NONE, (void*) GRID3D_TYPE::GRID_5MM );
TOOL_ACTION EDA_3D_ACTIONS::materialNormal( TOOL_ACTION_ARGS()
.Name( "3DViewer.Control.materialNormal" )
.Scope( AS_ACTIVE )
.FriendlyName( _( "Render Realistic Materials" ) )
.Tooltip( _( "Use all material properties from each 3D model file" ) )
.Flags( AF_NONE )
.Parameter( MATERIAL_MODE::NORMAL ) );
TOOL_ACTION EDA_3D_ACTIONS::show2_5mmGrid( "3DViewer.Control.show2_5mmGrid",
AS_GLOBAL, 0, "",
_( "3D Grid 2.5mm" ), _( "3D Grid 2.5mm" ),
BITMAPS::INVALID_BITMAP, AF_NONE, (void*) GRID3D_TYPE::GRID_2P5MM );
TOOL_ACTION EDA_3D_ACTIONS::materialDiffuse( TOOL_ACTION_ARGS()
.Name( "3DViewer.Control.materialDiffuse" )
.Scope( AS_ACTIVE )
.FriendlyName( _( "Render Solid Colors" ) )
.Tooltip( _( "Use only the diffuse color property from 3D model file" ) )
.Flags( AF_NONE )
.Parameter( MATERIAL_MODE::DIFFUSE_ONLY ) );
TOOL_ACTION EDA_3D_ACTIONS::show1mmGrid( "3DViewer.Control.show1mmGrid",
AS_GLOBAL, 0, "",
_( "3D Grid 1mm" ), _( "3D Grid 1mm" ),
BITMAPS::INVALID_BITMAP, AF_NONE, (void*) GRID3D_TYPE::GRID_1MM );
TOOL_ACTION EDA_3D_ACTIONS::materialCAD( TOOL_ACTION_ARGS()
.Name( "3DViewer.Control.materialCAD" )
.Scope( AS_ACTIVE )
.FriendlyName( _( "Render CAD Colors" ) )
.Tooltip( _( "Use a CAD color style based on the diffuse color of the material" ) )
.Flags( AF_NONE )
.Parameter( MATERIAL_MODE::CAD_MODE ) );
TOOL_ACTION EDA_3D_ACTIONS::materialNormal( "3DViewer.Control.materialNormal",
AS_ACTIVE,
0, "",
_( "Render Realistic Materials" ),
_( "Use all material properties from each 3D model file" ),
BITMAPS::INVALID_BITMAP, AF_NONE, (void*) MATERIAL_MODE::NORMAL );
TOOL_ACTION EDA_3D_ACTIONS::showTHT( TOOL_ACTION_ARGS()
.Name( "3DViewer.Control.attributesTHT" )
.Scope( AS_ACTIVE )
.DefaultHotkey( 'T' )
.FriendlyName( _( "Show Through Hole 3D Models" ) )
.Tooltip( _( "Show 3D models for 'Through hole' type footprints" ) )
.Icon( BITMAPS::show_tht )
.Flags( AF_NONE ) );
TOOL_ACTION EDA_3D_ACTIONS::materialDiffuse( "3DViewer.Control.materialDiffuse",
AS_ACTIVE,
0, "",
_( "Render Solid Colors" ),
_( "Use only the diffuse color property from model 3D model file" ),
BITMAPS::INVALID_BITMAP, AF_NONE, (void*) MATERIAL_MODE::DIFFUSE_ONLY );
TOOL_ACTION EDA_3D_ACTIONS::showSMD( TOOL_ACTION_ARGS()
.Name( "3DViewer.Control.attributesSMD" )
.Scope( AS_ACTIVE )
.DefaultHotkey( 'S' )
.FriendlyName( _( "Show SMD 3D Models" ) )
.Tooltip( _( "Show 3D models for 'Surface mount' type footprints" ) )
.Icon( BITMAPS::show_smt )
.Flags( AF_NONE ) );
TOOL_ACTION EDA_3D_ACTIONS::materialCAD( "3DViewer.Control.materialCAD",
AS_ACTIVE,
0, "",
_( "Render CAD Colors" ),
_( "Use a CAD color style based on the diffuse color of the material" ),
BITMAPS::INVALID_BITMAP, AF_NONE, (void*) MATERIAL_MODE::CAD_MODE );
TOOL_ACTION EDA_3D_ACTIONS::showVirtual( TOOL_ACTION_ARGS()
.Name( "3DViewer.Control.attributesOther" )
.Scope( AS_ACTIVE )
.DefaultHotkey( 'V' )
.FriendlyName( _( "Show Unspecified 3D Models" ) )
.Tooltip( _( "Show 3D models for 'unspecified' type footprints" ) )
.Icon( BITMAPS::show_other )
.Flags( AF_NONE ) );
TOOL_ACTION EDA_3D_ACTIONS::showTHT( "3DViewer.Control.attributesTHT",
AS_ACTIVE,
'T', "",
_( "Toggle Through Hole 3D models" ),
_( "Toggle 3D models for 'Through hole' type components" ),
BITMAPS::show_tht, AF_NONE );
TOOL_ACTION EDA_3D_ACTIONS::showNotInPosFile( TOOL_ACTION_ARGS()
.Name( "3DViewer.Control.attribute_not_in_posfile" )
.Scope( AS_ACTIVE )
.DefaultHotkey( 'P' )
.FriendlyName( _( "Show 3D Models not in POS File" ) )
.Tooltip( _( "Show 3D models even if not found in .pos file" ) )
.Icon( BITMAPS::show_not_in_posfile )
.Flags( AF_NONE ) );
TOOL_ACTION EDA_3D_ACTIONS::showSMD( "3DViewer.Control.attributesSMD",
AS_ACTIVE,
'S', "",
_( "Toggle SMD 3D models" ),
_( "Toggle 3D models for 'Surface mount' type components" ),
BITMAPS::show_smt, AF_NONE );
TOOL_ACTION EDA_3D_ACTIONS::showDNP( TOOL_ACTION_ARGS()
.Name( "3DViewer.Control.attribute_dnp" )
.Scope( AS_ACTIVE )
.DefaultHotkey( 'D' )
.FriendlyName( _( "Show 3D Models marked DNP" ) )
.Tooltip( _( "Show 3D models even if marked 'Do Not Place'" ) )
.Icon( BITMAPS::show_dnp )
.Flags( AF_NONE ) );
TOOL_ACTION EDA_3D_ACTIONS::showVirtual( "3DViewer.Control.attributesOther",
AS_ACTIVE,
'V', "",
_( "Toggle unspecified 3D models" ), _( "Toggle 3D models for 'unspecified' type components" ),
BITMAPS::show_other, AF_NONE );
TOOL_ACTION EDA_3D_ACTIONS::showBBoxes( TOOL_ACTION_ARGS()
.Name( "3DViewer.Control.showBoundingBoxes" )
.Scope( AS_GLOBAL )
.FriendlyName( _( "Show Model Bounding Boxes" ) )
.Tooltip( _( "Show 3D model bounding boxes in realtime renderer" ) )
.Icon( BITMAPS::ortho )
.Flags( AF_NONE ) );
TOOL_ACTION EDA_3D_ACTIONS::showNotInPosFile( "3DViewer.Control.attribute_not_in_posfile",
AS_ACTIVE,
'P', "",
_( "Toggle 3D models not in pos file" ), _( "Toggle 3D models not in pos file" ),
BITMAPS::show_not_in_posfile, AF_NONE );
TOOL_ACTION EDA_3D_ACTIONS::showAxis( TOOL_ACTION_ARGS()
.Name( "3DViewer.Control.showAxis" )
.Scope( AS_GLOBAL )
.FriendlyName( _( "Show 3D Axis" ) )
.Icon( BITMAPS::axis3d_front )
.Flags( AF_NONE ) );
TOOL_ACTION EDA_3D_ACTIONS::showBBoxes( "3DViewer.Control.showBoundingBoxes",
AS_GLOBAL, 0, "",
_( "Show Model Bounding Boxes" ), _( "Show Model Bounding Boxes" ),
BITMAPS::ortho, AF_NONE );
TOOL_ACTION EDA_3D_ACTIONS::showLayersManager( TOOL_ACTION_ARGS()
.Name( "3DViewer.Control.showLayersManager" )
.Scope( AS_GLOBAL )
.FriendlyName( _( "Show Appearance Manager" ) )
.Tooltip( _( "Show/hide the appearance manager" ) )
.Icon( BITMAPS::layers_manager ) );
TOOL_ACTION EDA_3D_ACTIONS::toggleRealisticMode( "3DViewer.Control.toggleRealisticMode",
AS_GLOBAL, 0, "",
_( "Toggle realistic mode" ), _( "Toggle realistic mode" ) );
TOOL_ACTION EDA_3D_ACTIONS::toggleBoardBody( "3DViewer.Control.toggleBoardBody",
AS_GLOBAL, 0, "",
_( "Toggle board body display" ), _( "Toggle board body display" ) );
TOOL_ACTION EDA_3D_ACTIONS::showAxis( "3DViewer.Control.showAxis",
AS_GLOBAL, 0, "",
_( "Show 3D Axis" ), _( "Show 3D Axis" ),
BITMAPS::axis3d_front, AF_NONE );
TOOL_ACTION EDA_3D_ACTIONS::toggleZones( "3DViewer.Control.toggleZones",
AS_GLOBAL, 0, "",
_( "Toggle zone display" ), _( "Toggle zone display" ) );
TOOL_ACTION EDA_3D_ACTIONS::toggleAdhesive( "3DViewer.Control.toggleAdhesive",
AS_GLOBAL, 0, "",
_( "Toggle adhesive display" ), _( "Toggle display of adhesive layers" ) );
TOOL_ACTION EDA_3D_ACTIONS::toggleSilk( "3DViewer.Control.toggleSilk",
AS_GLOBAL, 0, "",
_( "Toggle silkscreen display" ), _( "Toggle display of silkscreen layers" ) );
TOOL_ACTION EDA_3D_ACTIONS::toggleSolderMask( "3DViewer.Control.toggleSolderMask",
AS_GLOBAL, 0, "",
_( "Toggle solder mask display" ), _( "Toggle display of solder mask layers" ) );
TOOL_ACTION EDA_3D_ACTIONS::toggleSolderPaste( "3DViewer.Control.toggleSolderPaste",
AS_GLOBAL, 0, "",
_( "Toggle solder paste display" ), _( "Toggle display of solder paste layers" ) );
TOOL_ACTION EDA_3D_ACTIONS::toggleComments( "3DViewer.Control.toggleComments",
AS_GLOBAL, 0, "",
_( "Toggle comments display" ), _( "Toggle display of comments and drawings layers" ) );
TOOL_ACTION EDA_3D_ACTIONS::toggleECO( "3DViewer.Control.toggleECO",
AS_GLOBAL, 0, "",
_( "Toggle ECO display" ), _( "Toggle display of ECO layers" ) );
+12 -4
View File
@@ -1,8 +1,8 @@
/*
* This program source code file is part of KiCad, a free EDA CAD application.
*
* Copyright (C) 2013-2023 CERN
* Copyright (C) 2020-2023 KiCad Developers, see AUTHORS.txt for contributors.
* Copyright (C) 2013-2016 CERN
* Copyright (C) 2020-2021 KiCad Developers, see AUTHORS.txt for contributors.
* @author Maciej Suminski <maciej.suminski@cern.ch>
*
* This program is free software; you can redistribute it and/or
@@ -54,6 +54,7 @@ public:
static TOOL_ACTION moveUp;
static TOOL_ACTION moveDown;
static TOOL_ACTION homeView;
static TOOL_ACTION resetView;
static TOOL_ACTION flipView;
static TOOL_ACTION toggleOrtho;
@@ -78,10 +79,17 @@ public:
static TOOL_ACTION showSMD;
static TOOL_ACTION showVirtual;
static TOOL_ACTION showNotInPosFile;
static TOOL_ACTION showDNP;
static TOOL_ACTION showBBoxes;
static TOOL_ACTION toggleRealisticMode;
static TOOL_ACTION toggleBoardBody;
static TOOL_ACTION showAxis;
static TOOL_ACTION showLayersManager;
static TOOL_ACTION toggleZones;
static TOOL_ACTION toggleAdhesive;
static TOOL_ACTION toggleSilk;
static TOOL_ACTION toggleSolderMask;
static TOOL_ACTION toggleSolderPaste;
static TOOL_ACTION toggleComments;
static TOOL_ACTION toggleECO;
};
#endif
+116 -52
View File
@@ -1,8 +1,7 @@
/*
* This program source code file is part of KiCad, a free EDA CAD application.
*
* Copyright (C) 2023 CERN
* Copyright (C) 2020-2023 KiCad Developers, see AUTHORS.txt for contributors.
* Copyright (C) 2020-2021 KiCad Developers, see AUTHORS.txt for contributors.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
@@ -29,9 +28,8 @@
#include <id.h>
#include <kiface_base.h>
#include <tools/eda_3d_controller.h>
#include <tools/eda_3d_actions.h>
#include <dialogs/panel_preview_3d_model.h>
#include <dialogs/appearance_controls_3D.h>
#include "eda_3d_actions.h"
#include "dialogs/panel_preview_3d_model.h"
#include <3d_rendering/opengl/render_3d_opengl.h>
@@ -81,7 +79,8 @@ void EDA_3D_CONTROLLER::Reset( RESET_REASON aReason )
{
m_canvas = dynamic_cast<EDA_3D_CANVAS*>( holder->GetToolCanvas() );
EDA_3D_BOARD_HOLDER* holder3d = dynamic_cast<EDA_3D_BOARD_HOLDER*>( holder );
EDA_3D_BOARD_HOLDER* holder3d =
dynamic_cast<EDA_3D_BOARD_HOLDER*>( holder );
wxASSERT( holder3d );
@@ -118,7 +117,10 @@ int EDA_3D_CONTROLLER::Main( const TOOL_EVENT& aEvent )
if( evt->IsCancelInteractive() )
{
wxWindow* canvas = m_toolMgr->GetToolHolder()->GetToolCanvas();
wxWindow* topLevelParent = wxGetTopLevelParent( canvas->GetParent() );
wxWindow* topLevelParent = canvas->GetParent();
while( topLevelParent && !topLevelParent->IsTopLevel() )
topLevelParent = topLevelParent->GetParent();
if( topLevelParent && dynamic_cast<DIALOG_SHIM*>( topLevelParent ) )
{
@@ -150,7 +152,7 @@ int EDA_3D_CONTROLLER::Main( const TOOL_EVENT& aEvent )
int EDA_3D_CONTROLLER::ViewControl( const TOOL_EVENT& aEvent )
{
m_canvas->SetView3D( aEvent.Parameter<VIEW3D_TYPE>() );
m_canvas->SetView3D( aEvent.Parameter<intptr_t>() );
return 0;
}
@@ -158,13 +160,13 @@ int EDA_3D_CONTROLLER::ViewControl( const TOOL_EVENT& aEvent )
int EDA_3D_CONTROLLER::PanControl( const TOOL_EVENT& aEvent )
{
switch( aEvent.Parameter<ACTIONS::CURSOR_EVENT_TYPE>() )
switch( aEvent.Parameter<intptr_t>() )
{
case ACTIONS::CURSOR_UP: m_canvas->SetView3D( VIEW3D_TYPE::VIEW3D_PAN_UP ); break;
case ACTIONS::CURSOR_DOWN: m_canvas->SetView3D( VIEW3D_TYPE::VIEW3D_PAN_DOWN ); break;
case ACTIONS::CURSOR_LEFT: m_canvas->SetView3D( VIEW3D_TYPE::VIEW3D_PAN_LEFT ); break;
case ACTIONS::CURSOR_RIGHT: m_canvas->SetView3D( VIEW3D_TYPE::VIEW3D_PAN_RIGHT ); break;
default: wxFAIL; break;
case ACTIONS::CURSOR_UP: m_canvas->SetView3D( WXK_UP ); break;
case ACTIONS::CURSOR_DOWN: m_canvas->SetView3D( WXK_DOWN ); break;
case ACTIONS::CURSOR_LEFT: m_canvas->SetView3D( WXK_LEFT ); break;
case ACTIONS::CURSOR_RIGHT: m_canvas->SetView3D( WXK_RIGHT ); break;
default: wxFAIL; break;
}
return 0;
@@ -184,7 +186,7 @@ int EDA_3D_CONTROLLER::RotateView( const TOOL_EVENT& aEvent )
case ROTATION_DIR::Y_CCW: m_camera->RotateY( -rotIncrement ); break;
case ROTATION_DIR::Z_CW: m_camera->RotateZ( -rotIncrement ); break;
case ROTATION_DIR::Z_CCW: m_camera->RotateZ( rotIncrement ); break;
default: wxFAIL; break;
default: wxFAIL; break;
}
if( m_boardAdapter->m_Cfg->m_Render.engine == RENDER_ENGINE::OPENGL )
@@ -223,44 +225,95 @@ int EDA_3D_CONTROLLER::ToggleOrtho( const TOOL_EVENT& aEvent )
int EDA_3D_CONTROLLER::ToggleVisibility( const TOOL_EVENT& aEvent )
{
std::bitset<LAYER_3D_END> visibilityFlags = m_boardAdapter->GetVisibleLayers();
APPEARANCE_CONTROLS_3D* appearanceManager = nullptr;
bool reload = false;
auto flipLayer =
[&]( int layer )
{
appearanceManager->OnLayerVisibilityChanged( layer, !visibilityFlags.test( layer ) );
};
#define FLIP( x ) x = !x
if( auto viewer = dynamic_cast<EDA_3D_VIEWER_FRAME*>( m_toolMgr->GetToolHolder() ) )
appearanceManager = viewer->GetAppearanceManager();
if( appearanceManager )
if( aEvent.IsAction( &EDA_3D_ACTIONS::showTHT ) )
{
if( aEvent.IsAction( &EDA_3D_ACTIONS::showTHT ) )
flipLayer( LAYER_3D_TH_MODELS );
else if( aEvent.IsAction( &EDA_3D_ACTIONS::showSMD ) )
flipLayer( LAYER_3D_SMD_MODELS );
else if( aEvent.IsAction( &EDA_3D_ACTIONS::showVirtual ) )
flipLayer( LAYER_3D_VIRTUAL_MODELS );
else if( aEvent.IsAction( &EDA_3D_ACTIONS::showNotInPosFile ) )
flipLayer( LAYER_3D_MODELS_NOT_IN_POS );
else if( aEvent.IsAction( &EDA_3D_ACTIONS::showDNP ) )
flipLayer( LAYER_3D_MODELS_MARKED_DNP );
else if( aEvent.IsAction( &EDA_3D_ACTIONS::showAxis ) )
flipLayer( LAYER_3D_AXES );
else if( aEvent.IsAction( &EDA_3D_ACTIONS::showBBoxes ) )
flipLayer( LAYER_3D_BOUNDING_BOXES );
FLIP( m_boardAdapter->m_Cfg->m_Render.show_footprints_normal );
reload = true;
}
else if( aEvent.IsAction( &EDA_3D_ACTIONS::showSMD ) )
{
FLIP( m_boardAdapter->m_Cfg->m_Render.show_footprints_insert );
reload = true;
}
else if( aEvent.IsAction( &EDA_3D_ACTIONS::showVirtual ) )
{
FLIP( m_boardAdapter->m_Cfg->m_Render.show_footprints_virtual );
reload = true;
}
else if( aEvent.IsAction( &EDA_3D_ACTIONS::showNotInPosFile ) )
{
FLIP( m_boardAdapter->m_Cfg->m_Render.show_footprints_not_in_posfile );
reload = true;
}
else if( aEvent.IsAction( &EDA_3D_ACTIONS::showBBoxes ) )
{
FLIP( m_boardAdapter->m_Cfg->m_Render.opengl_show_model_bbox );
}
else if( aEvent.IsAction( &EDA_3D_ACTIONS::toggleRealisticMode ) )
{
FLIP( m_boardAdapter->m_Cfg->m_Render.realistic );
}
else if( aEvent.IsAction( &EDA_3D_ACTIONS::toggleBoardBody ) )
{
FLIP( m_boardAdapter->m_Cfg->m_Render.show_board_body );
}
else if( aEvent.IsAction( &EDA_3D_ACTIONS::showAxis ) )
{
FLIP( m_boardAdapter->m_Cfg->m_Render.show_axis );
}
else if( aEvent.IsAction( &EDA_3D_ACTIONS::toggleZones ) )
{
FLIP( m_boardAdapter->m_Cfg->m_Render.show_zones );
}
else if( aEvent.IsAction( &EDA_3D_ACTIONS::toggleAdhesive ) )
{
FLIP( m_boardAdapter->m_Cfg->m_Render.show_adhesive );
}
else if( aEvent.IsAction( &EDA_3D_ACTIONS::toggleSilk ) )
{
FLIP( m_boardAdapter->m_Cfg->m_Render.show_silkscreen );
}
else if( aEvent.IsAction( &EDA_3D_ACTIONS::toggleSolderMask ) )
{
FLIP( m_boardAdapter->m_Cfg->m_Render.show_soldermask );
}
else if( aEvent.IsAction( &EDA_3D_ACTIONS::toggleSolderPaste ) )
{
FLIP( m_boardAdapter->m_Cfg->m_Render.show_solderpaste );
}
else if( aEvent.IsAction( &EDA_3D_ACTIONS::toggleComments ) )
{
FLIP( m_boardAdapter->m_Cfg->m_Render.show_comments );
}
else if( aEvent.IsAction( &EDA_3D_ACTIONS::toggleECO ) )
{
FLIP( m_boardAdapter->m_Cfg->m_Render.show_eco );
}
return 0;
}
int EDA_3D_CONTROLLER::ToggleLayersManager( const TOOL_EVENT& aEvent )
{
if( auto* viewer = dynamic_cast<EDA_3D_VIEWER_FRAME*>( m_toolMgr->GetToolHolder() ) )
viewer->ToggleAppearanceManager();
if( reload )
{
if( m_boardAdapter->m_Cfg->m_Render.engine == RENDER_ENGINE::OPENGL )
{
auto* renderer = static_cast<RENDER_3D_OPENGL*>( m_canvas->GetCurrentRender() );
renderer->Load3dModelsIfNeeded();
m_canvas->Request_refresh();
}
else
{
m_canvas->RenderRaytracingRequest();
}
}
else
{
if( auto viewer = dynamic_cast<EDA_3D_VIEWER_FRAME*>( m_toolMgr->GetToolHolder() ) )
viewer->NewDisplay( true );
else
m_canvas->Request_refresh();
}
return 0;
}
@@ -302,7 +355,7 @@ int EDA_3D_CONTROLLER::doZoomInOut( bool aDirection, bool aCenterOnCursor )
{
if( m_canvas )
{
m_canvas->SetView3D( aDirection ? VIEW3D_TYPE::VIEW3D_ZOOM_IN : VIEW3D_TYPE::VIEW3D_ZOOM_OUT );
m_canvas->SetView3D( aDirection ? WXK_F1 : WXK_F2 );
m_canvas->DisplayStatus();
}
@@ -314,7 +367,7 @@ int EDA_3D_CONTROLLER::ZoomFitScreen( const TOOL_EVENT& aEvent )
{
if( m_canvas )
{
m_canvas->SetView3D( VIEW3D_TYPE::VIEW3D_FIT_SCREEN );
m_canvas->SetView3D( WXK_HOME );
m_canvas->DisplayStatus();
}
@@ -346,6 +399,7 @@ void EDA_3D_CONTROLLER::setTransitions()
Go( &EDA_3D_CONTROLLER::ViewControl, EDA_3D_ACTIONS::viewBack.MakeEvent() );
Go( &EDA_3D_CONTROLLER::ViewControl, EDA_3D_ACTIONS::pivotCenter.MakeEvent() );
Go( &EDA_3D_CONTROLLER::ViewControl, EDA_3D_ACTIONS::homeView.MakeEvent() );
Go( &EDA_3D_CONTROLLER::ViewControl, EDA_3D_ACTIONS::resetView.MakeEvent() );
Go( &EDA_3D_CONTROLLER::ViewControl, EDA_3D_ACTIONS::flipView.MakeEvent() );
Go( &EDA_3D_CONTROLLER::RotateView, EDA_3D_ACTIONS::rotateXCW.MakeEvent() );
Go( &EDA_3D_CONTROLLER::RotateView, EDA_3D_ACTIONS::rotateXCCW.MakeEvent() );
@@ -383,8 +437,18 @@ void EDA_3D_CONTROLLER::setTransitions()
Go( &EDA_3D_CONTROLLER::ToggleVisibility, EDA_3D_ACTIONS::showSMD.MakeEvent() );
Go( &EDA_3D_CONTROLLER::ToggleVisibility, EDA_3D_ACTIONS::showVirtual.MakeEvent() );
Go( &EDA_3D_CONTROLLER::ToggleVisibility, EDA_3D_ACTIONS::showNotInPosFile.MakeEvent() );
Go( &EDA_3D_CONTROLLER::ToggleVisibility, EDA_3D_ACTIONS::showDNP.MakeEvent() );
Go( &EDA_3D_CONTROLLER::ToggleLayersManager,EDA_3D_ACTIONS::showLayersManager.MakeEvent() );
Go( &EDA_3D_CONTROLLER::ToggleVisibility, EDA_3D_ACTIONS::showVirtual.MakeEvent() );
Go( &EDA_3D_CONTROLLER::ToggleVisibility, EDA_3D_ACTIONS::showBBoxes.MakeEvent() );
Go( &EDA_3D_CONTROLLER::ToggleVisibility, EDA_3D_ACTIONS::toggleRealisticMode.MakeEvent() );
Go( &EDA_3D_CONTROLLER::ToggleVisibility, EDA_3D_ACTIONS::toggleBoardBody.MakeEvent() );
Go( &EDA_3D_CONTROLLER::ToggleVisibility, EDA_3D_ACTIONS::showAxis.MakeEvent() );
Go( &EDA_3D_CONTROLLER::ToggleVisibility, EDA_3D_ACTIONS::toggleZones.MakeEvent() );
Go( &EDA_3D_CONTROLLER::ToggleVisibility, EDA_3D_ACTIONS::toggleAdhesive.MakeEvent() );
Go( &EDA_3D_CONTROLLER::ToggleVisibility, EDA_3D_ACTIONS::toggleSilk.MakeEvent() );
Go( &EDA_3D_CONTROLLER::ToggleVisibility, EDA_3D_ACTIONS::toggleSolderMask.MakeEvent() );
Go( &EDA_3D_CONTROLLER::ToggleVisibility, EDA_3D_ACTIONS::toggleSolderPaste.MakeEvent() );
Go( &EDA_3D_CONTROLLER::ToggleVisibility, EDA_3D_ACTIONS::toggleComments.MakeEvent() );
Go( &EDA_3D_CONTROLLER::ToggleVisibility, EDA_3D_ACTIONS::toggleECO.MakeEvent() );
}
@@ -1,8 +1,7 @@
/*
* This program source code file is part of KiCad, a free EDA CAD application.
*
* Copyright (C) 2023 CERN
* Copyright (C) 2020-2023 KiCad Developers, see AUTHORS.txt for contributors.
* Copyright (C) 2020-2021 KiCad Developers, see AUTHORS.txt for contributors.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
@@ -96,7 +95,6 @@ public:
int ToggleOrtho( const TOOL_EVENT& aEvent );
int ToggleVisibility( const TOOL_EVENT& aEvent );
int ToggleLayersManager( const TOOL_EVENT& aEvent );
private:
///< Sets up handlers for various events.
+10 -19
View File
@@ -1,21 +1,5 @@
/*
* This program source code file is part of KiCad, a free EDA CAD application.
*
* Copyright (C) 2023 <author>
* Copyright (C) 2023 KiCad Developers, see AUTHORS.txt for contributors.
*
* This program is free software: you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the
* Free Software Foundation, either version 3 of the License, or (at your
* option) any later version.
*
* This program is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* General Public License for more details.
*
* You should have received a copy of the GNU General Public License along
* with this program. If not, see <http://www.gnu.org/licenses/>.
/**
* @file 3d_viewer_id.h
*/
/**
@@ -27,7 +11,6 @@
* However the number of IDs should be < ROOM_FOR_3D_VIEWER, defined in id.h
* Please change the value of ROOM_FOR_3D_VIEWER if too small.
*/
#pragma once
#include <id.h> // Generic Id.
@@ -35,6 +18,14 @@ enum id_3dview_frm
{
ID_START_COMMAND_3D = ID_KICAD_3D_VIEWER_START,
ID_RELOAD3D_BOARD,
ID_VIEW3D_TOP,
ID_VIEW3D_BOTTOM,
ID_VIEW3D_LEFT,
ID_VIEW3D_RIGHT,
ID_VIEW3D_FRONT,
ID_VIEW3D_BACK,
ID_VIEW3D_RESET,
ID_VIEW3D_FLIP,
ID_TOOL_SCREENCOPY_TOCLIBBOARD,
ID_MENU_SCREENCOPY_PNG,
+25 -24
View File
@@ -1,5 +1,5 @@
#add_definitions(-DPRINT_STATISTICS_3D_VIEWER)
add_compile_definitions( PCBNEW )
add_definitions(-DPCBNEW)
include_directories(BEFORE ${INC_BEFORE})
include_directories(
@@ -16,6 +16,7 @@ include_directories(
)
# directories
set( DIR_DLG dialogs )
set( DIR_RAY 3d_rendering/raytracing )
set( DIR_RAY_ACC ${DIR_RAY}/accelerators )
set( DIR_RAY_2D ${DIR_RAY}/shapes2D )
@@ -27,9 +28,15 @@ set(3D-VIEWER_SRCS
${DIR_3D_PLUGINS}/3d/pluginldr3D.cpp
3d_cache/3d_cache.cpp
3d_cache/3d_plugin_manager.cpp
${DIR_DLG}/3d_cache_dialogs.cpp
${DIR_DLG}/dialog_select_3d_model_base.cpp
${DIR_DLG}/dialog_select_3d_model.cpp
${DIR_DLG}/panel_preview_3d_model_base.cpp
${DIR_DLG}/panel_preview_3d_model.cpp
3d_canvas/board_adapter.cpp
3d_canvas/create_layer_items.cpp
3d_canvas/create_3Dgraphic_brd_items.cpp
3d_canvas/create_layer_poly.cpp
3d_canvas/eda_3d_canvas.cpp
3d_canvas/eda_3d_canvas_pivot.cpp
3d_model_viewer/eda_3d_model_viewer.cpp
@@ -45,9 +52,7 @@ set(3D-VIEWER_SRCS
${DIR_RAY_ACC}/container_2d.cpp
${DIR_RAY}/PerlinNoise.cpp
${DIR_RAY}/create_scene.cpp
${DIR_RAY}/render_3d_raytrace_base.cpp
${DIR_RAY}/render_3d_raytrace_gl.cpp
${DIR_RAY}/render_3d_raytrace_ram.cpp
${DIR_RAY}/render_3d_raytrace.cpp
${DIR_RAY}/frustum.cpp
${DIR_RAY}/material.cpp
${DIR_RAY}/mortoncodes.cpp
@@ -73,7 +78,8 @@ set(3D-VIEWER_SRCS
${DIR_RAY_3D}/triangle_3d.cpp
3d_rendering/buffers_debug.cpp
3d_rendering/render_3d_base.cpp
3d_rendering/color_rgba.cpp
3d_rendering/camera.cpp
3d_rendering/color_rgb.cpp
3d_rendering/image.cpp
3d_rendering/post_shader.cpp
3d_rendering/post_shader_ssao.cpp
@@ -82,6 +88,14 @@ set(3D-VIEWER_SRCS
3d_rendering/trackball.cpp
3d_viewer/3d_menubar.cpp
3d_viewer/3d_toolbar.cpp
dialogs/panel_3D_colors.cpp
dialogs/panel_3D_colors_base.cpp
dialogs/panel_3D_display_options.cpp
dialogs/panel_3D_display_options_base.cpp
dialogs/panel_3D_opengl_options.cpp
dialogs/panel_3D_opengl_options_base.cpp
dialogs/panel_3D_raytracing_options.cpp
dialogs/panel_3D_raytracing_options_base.cpp
3d_viewer/tools/eda_3d_actions.cpp
3d_viewer/tools/eda_3d_conditions.cpp
3d_viewer/tools/eda_3d_controller.cpp
@@ -91,19 +105,6 @@ set(3D-VIEWER_SRCS
common_ogl/ogl_utils.cpp
3d_fastmath.cpp
3d_math.cpp
dialogs/3d_cache_dialogs.cpp
dialogs/appearance_controls_3D.cpp
dialogs/appearance_controls_3D_base.cpp
dialogs/dialog_select_3d_model_base.cpp
dialogs/dialog_select_3d_model.cpp
dialogs/panel_preview_3d_model_base.cpp
dialogs/panel_preview_3d_model.cpp
dialogs/panel_3D_display_options.cpp
dialogs/panel_3D_display_options_base.cpp
dialogs/panel_3D_opengl_options.cpp
dialogs/panel_3D_opengl_options_base.cpp
dialogs/panel_3D_raytracing_options.cpp
dialogs/panel_3D_raytracing_options_base.cpp
)
add_library(3d-viewer STATIC ${3D-VIEWER_SRCS})
@@ -113,16 +114,16 @@ target_link_libraries( 3d-viewer
PRIVATE
gal
kimath
core
common
nlohmann_json
Boost::headers
${Boost_LIBRARIES}
${wxWidgets_LIBRARIES}
${OPENGL_LIBRARIES}
kicad_3dsg )
add_subdirectory( 3d_cache )
message( STATUS "Including 3Dconnexion SpaceMouse navigation support in 3d-viewer" )
add_subdirectory( 3d_navlib )
target_link_libraries( 3d-viewer PRIVATE 3d-viewer_navlib)
if( KICAD_USE_3DCONNEXION )
message( STATUS "Including 3Dconnexion SpaceMouse navigation support in 3d-viewer" )
add_subdirectory( 3d_navlib )
target_link_libraries( 3d-viewer PRIVATE 3d-viewer_navlib)
endif()
+75 -26
View File
@@ -2,7 +2,7 @@
* This program source code file is part of KiCad, a free EDA CAD application.
*
* Copyright (C) 2015-2016 Mario Luzeiro <mrluzeiro@ua.pt>
* Copyright (C) 1992-2024 KiCad Developers, see AUTHORS.txt for contributors.
* Copyright (C) 1992-2020 KiCad Developers, see AUTHORS.txt for contributors.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
@@ -33,45 +33,94 @@
#include <core/arraydim.h>
const wxGLAttributes OGL_ATT_LIST::GetAttributesList( ANTIALIASING_MODE aAntiAliasingMode,
bool aAlpha )
const int OGL_ATT_LIST::m_openGL_attributes_list[] = {
// Boolean attributes (using itself at padding):
// 0 1
WX_GL_RGBA, WX_GL_RGBA,
// 2 3
WX_GL_DOUBLEBUFFER, WX_GL_DOUBLEBUFFER,
// Normal attributes with values:
// 4 5
WX_GL_DEPTH_SIZE, 16,
// 6 7
WX_GL_STENCIL_SIZE, 8,
// This ones need to be the last in the list (as the tags will set to 0 if AA fails)
// 8 9
WX_GL_SAMPLES, 0, // Disable AA for the start.
//10 11
WX_GL_SAMPLE_BUFFERS, 1, // Enable multisampling support (antialiasing).
0, 0 // NULL termination
};
#define ATT_WX_GL_SAMPLES_OFFSET 8
#define ATT_WX_GL_SAMPLES_OFFSET_DATA 9
#define ATT_WX_GL_SAMPLE_BUFFERS_OFFSET 10
#define ATT_WX_GL_SAMPLE_BUFFERS_DATA 11
int OGL_ATT_LIST::m_openGL_attributes_list_to_use[
arrayDim( OGL_ATT_LIST::m_openGL_attributes_list ) ] = { 0 };
const int* OGL_ATT_LIST::GetAttributesList( ANTIALIASING_MODE aAntiAliasingMode )
{
wxASSERT( aAntiAliasingMode <= ANTIALIASING_MODE::AA_8X );
auto makeAttribs = [aAlpha]( int aSamplers )
{
wxGLAttributes dispAttrs;
dispAttrs.RGBA()
.DoubleBuffer()
.Depth( 16 )
.Stencil( 8 )
.Samplers( aSamplers )
.SampleBuffers( aSamplers >= 0 ? 1 : -1 )
.MinRGBA( 8, 8, 8, aAlpha ? 8 : -1 )
.EndList();
return dispAttrs;
};
int maxSamples = -1;
memcpy( m_openGL_attributes_list_to_use, m_openGL_attributes_list,
sizeof( m_openGL_attributes_list_to_use ) );
if( aAntiAliasingMode > ANTIALIASING_MODE::AA_NONE )
{
// There is a bug on wxGLCanvas that makes IsDisplaySupported fail
// while testing for antialiasing.
// http://trac.wxwidgets.org/ticket/16909
// this next code will only work after this bug is fixed
//
// On my experience (Mario) it was only working on Linux but failing on
// Windows, so there was no AA.
// Check if the canvas supports multisampling.
if( wxGLCanvas::IsDisplaySupported( makeAttribs( 0 ) ) )
if( wxGLCanvas::IsDisplaySupported( m_openGL_attributes_list_to_use ) )
{
static const int aaSamples[4] = { 0, 2, 4, 8 };
static const int aaSamples[4] = {0, 2, 4, 8};
// Check for possible sample sizes, start form the requested.
maxSamples = aaSamples[static_cast<int>( aAntiAliasingMode )];
int maxSamples = aaSamples[static_cast<int>( aAntiAliasingMode )];
while( maxSamples > 0 && !wxGLCanvas::IsDisplaySupported( makeAttribs( maxSamples ) ) )
m_openGL_attributes_list_to_use[ATT_WX_GL_SAMPLES_OFFSET_DATA] = maxSamples;
for( ; (maxSamples > 0) &&
( !wxGLCanvas::IsDisplaySupported( m_openGL_attributes_list_to_use ) );
maxSamples = maxSamples >> 1 )
{
maxSamples = maxSamples >> 1;
m_openGL_attributes_list_to_use[ATT_WX_GL_SAMPLES_OFFSET_DATA] = maxSamples;
}
}
else
{
aAntiAliasingMode = ANTIALIASING_MODE::AA_NONE;
}
}
return makeAttribs( maxSamples );
// Disable antialiasing if it failed or was not requested
if( aAntiAliasingMode == ANTIALIASING_MODE::AA_NONE )
{
// Remove multisampling information
// (hoping that the GPU driver will decide what is best)
m_openGL_attributes_list_to_use[ATT_WX_GL_SAMPLES_OFFSET] = 0;
m_openGL_attributes_list_to_use[ATT_WX_GL_SAMPLES_OFFSET_DATA] = 0;
m_openGL_attributes_list_to_use[ATT_WX_GL_SAMPLE_BUFFERS_OFFSET] = 0;
m_openGL_attributes_list_to_use[ATT_WX_GL_SAMPLE_BUFFERS_DATA] = 0;
}
return m_openGL_attributes_list_to_use;
}
+23 -8
View File
@@ -2,7 +2,7 @@
* This program source code file is part of KiCad, a free EDA CAD application.
*
* Copyright (C) 2015-2016 Mario Luzeiro <mrluzeiro@ua.pt>
* Copyright (C) 1992-2024 KiCad Developers, see AUTHORS.txt for contributors.
* Copyright (C) 1992-2020 KiCad Developers, see AUTHORS.txt for contributors.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
@@ -30,8 +30,6 @@
#ifndef _OGL_ATT_LIST_H
#define _OGL_ATT_LIST_H
#include <wx/glcanvas.h>
/// Anti-aliasing options
enum class ANTIALIASING_MODE
{
@@ -53,12 +51,29 @@ public:
* Get a list of attributes to pass to wxGLCanvas.
*
* @param aAntiAliasingMode = 0 - disabled; try to initialize (if is supported) the
* list with anti aliasing capabilities.
* @param aAlpha set to enable alpha channel.
* @return wxGLAttributes to be passed in the creation of a EDA_3D_CANVAS class
* list with anti aliasing capabilities
* @return a list of options to be passed in the creation of a EDA_3D_CANVAS class
*/
static const wxGLAttributes GetAttributesList( ANTIALIASING_MODE aAntiAliasingMode,
bool aAlpha = false );
static const int* GetAttributesList( ANTIALIASING_MODE aAntiAliasingMode );
private:
/**
* Attributes list to be passed to a wxGLCanvas creation.
*
* This array should be 2*n+1
* Sadly wxwidgets / glx < 13 allowed
* a thing named "boolean attributes" that don't take a value.
* (See src/unix/glx11.cpp -> wxGLCanvasX11::ConvertWXAttrsToGL() ).
* To avoid problems due to this, just specify those attributes twice.
* Only WX_GL_RGBA, WX_GL_DOUBLEBUFFER, WX_GL_STEREO are such boolean
* attributes.
*/
static const int m_openGL_attributes_list[];
/**
* Attributes list that was (eventually) changed and are passed to creation.
*/
static int m_openGL_attributes_list_to_use[];
};
#endif // _OGL_ATT_LIST_H
+7 -32
View File
@@ -46,7 +46,7 @@ void OglGetScreenshot( wxImage& aDstImage )
glGetIntegerv( GL_VIEWPORT, (GLint*) &viewport );
unsigned char* pixelbuffer = (unsigned char*) malloc( viewport.x * viewport.y * 4 );
unsigned char* pixelbuffer = (unsigned char*) malloc( viewport.x * viewport.y * 3 );
// Call glFinish before screenshot to ensure everything is fully drawn.
glFinish();
@@ -54,40 +54,15 @@ void OglGetScreenshot( wxImage& aDstImage )
glPixelStorei( GL_PACK_ALIGNMENT, 1 );
glReadBuffer( GL_BACK_LEFT );
glReadPixels( viewport.originX, viewport.originY, viewport.x, viewport.y, GL_RGBA,
glReadPixels( viewport.originX, viewport.originY, viewport.x, viewport.y, GL_RGB,
GL_UNSIGNED_BYTE, pixelbuffer );
unsigned char* rgbBuffer = (unsigned char*) malloc( viewport.x * viewport.y * 3 );
unsigned char* alphaBuffer = (unsigned char*) malloc( viewport.x * viewport.y );
unsigned char* rgbaPtr = pixelbuffer;
unsigned char* rgbPtr = rgbBuffer;
unsigned char* alphaPtr = alphaBuffer;
for( int y = 0; y < viewport.y; y++ )
{
for( int x = 0; x < viewport.x; x++ )
{
rgbPtr[0] = rgbaPtr[0];
rgbPtr[1] = rgbaPtr[1];
rgbPtr[2] = rgbaPtr[2];
alphaPtr[0] = rgbaPtr[3];
rgbaPtr += 4;
rgbPtr += 3;
alphaPtr += 1;
}
}
// "Sets the image data without performing checks.
// The data given must have the size (width*height*3)
// The data must have been allocated with malloc()
// If static_data is false, after this call the pointer to the data is owned
// by the wxImage object, that will be responsible for deleting it."
aDstImage.SetData( rgbBuffer, viewport.x, viewport.y, false );
aDstImage.SetAlpha( alphaBuffer, false );
free( pixelbuffer );
aDstImage.SetData( pixelbuffer, viewport.x, viewport.y, false );
aDstImage = aDstImage.Mirror( false );
}
@@ -182,7 +157,7 @@ void OglSetDiffuseMaterial( const SFVEC3F &aMaterialDiffuse, float aOpacity,
}
void OglDrawBackground( const SFVEC4F& aTopColor, const SFVEC4F& aBotColor )
void OglDrawBackground( const SFVEC3F& aTopColor, const SFVEC3F& aBotColor )
{
glMatrixMode( GL_PROJECTION );
glLoadIdentity();
@@ -198,14 +173,14 @@ void OglDrawBackground( const SFVEC4F& aTopColor, const SFVEC4F& aBotColor )
glDisable( GL_ALPHA_TEST );
glBegin( GL_QUADS );
glColor4f( aTopColor.r, aTopColor.g, aTopColor.b, aTopColor.a );
glColor4f( aTopColor.x, aTopColor.y, aTopColor.z, 1.0f );
glVertex2f( -1.0, 1.0 ); // Top left corner
glColor4f( aBotColor.r, aBotColor.g, aBotColor.b, aBotColor.a );
glColor4f( aBotColor.x, aBotColor.y, aBotColor.z, 1.0f );
glVertex2f( -1.0,-1.0 ); // bottom left corner
glVertex2f( 1.0,-1.0 ); // bottom right corner
glColor4f( aTopColor.r, aTopColor.g, aTopColor.b, aTopColor.a);
glColor4f( aTopColor.x, aTopColor.y, aTopColor.z, 1.0f );
glVertex2f( 1.0, 1.0 ); // top right corner
glEnd();
}
+1 -1
View File
@@ -71,7 +71,7 @@ GLuint OglLoadTexture( const IMAGE& aImage );
*/
void OglGetScreenshot( wxImage& aDstImage );
void OglDrawBackground( const SFVEC4F& aTopColor, const SFVEC4F& aBotColor );
void OglDrawBackground( const SFVEC3F& aTopColor, const SFVEC3F& aBotColor );
/**
* Reset to default state the texture settings.
-2
View File
@@ -31,11 +31,9 @@
#define OPENGL_INCLUDES_H
#ifdef __APPLE__
#ifndef GL_SILENCE_DEPRECATION
// Apple, in their infinite wisdom, has decided to mark OpenGL as deprecated.
// Luckily we can silence warnings about its deprecation.
#define GL_SILENCE_DEPRECATION 1
#endif
#include <OpenGL/gl.h>
#include <OpenGL/glu.h>
#else
@@ -1,987 +0,0 @@
/*
* This program source code file is part of KiCad, a free EDA CAD application.
*
* Copyright (C) 2023 CERN
* Copyright (C) 2023-2024 KiCad Developers, see AUTHORS.txt for contributors.
*
* This program is free software: you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the
* Free Software Foundation, either version 3 of the License, or (at your
* option) any later version.
*
* This program is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* General Public License for more details.
*
* You should have received a copy of the GNU General Public License along
* with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include <dialogs/appearance_controls_3D.h>
#include <bitmaps.h>
#include <confirm.h>
#include <pgm_base.h>
#include <dpi_scaling_common.h>
#include <eda_list_dialog.h>
#include <pcb_display_options.h>
#include <eda_3d_viewer_frame.h>
#include <pcbnew_settings.h>
#include <project.h>
#include <settings/settings_manager.h>
#include <settings/color_settings.h>
#include <tool/tool_manager.h>
#include <tools/pcb_actions.h>
#include <tools/eda_3d_actions.h>
#include <widgets/bitmap_toggle.h>
#include <widgets/color_swatch.h>
#include <widgets/grid_bitmap_toggle.h>
#include <dialogs/eda_view_switcher.h>
#include <wx/bmpbuttn.h>
#include <wx/sizer.h>
#include <wx/textdlg.h>
#include <wx/checkbox.h>
#include <../3d_rendering/opengl/render_3d_opengl.h>
#define RR APPEARANCE_CONTROLS_3D::APPEARANCE_SETTING_3D // Render Row abbreviation to reduce source width
/// Template for object appearance settings
const APPEARANCE_CONTROLS_3D::APPEARANCE_SETTING_3D APPEARANCE_CONTROLS_3D::s_layerSettings[] = {
// text id tooltip
RR( _HKI( "Board Body" ), LAYER_3D_BOARD, _HKI( "Show board body" ) ),
RR( _HKI( "F.Cu" ), LAYER_3D_COPPER_TOP, _HKI( "Show front copper / surface finish color" ) ),
RR( _HKI( "B.Cu" ), LAYER_3D_COPPER_BOTTOM, _HKI( "Show back copper / surface finish color" ) ),
RR( _HKI( "Adhesive" ), LAYER_3D_ADHESIVE, _HKI( "Show adhesive" ) ),
RR( _HKI( "Solder Paste" ), LAYER_3D_SOLDERPASTE, _HKI( "Show solder paste" ) ),
RR( _HKI( "F.Silkscreen" ), LAYER_3D_SILKSCREEN_TOP, _HKI( "Show front silkscreen" ) ),
RR( _HKI( "B.Silkscreen" ), LAYER_3D_SILKSCREEN_BOTTOM, _HKI( "Show back silkscreen" ) ),
RR( _HKI( "F.Mask" ), LAYER_3D_SOLDERMASK_TOP, _HKI( "Show front solder mask" ) ),
RR( _HKI( "B.Mask" ), LAYER_3D_SOLDERMASK_BOTTOM, _HKI( "Show back solder mask" ) ),
RR( _HKI( "User.Drawings" ), LAYER_3D_USER_DRAWINGS, _HKI( "Show user drawings layer" ) ),
RR( _HKI( "User.Comments" ), LAYER_3D_USER_COMMENTS, _HKI( "Show user comments layer" ) ),
RR( _HKI( "User.Eco1" ), LAYER_3D_USER_ECO1, _HKI( "Show user ECO1 layer" ) ),
RR( _HKI( "User.Eco2" ), LAYER_3D_USER_ECO2, _HKI( "Show user ECO2 layer" ) ),
RR(),
RR( _HKI( "Through-hole Models" ), LAYER_3D_TH_MODELS, EDA_3D_ACTIONS::showTHT ),
RR( _HKI( "SMD Models" ), LAYER_3D_SMD_MODELS, EDA_3D_ACTIONS::showSMD ),
RR( _HKI( "Virtual Models" ), LAYER_3D_VIRTUAL_MODELS, EDA_3D_ACTIONS::showVirtual ),
RR( _HKI( "Models not in POS File" ), LAYER_3D_MODELS_NOT_IN_POS, EDA_3D_ACTIONS::showNotInPosFile ),
RR( _HKI( "Models marked DNP" ), LAYER_3D_MODELS_MARKED_DNP, EDA_3D_ACTIONS::showDNP ),
RR( _HKI( "Model Bounding Boxes" ), LAYER_3D_BOUNDING_BOXES, EDA_3D_ACTIONS::showBBoxes ),
RR(),
RR( _HKI( "Values" ), LAYER_FP_VALUES, _HKI( "Show footprint values" ) ),
RR( _HKI( "References" ), LAYER_FP_REFERENCES, _HKI( "Show footprint references" ) ),
RR( _HKI( "Footprint Text" ), LAYER_FP_TEXT, _HKI( "Show all footprint text" ) ),
RR( _HKI( "Off-board Silkscreen" ), LAYER_3D_OFF_BOARD_SILK, _HKI( "Do not clip silk layers to board outline" ) ),
RR(),
RR( _HKI( "3D Axis" ), LAYER_3D_AXES, EDA_3D_ACTIONS::showAxis ),
RR( _HKI( "Background Start" ), LAYER_3D_BACKGROUND_TOP, _HKI( "Background gradient start color" ) ),
RR( _HKI( "Background End" ), LAYER_3D_BACKGROUND_BOTTOM, _HKI( "Background gradient end color" ) ),
};
// The list of IDs that can have colors coming from the board stackup, and cannot be
// modified if use colors from stackup is activated
static std::vector<int> inStackupColors{ LAYER_3D_BOARD, LAYER_3D_COPPER_TOP,
LAYER_3D_COPPER_BOTTOM, LAYER_3D_SOLDERPASTE,
LAYER_3D_SILKSCREEN_TOP, LAYER_3D_SILKSCREEN_BOTTOM,
LAYER_3D_SOLDERMASK_TOP, LAYER_3D_SOLDERMASK_BOTTOM
};
APPEARANCE_CONTROLS_3D::APPEARANCE_CONTROLS_3D( EDA_3D_VIEWER_FRAME* aParent,
wxWindow* aFocusOwner ) :
APPEARANCE_CONTROLS_3D_BASE( aParent ),
m_frame( aParent ),
m_focusOwner( aFocusOwner ),
m_lastSelectedViewport( nullptr )
{
DPI_SCALING_COMMON dpi( nullptr, m_frame );
int screenHeight = wxSystemSettings::GetMetric( wxSYS_SCREEN_Y );
m_pointSize = wxSystemSettings::GetFont( wxSYS_DEFAULT_GUI_FONT ).GetPointSize();
m_layerPanelColour = m_panelLayers->GetBackgroundColour().ChangeLightness( 110 );
SetBorders( true, false, false, false );
m_layersOuterSizer = new wxBoxSizer( wxVERTICAL );
m_windowLayers->SetSizer( m_layersOuterSizer );
m_windowLayers->SetScrollRate( 0, 5 );
m_windowLayers->Bind( wxEVT_SET_FOCUS, &APPEARANCE_CONTROLS_3D::OnSetFocus, this );
m_envOuterSizer = new wxBoxSizer( wxVERTICAL );
wxFont infoFont = KIUI::GetInfoFont( this );
m_panelLayers->SetFont( infoFont );
m_windowLayers->SetFont( infoFont );
m_presetsLabel->SetFont( infoFont );
m_viewportsLabel->SetFont( infoFont );
// Create display options
m_cbUseBoardStackupColors = new wxCheckBox( m_panelLayers, wxID_ANY,
_( "Use board stackup colors" ) );
m_cbUseBoardStackupColors->SetFont( infoFont );
m_cbUseBoardStackupColors->Bind( wxEVT_CHECKBOX,
[this]( wxCommandEvent& aEvent )
{
EDA_3D_VIEWER_SETTINGS* cfg = m_frame->GetAdapter().m_Cfg;
cfg->m_UseStackupColors = aEvent.IsChecked();
UpdateLayerCtls();
syncLayerPresetSelection();
m_frame->NewDisplay( true );
} );
m_panelLayersSizer->Add( m_cbUseBoardStackupColors, 0, wxEXPAND | wxTOP | wxLEFT | wxRIGHT, 7 );
m_cbLayerPresets->SetToolTip( wxString::Format( _( "Save and restore color and visibility "
"combinations.\n"
"Use %s+Tab to activate selector.\n"
"Successive Tabs while holding %s down will "
"cycle through presets in the popup." ),
KeyNameFromKeyCode( PRESET_SWITCH_KEY ),
KeyNameFromKeyCode( PRESET_SWITCH_KEY ) ) );
m_cbViewports->SetToolTip( wxString::Format( _( "Save and restore camera position and zoom.\n"
"Use %s+Tab to activate selector.\n"
"Successive Tabs while holding %s down will "
"cycle through viewports in the popup." ),
KeyNameFromKeyCode( VIEWPORT_SWITCH_KEY ),
KeyNameFromKeyCode( VIEWPORT_SWITCH_KEY ) ) );
if( screenHeight <= 900 && m_pointSize >= FromDIP( KIUI::c_IndicatorSizeDIP ) )
m_pointSize = m_pointSize * 8 / 10;
m_cbLayerPresets->Bind( wxEVT_CHOICE, &APPEARANCE_CONTROLS_3D::onLayerPresetChanged, this );
m_toggleGridRenderer = new GRID_BITMAP_TOGGLE_RENDERER(
KiBitmapBundle( BITMAPS::visibility ), KiBitmapBundle( BITMAPS::visibility_off ) );
m_frame->Bind( EDA_LANG_CHANGED, &APPEARANCE_CONTROLS_3D::OnLanguageChanged, this );
}
APPEARANCE_CONTROLS_3D::~APPEARANCE_CONTROLS_3D()
{
m_frame->Unbind( EDA_LANG_CHANGED, &APPEARANCE_CONTROLS_3D::OnLanguageChanged, this );
}
wxSize APPEARANCE_CONTROLS_3D::GetBestSize() const
{
DPI_SCALING_COMMON dpi( nullptr, m_frame );
wxSize size( 220 * dpi.GetScaleFactor(), 480 * dpi.GetScaleFactor() );
return size;
}
void APPEARANCE_CONTROLS_3D::OnSetFocus( wxFocusEvent& aEvent )
{
#ifdef __WXMSW__
// In wxMSW, buttons won't process events unless they have focus, so we'll let it take the
// focus and give it back to the parent in the button event handler.
if( wxBitmapButton* btn = dynamic_cast<wxBitmapButton*>( aEvent.GetEventObject() ) )
{
wxCommandEvent evt( wxEVT_BUTTON );
wxPostEvent( btn, evt );
}
#endif
passOnFocus();
aEvent.Skip();
}
void APPEARANCE_CONTROLS_3D::OnSize( wxSizeEvent& aEvent )
{
aEvent.Skip();
}
void APPEARANCE_CONTROLS_3D::rebuildControls()
{
Freeze();
rebuildLayers();
m_cbUseBoardStackupColors->SetLabel( _( "Use board stackup colors" ) );
rebuildLayerPresetsWidget();
rebuildViewportsWidget();
Thaw();
Refresh();
}
void APPEARANCE_CONTROLS_3D::OnLanguageChanged( wxCommandEvent& aEvent )
{
rebuildControls();
aEvent.Skip();
}
void APPEARANCE_CONTROLS_3D::OnDarkModeToggle()
{
// This is essentially a list of hacks because DarkMode isn't yet implemented inside
// wxWidgets.
//
// The individual wxPanels, COLOR_SWATCHes and GRID_CELL_COLOR_RENDERERs should really be
// overriding some virtual method or responding to some wxWidgets event so that the parent
// doesn't have to know what it contains. But, that's not where we are, so... :shrug:
m_layerPanelColour = m_panelLayers->GetBackgroundColour().ChangeLightness( 110 );
m_windowLayers->SetBackgroundColour( m_layerPanelColour );
for( wxSizerItem* child : m_layersOuterSizer->GetChildren() )
{
if( child && child->GetWindow() )
child->GetWindow()->SetBackgroundColour( m_layerPanelColour );
}
}
void APPEARANCE_CONTROLS_3D::CommonSettingsChanged()
{
rebuildControls();
UpdateLayerCtls();
syncLayerPresetSelection();
}
void APPEARANCE_CONTROLS_3D::ApplyLayerPreset( const wxString& aPresetName )
{
if( aPresetName == FOLLOW_PCB || aPresetName == FOLLOW_PLOT_SETTINGS )
{
m_frame->GetAdapter().m_Cfg->m_CurrentPreset = aPresetName;
UpdateLayerCtls();
m_frame->NewDisplay( true );
}
else if( LAYER_PRESET_3D* preset = m_frame->GetAdapter().m_Cfg->FindPreset( aPresetName ) )
{
doApplyLayerPreset( *preset );
}
// Move to front of MRU list
if( m_presetMRU.Index( aPresetName ) != wxNOT_FOUND )
m_presetMRU.Remove( aPresetName );
m_presetMRU.Insert( aPresetName, 0 );
updateLayerPresetWidget( aPresetName );
}
std::vector<VIEWPORT3D> APPEARANCE_CONTROLS_3D::GetUserViewports() const
{
std::vector<VIEWPORT3D> ret;
for( const auto& [name, viewport] : m_viewports )
ret.emplace_back( viewport );
return ret;
}
void APPEARANCE_CONTROLS_3D::SetUserViewports( std::vector<VIEWPORT3D>& aViewportList )
{
m_viewports.clear();
for( const VIEWPORT3D& viewport : aViewportList )
{
if( m_viewports.count( viewport.name ) )
continue;
m_viewports[viewport.name] = viewport;
m_viewportMRU.Add( viewport.name );
}
rebuildViewportsWidget();
// Now is as good a time as any to initialize the layer presets as well.
rebuildLayerPresetsWidget();
m_presetMRU.Add( FOLLOW_PCB );
m_presetMRU.Add( FOLLOW_PLOT_SETTINGS );
for( const LAYER_PRESET_3D& preset : m_frame->GetAdapter().m_Cfg->m_LayerPresets )
m_presetMRU.Add( preset.name );
}
void APPEARANCE_CONTROLS_3D::ApplyViewport( const wxString& aViewportName )
{
int idx = m_cbViewports->FindString( aViewportName );
if( idx >= 0 && idx < (int)m_cbViewports->GetCount() - 3 /* separator */ )
{
m_cbViewports->SetSelection( idx );
m_lastSelectedViewport = static_cast<VIEWPORT3D*>( m_cbViewports->GetClientData( idx ) );
}
else
{
m_cbViewports->SetSelection( m_cbViewports->GetCount() - 3 ); // separator
m_lastSelectedViewport = nullptr;
}
if( m_lastSelectedViewport )
doApplyViewport( *m_lastSelectedViewport );
}
void APPEARANCE_CONTROLS_3D::OnLayerVisibilityChanged( int aLayer, bool isVisible )
{
std::bitset<LAYER_3D_END> visibleLayers = m_frame->GetAdapter().GetVisibleLayers();
const std::map<int, COLOR4D>& colors = m_frame->GetAdapter().GetLayerColors();
bool killFollow = false;
bool doFastRefresh = false; // true to just refresh the display
// Special-case controls
switch( aLayer )
{
case LAYER_FP_TEXT:
// Because Footprint Text is a meta-control that also can disable values/references,
// drag them along here so that the user is less likely to be confused.
if( !isVisible )
{
visibleLayers.set( LAYER_FP_REFERENCES, false );
visibleLayers.set( LAYER_FP_VALUES, false );
}
visibleLayers.set( LAYER_FP_TEXT, isVisible );
killFollow = true;
break;
case LAYER_FP_REFERENCES:
case LAYER_FP_VALUES:
// In case that user changes Footprint Value/References when the Footprint Text
// meta-control is disabled, we should put it back on.
if( isVisible )
visibleLayers.set( LAYER_FP_TEXT, true );
visibleLayers.set( aLayer, isVisible );
killFollow = true;
break;
case LAYER_3D_BOARD:
case LAYER_3D_COPPER_TOP:
case LAYER_3D_COPPER_BOTTOM:
case LAYER_3D_SILKSCREEN_BOTTOM:
case LAYER_3D_SILKSCREEN_TOP:
case LAYER_3D_SOLDERMASK_BOTTOM:
case LAYER_3D_SOLDERMASK_TOP:
case LAYER_3D_SOLDERPASTE:
case LAYER_3D_ADHESIVE:
case LAYER_3D_USER_COMMENTS:
case LAYER_3D_USER_DRAWINGS:
case LAYER_3D_USER_ECO1:
case LAYER_3D_USER_ECO2:
visibleLayers.set( aLayer, isVisible );
killFollow = true;
break;
case LAYER_3D_TH_MODELS:
case LAYER_3D_SMD_MODELS:
case LAYER_3D_VIRTUAL_MODELS:
case LAYER_3D_MODELS_NOT_IN_POS:
case LAYER_3D_MODELS_MARKED_DNP:
doFastRefresh = true;
visibleLayers.set( aLayer, isVisible );
break;
default:
visibleLayers.set( aLayer, isVisible );
break;
}
m_frame->GetAdapter().SetVisibleLayers( visibleLayers );
m_frame->GetAdapter().SetLayerColors( colors );
const wxString& currentPreset = m_frame->GetAdapter().m_Cfg->m_CurrentPreset;
if( ( currentPreset != FOLLOW_PCB && currentPreset != FOLLOW_PLOT_SETTINGS ) || killFollow )
syncLayerPresetSelection();
UpdateLayerCtls();
if( doFastRefresh && m_frame->GetAdapter().m_Cfg->m_Render.engine == RENDER_ENGINE::OPENGL )
{
RENDER_3D_OPENGL* renderer =
static_cast<RENDER_3D_OPENGL*>( m_frame->GetCanvas()->GetCurrentRender() );
renderer->Load3dModelsIfNeeded();
m_frame->GetCanvas()->Request_refresh();
}
else
{
m_frame->NewDisplay( true );
}
}
void APPEARANCE_CONTROLS_3D::onColorSwatchChanged( COLOR_SWATCH* aSwatch )
{
std::bitset<LAYER_3D_END> visibleLayers = m_frame->GetAdapter().GetVisibleLayers();
std::map<int, COLOR4D> colors = m_frame->GetAdapter().GetLayerColors();
m_frame->GetAdapter().SetVisibleLayers( visibleLayers );
m_frame->GetAdapter().SetLayerColors( colors );
int layer = aSwatch->GetId();
COLOR4D newColor = aSwatch->GetSwatchColor();
colors[ layer ] = newColor;
if( layer == LAYER_3D_COPPER_TOP )
colors[ LAYER_3D_COPPER_BOTTOM ] = newColor;
else if( layer == LAYER_3D_COPPER_BOTTOM )
colors[ LAYER_3D_COPPER_TOP ] = newColor;
m_frame->GetAdapter().SetLayerColors( colors );
syncLayerPresetSelection();
m_frame->NewDisplay( true );
}
void APPEARANCE_CONTROLS_3D::rebuildLayers()
{
int swatchWidth = m_windowLayers->ConvertDialogToPixels( wxSize( 8, 0 ) ).x;
std::bitset<LAYER_3D_END> visibleLayers = m_frame->GetAdapter().GetVisibleLayers();
std::map<int, COLOR4D> colors = m_frame->GetAdapter().GetLayerColors();
std::map<int, COLOR4D> defaultColors = m_frame->GetAdapter().GetDefaultColors();
m_layerSettings.clear();
m_layersOuterSizer->Clear( true );
m_layersOuterSizer->AddSpacer( 5 );
m_envOuterSizer->Clear( true );
auto appendLayer =
[&]( const std::unique_ptr<APPEARANCE_SETTING_3D>& aSetting )
{
wxBoxSizer* sizer = new wxBoxSizer( wxHORIZONTAL );
int layer = aSetting->m_Id;
aSetting->m_Visible = visibleLayers.test( layer );
if( colors.count( layer ) )
{
COLOR_SWATCH* swatch = new COLOR_SWATCH( m_windowLayers, colors[ layer ], layer,
COLOR4D::WHITE, defaultColors[ layer ],
SWATCH_SMALL );
swatch->SetToolTip( _( "Left double click or middle click to change color" ) );
swatch->SetReadOnlyCallback(
[this]()
{
WX_INFOBAR* infobar = m_frame->GetInfoBar();
infobar->RemoveAllButtons();
infobar->AddCloseButton();
infobar->ShowMessageFor( _( "Uncheck 'Use board stackup colors' to "
"allow color editing." ),
10000, wxICON_INFORMATION );
} );
sizer->Add( swatch, 0, wxALIGN_CENTER_VERTICAL, 0 );
aSetting->m_Ctl_color = swatch;
swatch->Bind( COLOR_SWATCH_CHANGED,
[this]( wxCommandEvent& event )
{
auto swatch = static_cast<COLOR_SWATCH*>( event.GetEventObject() );
onColorSwatchChanged( swatch );
passOnFocus();
} );
}
else
{
sizer->AddSpacer( swatchWidth );
}
sizer->AddSpacer( 5 );
wxStaticText* label = new wxStaticText( m_windowLayers, layer, aSetting->GetLabel() );
label->Wrap( -1 );
label->SetToolTip( aSetting->GetTooltip() );
if( layer == LAYER_3D_BACKGROUND_TOP || layer == LAYER_3D_BACKGROUND_BOTTOM )
{
sizer->AddSpacer( swatchWidth );
}
else
{
BITMAP_TOGGLE* btn_visible = new BITMAP_TOGGLE(
m_windowLayers, layer, KiBitmapBundle( BITMAPS::visibility ),
KiBitmapBundle( BITMAPS::visibility_off ), aSetting->m_Visible );
btn_visible->Bind( TOGGLE_CHANGED,
[this]( wxCommandEvent& aEvent )
{
int id = static_cast<wxWindow*>( aEvent.GetEventObject() )->GetId();
bool isVisible = aEvent.GetInt();
OnLayerVisibilityChanged( id, isVisible );
passOnFocus();
} );
wxString tip;
tip.Printf( _( "Show or hide %s" ), aSetting->GetLabel().Lower() );
btn_visible->SetToolTip( tip );
aSetting->m_Ctl_visibility = btn_visible;
sizer->Add( btn_visible, 0, wxALIGN_CENTER_VERTICAL, 0 );
}
sizer->AddSpacer( 5 );
sizer->Add( label, 0, wxALIGN_CENTER_VERTICAL, 0 );
m_layersOuterSizer->Add( sizer, 0, wxEXPAND | wxLEFT | wxRIGHT, 5 );
m_layersOuterSizer->AddSpacer( 2 );
};
for( const APPEARANCE_SETTING_3D& s_setting : s_layerSettings )
{
m_layerSettings.emplace_back( std::make_unique<APPEARANCE_SETTING_3D>( s_setting ) );
std::unique_ptr<APPEARANCE_SETTING_3D>& setting = m_layerSettings.back();
if( setting->m_Spacer )
m_layersOuterSizer->AddSpacer( m_pointSize );
else
appendLayer( setting );
m_layerSettingsMap[setting->m_Id] = setting.get();
}
m_sizerOuter->Layout();
}
void APPEARANCE_CONTROLS_3D::UpdateLayerCtls()
{
EDA_3D_VIEWER_SETTINGS* cfg = m_frame->GetAdapter().m_Cfg;
std::bitset<LAYER_3D_END> visibleLayers = m_frame->GetAdapter().GetVisibleLayers();
std::map<int, COLOR4D> colors = m_frame->GetAdapter().GetLayerColors();
for( std::unique_ptr<APPEARANCE_SETTING_3D>& setting : m_layerSettings )
{
if( setting->m_Spacer )
continue;
if( setting->m_Ctl_visibility )
setting->m_Ctl_visibility->SetValue( visibleLayers.test( setting->m_Id ) );
if( setting->m_Ctl_color )
{
setting->m_Ctl_color->SetSwatchColor( colors[ setting->m_Id ], false );
// if cfg->m_UseStackupColors is set, board colors cannot be modified locally, but
// other colors can be
if( std::find( inStackupColors.begin(), inStackupColors.end(), setting->m_Id )
!= inStackupColors.end() )
{
if( cfg )
setting->m_Ctl_color->SetReadOnly( cfg->m_UseStackupColors );
}
}
}
if( cfg )
m_cbUseBoardStackupColors->SetValue( cfg->m_UseStackupColors );
}
void APPEARANCE_CONTROLS_3D::rebuildLayerPresetsWidget()
{
m_presetsLabel->SetLabel( wxString::Format( _( "Presets (%s+Tab):" ),
KeyNameFromKeyCode( PRESET_SWITCH_KEY ) ) );
m_cbLayerPresets->Clear();
// Build the layers preset list.
m_cbLayerPresets->Append( _( "Follow PCB Editor" ) );
m_cbLayerPresets->Append( _( "Follow PCB Plot Settings" ) );
for( const LAYER_PRESET_3D& preset : m_frame->GetAdapter().m_Cfg->m_LayerPresets )
m_cbLayerPresets->Append( preset.name );
m_cbLayerPresets->Append( wxT( "---" ) );
m_cbLayerPresets->Append( _( "Save preset..." ) );
m_cbLayerPresets->Append( _( "Delete preset..." ) );
updateLayerPresetWidget( m_frame->GetAdapter().m_Cfg->m_CurrentPreset );
}
void APPEARANCE_CONTROLS_3D::syncLayerPresetSelection()
{
m_frame->GetAdapter().m_Cfg->m_CurrentPreset = wxEmptyString;
std::vector<LAYER_PRESET_3D>& presets = m_frame->GetAdapter().m_Cfg->m_LayerPresets;
std::bitset<LAYER_3D_END> visibleLayers = m_frame->GetAdapter().GetVisibleLayers();
std::map<int, COLOR4D> colors = m_frame->GetAdapter().GetLayerColors();
auto it = std::find_if(
presets.begin(), presets.end(),
[&]( const LAYER_PRESET_3D& aPreset )
{
if( aPreset.name.Lower() == _( "legacy colors" )
&& m_cbUseBoardStackupColors->GetValue() )
{
return false;
}
for( int layer = LAYER_3D_BOARD; layer < LAYER_3D_END; ++layer )
{
if( aPreset.layers.test( layer ) != visibleLayers.test( layer ) )
return false;
}
for( int layer : { LAYER_FP_REFERENCES, LAYER_FP_VALUES, LAYER_FP_TEXT } )
{
if( aPreset.layers.test( layer ) != visibleLayers.test( layer ) )
return false;
}
for( int layer = LAYER_3D_START + 1; layer < LAYER_3D_END; ++layer )
{
auto it1 = aPreset.colors.find( layer );
auto it2 = colors.find( layer );
if( it1 != aPreset.colors.end() && it2 != colors.end() && *it1 != *it2 )
return false;
}
return true;
} );
if( it != presets.end() )
{
m_frame->GetAdapter().m_Cfg->m_CurrentPreset = it->name;
m_cbLayerPresets->SetStringSelection( it->name );
}
else
{
m_cbLayerPresets->SetSelection( m_cbLayerPresets->GetCount() - 3 ); // separator
}
}
void APPEARANCE_CONTROLS_3D::updateLayerPresetWidget( const wxString& aName )
{
if( aName == FOLLOW_PCB )
m_cbLayerPresets->SetSelection( 0 );
else if( aName == FOLLOW_PLOT_SETTINGS )
m_cbLayerPresets->SetSelection( 1 );
else if( !m_cbLayerPresets->SetStringSelection( aName ) )
m_cbLayerPresets->SetSelection( m_cbLayerPresets->GetCount() - 3 ); // separator
}
void APPEARANCE_CONTROLS_3D::onLayerPresetChanged( wxCommandEvent& aEvent )
{
EDA_3D_VIEWER_SETTINGS* cfg = m_frame->GetAdapter().m_Cfg;
int count = m_cbLayerPresets->GetCount();
int index = m_cbLayerPresets->GetSelection();
wxString name;
auto resetSelection =
[&]()
{
updateLayerPresetWidget( cfg->m_CurrentPreset );
};
if( index == 0 )
{
name = FOLLOW_PCB;
cfg->m_CurrentPreset = name;
UpdateLayerCtls();
m_frame->NewDisplay( true );
}
else if( index == 1 )
{
name = FOLLOW_PLOT_SETTINGS;
cfg->m_CurrentPreset = name;
UpdateLayerCtls();
m_frame->NewDisplay( true );
}
else if( index == count - 3 )
{
// Separator: reject the selection
resetSelection();
return;
}
else if( index == count - 2 )
{
wxTextEntryDialog dlg( wxGetTopLevelParent( this ), _( "Layer preset name:" ),
_( "Save Layer Preset" ) );
if( dlg.ShowModal() != wxID_OK )
{
resetSelection();
return;
}
std::bitset<LAYER_3D_END> visibleLayers = m_frame->GetAdapter().GetVisibleLayers();
std::map<int, COLOR4D> colors = m_frame->GetAdapter().GetLayerColors();
name = dlg.GetValue();
if( LAYER_PRESET_3D* preset = cfg->FindPreset( name ) )
{
if( !IsOK( wxGetTopLevelParent( this ), _( "Overwrite existing preset?" ) ) )
{
resetSelection();
return;
}
preset->layers = visibleLayers;
preset->colors = colors;
m_cbLayerPresets->SetSelection( m_cbLayerPresets->FindString( name ) );
}
else
{
cfg->m_LayerPresets.emplace_back( name, visibleLayers, colors );
m_cbLayerPresets->SetSelection( m_cbLayerPresets->Insert( name, index - 1 ) );
}
cfg->m_CurrentPreset = name;
m_presetMRU.Insert( name, 0 );
return;
}
else if( index == count - 1 )
{
wxArrayString headers;
std::vector<wxArrayString> items;
headers.Add( _( "Presets" ) );
for( LAYER_PRESET_3D& preset : cfg->m_LayerPresets )
{
wxArrayString item;
item.Add( preset.name );
items.emplace_back( item );
}
EDA_LIST_DIALOG dlg( m_frame, _( "Delete Preset" ), headers, items );
dlg.SetListLabel( _( "Select preset:" ) );
if( dlg.ShowModal() == wxID_OK )
{
name = dlg.GetTextSelection();
if( m_cbLayerPresets->FindString( name ) != wxNOT_FOUND )
m_cbLayerPresets->Delete( m_cbLayerPresets->FindString( name ) );
alg::delete_if( cfg->m_LayerPresets,
[name]( const LAYER_PRESET_3D& preset )
{
return preset.name == name;
} );
if( cfg->m_CurrentPreset == name )
cfg->m_CurrentPreset = wxEmptyString;
m_presetMRU.Remove( name );
}
resetSelection();
return;
}
else if( LAYER_PRESET_3D* preset = cfg->FindPreset( m_cbLayerPresets->GetStringSelection() ) )
{
name = preset->name;
doApplyLayerPreset( *preset );
}
// Move to front of MRU list
if( m_presetMRU.Index( name ) != wxNOT_FOUND )
m_presetMRU.Remove( name );
m_presetMRU.Insert( name, 0 );
passOnFocus();
}
void APPEARANCE_CONTROLS_3D::doApplyLayerPreset( const LAYER_PRESET_3D& aPreset )
{
BOARD_ADAPTER& adapter = m_frame->GetAdapter();
adapter.m_Cfg->m_CurrentPreset = aPreset.name;
adapter.SetVisibleLayers( aPreset.layers );
adapter.SetLayerColors( aPreset.colors );
if( aPreset.name.Lower() == _( "legacy colors" ) )
adapter.m_Cfg->m_UseStackupColors = false;
UpdateLayerCtls();
m_frame->NewDisplay( true );
}
void APPEARANCE_CONTROLS_3D::rebuildViewportsWidget()
{
m_viewportsLabel->SetLabel( wxString::Format( _( "Viewports (%s+Tab):" ),
KeyNameFromKeyCode( VIEWPORT_SWITCH_KEY ) ) );
m_cbViewports->Clear();
for( std::pair<const wxString, VIEWPORT3D>& pair : m_viewports )
m_cbViewports->Append( pair.first, static_cast<void*>( &pair.second ) );
m_cbViewports->Append( wxT( "---" ) );
m_cbViewports->Append( _( "Save viewport..." ) );
m_cbViewports->Append( _( "Delete viewport..." ) );
m_cbViewports->SetSelection( m_cbViewports->GetCount() - 3 );
m_lastSelectedViewport = nullptr;
}
void APPEARANCE_CONTROLS_3D::onViewportChanged( wxCommandEvent& aEvent )
{
int count = m_cbViewports->GetCount();
int index = m_cbViewports->GetSelection();
if( index >= 0 && index < count - 3 )
{
VIEWPORT3D* viewport = static_cast<VIEWPORT3D*>( m_cbViewports->GetClientData( index ) );
wxCHECK( viewport, /* void */ );
doApplyViewport( *viewport );
if( !viewport->name.IsEmpty() )
{
m_viewportMRU.Remove( viewport->name );
m_viewportMRU.Insert( viewport->name, 0 );
}
}
else if( index == count - 2 )
{
// Save current state to new preset
wxString name;
wxTextEntryDialog dlg( wxGetTopLevelParent( this ), _( "Viewport name:" ),
_( "Save Viewport" ), name );
if( dlg.ShowModal() != wxID_OK )
{
if( m_lastSelectedViewport )
m_cbViewports->SetStringSelection( m_lastSelectedViewport->name );
else
m_cbViewports->SetSelection( m_cbViewports->GetCount() - 3 );
return;
}
name = dlg.GetValue();
bool exists = m_viewports.count( name );
if( !exists )
{
m_viewports[name] = VIEWPORT3D( name, m_frame->GetCurrentCamera().GetViewMatrix() );
index = m_cbViewports->Insert( name, index-1, static_cast<void*>( &m_viewports[name] ) );
}
else
{
m_viewports[name].matrix = m_frame->GetCurrentCamera().GetViewMatrix();
index = m_cbViewports->FindString( name );
m_viewportMRU.Remove( name );
}
m_cbViewports->SetSelection( index );
m_viewportMRU.Insert( name, 0 );
return;
}
else if( index == count - 1 )
{
// Delete an existing viewport
wxArrayString headers;
std::vector<wxArrayString> items;
headers.Add( _( "Viewports" ) );
for( std::pair<const wxString, VIEWPORT3D>& pair : m_viewports )
{
wxArrayString item;
item.Add( pair.first );
items.emplace_back( item );
}
EDA_LIST_DIALOG dlg( m_frame, _( "Delete Viewport" ), headers, items );
dlg.SetListLabel( _( "Select viewport:" ) );
if( dlg.ShowModal() == wxID_OK )
{
wxString viewportName = dlg.GetTextSelection();
int idx = m_cbViewports->FindString( viewportName );
if( idx != wxNOT_FOUND )
{
m_viewports.erase( viewportName );
m_cbViewports->Delete( idx );
m_viewportMRU.Remove( viewportName );
}
}
if( m_lastSelectedViewport )
m_cbViewports->SetStringSelection( m_lastSelectedViewport->name );
else
m_cbViewports->SetSelection( m_cbViewports->GetCount() - 3 );
return;
}
passOnFocus();
}
void APPEARANCE_CONTROLS_3D::onUpdateViewportsCb( wxUpdateUIEvent& aEvent )
{
int count = m_cbViewports->GetCount();
int index = m_cbViewports->GetSelection();
if( index >= 0 && index < count - 3 )
{
VIEWPORT3D* viewport = static_cast<VIEWPORT3D*>( m_cbViewports->GetClientData( index ) );
wxCHECK( viewport, /* void */ );
if( m_frame->GetCurrentCamera().GetViewMatrix() != viewport->matrix )
m_cbViewports->SetSelection( -1 );
}
}
void APPEARANCE_CONTROLS_3D::doApplyViewport( const VIEWPORT3D& aViewport )
{
m_frame->GetCurrentCamera().SetViewMatrix( aViewport.matrix );
if( m_frame->GetAdapter().m_Cfg->m_Render.engine == RENDER_ENGINE::OPENGL )
m_frame->GetCanvas()->Request_refresh();
else
m_frame->GetCanvas()->RenderRaytracingRequest();
}
void APPEARANCE_CONTROLS_3D::passOnFocus()
{
m_focusOwner->SetFocus();
}
-192
View File
@@ -1,192 +0,0 @@
/*
* This program source code file is part of KiCad, a free EDA CAD application.
*
* Copyright (C) 2023 CERN
* Copyright (C) 2023 KiCad Developers, see AUTHORS.txt for contributors.
*
* This program is free software: you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the
* Free Software Foundation, either version 3 of the License, or (at your
* option) any later version.
*
* This program is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* General Public License for more details.
*
* You should have received a copy of the GNU General Public License along
* with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef APPEARANCE_CONTROLS_3D_H
#define APPEARANCE_CONTROLS_3D_H
#include <vector>
#include <gal/color4d.h>
#include <layer_ids.h>
#include <3d_canvas/board_adapter.h>
#include <dialogs/appearance_controls_3D_base.h>
#include <tool/tool_action.h>
#include <wx/intl.h>
class BITMAP_TOGGLE;
class COLOR_SWATCH;
class EDA_3D_VIEWER_FRAME;
class ROW_ICON_PROVIDER;
class GRID_BITMAP_TOGGLE_RENDERER;
using KIGFX::COLOR4D;
class APPEARANCE_CONTROLS_3D : public APPEARANCE_CONTROLS_3D_BASE
{
public:
/**
* Container for an appearance setting (can control a layer class, object type, etc.)
*/
class APPEARANCE_SETTING_3D
{
public:
int m_Id;
bool m_Visible;
bool m_Spacer;
BITMAP_TOGGLE* m_Ctl_visibility;
COLOR_SWATCH* m_Ctl_color;
APPEARANCE_SETTING_3D( const wxString& aLabel, int aId, const wxString& aTooltip ) :
m_Id( aId ),
m_Visible( true ),
m_Spacer( false ),
m_Ctl_visibility( nullptr ),
m_Ctl_color( nullptr ),
m_tooltip( aTooltip ),
m_label( aLabel )
{
}
APPEARANCE_SETTING_3D( const wxString& aLabel, int aId, const TOOL_ACTION& aAction ) :
m_Id( aId ),
m_Visible( true ),
m_Spacer( false ),
m_Ctl_visibility( nullptr ),
m_Ctl_color( nullptr ),
m_label( aLabel ),
m_action( &aAction )
{
}
APPEARANCE_SETTING_3D() :
m_Id( -1 ),
m_Visible( false ),
m_Spacer( true ),
m_Ctl_visibility( nullptr ),
m_Ctl_color( nullptr )
{
}
wxString GetTooltip() const
{
if( m_tooltip.has_value() )
return wxGetTranslation( m_tooltip.value() );
else if( m_action.has_value() )
return m_action.value()->GetTooltip( true );
else
return wxEmptyString;
}
wxString GetLabel() const
{
return wxGetTranslation( m_label );
}
private:
wxString m_label;
std::optional<wxString> m_tooltip;
std::optional<const TOOL_ACTION*> m_action;
};
APPEARANCE_CONTROLS_3D( EDA_3D_VIEWER_FRAME* aParent, wxWindow* aFocusOwner );
~APPEARANCE_CONTROLS_3D();
wxSize GetBestSize() const;
void OnDarkModeToggle();
void OnLayerVisibilityChanged( int aLayer, bool isVisible );
void CommonSettingsChanged();
void UpdateLayerCtls();
void ApplyLayerPreset( const wxString& aPresetName );
const wxArrayString& GetLayerPresetsMRU() { return m_presetMRU; }
///< Return a list of viewports created by the user.
std::vector<VIEWPORT3D> GetUserViewports() const;
///< Update the current viewports from those saved in the project file.
void SetUserViewports( std::vector<VIEWPORT3D>& aPresetList );
void ApplyViewport( const wxString& aPresetName );
const wxArrayString& GetViewportsMRU() { return m_viewportMRU; }
protected:
void OnSetFocus( wxFocusEvent& aEvent ) override;
void OnSize( wxSizeEvent& aEvent ) override;
void OnLanguageChanged( wxCommandEvent& aEvent );
private:
void rebuildControls();
void rebuildLayers();
void rebuildLayerPresetsWidget();
void syncLayerPresetSelection();
void rebuildViewportsWidget();
void onColorSwatchChanged( COLOR_SWATCH* aSwatch );
void updateLayerPresetWidget( const wxString& aName );
void onLayerPresetChanged( wxCommandEvent& aEvent ) override;
void doApplyLayerPreset( const LAYER_PRESET_3D& aPreset );
void onViewportChanged( wxCommandEvent& aEvent ) override;
void onUpdateViewportsCb( wxUpdateUIEvent& aEvent ) override;
void doApplyViewport( const VIEWPORT3D& aViewport );
void passOnFocus();
private:
static const APPEARANCE_SETTING_3D s_layerSettings[];
EDA_3D_VIEWER_FRAME* m_frame;
wxWindow* m_focusOwner;
std::vector<std::unique_ptr<APPEARANCE_SETTING_3D>> m_layerSettings;
std::map<int, APPEARANCE_SETTING_3D*> m_layerSettingsMap;
wxArrayString m_presetMRU;
std::map<wxString, VIEWPORT3D> m_viewports;
VIEWPORT3D* m_lastSelectedViewport;
wxArrayString m_viewportMRU;
wxBoxSizer* m_layersOuterSizer;
wxBoxSizer* m_envOuterSizer;
int m_pointSize;
wxColour m_layerPanelColour;
GRID_BITMAP_TOGGLE_RENDERER* m_toggleGridRenderer;
wxCheckBox* m_cbUseBoardStackupColors;
};
#endif
@@ -1,98 +0,0 @@
///////////////////////////////////////////////////////////////////////////
// C++ code generated with wxFormBuilder (version 4.0.0-0-g0efcecf)
// http://www.wxformbuilder.org/
//
// PLEASE DO *NOT* EDIT THIS FILE!
///////////////////////////////////////////////////////////////////////////
#include "appearance_controls_3D_base.h"
///////////////////////////////////////////////////////////////////////////
APPEARANCE_CONTROLS_3D_BASE::APPEARANCE_CONTROLS_3D_BASE( wxWindow* parent, wxWindowID id, const wxPoint& pos, const wxSize& size, long style, const wxString& name ) : WX_PANEL( parent, id, pos, size, style, name )
{
this->SetMinSize( wxSize( 200,360 ) );
m_sizerOuter = new wxBoxSizer( wxVERTICAL );
m_panelLayers = new wxPanel( this, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxTAB_TRAVERSAL );
m_panelLayersSizer = new wxBoxSizer( wxVERTICAL );
m_windowLayers = new wxScrolledCanvas( m_panelLayers, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxVSCROLL );
m_panelLayersSizer->Add( m_windowLayers, 1, wxEXPAND, 5 );
m_panelLayers->SetSizer( m_panelLayersSizer );
m_panelLayers->Layout();
m_panelLayersSizer->Fit( m_panelLayers );
m_sizerOuter->Add( m_panelLayers, 1, wxEXPAND, 5 );
wxBoxSizer* bBottomMargin;
bBottomMargin = new wxBoxSizer( wxVERTICAL );
m_staticline1 = new wxStaticLine( this, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxLI_HORIZONTAL );
bBottomMargin->Add( m_staticline1, 0, wxEXPAND|wxBOTTOM, 3 );
wxBoxSizer* bPresets;
bPresets = new wxBoxSizer( wxVERTICAL );
m_presetsLabel = new wxStaticText( this, wxID_ANY, _("Presets (Ctrl+Tab):"), wxDefaultPosition, wxDefaultSize, 0 );
m_presetsLabel->Wrap( -1 );
bPresets->Add( m_presetsLabel, 1, wxRIGHT|wxLEFT, 2 );
wxString m_cbLayerPresetsChoices[] = { _("Follow PCB Editor"), _("Follow PCB Plot Settings") };
int m_cbLayerPresetsNChoices = sizeof( m_cbLayerPresetsChoices ) / sizeof( wxString );
m_cbLayerPresets = new wxChoice( this, wxID_ANY, wxDefaultPosition, wxDefaultSize, m_cbLayerPresetsNChoices, m_cbLayerPresetsChoices, 0 );
m_cbLayerPresets->SetSelection( 1 );
bPresets->Add( m_cbLayerPresets, 0, wxALL|wxEXPAND, 2 );
bBottomMargin->Add( bPresets, 0, wxEXPAND|wxTOP|wxRIGHT|wxLEFT, 5 );
bBottomMargin->Add( 0, 2, 0, wxEXPAND, 5 );
wxBoxSizer* bViewports;
bViewports = new wxBoxSizer( wxVERTICAL );
m_viewportsLabel = new wxStaticText( this, wxID_ANY, _("Viewports (Alt+Tab):"), wxDefaultPosition, wxDefaultSize, 0 );
m_viewportsLabel->Wrap( -1 );
bViewports->Add( m_viewportsLabel, 1, wxRIGHT|wxLEFT, 2 );
wxString m_cbViewportsChoices[] = { _("(unsaved)") };
int m_cbViewportsNChoices = sizeof( m_cbViewportsChoices ) / sizeof( wxString );
m_cbViewports = new wxChoice( this, wxID_ANY, wxDefaultPosition, wxDefaultSize, m_cbViewportsNChoices, m_cbViewportsChoices, 0 );
m_cbViewports->SetSelection( 1 );
bViewports->Add( m_cbViewports, 0, wxEXPAND|wxTOP|wxRIGHT|wxLEFT, 2 );
bBottomMargin->Add( bViewports, 1, wxEXPAND|wxBOTTOM|wxRIGHT|wxLEFT, 5 );
m_sizerOuter->Add( bBottomMargin, 0, wxEXPAND|wxTOP|wxBOTTOM, 2 );
this->SetSizer( m_sizerOuter );
this->Layout();
m_sizerOuter->Fit( this );
// Connect Events
this->Connect( wxEVT_SET_FOCUS, wxFocusEventHandler( APPEARANCE_CONTROLS_3D_BASE::OnSetFocus ) );
this->Connect( wxEVT_SIZE, wxSizeEventHandler( APPEARANCE_CONTROLS_3D_BASE::OnSize ) );
m_panelLayers->Connect( wxEVT_SET_FOCUS, wxFocusEventHandler( APPEARANCE_CONTROLS_3D_BASE::OnSetFocus ), NULL, this );
m_cbLayerPresets->Connect( wxEVT_COMMAND_CHOICE_SELECTED, wxCommandEventHandler( APPEARANCE_CONTROLS_3D_BASE::onLayerPresetChanged ), NULL, this );
m_cbViewports->Connect( wxEVT_COMMAND_CHOICE_SELECTED, wxCommandEventHandler( APPEARANCE_CONTROLS_3D_BASE::onViewportChanged ), NULL, this );
m_cbViewports->Connect( wxEVT_UPDATE_UI, wxUpdateUIEventHandler( APPEARANCE_CONTROLS_3D_BASE::onUpdateViewportsCb ), NULL, this );
}
APPEARANCE_CONTROLS_3D_BASE::~APPEARANCE_CONTROLS_3D_BASE()
{
// Disconnect Events
this->Disconnect( wxEVT_SET_FOCUS, wxFocusEventHandler( APPEARANCE_CONTROLS_3D_BASE::OnSetFocus ) );
this->Disconnect( wxEVT_SIZE, wxSizeEventHandler( APPEARANCE_CONTROLS_3D_BASE::OnSize ) );
m_panelLayers->Disconnect( wxEVT_SET_FOCUS, wxFocusEventHandler( APPEARANCE_CONTROLS_3D_BASE::OnSetFocus ), NULL, this );
m_cbLayerPresets->Disconnect( wxEVT_COMMAND_CHOICE_SELECTED, wxCommandEventHandler( APPEARANCE_CONTROLS_3D_BASE::onLayerPresetChanged ), NULL, this );
m_cbViewports->Disconnect( wxEVT_COMMAND_CHOICE_SELECTED, wxCommandEventHandler( APPEARANCE_CONTROLS_3D_BASE::onViewportChanged ), NULL, this );
m_cbViewports->Disconnect( wxEVT_UPDATE_UI, wxUpdateUIEventHandler( APPEARANCE_CONTROLS_3D_BASE::onUpdateViewportsCb ), NULL, this );
}
@@ -1,553 +0,0 @@
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<wxFormBuilder_Project>
<FileVersion major="1" minor="17"/>
<object class="Project" expanded="true">
<property name="class_decoration">; </property>
<property name="code_generation">C++</property>
<property name="disconnect_events">1</property>
<property name="disconnect_mode">source_name</property>
<property name="disconnect_php_events">0</property>
<property name="disconnect_python_events">0</property>
<property name="embedded_files_path">res</property>
<property name="encoding">UTF-8</property>
<property name="event_generation">connect</property>
<property name="file">appearance_controls_3D_base</property>
<property name="first_id">1000</property>
<property name="help_provider">none</property>
<property name="image_path_wrapper_function_name"></property>
<property name="indent_with_spaces"></property>
<property name="internationalize">1</property>
<property name="name">Appearance Panel 3D</property>
<property name="namespace"></property>
<property name="path">.</property>
<property name="precompiled_header"></property>
<property name="relative_path">1</property>
<property name="skip_lua_events">1</property>
<property name="skip_php_events">1</property>
<property name="skip_python_events">1</property>
<property name="ui_table">UI</property>
<property name="use_array_enum">0</property>
<property name="use_enum">0</property>
<property name="use_microsoft_bom">0</property>
<object class="Panel" expanded="true">
<property name="aui_managed">0</property>
<property name="aui_manager_style">wxAUI_MGR_DEFAULT</property>
<property name="bg"></property>
<property name="context_help"></property>
<property name="context_menu">1</property>
<property name="drag_accept_files">0</property>
<property name="enabled">1</property>
<property name="event_handler">impl_virtual</property>
<property name="fg"></property>
<property name="font"></property>
<property name="hidden">0</property>
<property name="id">wxID_ANY</property>
<property name="maximum_size"></property>
<property name="minimum_size">200,360</property>
<property name="name">APPEARANCE_CONTROLS_3D_BASE</property>
<property name="pos"></property>
<property name="size">-1,-1</property>
<property name="subclass">WX_PANEL; widgets/wx_panel.h; forward_declare</property>
<property name="tooltip"></property>
<property name="two_step_creation">0</property>
<property name="window_extra_style"></property>
<property name="window_name"></property>
<property name="window_style">wxTAB_TRAVERSAL</property>
<event name="OnSetFocus">OnSetFocus</event>
<event name="OnSize">OnSize</event>
<object class="wxBoxSizer" expanded="true">
<property name="minimum_size"></property>
<property name="name">m_sizerOuter</property>
<property name="orient">wxVERTICAL</property>
<property name="permission">protected</property>
<object class="sizeritem" expanded="true">
<property name="border">5</property>
<property name="flag">wxEXPAND</property>
<property name="proportion">1</property>
<object class="wxPanel" expanded="true">
<property name="BottomDockable">1</property>
<property name="LeftDockable">1</property>
<property name="RightDockable">1</property>
<property name="TopDockable">1</property>
<property name="aui_layer"></property>
<property name="aui_name"></property>
<property name="aui_position"></property>
<property name="aui_row"></property>
<property name="best_size"></property>
<property name="bg"></property>
<property name="caption"></property>
<property name="caption_visible">1</property>
<property name="center_pane">0</property>
<property name="close_button">1</property>
<property name="context_help"></property>
<property name="context_menu">1</property>
<property name="default_pane">0</property>
<property name="dock">Dock</property>
<property name="dock_fixed">0</property>
<property name="docking">Left</property>
<property name="drag_accept_files">0</property>
<property name="enabled">1</property>
<property name="fg"></property>
<property name="floatable">1</property>
<property name="font"></property>
<property name="gripper">0</property>
<property name="hidden">0</property>
<property name="id">wxID_ANY</property>
<property name="max_size"></property>
<property name="maximize_button">0</property>
<property name="maximum_size"></property>
<property name="min_size"></property>
<property name="minimize_button">0</property>
<property name="minimum_size"></property>
<property name="moveable">1</property>
<property name="name">m_panelLayers</property>
<property name="pane_border">1</property>
<property name="pane_position"></property>
<property name="pane_size"></property>
<property name="permission">protected</property>
<property name="pin_button">1</property>
<property name="pos"></property>
<property name="resize">Resizable</property>
<property name="show">1</property>
<property name="size"></property>
<property name="subclass">; ; forward_declare</property>
<property name="toolbar_pane">0</property>
<property name="tooltip"></property>
<property name="window_extra_style"></property>
<property name="window_name"></property>
<property name="window_style">wxTAB_TRAVERSAL</property>
<event name="OnSetFocus">OnSetFocus</event>
<object class="wxBoxSizer" expanded="true">
<property name="minimum_size"></property>
<property name="name">m_panelLayersSizer</property>
<property name="orient">wxVERTICAL</property>
<property name="permission">protected</property>
<object class="sizeritem" expanded="true">
<property name="border">5</property>
<property name="flag">wxEXPAND</property>
<property name="proportion">1</property>
<object class="CustomControl" expanded="true">
<property name="BottomDockable">1</property>
<property name="LeftDockable">1</property>
<property name="RightDockable">1</property>
<property name="TopDockable">1</property>
<property name="aui_layer"></property>
<property name="aui_name"></property>
<property name="aui_position"></property>
<property name="aui_row"></property>
<property name="best_size"></property>
<property name="bg"></property>
<property name="caption"></property>
<property name="caption_visible">1</property>
<property name="center_pane">0</property>
<property name="class">wxScrolledCanvas</property>
<property name="close_button">1</property>
<property name="construction"></property>
<property name="context_help"></property>
<property name="context_menu">1</property>
<property name="declaration"></property>
<property name="default_pane">0</property>
<property name="dock">Dock</property>
<property name="dock_fixed">0</property>
<property name="docking">Left</property>
<property name="drag_accept_files">0</property>
<property name="enabled">1</property>
<property name="fg"></property>
<property name="floatable">1</property>
<property name="font"></property>
<property name="gripper">0</property>
<property name="hidden">0</property>
<property name="id">wxID_ANY</property>
<property name="include">#include &lt;wx/scrolwin.h&gt;&#x0A;#include &lt;wx/grid.h&gt; // needed for MSVC to see wxScrolledCanvas indirectly exported</property>
<property name="max_size"></property>
<property name="maximize_button">0</property>
<property name="maximum_size"></property>
<property name="min_size"></property>
<property name="minimize_button">0</property>
<property name="minimum_size"></property>
<property name="moveable">1</property>
<property name="name">m_windowLayers</property>
<property name="pane_border">1</property>
<property name="pane_position"></property>
<property name="pane_size"></property>
<property name="permission">protected</property>
<property name="pin_button">1</property>
<property name="pos"></property>
<property name="resize">Resizable</property>
<property name="settings"></property>
<property name="show">1</property>
<property name="size"></property>
<property name="subclass">; ; forward_declare</property>
<property name="toolbar_pane">0</property>
<property name="tooltip"></property>
<property name="window_extra_style"></property>
<property name="window_name"></property>
<property name="window_style">wxVSCROLL</property>
</object>
</object>
</object>
</object>
</object>
<object class="sizeritem" expanded="true">
<property name="border">2</property>
<property name="flag">wxEXPAND|wxTOP|wxBOTTOM</property>
<property name="proportion">0</property>
<object class="wxBoxSizer" expanded="true">
<property name="minimum_size"></property>
<property name="name">bBottomMargin</property>
<property name="orient">wxVERTICAL</property>
<property name="permission">none</property>
<object class="sizeritem" expanded="true">
<property name="border">3</property>
<property name="flag">wxEXPAND|wxBOTTOM</property>
<property name="proportion">0</property>
<object class="wxStaticLine" expanded="true">
<property name="BottomDockable">1</property>
<property name="LeftDockable">1</property>
<property name="RightDockable">1</property>
<property name="TopDockable">1</property>
<property name="aui_layer"></property>
<property name="aui_name"></property>
<property name="aui_position"></property>
<property name="aui_row"></property>
<property name="best_size"></property>
<property name="bg"></property>
<property name="caption"></property>
<property name="caption_visible">1</property>
<property name="center_pane">0</property>
<property name="close_button">1</property>
<property name="context_help"></property>
<property name="context_menu">1</property>
<property name="default_pane">0</property>
<property name="dock">Dock</property>
<property name="dock_fixed">0</property>
<property name="docking">Left</property>
<property name="drag_accept_files">0</property>
<property name="enabled">1</property>
<property name="fg"></property>
<property name="floatable">1</property>
<property name="font"></property>
<property name="gripper">0</property>
<property name="hidden">0</property>
<property name="id">wxID_ANY</property>
<property name="max_size"></property>
<property name="maximize_button">0</property>
<property name="maximum_size"></property>
<property name="min_size"></property>
<property name="minimize_button">0</property>
<property name="minimum_size"></property>
<property name="moveable">1</property>
<property name="name">m_staticline1</property>
<property name="pane_border">1</property>
<property name="pane_position"></property>
<property name="pane_size"></property>
<property name="permission">protected</property>
<property name="pin_button">1</property>
<property name="pos"></property>
<property name="resize">Resizable</property>
<property name="show">1</property>
<property name="size"></property>
<property name="style">wxLI_HORIZONTAL</property>
<property name="subclass">; ; forward_declare</property>
<property name="toolbar_pane">0</property>
<property name="tooltip"></property>
<property name="window_extra_style"></property>
<property name="window_name"></property>
<property name="window_style"></property>
</object>
</object>
<object class="sizeritem" expanded="true">
<property name="border">5</property>
<property name="flag">wxEXPAND|wxTOP|wxRIGHT|wxLEFT</property>
<property name="proportion">0</property>
<object class="wxBoxSizer" expanded="true">
<property name="minimum_size"></property>
<property name="name">bPresets</property>
<property name="orient">wxVERTICAL</property>
<property name="permission">none</property>
<object class="sizeritem" expanded="false">
<property name="border">2</property>
<property name="flag">wxRIGHT|wxLEFT</property>
<property name="proportion">1</property>
<object class="wxStaticText" expanded="false">
<property name="BottomDockable">1</property>
<property name="LeftDockable">1</property>
<property name="RightDockable">1</property>
<property name="TopDockable">1</property>
<property name="aui_layer"></property>
<property name="aui_name"></property>
<property name="aui_position"></property>
<property name="aui_row"></property>
<property name="best_size"></property>
<property name="bg"></property>
<property name="caption"></property>
<property name="caption_visible">1</property>
<property name="center_pane">0</property>
<property name="close_button">1</property>
<property name="context_help"></property>
<property name="context_menu">1</property>
<property name="default_pane">0</property>
<property name="dock">Dock</property>
<property name="dock_fixed">0</property>
<property name="docking">Left</property>
<property name="drag_accept_files">0</property>
<property name="enabled">1</property>
<property name="fg"></property>
<property name="floatable">1</property>
<property name="font"></property>
<property name="gripper">0</property>
<property name="hidden">0</property>
<property name="id">wxID_ANY</property>
<property name="label">Presets (Ctrl+Tab):</property>
<property name="markup">0</property>
<property name="max_size"></property>
<property name="maximize_button">0</property>
<property name="maximum_size"></property>
<property name="min_size"></property>
<property name="minimize_button">0</property>
<property name="minimum_size"></property>
<property name="moveable">1</property>
<property name="name">m_presetsLabel</property>
<property name="pane_border">1</property>
<property name="pane_position"></property>
<property name="pane_size"></property>
<property name="permission">protected</property>
<property name="pin_button">1</property>
<property name="pos"></property>
<property name="resize">Resizable</property>
<property name="show">1</property>
<property name="size"></property>
<property name="style"></property>
<property name="subclass">; ; forward_declare</property>
<property name="toolbar_pane">0</property>
<property name="tooltip"></property>
<property name="window_extra_style"></property>
<property name="window_name"></property>
<property name="window_style"></property>
<property name="wrap">-1</property>
</object>
</object>
<object class="sizeritem" expanded="false">
<property name="border">2</property>
<property name="flag">wxALL|wxEXPAND</property>
<property name="proportion">0</property>
<object class="wxChoice" expanded="false">
<property name="BottomDockable">1</property>
<property name="LeftDockable">1</property>
<property name="RightDockable">1</property>
<property name="TopDockable">1</property>
<property name="aui_layer"></property>
<property name="aui_name"></property>
<property name="aui_position"></property>
<property name="aui_row"></property>
<property name="best_size"></property>
<property name="bg"></property>
<property name="caption"></property>
<property name="caption_visible">1</property>
<property name="center_pane">0</property>
<property name="choices">&quot;Follow PCB Editor&quot; &quot;Follow PCB Plot Settings&quot;</property>
<property name="close_button">1</property>
<property name="context_help"></property>
<property name="context_menu">1</property>
<property name="default_pane">0</property>
<property name="dock">Dock</property>
<property name="dock_fixed">0</property>
<property name="docking">Left</property>
<property name="drag_accept_files">0</property>
<property name="enabled">1</property>
<property name="fg"></property>
<property name="floatable">1</property>
<property name="font"></property>
<property name="gripper">0</property>
<property name="hidden">0</property>
<property name="id">wxID_ANY</property>
<property name="max_size"></property>
<property name="maximize_button">0</property>
<property name="maximum_size"></property>
<property name="min_size"></property>
<property name="minimize_button">0</property>
<property name="minimum_size"></property>
<property name="moveable">1</property>
<property name="name">m_cbLayerPresets</property>
<property name="pane_border">1</property>
<property name="pane_position"></property>
<property name="pane_size"></property>
<property name="permission">protected</property>
<property name="pin_button">1</property>
<property name="pos"></property>
<property name="resize">Resizable</property>
<property name="selection">1</property>
<property name="show">1</property>
<property name="size"></property>
<property name="style"></property>
<property name="subclass">; ; forward_declare</property>
<property name="toolbar_pane">0</property>
<property name="tooltip"></property>
<property name="validator_data_type"></property>
<property name="validator_style">wxFILTER_NONE</property>
<property name="validator_type">wxDefaultValidator</property>
<property name="validator_variable"></property>
<property name="window_extra_style"></property>
<property name="window_name"></property>
<property name="window_style"></property>
<event name="OnChoice">onLayerPresetChanged</event>
</object>
</object>
</object>
</object>
<object class="sizeritem" expanded="false">
<property name="border">5</property>
<property name="flag">wxEXPAND</property>
<property name="proportion">0</property>
<object class="spacer" expanded="false">
<property name="height">2</property>
<property name="permission">protected</property>
<property name="width">0</property>
</object>
</object>
<object class="sizeritem" expanded="true">
<property name="border">5</property>
<property name="flag">wxEXPAND|wxBOTTOM|wxRIGHT|wxLEFT</property>
<property name="proportion">1</property>
<object class="wxBoxSizer" expanded="true">
<property name="minimum_size"></property>
<property name="name">bViewports</property>
<property name="orient">wxVERTICAL</property>
<property name="permission">none</property>
<object class="sizeritem" expanded="false">
<property name="border">2</property>
<property name="flag">wxRIGHT|wxLEFT</property>
<property name="proportion">1</property>
<object class="wxStaticText" expanded="false">
<property name="BottomDockable">1</property>
<property name="LeftDockable">1</property>
<property name="RightDockable">1</property>
<property name="TopDockable">1</property>
<property name="aui_layer"></property>
<property name="aui_name"></property>
<property name="aui_position"></property>
<property name="aui_row"></property>
<property name="best_size"></property>
<property name="bg"></property>
<property name="caption"></property>
<property name="caption_visible">1</property>
<property name="center_pane">0</property>
<property name="close_button">1</property>
<property name="context_help"></property>
<property name="context_menu">1</property>
<property name="default_pane">0</property>
<property name="dock">Dock</property>
<property name="dock_fixed">0</property>
<property name="docking">Left</property>
<property name="drag_accept_files">0</property>
<property name="enabled">1</property>
<property name="fg"></property>
<property name="floatable">1</property>
<property name="font"></property>
<property name="gripper">0</property>
<property name="hidden">0</property>
<property name="id">wxID_ANY</property>
<property name="label">Viewports (Alt+Tab):</property>
<property name="markup">0</property>
<property name="max_size"></property>
<property name="maximize_button">0</property>
<property name="maximum_size"></property>
<property name="min_size"></property>
<property name="minimize_button">0</property>
<property name="minimum_size"></property>
<property name="moveable">1</property>
<property name="name">m_viewportsLabel</property>
<property name="pane_border">1</property>
<property name="pane_position"></property>
<property name="pane_size"></property>
<property name="permission">protected</property>
<property name="pin_button">1</property>
<property name="pos"></property>
<property name="resize">Resizable</property>
<property name="show">1</property>
<property name="size"></property>
<property name="style"></property>
<property name="subclass">; ; forward_declare</property>
<property name="toolbar_pane">0</property>
<property name="tooltip"></property>
<property name="window_extra_style"></property>
<property name="window_name"></property>
<property name="window_style"></property>
<property name="wrap">-1</property>
</object>
</object>
<object class="sizeritem" expanded="false">
<property name="border">2</property>
<property name="flag">wxEXPAND|wxTOP|wxRIGHT|wxLEFT</property>
<property name="proportion">0</property>
<object class="wxChoice" expanded="false">
<property name="BottomDockable">1</property>
<property name="LeftDockable">1</property>
<property name="RightDockable">1</property>
<property name="TopDockable">1</property>
<property name="aui_layer"></property>
<property name="aui_name"></property>
<property name="aui_position"></property>
<property name="aui_row"></property>
<property name="best_size"></property>
<property name="bg"></property>
<property name="caption"></property>
<property name="caption_visible">1</property>
<property name="center_pane">0</property>
<property name="choices">&quot;(unsaved)&quot;</property>
<property name="close_button">1</property>
<property name="context_help"></property>
<property name="context_menu">1</property>
<property name="default_pane">0</property>
<property name="dock">Dock</property>
<property name="dock_fixed">0</property>
<property name="docking">Left</property>
<property name="drag_accept_files">0</property>
<property name="enabled">1</property>
<property name="fg"></property>
<property name="floatable">1</property>
<property name="font"></property>
<property name="gripper">0</property>
<property name="hidden">0</property>
<property name="id">wxID_ANY</property>
<property name="max_size"></property>
<property name="maximize_button">0</property>
<property name="maximum_size"></property>
<property name="min_size"></property>
<property name="minimize_button">0</property>
<property name="minimum_size"></property>
<property name="moveable">1</property>
<property name="name">m_cbViewports</property>
<property name="pane_border">1</property>
<property name="pane_position"></property>
<property name="pane_size"></property>
<property name="permission">protected</property>
<property name="pin_button">1</property>
<property name="pos"></property>
<property name="resize">Resizable</property>
<property name="selection">1</property>
<property name="show">1</property>
<property name="size"></property>
<property name="style"></property>
<property name="subclass">; ; forward_declare</property>
<property name="toolbar_pane">0</property>
<property name="tooltip"></property>
<property name="validator_data_type"></property>
<property name="validator_style">wxFILTER_NONE</property>
<property name="validator_type">wxDefaultValidator</property>
<property name="validator_variable"></property>
<property name="window_extra_style"></property>
<property name="window_name"></property>
<property name="window_style"></property>
<event name="OnChoice">onViewportChanged</event>
<event name="OnUpdateUI">onUpdateViewportsCb</event>
</object>
</object>
</object>
</object>
</object>
</object>
</object>
</object>
</object>
</wxFormBuilder_Project>
@@ -1,63 +0,0 @@
///////////////////////////////////////////////////////////////////////////
// C++ code generated with wxFormBuilder (version 4.0.0-0-g0efcecf)
// http://www.wxformbuilder.org/
//
// PLEASE DO *NOT* EDIT THIS FILE!
///////////////////////////////////////////////////////////////////////////
#pragma once
#include <wx/artprov.h>
#include <wx/xrc/xmlres.h>
#include <wx/intl.h>
#include "widgets/wx_panel.h"
#include <wx/scrolwin.h>
#include <wx/grid.h> // needed for MSVC to see wxScrolledCanvas indirectly exported
#include <wx/gdicmn.h>
#include <wx/font.h>
#include <wx/colour.h>
#include <wx/settings.h>
#include <wx/string.h>
#include <wx/sizer.h>
#include <wx/panel.h>
#include <wx/statline.h>
#include <wx/stattext.h>
#include <wx/choice.h>
///////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////
/// Class APPEARANCE_CONTROLS_3D_BASE
///////////////////////////////////////////////////////////////////////////////
class APPEARANCE_CONTROLS_3D_BASE : public WX_PANEL
{
private:
protected:
wxBoxSizer* m_sizerOuter;
wxPanel* m_panelLayers;
wxBoxSizer* m_panelLayersSizer;
wxScrolledCanvas* m_windowLayers;
wxStaticLine* m_staticline1;
wxStaticText* m_presetsLabel;
wxChoice* m_cbLayerPresets;
wxStaticText* m_viewportsLabel;
wxChoice* m_cbViewports;
// Virtual event handlers, override them in your derived class
virtual void OnSetFocus( wxFocusEvent& event ) { event.Skip(); }
virtual void OnSize( wxSizeEvent& event ) { event.Skip(); }
virtual void onLayerPresetChanged( wxCommandEvent& event ) { event.Skip(); }
virtual void onViewportChanged( wxCommandEvent& event ) { event.Skip(); }
virtual void onUpdateViewportsCb( wxUpdateUIEvent& event ) { event.Skip(); }
public:
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 );
~APPEARANCE_CONTROLS_3D_BASE();
};
+127
View File
@@ -0,0 +1,127 @@
/*
* This program source code file is part of KiCad, a free EDA CAD application.
*
* Copyright (C) 2021 KiCad Developers, see AUTHORS.txt for contributors.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, you may find one here:
* http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
* or you may search the http://www.gnu.org website for the version 2 license,
* or you may write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
*/
#include "panel_3D_colors.h"
#include <widgets/color_swatch.h>
#include <settings/settings_manager.h>
#include <pgm_base.h>
PANEL_3D_COLORS::PANEL_3D_COLORS( wxWindow* aParent ) :
PANEL_3D_COLORS_BASE( aParent )
{
m_backgroundTop->SetDefaultColor( BOARD_ADAPTER::g_DefaultBackgroundTop );
m_backgroundBottom->SetDefaultColor( BOARD_ADAPTER::g_DefaultBackgroundBot );
m_silkscreenTop->SetUserColors( &BOARD_ADAPTER::g_SilkscreenColors );
m_silkscreenTop->SetDefaultColor( BOARD_ADAPTER::g_DefaultSilkscreen );
m_silkscreenBottom->SetUserColors( &BOARD_ADAPTER::g_SilkscreenColors );
m_silkscreenBottom->SetDefaultColor( BOARD_ADAPTER::g_DefaultSilkscreen );
m_solderMaskTop->SetUserColors( &BOARD_ADAPTER::g_MaskColors );
m_solderMaskTop->SetDefaultColor( BOARD_ADAPTER::g_DefaultSolderMask );
m_solderMaskBottom->SetUserColors( &BOARD_ADAPTER::g_MaskColors );
m_solderMaskBottom->SetDefaultColor( BOARD_ADAPTER::g_DefaultSolderMask );
m_solderPaste->SetUserColors( &BOARD_ADAPTER::g_PasteColors );
m_solderPaste->SetDefaultColor( BOARD_ADAPTER::g_DefaultSolderPaste );
m_surfaceFinish->SetUserColors( &BOARD_ADAPTER::g_FinishColors );
m_surfaceFinish->SetDefaultColor( BOARD_ADAPTER::g_DefaultSurfaceFinish );
m_boardBody->SetUserColors( &BOARD_ADAPTER::g_BoardColors );
m_boardBody->SetDefaultColor( BOARD_ADAPTER::g_DefaultBoardBody );
}
bool PANEL_3D_COLORS::TransferDataToWindow()
{
COLOR_SETTINGS* colors = Pgm().GetSettingsManager().GetColorSettings();
m_backgroundTop->SetSupportsOpacity( false );
m_backgroundBottom->SetSupportsOpacity( false );
m_silkscreenTop->SetSupportsOpacity( false );
m_silkscreenBottom->SetSupportsOpacity( false );
m_solderMaskTop->SetBackgroundColour( *wxWHITE );
m_solderMaskBottom->SetBackgroundColour( *wxWHITE );
m_solderPaste->SetSupportsOpacity( false );
m_surfaceFinish->SetSupportsOpacity( false );
m_boardBody->SetBackgroundColour( *wxWHITE );
m_backgroundTop->SetSwatchColor( colors->GetColor( LAYER_3D_BACKGROUND_TOP ), false );
m_backgroundBottom->SetSwatchColor( colors->GetColor( LAYER_3D_BACKGROUND_BOTTOM ), false );
m_silkscreenTop->SetSwatchColor( colors->GetColor( LAYER_3D_SILKSCREEN_TOP ), false );
m_silkscreenBottom->SetSwatchColor( colors->GetColor( LAYER_3D_SILKSCREEN_BOTTOM ), false );
m_solderMaskTop->SetSwatchColor( colors->GetColor( LAYER_3D_SOLDERMASK_TOP ), false );
m_solderMaskBottom->SetSwatchColor( colors->GetColor( LAYER_3D_SOLDERMASK_BOTTOM ), false );
m_solderPaste->SetSwatchColor( colors->GetColor( LAYER_3D_SOLDERPASTE ), false );
m_surfaceFinish->SetSwatchColor( colors->GetColor( LAYER_3D_COPPER ), false );
m_boardBody->SetSwatchColor( colors->GetColor( LAYER_3D_BOARD ), false );
if( colors->GetUseBoardStackupColors() )
m_boardStackupRB->SetValue( true );
else
m_specificColorsRB->SetValue( true );
return true;
}
bool PANEL_3D_COLORS::TransferDataFromWindow()
{
COLOR_SETTINGS* colors = Pgm().GetSettingsManager().GetColorSettings();
colors->SetColor( LAYER_3D_BACKGROUND_TOP, m_backgroundTop->GetSwatchColor() );
colors->SetColor( LAYER_3D_BACKGROUND_BOTTOM, m_backgroundBottom->GetSwatchColor() );
colors->SetColor( LAYER_3D_SILKSCREEN_TOP, m_silkscreenTop->GetSwatchColor() );
colors->SetColor( LAYER_3D_SILKSCREEN_BOTTOM, m_silkscreenBottom->GetSwatchColor() );
colors->SetColor( LAYER_3D_SOLDERMASK_TOP, m_solderMaskTop->GetSwatchColor() );
colors->SetColor( LAYER_3D_SOLDERMASK_BOTTOM, m_solderMaskBottom->GetSwatchColor() );
colors->SetColor( LAYER_3D_SOLDERPASTE, m_solderPaste->GetSwatchColor() );
colors->SetColor( LAYER_3D_COPPER, m_surfaceFinish->GetSwatchColor() );
colors->SetColor( LAYER_3D_BOARD, m_boardBody->GetSwatchColor() );
colors->SetUseBoardStackupColors( m_boardStackupRB->GetValue() );
Pgm().GetSettingsManager().SaveColorSettings( colors, "3d_viewer" );
return true;
}
void PANEL_3D_COLORS::ResetPanel()
{
COLOR_SETTINGS* colors = Pgm().GetSettingsManager().GetColorSettings();
m_backgroundTop->SetSwatchColor( colors->GetDefaultColor( LAYER_3D_BACKGROUND_TOP ), false );
m_backgroundBottom->SetSwatchColor( colors->GetDefaultColor( LAYER_3D_BACKGROUND_BOTTOM ), false );
m_silkscreenTop->SetSwatchColor( colors->GetDefaultColor( LAYER_3D_SILKSCREEN_TOP ), false );
m_silkscreenBottom->SetSwatchColor( colors->GetDefaultColor( LAYER_3D_SILKSCREEN_BOTTOM ), false );
m_solderMaskTop->SetSwatchColor( colors->GetDefaultColor( LAYER_3D_SOLDERMASK_TOP ), false );
m_solderMaskBottom->SetSwatchColor( colors->GetDefaultColor( LAYER_3D_SOLDERMASK_BOTTOM ), false );
m_solderPaste->SetSwatchColor( colors->GetDefaultColor( LAYER_3D_SOLDERPASTE ), false );
m_surfaceFinish->SetSwatchColor( colors->GetDefaultColor( LAYER_3D_COPPER ), false );
m_boardBody->SetSwatchColor( colors->GetDefaultColor( LAYER_3D_BOARD ), false );
m_boardStackupRB->SetValue( true );
}
+42
View File
@@ -0,0 +1,42 @@
/*
* This program source code file is part of KiCad, a free EDA CAD application.
*
* Copyright (C) 2021 KiCad Developers, see AUTHORS.txt for contributors.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, you may find one here:
* http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
* or you may search the http://www.gnu.org website for the version 2 license,
* or you may write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
*/
#ifndef PANEL_3D_COLORS_H
#define PANEL_3D_COLORS_H
#include "panel_3D_colors_base.h"
#include <3d_viewer/eda_3d_viewer_frame.h>
class PANEL_3D_COLORS : public PANEL_3D_COLORS_BASE
{
public:
explicit PANEL_3D_COLORS( wxWindow* aParent );
bool TransferDataFromWindow() override;
bool TransferDataToWindow() override;
void ResetPanel() override;
};
#endif // PANEL_3D_COLORS_H
+153
View File
@@ -0,0 +1,153 @@
///////////////////////////////////////////////////////////////////////////
// C++ code generated with wxFormBuilder (version 3.10.1-0-g8feb16b)
// http://www.wxformbuilder.org/
//
// PLEASE DO *NOT* EDIT THIS FILE!
///////////////////////////////////////////////////////////////////////////
#include "widgets/color_swatch.h"
#include "panel_3D_colors_base.h"
///////////////////////////////////////////////////////////////////////////
PANEL_3D_COLORS_BASE::PANEL_3D_COLORS_BASE( wxWindow* parent, wxWindowID id, const wxPoint& pos, const wxSize& size, long style, const wxString& name ) : RESETTABLE_PANEL( parent, id, pos, size, style, name )
{
wxBoxSizer* bSizerMain;
bSizerMain = new wxBoxSizer( wxVERTICAL );
m_environmentLable = new wxStaticText( this, wxID_ANY, _("Environment Colors"), wxDefaultPosition, wxDefaultSize, 0 );
m_environmentLable->Wrap( -1 );
bSizerMain->Add( m_environmentLable, 0, wxTOP|wxRIGHT|wxLEFT|wxEXPAND, 13 );
m_staticline1 = new wxStaticLine( this, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxLI_HORIZONTAL );
bSizerMain->Add( m_staticline1, 0, wxEXPAND|wxBOTTOM, 5 );
wxFlexGridSizer* fgSizer1;
fgSizer1 = new wxFlexGridSizer( 0, 2, 5, 0 );
fgSizer1->SetFlexibleDirection( wxBOTH );
fgSizer1->SetNonFlexibleGrowMode( wxFLEX_GROWMODE_SPECIFIED );
backgroundTopLabel = new wxStaticText( this, wxID_ANY, _("Background gradient start:"), wxDefaultPosition, wxDefaultSize, 0 );
backgroundTopLabel->Wrap( -1 );
fgSizer1->Add( backgroundTopLabel, 0, wxALIGN_CENTER_VERTICAL|wxLEFT, 5 );
m_backgroundTop = new COLOR_SWATCH( this, wxID_ANY, wxDefaultPosition, wxDefaultSize, 0 );
fgSizer1->Add( m_backgroundTop, 0, wxALIGN_CENTER_VERTICAL|wxRIGHT|wxLEFT, 5 );
backgroundBotLabel = new wxStaticText( this, wxID_ANY, _("Background gradient end:"), wxDefaultPosition, wxDefaultSize, 0 );
backgroundBotLabel->Wrap( -1 );
fgSizer1->Add( backgroundBotLabel, 0, wxALIGN_CENTER_VERTICAL|wxLEFT, 5 );
m_backgroundBottom = new COLOR_SWATCH( this, wxID_ANY, wxDefaultPosition, wxDefaultSize, 0 );
fgSizer1->Add( m_backgroundBottom, 0, wxALIGN_CENTER_VERTICAL|wxRIGHT|wxLEFT, 5 );
fgSizer1->Add( 0, 6, 1, wxEXPAND, 5 );
fgSizer1->Add( 0, 0, 1, wxEXPAND, 5 );
solderPasteLabel = new wxStaticText( this, wxID_ANY, _("Solder paste:"), wxDefaultPosition, wxDefaultSize, 0 );
solderPasteLabel->Wrap( -1 );
fgSizer1->Add( solderPasteLabel, 0, wxALIGN_CENTER_VERTICAL|wxLEFT, 5 );
m_solderPaste = new COLOR_SWATCH( this, wxID_ANY, wxDefaultPosition, wxDefaultSize, 0 );
fgSizer1->Add( m_solderPaste, 0, wxRIGHT|wxLEFT|wxALIGN_CENTER_VERTICAL, 5 );
bSizerMain->Add( fgSizer1, 0, wxTOP|wxBOTTOM|wxLEFT, 5 );
bSizerMain->Add( 0, 15, 0, wxEXPAND, 5 );
m_boardColorsLabel = new wxStaticText( this, wxID_ANY, _("Board Colors"), wxDefaultPosition, wxDefaultSize, 0 );
m_boardColorsLabel->Wrap( -1 );
bSizerMain->Add( m_boardColorsLabel, 0, wxTOP|wxRIGHT|wxLEFT|wxEXPAND, 13 );
m_staticline2 = new wxStaticLine( this, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxLI_HORIZONTAL );
bSizerMain->Add( m_staticline2, 0, wxEXPAND|wxBOTTOM, 5 );
m_boardStackupRB = new wxRadioButton( this, wxID_ANY, _("Use board stackup colors"), wxDefaultPosition, wxDefaultSize, 0 );
bSizerMain->Add( m_boardStackupRB, 0, wxTOP|wxBOTTOM|wxLEFT, 8 );
m_specificColorsRB = new wxRadioButton( this, wxID_ANY, _("Use colors:"), wxDefaultPosition, wxDefaultSize, 0 );
bSizerMain->Add( m_specificColorsRB, 0, wxTOP|wxBOTTOM|wxLEFT, 8 );
wxFlexGridSizer* fgSizer2;
fgSizer2 = new wxFlexGridSizer( 0, 2, 5, 0 );
fgSizer2->SetFlexibleDirection( wxBOTH );
fgSizer2->SetNonFlexibleGrowMode( wxFLEX_GROWMODE_SPECIFIED );
silkscreenTopLabel = new wxStaticText( this, wxID_ANY, _("Silkscreen top:"), wxDefaultPosition, wxDefaultSize, 0 );
silkscreenTopLabel->Wrap( -1 );
fgSizer2->Add( silkscreenTopLabel, 0, wxLEFT|wxALIGN_CENTER_VERTICAL, 20 );
m_silkscreenTop = new COLOR_SWATCH( this, wxID_ANY, wxDefaultPosition, wxDefaultSize, 0 );
fgSizer2->Add( m_silkscreenTop, 0, wxALIGN_CENTER_VERTICAL|wxRIGHT|wxLEFT, 5 );
silkscreenBottomLabel = new wxStaticText( this, wxID_ANY, _("Silkscreen bottom:"), wxDefaultPosition, wxDefaultSize, 0 );
silkscreenBottomLabel->Wrap( -1 );
fgSizer2->Add( silkscreenBottomLabel, 0, wxALIGN_CENTER_VERTICAL|wxLEFT, 20 );
m_silkscreenBottom = new COLOR_SWATCH( this, wxID_ANY, wxDefaultPosition, wxDefaultSize, 0 );
fgSizer2->Add( m_silkscreenBottom, 0, wxALIGN_CENTER_VERTICAL|wxRIGHT|wxLEFT, 5 );
fgSizer2->Add( 0, 6, 1, wxEXPAND, 5 );
fgSizer2->Add( 0, 0, 1, wxEXPAND, 5 );
solderMaskTopLabel = new wxStaticText( this, wxID_ANY, _("Solder mask top:"), wxDefaultPosition, wxDefaultSize, 0 );
solderMaskTopLabel->Wrap( -1 );
fgSizer2->Add( solderMaskTopLabel, 0, wxALIGN_CENTER_VERTICAL|wxLEFT, 20 );
m_solderMaskTop = new COLOR_SWATCH( this, wxID_ANY, wxDefaultPosition, wxDefaultSize, 0 );
fgSizer2->Add( m_solderMaskTop, 0, wxRIGHT|wxLEFT|wxALIGN_CENTER_VERTICAL, 5 );
solderMaskBottomLabel = new wxStaticText( this, wxID_ANY, _("Solder mask bottom:"), wxDefaultPosition, wxDefaultSize, 0 );
solderMaskBottomLabel->Wrap( -1 );
fgSizer2->Add( solderMaskBottomLabel, 0, wxALIGN_CENTER_VERTICAL|wxLEFT, 20 );
m_solderMaskBottom = new COLOR_SWATCH( this, wxID_ANY, wxDefaultPosition, wxDefaultSize, 0 );
fgSizer2->Add( m_solderMaskBottom, 0, wxALIGN_CENTER_VERTICAL|wxRIGHT|wxLEFT, 5 );
fgSizer2->Add( 0, 6, 1, wxEXPAND, 5 );
fgSizer2->Add( 0, 0, 1, wxEXPAND, 5 );
surfaceFinishLabel = new wxStaticText( this, wxID_ANY, _("Copper/surface finish:"), wxDefaultPosition, wxDefaultSize, 0 );
surfaceFinishLabel->Wrap( -1 );
fgSizer2->Add( surfaceFinishLabel, 0, wxALIGN_CENTER_VERTICAL|wxLEFT, 20 );
m_surfaceFinish = new COLOR_SWATCH( this, wxID_ANY, wxDefaultPosition, wxDefaultSize, 0 );
fgSizer2->Add( m_surfaceFinish, 0, wxALIGN_CENTER_VERTICAL|wxRIGHT|wxLEFT, 5 );
fgSizer2->Add( 0, 6, 1, wxEXPAND, 5 );
fgSizer2->Add( 0, 0, 1, wxEXPAND, 5 );
boardBodyLabel = new wxStaticText( this, wxID_ANY, _("Board body:"), wxDefaultPosition, wxDefaultSize, 0 );
boardBodyLabel->Wrap( -1 );
fgSizer2->Add( boardBodyLabel, 0, wxALIGN_CENTER_VERTICAL|wxLEFT, 20 );
m_boardBody = new COLOR_SWATCH( this, wxID_ANY, wxDefaultPosition, wxDefaultSize, 0 );
fgSizer2->Add( m_boardBody, 0, wxALIGN_CENTER_VERTICAL|wxBOTTOM|wxLEFT|wxRIGHT, 5 );
bSizerMain->Add( fgSizer2, 1, wxEXPAND|wxLEFT, 8 );
this->SetSizer( bSizerMain );
this->Layout();
bSizerMain->Fit( this );
}
PANEL_3D_COLORS_BASE::~PANEL_3D_COLORS_BASE()
{
}
File diff suppressed because it is too large Load Diff
+70
View File
@@ -0,0 +1,70 @@
///////////////////////////////////////////////////////////////////////////
// C++ code generated with wxFormBuilder (version 3.10.1-0-g8feb16b)
// http://www.wxformbuilder.org/
//
// PLEASE DO *NOT* EDIT THIS FILE!
///////////////////////////////////////////////////////////////////////////
#pragma once
#include <wx/artprov.h>
#include <wx/xrc/xmlres.h>
#include <wx/intl.h>
class COLOR_SWATCH;
#include "widgets/resettable_panel.h"
#include <wx/string.h>
#include <wx/stattext.h>
#include <wx/gdicmn.h>
#include <wx/font.h>
#include <wx/colour.h>
#include <wx/settings.h>
#include <wx/statline.h>
#include <wx/sizer.h>
#include <wx/radiobut.h>
#include <wx/panel.h>
///////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////
/// Class PANEL_3D_COLORS_BASE
///////////////////////////////////////////////////////////////////////////////
class PANEL_3D_COLORS_BASE : public RESETTABLE_PANEL
{
private:
protected:
wxStaticText* m_environmentLable;
wxStaticLine* m_staticline1;
wxStaticText* backgroundTopLabel;
COLOR_SWATCH* m_backgroundTop;
wxStaticText* backgroundBotLabel;
COLOR_SWATCH* m_backgroundBottom;
wxStaticText* solderPasteLabel;
COLOR_SWATCH* m_solderPaste;
wxStaticText* m_boardColorsLabel;
wxStaticLine* m_staticline2;
wxRadioButton* m_boardStackupRB;
wxRadioButton* m_specificColorsRB;
wxStaticText* silkscreenTopLabel;
COLOR_SWATCH* m_silkscreenTop;
wxStaticText* silkscreenBottomLabel;
COLOR_SWATCH* m_silkscreenBottom;
wxStaticText* solderMaskTopLabel;
COLOR_SWATCH* m_solderMaskTop;
wxStaticText* solderMaskBottomLabel;
COLOR_SWATCH* m_solderMaskBottom;
wxStaticText* surfaceFinishLabel;
COLOR_SWATCH* m_surfaceFinish;
wxStaticText* boardBodyLabel;
COLOR_SWATCH* m_boardBody;
public:
PANEL_3D_COLORS_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 );
~PANEL_3D_COLORS_BASE();
};
+24 -5
View File
@@ -45,11 +45,18 @@ void PANEL_3D_DISPLAY_OPTIONS::OnCheckEnableAnimation( wxCommandEvent& event )
void PANEL_3D_DISPLAY_OPTIONS::loadViewSettings( EDA_3D_VIEWER_SETTINGS* aCfg )
{
// Check/uncheck checkboxes
m_checkBoxRealisticMode->SetValue( aCfg->m_Render.realistic );
m_checkBoxBoardBody->SetValue( aCfg->m_Render.show_board_body );
m_checkBoxAreas->SetValue( aCfg->m_Render.show_zones );
m_checkBoxSilkscreen->SetValue( aCfg->m_Render.show_silkscreen );
m_checkBoxSolderMask->SetValue( aCfg->m_Render.show_soldermask );
m_checkBoxSolderpaste->SetValue( aCfg->m_Render.show_solderpaste );
m_checkBoxAdhesive->SetValue( aCfg->m_Render.show_adhesive );
m_checkBoxComments->SetValue( aCfg->m_Render.show_comments );
m_checkBoxECO->SetValue( aCfg->m_Render.show_eco );
m_checkBoxSubtractMaskFromSilk->SetValue( aCfg->m_Render.subtract_mask_from_silk );
m_checkBoxClipSilkOnViaAnnulus->SetValue( aCfg->m_Render.clip_silk_on_via_annuli );
m_checkBoxRenderPlatedPadsAsPlated->SetValue( aCfg->m_Render.differentiate_plated_copper );
m_checkBoxClipSilkOnViaAnnulus->SetValue( aCfg->m_Render.clip_silk_on_via_annulus );
m_checkBoxRenderPlatedPadsAsPlated->SetValue( aCfg->m_Render.renderPlatedPadsAsPlated );
m_materialProperties->SetSelection( static_cast<int>( aCfg->m_Render.material_mode ) );
@@ -76,14 +83,26 @@ bool PANEL_3D_DISPLAY_OPTIONS::TransferDataFromWindow()
{
EDA_3D_VIEWER_SETTINGS* cfg = Pgm().GetSettingsManager().GetAppSettings<EDA_3D_VIEWER_SETTINGS>();
// Set render mode
cfg->m_Render.realistic = m_checkBoxRealisticMode->GetValue();
// Set visibility of items
cfg->m_Render.show_board_body = m_checkBoxBoardBody->GetValue();
cfg->m_Render.show_zones = m_checkBoxAreas->GetValue();
cfg->m_Render.subtract_mask_from_silk = m_checkBoxSubtractMaskFromSilk->GetValue();
cfg->m_Render.clip_silk_on_via_annuli = m_checkBoxClipSilkOnViaAnnulus->GetValue();
cfg->m_Render.differentiate_plated_copper = m_checkBoxRenderPlatedPadsAsPlated->GetValue();
cfg->m_Render.clip_silk_on_via_annulus = m_checkBoxClipSilkOnViaAnnulus->GetValue();
cfg->m_Render.renderPlatedPadsAsPlated = m_checkBoxRenderPlatedPadsAsPlated->GetValue();
cfg->m_Render.material_mode = static_cast<MATERIAL_MODE>( m_materialProperties->GetSelection() );
// Set Layer visibility
cfg->m_Render.show_silkscreen = m_checkBoxSilkscreen->GetValue();
cfg->m_Render.show_soldermask = m_checkBoxSolderMask->GetValue();
cfg->m_Render.show_solderpaste = m_checkBoxSolderpaste->GetValue();
cfg->m_Render.show_adhesive = m_checkBoxAdhesive->GetValue();
cfg->m_Render.show_comments = m_checkBoxComments->GetValue();
cfg->m_Render.show_eco = m_checkBoxECO->GetValue( );
// Camera Options
cfg->m_Camera.animation_enabled = m_checkBoxEnableAnimation->GetValue();
cfg->m_Camera.moving_speed_multiplier = m_sliderAnimationSpeed->GetValue();

Some files were not shown because too many files have changed in this diff Show More