Compare commits

..

291 Commits

Author SHA1 Message Date
Wayne Stambaugh 702e8b8915 Tag release version 6.0.2. 2022-02-10 19:29:07 -05:00
Marco Ciampa 9226144312 Typo fixed in Italian translation 2022-02-10 21:57:07 +01:00
Seth Hillbrand d937abb5b8 Fix float scaling to use single fn
Function `scaletoIU` was updated in a8c275ae5d but this missed other
conversion points that re-implemented the same routine.  This unifies
the scaling for both ReadIJCoord and ReadXYCoord to use the same routine
as calls from am_primitive

Fixes https://gitlab.com/kicad/code/kicad/issues/10800
2022-02-10 12:36:10 -08:00
Seth Hillbrand bfd5afd6c8 Fix broken wide string for Mac 2022-02-10 09:48:27 -08:00
jean-pierre charras ab878cc257 gerbview: fix incorrect render of regions defined by a 360 deg arcd (a circle)
these regions were missing.
2022-02-10 09:52:14 +01:00
Seth Hillbrand a8c275ae5d Fix relative return with nullptr condition
Previous fix for CVE munged return conditions for gerber files in some
cases.  This restores the proper order where a nullptr will return 0,0
in the relative case and the current coordinate in others

Also fixes incorrect scale factor for inches/mils conversion to mm
2022-02-09 13:09:19 -08:00
Seth Hillbrand d75329b6f1 Quote BOM executable for spaces 2022-02-09 10:53:09 -08:00
Seth Hillbrand 861589d837 Use wxEmptyString instead of wxT( "" )
Also fixes places where ternaries did autopromotion instead of returning
an empty wxString
2022-02-09 10:33:52 -08:00
Wayne Stambaugh 54f91a0221 Wide characterize libs and bitmap2component source. 2022-02-09 09:01:53 -05:00
Jeff Young 8e1e8e1492 More wxT-ification. 2022-02-09 11:14:38 +00:00
Seth Hillbrand 20ef0e54fe Widen text in pcb_calculator 2022-02-08 17:08:22 -08:00
Seth Hillbrand aa126a12f2 Widen QA strings 2022-02-08 16:22:30 -08:00
Seth Hillbrand eecb54bff2 Widen strings in cvpcb 2022-02-08 16:03:23 -08:00
Seth Hillbrand b554c4cb66 Fix a couple of PCM formatting issues
- Include files using global includes
- Use standard file format extensions
2022-02-08 15:52:51 -08:00
Seth Hillbrand b447d55900 Update kicad manager strings to wide 2022-02-08 15:52:24 -08:00
Seth Hillbrand a444addd89 Default eeschema strings to wide
Prevents stack bug on MacOS
2022-02-08 15:14:54 -08:00
Jeff Young 209d593ca0 wxT-ify utils. 2022-02-08 22:24:29 +00:00
Henrik Kauhanen 4fbb957fa3 Translated using Weblate (Swedish)
Currently translated at 99.4% (7144 of 7186 strings)

Translation: KiCad EDA/v6
Translate-URL: https://hosted.weblate.org/projects/kicad/v6/sv/
2022-02-08 02:49:15 +01:00
Henrik Kauhanen 8100a8940f Translated using Weblate (Finnish)
Currently translated at 87.8% (6315 of 7186 strings)

Translation: KiCad EDA/v6
Translate-URL: https://hosted.weblate.org/projects/kicad/v6/fi/
2022-02-08 02:49:15 +01:00
Mustafa Selçuk ÇAVDAR 485e4ddf05 Translated using Weblate (Turkish)
Currently translated at 43.0% (3095 of 7186 strings)

Translation: KiCad EDA/v6
Translate-URL: https://hosted.weblate.org/projects/kicad/v6/tr/
2022-02-08 02:49:15 +01:00
Henrik Kauhanen 4ab750e926 Translated using Weblate (Swedish)
Currently translated at 99.4% (7147 of 7186 strings)

Translation: KiCad EDA/v6
Translate-URL: https://hosted.weblate.org/projects/kicad/v6/sv/
2022-02-08 02:49:15 +01:00
Henrik Kauhanen a10d9628c9 Translated using Weblate (Finnish)
Currently translated at 87.8% (6311 of 7186 strings)

Translation: KiCad EDA/v6
Translate-URL: https://hosted.weblate.org/projects/kicad/v6/fi/
2022-02-08 02:49:15 +01:00
Arnau Llovet Vidal 5b175d6d53 Translated using Weblate (Catalan)
Currently translated at 58.4% (4202 of 7186 strings)

Translation: KiCad EDA/v6
Translate-URL: https://hosted.weblate.org/projects/kicad/v6/ca/
2022-02-08 02:49:15 +01:00
Axel Henriksson 10217f5507 Translated using Weblate (Swedish)
Currently translated at 99.4% (7147 of 7186 strings)

Translation: KiCad EDA/v6
Translate-URL: https://hosted.weblate.org/projects/kicad/v6/sv/
2022-02-08 02:49:15 +01:00
Henrik Kauhanen f185511698 Translated using Weblate (Swedish)
Currently translated at 99.4% (7147 of 7186 strings)

Translation: KiCad EDA/v6
Translate-URL: https://hosted.weblate.org/projects/kicad/v6/sv/
2022-02-08 02:49:15 +01:00
Axel Henriksson db972a708a Translated using Weblate (Swedish)
Currently translated at 99.4% (7145 of 7186 strings)

Translation: KiCad EDA/v6
Translate-URL: https://hosted.weblate.org/projects/kicad/v6/sv/
2022-02-08 02:49:15 +01:00
Petri Niemelä efaabfa852 Translated using Weblate (Finnish)
Currently translated at 87.7% (6303 of 7186 strings)

Translation: KiCad EDA/v6
Translate-URL: https://hosted.weblate.org/projects/kicad/v6/fi/
2022-02-08 02:49:15 +01:00
Mark Hämmerling 932cb82c82 Translated using Weblate (German)
Currently translated at 100.0% (7186 of 7186 strings)

Translation: KiCad EDA/v6
Translate-URL: https://hosted.weblate.org/projects/kicad/v6/de/
2022-02-08 02:49:15 +01:00
Arnau Llovet Vidal f0d52ff2de Translated using Weblate (Catalan)
Currently translated at 56.9% (4092 of 7186 strings)

Translation: KiCad EDA/v6
Translate-URL: https://hosted.weblate.org/projects/kicad/v6/ca/
2022-02-08 02:49:14 +01:00
Henrik Kauhanen fc737ffffd Translated using Weblate (Swedish)
Currently translated at 99.4% (7145 of 7186 strings)

Translation: KiCad EDA/v6
Translate-URL: https://hosted.weblate.org/projects/kicad/v6/sv/
2022-02-08 02:49:14 +01:00
Marco Ciampa 4df36a3438 Updated Italian translation 2022-02-07 11:27:56 +01:00
Marek Roszko e72bd34383 Fix color4d distance return type
(cherry picked from commit 1f8d101b1d)
2022-02-07 02:11:55 +00:00
Seth Hillbrand 8fc831cbc2 Validate arc output when editing
Handles checking output of the arc to ensure we don't end up generating
an invalid arc.  Also keeps the limit of the arc angle to be (360,360)
excluding 0.

Fixes https://gitlab.com/kicad/code/kicad/issues/10070
2022-02-06 17:18:04 -08:00
Marek Roszko aa5b6c70a7 Ensure we close the occt document at the end of loading
(cherry picked from commit d211ef1ea3)
2022-02-06 16:18:31 +00:00
Jon Evans 7d5c1d7b5c Disable Ubuntu CI for now
Build box is going down for a time

(cherry picked from commit 41b6c9bf8f)
2022-02-06 09:13:35 -05:00
Mark Roszko f5a56c1ebc Use unique_ptr to avoid memory leak in 3d model cache loading
PVS V773
2022-02-05 20:20:45 +00:00
Jeff Young 3af606a020 Wide string decls for gerbview. 2022-02-05 19:59:29 +00:00
Marek Roszko 132358211e Fix a set of odd null on new checks PVS V668
(cherry picked from commit 1c77eb14d7)
2022-02-05 19:43:21 +00:00
Roberto Fernandez Bautista f412d8d461 CADSTAR: Fix potential nullptr dereferencing bug
Don't assume the footprint will have the pad index that the file references.
2022-02-05 19:22:05 +00:00
Marek Roszko 71bcc9883a Fix typoed test condition for TH no hole pads PVS V501
(cherry picked from commit b9f1aaf029)
2022-02-05 18:32:08 +00:00
Marek Roszko be958e3fdb Avoid potential divide by zero in footprint spreading PVS V609
(cherry picked from commit 8588bea4b2)
2022-02-05 18:31:00 +00:00
Marek Roszko b2c99dd953 Fix some leaking objects identified by PVS Studio V773
(cherry picked from commit a7ebfc31f9)
2022-02-05 18:30:24 +00:00
Wayne Stambaugh c875af48e7 Don't create new project on save as when project file already exists.
Fixes https://gitlab.com/kicad/code/kicad/-/issues/10625
2022-02-05 11:30:21 -05:00
Jeff Young 471c0c4c1d More wide-string declarations. 2022-02-05 13:29:00 +00:00
Jeff Young 9e5e46514d More wide-string declarations. 2022-02-05 13:29:00 +00:00
jean-pierre charras ba70f202ce Fix a compil issue. 2022-02-05 11:16:56 +01:00
Seth Hillbrand e18fc36646 wxT rework for common directory 2022-02-04 16:24:50 -08:00
Jeff Young 4657614e4f More wxString wide literals. 2022-02-04 23:12:09 +00:00
Jeff Young d295025964 Be explicit about literal wide-strings. 2022-02-04 20:21:07 +00:00
Jeff Young 2365c1e96f Add duplicated items to parent group.
Fixes https://gitlab.com/kicad/code/kicad/issues/10155

(cherry picked from commit 42917874dd)
2022-02-04 18:14:25 +00:00
Jeff Young 430c4862b6 Log an undo item when filling zones.
If we wanted to put it into the parent's undo item, then the *parent*
would need to not start a new undo record.  Not starting one in the
zone filler tries to add it to the *previous* change, not to the parent
change.

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

(cherry picked from commit 4cc1ced2f3)
2022-02-04 18:14:25 +00:00
Seth Hillbrand 4c81307391 Allow dialogs to force evaluation of UNIT_BINDER
When setting previous values, we don't get the "OnFocus" event, so the
evaluation would not get triggered by simply repeating (using the
keyboard)

Fixes https://gitlab.com/kicad/code/kicad/issues/10752
2022-02-04 10:03:23 -08:00
jean-pierre charras 57cbe261f2 WX_GRID: highlight the selected cell after selection by tab or arrow keys.
Fixes #9290
https://gitlab.com/kicad/code/kicad/issues/9290
2022-02-04 13:55:00 +01:00
Marek Roszko 50d3a507d0 Mark some limits as constexpr
gcc doesn't need it and computes during compile regardless, but experimenting in godbolt, both clang and MSVC actually do need it or else it's partially computed at runtime


(cherry picked from commit ca7840334c)
2022-02-04 12:50:54 +00:00
Seth Hillbrand 7642a9db79 Setup selection when repeating
We need the item to be currently selected when repeating the last symbol
insert.  This ensures we have a valid selection before starting the move
tool and possibly getting odd system behavior from mouse positions

Fixes https://gitlab.com/kicad/code/kicad/issues/10619
2022-02-03 17:09:31 -08:00
Jeff Young 527e06d989 Fix some overly-large text spacing.
While overly-large bounding boxes mostly don't matter, they make us
knock out holes in zones that are too large.
2022-02-04 00:34:20 +00:00
Jeff Young 69b69aa431 Update text variables when they change.
Fixes https://gitlab.com/kicad/code/kicad/issues/10734
2022-02-04 00:34:20 +00:00
Jeff Young d6a86fa9e0 Don't double-count the text thickness in its polygon shape.
The stroke font already takes the thickness into account in
ComputeStringBoundaryLimits() (which is called by GetTextBox()).
2022-02-04 00:34:20 +00:00
Seth Hillbrand 0a13f15a9d Ensure we can version scripting properly
Adds Version() and FullVersion() calls to support reporting version to
scripts and scripting window

Fixes https://gitlab.com/kicad/code/kicad/issues/10079
2022-02-03 15:54:07 -08:00
Seth Hillbrand ef94f31204 Update error message to match new arc dialog
We now provide arc end points and interior angle, so we cannot check for
null radius in the same fashion.  Instead, the starpoint==endpoint
indicates a zero radius

Fixes https://gitlab.com/kicad/code/kicad/issues/10714
2022-02-03 14:31:58 -08:00
Seth Hillbrand 7601a3385f Convert strings to wide when using wxString routines
WxString does not allocate space for wide strings needed during
conversion unless the string is explicitly wide.  This can cause buffer
over/underflow

Fixes https://gitlab.com/kicad/code/kicad/issues/10605
2022-02-03 13:08:07 -08:00
Seth Hillbrand ccf2a63f45 When undoing creation of the sheet, get out first
We can't stay in a sheet that is deleted by the action of undo.  Checks
the current sheet and, if we are currently using it, ensures that the
following action is to leave the current sheet

Fixes https://gitlab.com/kicad/code/kicad/issues/10733
2022-02-03 11:19:33 -08:00
Seth Hillbrand 901685f01b Don't convert KIID on the fly
Converting to string on save prevent unneeded ops
2022-02-03 10:34:14 -08:00
Seth Hillbrand bdf235c25f Restore missing bitmaps 2022-02-03 09:23:27 -08:00
jean-pierre charras 0ffa266315 DIALOG_SPICE_MODEL: fix a cosmetic issue (no room for the help text)
Fixes #10170
https://gitlab.com/kicad/code/kicad/issues/10170

(cherry picked from commit 7c3f0612f1)
2022-02-03 15:01:04 +00:00
Jeff Young 5c94d59e75 Use natural order sorting for FP libraries.
Fixes https://gitlab.com/kicad/code/kicad/issues/10349

(cherry picked from commit a187076438)
2022-02-03 15:01:04 +00:00
Scott Candey 02f93805d0 Common: Corrects Mac OS text navigation shortcuts in Scintilla
Ctrl-A moves cursor to beginning of current line in text box.
Ctrl-E moves cursor to the end of the line.
This change makes navigation in Scintilla text boxes consistent
with other text boxes in KiCad.

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

(cherry picked from commit 23fdbe4b21)
2022-02-03 15:01:04 +00:00
Jeff Young 2e324aa845 Promote to cell selection for spreadsheet-style paste.
Fixes https://gitlab.com/kicad/code/kicad/issues/9211

(cherry picked from commit 9de62d1dd4)
2022-02-03 15:01:04 +00:00
Jeff Young fecb625459 Resolve text variables in eeschema before passing to pcbnew.
Fixes https://gitlab.com/kicad/code/kicad/issues/10429

(cherry picked from commit 2b14b60c32)
2022-02-03 15:00:39 +00:00
Jeff Young b883eee911 Use superclass's copy c'tor from within subclass copy c'tor.
Fixes https://gitlab.com/kicad/code/kicad/issues/10481

(cherry picked from commit 8c758aeeb5)
2022-02-03 15:00:39 +00:00
Jeff Young 01f3a14dc3 Allow more (lots more) unfold from bus menu entries.
Fixes https://gitlab.com/kicad/code/kicad/issues/10529

(cherry picked from commit 4665cdcdc5)
2022-02-03 15:00:39 +00:00
Jeff Young 2425444947 Map zone layers before checking their visibility.
Fixes https://gitlab.com/kicad/code/kicad/issues/10509

(cherry picked from commit 09d0f6e17c)
2022-02-03 15:00:39 +00:00
Jeff Young 66e12af548 Expand text vars in titleblock before exporting.
Fixes https://gitlab.com/kicad/code/kicad/issues/10197

(cherry picked from commit 407660201e)
2022-02-03 15:00:39 +00:00
Jeff Young ea38056e33 Resolve textvars in plot directory.
Fixes https://gitlab.com/kicad/code/kicad/issues/10405

(cherry picked from commit e5d5ee07f0)
2022-02-03 15:00:39 +00:00
Jeff Young c805144c08 Support (and save/recall) zoom in/out in Custom Rules editor.
Fixes https://gitlab.com/kicad/code/kicad/issues/5796

(cherry picked from commit 0036f44e37)
2022-02-03 15:00:39 +00:00
Seth Hillbrand 927afe313d Review ReadXY/ReadIJ to avoid static char arrays
Tighten up the code a bit, removing extra calls and loops.  Removes
unchecked use of stack char array

Fixes https://gitlab.com/kicad/code/kicad/issues/10719
2022-02-02 17:16:30 -08:00
Henrik Kauhanen 03f643ca42 Translated using Weblate (Swedish)
Currently translated at 98.4% (7072 of 7186 strings)

Translation: KiCad EDA/v6
Translate-URL: https://hosted.weblate.org/projects/kicad/v6/sv/
2022-02-02 22:43:15 +01:00
Axel Henriksson 945b841e1b Translated using Weblate (Swedish)
Currently translated at 98.4% (7072 of 7186 strings)

Translation: KiCad EDA/v6
Translate-URL: https://hosted.weblate.org/projects/kicad/v6/sv/
2022-02-02 22:43:15 +01:00
Arnau Llovet Vidal 6771ceb050 Translated using Weblate (Catalan)
Currently translated at 53.5% (3850 of 7186 strings)

Translation: KiCad EDA/v6
Translate-URL: https://hosted.weblate.org/projects/kicad/v6/ca/
2022-02-02 22:43:15 +01:00
Ian McInerney 61853a2d7c Translated using Weblate (Chinese (Simplified))
Currently translated at 100.0% (7186 of 7186 strings)

Translation: KiCad EDA/v6
Translate-URL: https://hosted.weblate.org/projects/kicad/v6/zh_Hans/
2022-02-02 22:43:15 +01:00
taotieren 92773335f7 Translated using Weblate (Chinese (Traditional))
Currently translated at 100.0% (7186 of 7186 strings)

Translation: KiCad EDA/v6
Translate-URL: https://hosted.weblate.org/projects/kicad/v6/zh_Hant/
2022-02-02 22:43:15 +01:00
CloverGit ef58267013 Translated using Weblate (Chinese (Simplified))
Currently translated at 100.0% (7186 of 7186 strings)

Translation: KiCad EDA/v6
Translate-URL: https://hosted.weblate.org/projects/kicad/v6/zh_Hans/
2022-02-02 22:43:15 +01:00
Mustafa Selçuk ÇAVDAR 35e9c57555 Translated using Weblate (Turkish)
Currently translated at 43.0% (3093 of 7186 strings)

Translation: KiCad EDA/v6
Translate-URL: https://hosted.weblate.org/projects/kicad/v6/tr/
2022-02-02 22:43:15 +01:00
Axel Henriksson 1e3b3df808 Translated using Weblate (Swedish)
Currently translated at 98.3% (7066 of 7186 strings)

Translation: KiCad EDA/v6
Translate-URL: https://hosted.weblate.org/projects/kicad/v6/sv/
2022-02-02 22:43:15 +01:00
Dejan Smole c062ba3044 Translated using Weblate (Slovenian)
Currently translated at 77.2% (5553 of 7186 strings)

Translation: KiCad EDA/v6
Translate-URL: https://hosted.weblate.org/projects/kicad/v6/sl/
2022-02-02 22:43:15 +01:00
Jakub Janek 44b4e6753c Translated using Weblate (Slovak)
Currently translated at 75.5% (5430 of 7186 strings)

Translation: KiCad EDA/v6
Translate-URL: https://hosted.weblate.org/projects/kicad/v6/sk/
2022-02-02 22:43:15 +01:00
dsa-t 9c22a8000e Translated using Weblate (Russian)
Currently translated at 100.0% (7186 of 7186 strings)

Translation: KiCad EDA/v6
Translate-URL: https://hosted.weblate.org/projects/kicad/v6/ru/
2022-02-02 22:43:15 +01:00
ZbeeGin 83729adca4 Translated using Weblate (Polish)
Currently translated at 100.0% (7186 of 7186 strings)

Translation: KiCad EDA/v6
Translate-URL: https://hosted.weblate.org/projects/kicad/v6/pl/
2022-02-02 22:43:14 +01:00
김랑기 2585f7e7a4 Translated using Weblate (Korean)
Currently translated at 100.0% (7186 of 7186 strings)

Translation: KiCad EDA/v6
Translate-URL: https://hosted.weblate.org/projects/kicad/v6/ko/
2022-02-02 22:43:14 +01:00
Tokita, Hiroshi a7d586818c Translated using Weblate (Japanese)
Currently translated at 100.0% (7186 of 7186 strings)

Translation: KiCad EDA/v6
Translate-URL: https://hosted.weblate.org/projects/kicad/v6/ja/
2022-02-02 22:43:14 +01:00
Mark Hämmerling 0030ddee26 Translated using Weblate (German)
Currently translated at 100.0% (7186 of 7186 strings)

Translation: KiCad EDA/v6
Translate-URL: https://hosted.weblate.org/projects/kicad/v6/de/
2022-02-02 22:43:14 +01:00
Arnau Llovet Vidal 1853900389 Translated using Weblate (Catalan)
Currently translated at 53.4% (3842 of 7186 strings)

Translation: KiCad EDA/v6
Translate-URL: https://hosted.weblate.org/projects/kicad/v6/ca/
2022-02-02 22:43:14 +01:00
Eric f1a04828f7 Translated using Weblate (Chinese (Simplified))
Currently translated at 100.0% (7186 of 7186 strings)

Translation: KiCad EDA/v6
Translate-URL: https://hosted.weblate.org/projects/kicad/v6/zh_Hans/
2022-02-02 22:43:14 +01:00
Rigo Ligo c8b0a3697f Translated using Weblate (Chinese (Simplified))
Currently translated at 100.0% (7186 of 7186 strings)

Translation: KiCad EDA/v6
Translate-URL: https://hosted.weblate.org/projects/kicad/v6/zh_Hans/
2022-02-02 22:43:14 +01:00
Tian Yunhao e8774181f8 Translated using Weblate (Chinese (Simplified))
Currently translated at 100.0% (7186 of 7186 strings)

Translation: KiCad EDA/v6
Translate-URL: https://hosted.weblate.org/projects/kicad/v6/zh_Hans/
2022-02-02 22:43:14 +01:00
taotieren b253d9085d Translated using Weblate (Chinese (Simplified))
Currently translated at 100.0% (7186 of 7186 strings)

Translation: KiCad EDA/v6
Translate-URL: https://hosted.weblate.org/projects/kicad/v6/zh_Hans/
2022-02-02 22:43:14 +01:00
taotieren 6d1351fa98 Translated using Weblate (Chinese (Traditional))
Currently translated at 100.0% (7186 of 7186 strings)

Translation: KiCad EDA/v6
Translate-URL: https://hosted.weblate.org/projects/kicad/v6/zh_Hant/
2022-02-02 22:43:14 +01:00
taotieren d7eef72c29 Translated using Weblate (Chinese (Simplified))
Currently translated at 100.0% (7186 of 7186 strings)

Translation: KiCad EDA/v6
Translate-URL: https://hosted.weblate.org/projects/kicad/v6/zh_Hans/
2022-02-02 22:43:14 +01:00
Eric 84bae1f3df Translated using Weblate (Chinese (Simplified))
Currently translated at 100.0% (7186 of 7186 strings)

Translation: KiCad EDA/v6
Translate-URL: https://hosted.weblate.org/projects/kicad/v6/zh_Hans/
2022-02-02 22:43:14 +01:00
Mustafa Selçuk ÇAVDAR b5bc942758 Translated using Weblate (Turkish)
Currently translated at 23.9% (1718 of 7186 strings)

Translation: KiCad EDA/v6
Translate-URL: https://hosted.weblate.org/projects/kicad/v6/tr/
2022-02-02 22:43:14 +01:00
Wellington Terumi Uemura 86f485619a Translated using Weblate (Portuguese (Brazil))
Currently translated at 100.0% (7186 of 7186 strings)

Translation: KiCad EDA/v6
Translate-URL: https://hosted.weblate.org/projects/kicad/v6/pt_BR/
2022-02-02 22:43:14 +01:00
Tokita, Hiroshi a9f832556c Translated using Weblate (Japanese)
Currently translated at 100.0% (7186 of 7186 strings)

Translation: KiCad EDA/v6
Translate-URL: https://hosted.weblate.org/projects/kicad/v6/ja/
2022-02-02 22:43:13 +01:00
Arnau Llovet Vidal 01aff3bf80 Translated using Weblate (Catalan)
Currently translated at 47.1% (3386 of 7186 strings)

Translation: KiCad EDA/v6
Translate-URL: https://hosted.weblate.org/projects/kicad/v6/ca/
2022-02-02 22:43:13 +01:00
Mustafa Selçuk ÇAVDAR 5ba8dcdcf1 Translated using Weblate (Turkish)
Currently translated at 12.7% (914 of 7186 strings)

Translation: KiCad EDA/v6
Translate-URL: https://hosted.weblate.org/projects/kicad/v6/tr/
2022-02-02 22:43:13 +01:00
Mustafa Selçuk ÇAVDAR c2edf23118 Translated using Weblate (Turkish)
Currently translated at 10.3% (742 of 7186 strings)

Translation: KiCad EDA/v6
Translate-URL: https://hosted.weblate.org/projects/kicad/v6/tr/
2022-02-02 22:43:13 +01:00
Rigo Ligo 00dd29ae8b Translated using Weblate (Chinese (Simplified))
Currently translated at 100.0% (7186 of 7186 strings)

Translation: KiCad EDA/v6
Translate-URL: https://hosted.weblate.org/projects/kicad/v6/zh_Hans/
2022-02-02 22:43:13 +01:00
Wellington Terumi Uemura 5c4389a3c4 Translated using Weblate (Portuguese (Brazil))
Currently translated at 100.0% (7186 of 7186 strings)

Translation: KiCad EDA/v6
Translate-URL: https://hosted.weblate.org/projects/kicad/v6/pt_BR/
2022-02-02 22:43:13 +01:00
Arnau Llovet Vidal c81a71627f Translated using Weblate (Catalan)
Currently translated at 46.9% (3377 of 7186 strings)

Translation: KiCad EDA/v6
Translate-URL: https://hosted.weblate.org/projects/kicad/v6/ca/
2022-02-02 22:43:13 +01:00
Seth Hillbrand 6d84acfacd Handle invalid pads more gracefully
Pads generated outside of KiCad may have self-intersecting polygons that
simplify to multiple sets.  We handle this by adding multiple primitives
for such polygons and limiting our fracture calls to only polygons that
have holes

Fixes https://gitlab.com/kicad/code/kicad/issues/10712
2022-02-02 13:36:24 -08:00
jean-pierre charras 788c607d47 EDA_SHAPE::MakeEffectiveShapes(): protect against empty polygons.
Fixes #10713
https://gitlab.com/kicad/code/kicad/issues/10713
2022-02-02 20:48:42 +01:00
Steffen Mauch 169881dcf1 EAGLE plugin: use specified RATIO value for text size calculation
(cherry picked from commit 61b2b0ff0c)
2022-02-02 08:48:25 -08:00
Seth Hillbrand a7fbdfe918 Fix overflow vulnerability in Gerbview
Corrects an unguarded read that could lead to arbitrary code execution
in specifically crafted gerber files.

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

(cherry picked from commit 54b20cb049)
2022-02-02 08:31:15 -08:00
jean-pierre charras 3d11ce5139 export D356 netlist: fix incorrect id for pads type connectors.
these pads are similar to SMD pads and should have the same id.
Fixes #10694
https://gitlab.com/kicad/code/kicad/issues/10694
2022-02-01 08:45:02 +01:00
Seth Hillbrand 833ce19221 Be more diligent in preventing drag line errors
They can happen even when there are no collisions, so we need to reset
the 'ok' flag before using the line again.

Fixes https://gitlab.com/kicad/code/kicad/issues/9555
2022-01-31 16:09:14 -08:00
Alex 73d0d7796c Allow overlay scrolling on GTK, except for GAL canvases.
This prevents glitches when both scrollbars
are visible and scrolling to the end.

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

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

(cherry picked from commit 4c4089e836)
2022-01-31 15:43:31 -05:00
jean-pierre charras 42dfdf8c38 PCB_CONTROL::unfilledZoneCheck(): skip rule areas: they are not filled by definition.
Fixes #10691
https://gitlab.com/kicad/code/kicad/issues/10691
2022-01-31 17:04:05 +01:00
Seth Hillbrand 70d00689ca Fully select a line for transformation
When not trying to select points, we need to ensure that the full
line is selected for transformation

Fixes https://gitlab.com/kicad/code/kicad/issues/10566
2022-01-29 17:36:54 -08:00
jean-pierre charras 26dfc4477f PCB_TARGET: add missing TransformShapeWithClearanceToPolygon() method.
From Master branch.
2022-01-29 20:07:14 +01:00
Seth Hillbrand 38a4894d92 Prevent multiple single-point line solutions
Suggested by @rivimey, we test the case where both lines return singular
point lines and prevent them leaking into our drag solution

Fixes https://gitlab.com/kicad/code/kicad/issues/9555
2022-01-29 07:07:03 -08:00
Seth Hillbrand c2707f3cc0 Fix large memory leak in DRC
All elements get effective shapes, many of which get triangulated.  This
memory needs to be freed when destroying the tree
2022-01-28 17:07:11 -08:00
Seth Hillbrand 8753051db6 Don't count zero-length as duplicate
We were checking for duplicate tracks by looking to see if the two
tracks had two shared points.  A null track always matched this case,
which removed the valid track.  We solve this by avoiding null tracks in
the duplicate checker.  They are removed separately in the null track
stage.

This also fixes a GTK-specific tree issue where we require the
BeforeReset()/AfterReset() calls instead of Cleared() to prevent GTK
from dereferencing a parent after freeing

Fixes https://gitlab.com/kicad/code/kicad/issues/10624
2022-01-28 16:34:00 -08:00
Seth Hillbrand 8ae304dcca Don't allow degenerate lines in dragger
If walkaround returns an invalid line, don't consider it for a track

Fixes https://gitlab.com/kicad/code/kicad/issues/9555
2022-01-28 15:18:42 -08:00
Seth Hillbrand 796893de56 Fix negative arc angles in PCAD import 2022-01-28 10:18:17 -08:00
alexfanqi ea52101c1b Add riscv64 support for libcontext
modified to match function arguments different from upstream

Author: Andreas Schwab
(cherry picked from commit 01f0aad7c0)
2022-01-27 08:56:46 -05:00
Wayne Stambaugh ca27b38182 Fix broken environment variable substitution on Windows.
Fixes https://gitlab.com/kicad/code/kicad/-/issues/10303

(cherry picked from commit 9af365b5b3)
2022-01-27 08:56:46 -05:00
jean-pierre charras 3f6a4296d9 Pcbnew, export svg: Fix incorrect saving of layer set.
From Master branch
2022-01-27 13:07:40 +01:00
jean-pierre charras 2a27899b9b French translation update.
Fixes #10588
https://gitlab.com/kicad/code/kicad/issues/10588
2022-01-25 09:38:39 +01:00
Marek Roszko 1a534ade89 Remove UpdateUI from preferences pdf viewer option
Partial fix for https://gitlab.com/kicad/code/kicad/-/issues/10590
2022-01-24 20:36:21 -05:00
Seth Hillbrand fddfce4fb1 Force a size event to avoid multiple yields
When the grid editor is shown, we also want to ensure that the grid gets
resized to account for the new editor.  Queuing the event will ensure
that happens after the editor is emplaced in the grid

Fixes https://gitlab.com/kicad/code/kicad/issues/5690
2022-01-24 15:31:45 -08:00
Wayne Stambaugh ab184ba9f3 Fix wxWidgets invalid string specifier assertion. 2022-01-24 15:44:42 -05:00
Seth Hillbrand a1615cce7e Enforce strictly weak ordering in sheets
This ensures that irreflexivity is given in sort ordering.  This may
have been triggering issues in MacOS when adding sheets

Fixes https://gitlab.com/kicad/code/kicad/issues/10557
2022-01-24 10:41:02 -08:00
Seth Hillbrand 871556ebda Allow time to update editor
On GTK, the full editor needs to be shown and, for some systems, the
editor will not show correctly.  By yielding we should allow the time to
recalculate sizes for the editor in the grid

Fixes https://gitlab.com/kicad/code/kicad/issues/5690
2022-01-24 09:55:46 -08:00
Marek Roszko 7152c4ebb8 Add extraction of patch version to feed to resource defines 2022-01-23 14:47:54 -05:00
Mark Roszko 34dafdd2c1 Try and silence the ci failure on windows 2022-01-23 19:23:43 +00:00
Seth Hillbrand f12d0cb0e2 Get all eeschema layers properly ordered
Layers not in the given order are drawn behind everyone else.  Missing
the text prevents global labels from showing properly in GAL order

Fixes https://gitlab.com/kicad/code/kicad/issues/10546
2022-01-23 10:03:03 -08:00
jean-pierre charras 029e42f8d1 DIALOG_SIM_SETTINGS: fix incorrect validation of DC souces in DC Transfer panel
From Master branch
Fixes #10568
https://gitlab.com/kicad/code/kicad/issues/10568
2022-01-23 17:01:55 +01:00
jean-pierre charras 60ae18893e PCB_POINT_EDITOR: fix missing init of PAD pos0 after changing
(From Master branch)
2022-01-22 10:43:23 +01:00
Marek Roszko e0b835fe20 Set curl to use the Windows cert store
(cherry picked from commit 3ede5f42be)
2022-01-22 03:10:11 +00:00
Steffen Mauch d6c4215a1f pcbnew: EAGLE importer does map value to wrong layer if nothing is defined in original EAGLE footprint
Fixes https://gitlab.com/kicad/code/kicad/issues/10311

(cherry picked from commit 55b782d66e)
2022-01-21 13:16:41 -08:00
Steven A. Falco 8b6a166698 Missing include file
(cherry picked from commit 042f584859)
2022-01-21 09:01:33 -08:00
jean-pierre charras e9a5e5466c SYMBOL_VIEWER_FRAME: fix refresh of the canvas after selecting a new symbol.
From Master branch
2022-01-21 17:34:51 +01:00
Jeff Young 0317185860 Don't update units for UNSCALED, PERCENT or DEGREES.
Fixes https://gitlab.com/kicad/code/kicad/issues/10020

(cherry picked from commit 27d8df1122)
2022-01-21 15:42:48 +00:00
Jeff Young c02cadec2a Exclude rules which match no enabled layers.
Fixes https://gitlab.com/kicad/code/kicad/issues/10227

(cherry picked from commit 0967cc82e2)
2022-01-21 15:06:18 +00:00
Jeff Young b608ebd058 Don't findnext on an empty string; show the dialog.
Fixes https://gitlab.com/kicad/code/kicad/issues/10313

(cherry picked from commit 60fc75e239)
2022-01-21 15:05:27 +00:00
Jeff Young 6d7659fb20 Flip arc endpoints when mirroring in FPEditor.
Fixes https://gitlab.com/kicad/code/kicad/issues/10550

(cherry picked from commit 7f6bc28f87)
2022-01-21 15:02:15 +00:00
Seth Hillbrand dd7029ea07 Always use the project directory for default save
Fixes https://gitlab.com/kicad/code/kicad/issues/10478
2022-01-20 11:51:16 -08:00
Seth Hillbrand 323a069738 Clear Undo list when renaming
Our undo/redo list is tied to the screen that gets cleared when we
reload the file after renaming.  We need to clear the Undo list at this
point to prevent possible crashes when moving too far back in the stack

Fixes https://gitlab.com/kicad/code/kicad/issues/10504
2022-01-20 11:28:41 -08:00
Seth Hillbrand 615eda816e Don't close filled polylines when printing
Eeschema/libedit support open, filled polylines.  When printing, this
should be drawn as a fill, followed by the polyline to avoid assumptions
about closed polygons in the graphic code

Fixes https://gitlab.com/kicad/code/kicad/issues/10537
2022-01-20 10:53:57 -08:00
Seth Hillbrand 6810479a19 Prevent UI updates from changing zoom selection
The zoom selection should only change when requested by the user, not in
response to UI updates.  This can cause unexpected zoom shifts when the
calculated zoom is within a range of one of the presets.  It also adds
unneeded calls during the UI update cycle

Fixes https://gitlab.com/kicad/code/kicad/issues/10498
2022-01-20 10:09:25 -08:00
jean-pierre charras d9c6765be7 ITMAP_BASE::DrawBitmap(): fix position of the clipping area when using matrix transform.
Fixes #10525
https://gitlab.com/kicad/code/kicad/issues/10525
From Master branch
2022-01-20 16:27:18 +01:00
Seth Hillbrand 857683d372 Remove unneeded distance calc 2022-01-18 15:58:20 -08:00
jean-pierre charras 24865971af DRAWING_SHEET_PARSER: fix missing parse of "T_comment" case for DS_DATA_ITEM_BITMAP.
Fixes #10477
https://gitlab.com/kicad/code/kicad/issues/10477
From Master.
2022-01-17 18:04:26 +01:00
jean-pierre charras 10ce515aca LSET::SeqStackupBottom2Top(): add missing user layers to list of layers
These missing layers were not exported in export SVG.
From master branch
2022-01-17 11:01:11 +01:00
Wayne Stambaugh da28ade004 Footprint editor: use most recently used path on footprint import.
Fixes https://gitlab.com/kicad/code/kicad/-/issues/10418

(cherry picked from commit c154e85ebd)
2022-01-16 09:48:21 -05:00
Marek Roszko f97a0fb3e9 Add a way to add a "revision" for use in windows manifests
(cherry picked from commit d4ee74a832)
2022-01-15 20:20:53 +00:00
Seth Hillbrand cccdac136f Fix transparent circle printing
DrawEllipse seems to work fine using transparent bg for all DCs except
printing (which is the only one we use now)  Use two arcs to draw a
transparent fill for the circle instead as a workaround until we
implement Cairo printing

Fixes https://gitlab.com/kicad/code/kicad/issues/10431
2022-01-14 16:13:05 -08:00
Jon Evans 2306d00c89 Do not check key states for non-key events in TryBefore
Fixes https://gitlab.com/kicad/code/kicad/-/issues/10127
2022-01-13 22:28:45 -05:00
Jon Evans 20bbf9b179 PNS: Do not clear layer pairs when importing new sizes
Fixes https://gitlab.com/kicad/code/kicad/-/issues/10225
2022-01-13 20:37:37 -05:00
Jon Evans cf4d46b24d PNS: Do not allow smart pads when in 90-degree mode
Fixes https://gitlab.com/kicad/code/kicad/-/issues/10386
2022-01-13 20:21:19 -05:00
qu1ck 739c14eaa2 FOOTPRINT::GetProperty() swig extension
(cherry picked from commit 33a4c9b08e)
2022-01-13 13:10:44 -08:00
Wayne Stambaugh adfbfc27af Footprint editor: fix Eagle plugin footprint library layer mapping bug.
Fixes https://gitlab.com/kicad/code/kicad/-/issues/10354

(cherry picked from commit a77b5649cc)
2022-01-12 20:52:55 -05:00
Wayne Stambaugh 26047615bd Fix X3D model parser.
Fixes https://gitlab.com/kicad/code/kicad/-/issues/10385

(cherry picked from commit 44e4abde0e)
2022-01-12 19:00:27 -05:00
Seth Hillbrand dcb8f29317 Handle rotated symbol rectangles in Eagle import
Fixes https://gitlab.com/kicad/code/kicad/issues/10360
2022-01-12 15:10:42 -08:00
dana 57d58fe335 Handle Unicode clipboard data in pcbnew and symbol editor
Fixes #10323

(cherry picked from commit 8373180cbb)
2022-01-12 09:23:24 -08:00
Seth Hillbrand 56d87a8613 Catch default autowire case
Since we are dereferencing the optional, we need to ensure it exists in
all cases

Fixes https://gitlab.com/kicad/code/kicad/issues/10394
2022-01-12 09:02:39 -08:00
Wayne Stambaugh 9a0323fe17 Begin version 6.0.2 development. 2022-01-11 21:22:36 -05:00
Wayne Stambaugh 0a9271f98e Tag release version 6.0.2. 2022-01-11 21:18:26 -05:00
prometheus 3c91b0c693 Translated using Weblate (Turkish)
Currently translated at 10.2% (737 of 7186 strings)

Translation: KiCad EDA/v6
Translate-URL: https://hosted.weblate.org/projects/kicad/v6/tr/
2022-01-12 01:42:50 +01:00
Arnau Llovet Vidal 562bd7d564 Translated using Weblate (Catalan)
Currently translated at 46.6% (3353 of 7186 strings)

Translation: KiCad EDA/v6
Translate-URL: https://hosted.weblate.org/projects/kicad/v6/ca/
2022-01-12 01:42:49 +01:00
Seth Hillbrand ad726dc6e4 Rework cd8d6ba0 for 6.0.1
Addresses https://gitlab.com/kicad/code/kicad/-/issues/10357 as well as
a few additional rounding points in 3d viewer based on master commit
2022-01-11 13:49:57 -08:00
Roberto Fernandez Bautista b2ecf097ed Include Footprints within Groups when re annotating duplicates
Fixes https://gitlab.com/kicad/code/kicad/-/issues/10329

(cherry picked from commit de7158b80e)
2022-01-11 20:52:01 +00:00
Seth Hillbrand 8dca61ce9c Fix copy-paste error 2022-01-11 06:08:15 -08:00
Steven A. Falco e8e25fd732 Launchers must specify WM_CLASS
On some Linux desktops, we get extra icons in the application dock.
This happens because the dock doesn't know the "class" of the
application.  We need to add StartupWMClass=xxx lines, where xxx is
the name associated with the application.

This patch addresses the following issue:

https://gitlab.com/kicad/packaging/kicad-ubuntu-builder/kicad-daily-package/-/issues/30

While it was written against Ubuntu, it also affects Fedora, and
probably other Linux systems too.
2022-01-11 01:25:16 +00:00
Seth Hillbrand bd7841bf96 Handle arcs in global track width changes
Also add defensive code against invalid indices

Fixes https://gitlab.com/kicad/code/kicad/issues/10325
2022-01-10 17:19:49 -08:00
Seth Hillbrand 55020c2b89 Better fix for missing end segment
Rather than skipping our endEdit() call in libedit, we need to
parameterize whether we want the shape open/closed.  Closed will remove
the last segment if it lands on the first point.  We don't want that
but we do want to remove the last point if it duplicates the second to
last (in the case of double-clicking)

Fixes https://gitlab.com/kicad/code/kicad/issues/10334
2022-01-10 13:37:47 -08:00
Seth Hillbrand a74d1d9962 Keep ratsnest setting when pasting
Paste items should copy the global ratsnest visibility setting

Fixes https://gitlab.com/kicad/code/kicad/issues/10346
2022-01-10 12:48:03 -08:00
Seth Hillbrand 4d899d7820 Remove default hotkey for toggle zone display
It is too easy to accidentally hide your zones and the 'A' hotkey is
intuitively mapped to Add Footprint, to match Add Symbol in eeschema.

This won't change current hotkey customizations but will help prevent
future user error.  Users can still map the action to a hotkey if the
new toggle is useful to their workflow
2022-01-10 11:48:26 -08:00
Seth Hillbrand 4907b90215 Fix FP circle validity check
Radius is encoded by m_endX

Fixes https://gitlab.com/kicad/code/kicad/issues/10337
2022-01-10 10:54:23 -08:00
Jan Straka a399f799ad Translated using Weblate (Czech)
Currently translated at 90.5% (6507 of 7186 strings)

Translation: KiCad EDA/v6
Translate-URL: https://hosted.weblate.org/projects/kicad/v6/cs/
2022-01-10 18:58:11 +01:00
Jan Straka 55cd2da432 Translated using Weblate (Czech)
Currently translated at 89.5% (6432 of 7186 strings)

Translation: KiCad EDA/v6
Translate-URL: https://hosted.weblate.org/projects/kicad/v6/cs/
2022-01-10 18:58:11 +01:00
obit 096600ffc4 Translated using Weblate (Chinese (Simplified))
Currently translated at 100.0% (7186 of 7186 strings)

Translation: KiCad EDA/v6
Translate-URL: https://hosted.weblate.org/projects/kicad/v6/zh_Hans/
2022-01-10 18:58:11 +01:00
Axel Henriksson b4bae29c02 Translated using Weblate (Swedish)
Currently translated at 98.3% (7066 of 7186 strings)

Translation: KiCad EDA/v6
Translate-URL: https://hosted.weblate.org/projects/kicad/v6/sv/
2022-01-10 18:58:11 +01:00
Mark Hämmerling e4a5ce78aa Translated using Weblate (German)
Currently translated at 100.0% (7186 of 7186 strings)

Translation: KiCad EDA/v6
Translate-URL: https://hosted.weblate.org/projects/kicad/v6/de/
2022-01-10 18:58:11 +01:00
Mark Hämmerling 522738284d Translated using Weblate (German)
Currently translated at 100.0% (7186 of 7186 strings)

Translation: KiCad EDA/v6
Translate-URL: https://hosted.weblate.org/projects/kicad/v6/de/
2022-01-10 18:58:11 +01:00
pondahai cc0d5ec46a Translated using Weblate (Chinese (Traditional))
Currently translated at 100.0% (7186 of 7186 strings)

Translation: KiCad EDA/v6
Translate-URL: https://hosted.weblate.org/projects/kicad/v6/zh_Hant/
2022-01-10 18:58:11 +01:00
Tian Yunhao f2018a09d8 Translated using Weblate (Chinese (Simplified))
Currently translated at 100.0% (7186 of 7186 strings)

Translation: KiCad EDA/v6
Translate-URL: https://hosted.weblate.org/projects/kicad/v6/zh_Hans/
2022-01-10 18:58:11 +01:00
김랑기 54952ca97e Translated using Weblate (Korean)
Currently translated at 100.0% (7186 of 7186 strings)

Translation: KiCad EDA/v6
Translate-URL: https://hosted.weblate.org/projects/kicad/v6/ko/
2022-01-10 18:58:10 +01:00
Tokita, Hiroshi a8543b1122 Translated using Weblate (Japanese)
Currently translated at 100.0% (7186 of 7186 strings)

Translation: KiCad EDA/v6
Translate-URL: https://hosted.weblate.org/projects/kicad/v6/ja/
2022-01-10 18:58:10 +01:00
Tian Yunhao 790ca19445 Translated using Weblate (Chinese (Simplified))
Currently translated at 100.0% (7186 of 7186 strings)

Translation: KiCad EDA/v6
Translate-URL: https://hosted.weblate.org/projects/kicad/v6/zh_Hans/
2022-01-10 18:58:10 +01:00
Wellington Terumi Uemura f56b3bdd07 Translated using Weblate (Portuguese (Brazil))
Currently translated at 100.0% (7186 of 7186 strings)

Translation: KiCad EDA/v6
Translate-URL: https://hosted.weblate.org/projects/kicad/v6/pt_BR/
2022-01-10 18:58:10 +01:00
Rafael Silva 7d635d3d43 Translated using Weblate (Portuguese)
Currently translated at 100.0% (7186 of 7186 strings)

Translation: KiCad EDA/v6
Translate-URL: https://hosted.weblate.org/projects/kicad/v6/pt/
2022-01-10 18:58:10 +01:00
Jose Perez 37f62e539b Translated using Weblate (Spanish)
Currently translated at 99.9% (7185 of 7186 strings)

Translation: KiCad EDA/v6
Translate-URL: https://hosted.weblate.org/projects/kicad/v6/es/
2022-01-10 18:58:10 +01:00
Jan Straka 3196f4adb6 Translated using Weblate (Czech)
Currently translated at 88.9% (6395 of 7186 strings)

Translation: KiCad EDA/v6
Translate-URL: https://hosted.weblate.org/projects/kicad/v6/cs/
2022-01-10 18:58:10 +01:00
Gökhan Koçmarlı b4d67b6b29 Translated using Weblate (Turkish)
Currently translated at 9.9% (712 of 7186 strings)

Translation: KiCad EDA/v6
Translate-URL: https://hosted.weblate.org/projects/kicad/v6/tr/
2022-01-10 18:58:10 +01:00
Eric f7d790598b Translated using Weblate (Chinese (Simplified))
Currently translated at 100.0% (7186 of 7186 strings)

Translation: KiCad EDA/v6
Translate-URL: https://hosted.weblate.org/projects/kicad/v6/zh_Hans/
2022-01-10 18:58:10 +01:00
Wayne Stambaugh bbf00e0461 Pcbnew: honor footprint exclude from BOM setting.
Fixes https://gitlab.com/kicad/code/kicad/-/issues/10297

(cherry picked from commit f379c49084)
2022-01-09 11:30:06 -05:00
Mikolaj Wielgus a91f807e13 Update contributor name 2022-01-09 09:29:54 +01:00
Seth Hillbrand 100cf757fe Force Mesa to use its own call
Mesa does not support adaptive swapping but will sometimes report that
it does.  This prevents Mesa drivers from testing (and segfaulting) the
limits of their call

Fixes https://gitlab.com/kicad/code/kicad/issues/10069
2022-01-08 17:13:25 -08:00
Jon Evans 76f21d950d Ensure LIB_TREE cleans up while frame still exists
Fixes https://gitlab.com/kicad/code/kicad/-/issues/10266
2022-01-08 17:32:17 -05:00
Seth Hillbrand 69469b254a Printing multiple bitmaps
A long-standing issue with multiple workarounds
(https://gitlab.com/kicad/code/kicad/-/issues/1877) prevented eeschema
printouts with multiple images or images in both the worksheet and the
schematic.

We worked around this by ordering the bitmap printing to be the first
step in the printing process.  This partially worked but didn't get
everything correct.  The primary difficulty in debugging this was that
the wxPrintPreview that we generate looked correct.  Only the actual
printout was incorrect.

The fix is to explicitly clip bitmap drawing to the bitmap area,
regardless of how large the bitmap is.
2022-01-07 17:15:59 -08:00
Seth Hillbrand bfca928900 Plot pads in layer color
v6 pads are not allowed to be a different color from the rest of the
copper layer, so don't query the GAL layer for a color

Fixes https://gitlab.com/kicad/code/kicad/issues/10293
2022-01-07 08:55:59 -08:00
Seth Hillbrand 62f8603353 Don't deduplicate symbol polygons
SHAPE_LINE_CHAIN will, by default, remove duplicate points when
appending.  We don't want to do this when constructing our polygons in
symbol editor, so we need to explicitly call the routine without
deduplication

Fixes https://gitlab.com/kicad/code/kicad/issues/10289
2022-01-07 08:25:09 -08:00
Seth Hillbrand 9a2332dfcf Clear edited point when exiting tool
When leaving the main point editor loop, we need to ensure that the edit
point is cleared as well.  This is usually cleared by a ClearEvent call
but in case this is missed, we need to ensure that other tools are not
caught out

Fixes https://gitlab.com/kicad/code/kicad/issues/10288
2022-01-07 08:23:31 -08:00
qu1ck 4bcfa8df1f Template for vector<VECTOR2I> in swig 2022-01-06 23:48:52 -05:00
Seth Hillbrand a0e424c2ac Forgot to build ninja files 2022-01-06 20:09:44 -08:00
Seth Hillbrand f4b9a92b94 Swap make for ninja in Fedora CI
Take advantage of extra cores on hetzner machine
2022-01-06 20:09:44 -08:00
Seth Hillbrand 184a592f82 Use KiCad builders for Fedora 2022-01-06 20:09:44 -08:00
Seth Hillbrand 3e6bf7814b Safely sort view layers
Changing view order of only some layers can cause overwriting of the
original layer if not pre-staged

Fixes https://gitlab.com/kicad/code/kicad/issues/10283
2022-01-06 14:41:10 -08:00
Seth Hillbrand 9864337914 Do not call SafeYield on close
wxSafeYield() is not "safe".  Pending actions may include deletion of
the currently active class.  This will cause crashes when exiting.  If
needed for specific behaviors, we should use wxSafeYieldFor( flag ) with
the appropriate events specified rather than a general yield which can
cause more problems
2022-01-06 12:31:59 -08:00
Seth Hillbrand 78e737b9d8 DRC scripting: load project from board if possible
s_SettingsManager is not always initialized when the WriteDRCReport is
run.  We should first attempt to extract the project from the actual
board being checked.  Failing that, we fall back to the static settings manager and then exit if we don't have a project associated.

Fixes https://gitlab.com/kicad/code/kicad/issues/10221
2022-01-06 11:50:21 -08:00
Brian Mayton d014f0307b Add ORANGE to DXF output
Matches the schematic color options to DXF layers

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

Signed-off-by: Seth Hillbrand <seth@kipro-pcb.com>
2022-01-06 11:02:57 -08:00
Seth Hillbrand 7c9340f855 Fix swap interval checking
Checking for the existence of the call only validated that our header
defined the value, not that the video card/driver supported the call.
We query the extensions string directly to check for support.  This
should fix both the X11 and virtualization issues (potentially other
crashes with older video cards as well)

Fixes https://gitlab.com/kicad/code/kicad/issues/8944
2022-01-06 10:53:13 -08:00
jean-pierre charras 3069b198b1 PANEL_TEMPLATE_FIELDNAMES: fix incorrect management of boolean options
(it was impossible to disable them)
From Master branch.
Fixes https://gitlab.com/kicad/code/kicad/issues/10280
2022-01-06 19:44:23 +01:00
Seth Hillbrand 05d3dc533b Prevent cvpcb from losing text focus on filter
Refresh event changes focus (on GTK).  We fix this by storing the
existing insertion point in the text box, refocusing and restoring the
text position

Fixes https://gitlab.com/kicad/code/kicad/issues/10029
2022-01-06 09:16:34 -08:00
Marek Roszko 1e05732f55 Add std::hash specialization for VECTOR2I
(cherry picked from commit 589a03afcd)

Fixes https://gitlab.com/kicad/code/kicad/issues/10275
2022-01-05 20:32:46 -08:00
Seth Hillbrand 71e7b4b77b Use 'special' escaping for certain fields
Most fields are escaped using the `\` notation.  But the VALUE field and
the symbol name need to be escaped using braces notation.

Fixes https://gitlab.com/kicad/code/kicad/issues/10097
2022-01-05 17:18:39 -08:00
Seth Hillbrand b8a7a66a0a Keep symbol synced with edit tool
Undo/Redo can change the symbol referenced by the symbol drawing tool.
This updates the current symbol before important steps to keep the
system synced

Fixes https://gitlab.com/kicad/code/kicad/issues/10125
2022-01-05 16:51:41 -08:00
Seth Hillbrand 55087a9e82 Don't remove last point in libedit
SHAPE_LINE_CHAIN in libedit doesn't make a polygon, so we always need
the last point and it shouldn't be closed

Fixes https://gitlab.com/kicad/code/kicad/issues/9934
2022-01-05 16:02:50 -08:00
Seth Hillbrand 444801ada6 Prevent unneeded fallback
Starting in be8327bd54, we assume that all
exceptions in DoRePaint() are caused by OpenGL.  But many calls in
UpdateItems() will throw if there are internal errors such as
std::out_of_range.  Here, we catch those errors and simply skip ahead
rather than falling back to Cairo
2022-01-05 13:46:15 -08:00
Steffen Mauch 7afe188a29 eeschema: automatic generated symbol library from EAGLE plugin does not include footprint reference
Fixes https://gitlab.com/kicad/code/kicad/issues/10262

(cherry picked from commit 3ced3afa68)
2022-01-05 15:28:05 -05:00
Ian McInerney 1ad1cf8374 Fix compile error with UTF8 unicode wxWidgets build
Fixes https://gitlab.com/kicad/code/kicad/issues/10210

(Cherry-picked from bd828f598c)
2022-01-05 19:45:27 +00:00
Ian McInerney abaee94109 Revert caf406943e and don't install the kicad2step lib
This fixes https://gitlab.com/kicad/code/kicad/-/issues/9944 and reverts
caf406943e. The original fix caused issues
with some CMake versions because it tried to give library dependencies
to an object library, which can't have any library dependencies.
Instead, we need it as a static library, and since there is no need to
actually have it as an end-user library, it shouldn't be in the install
command.

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

(Cherry-picked from commit fb36e1b582)
2022-01-05 19:45:27 +00:00
Steffen Mauch d60e77176f eeschema: EAGLE plugin does not reference footprint with library suffix
Fixes https://gitlab.com/kicad/code/kicad/issues/10261

(cherry picked from commit 502e34349e)
2022-01-05 14:39:43 -05:00
Seth Hillbrand 7f1648934f Update pin cache when undoing
The pin cache is invalidated by swap, so we need to ensure that it is
reset when we undo a change to the pins in schematic editor

Fixes https://gitlab.com/kicad/code/kicad/issues/10272
2022-01-05 11:33:03 -08:00
Seth Hillbrand bef762e652 Don't strip extensions twice in BOM export
Exporting the Bill of Materials uses the netlist exporter.  Both of
these routines were stripping the extension, leading to projects like
"test.project.kicad_pro" having the project name stripped.  We separate
the BOM netlist export from generic plugin netlist export to allow the
correct behavior when exporting netlists and generating BOMs

Fixes https://gitlab.com/kicad/code/kicad/issues/10270
2022-01-05 11:07:23 -08:00
Seth Hillbrand a05ec04ee8 Set readable flags correctly on open
Missing files may be thrown during open.  These should have existence
and readable flags set correctly
2022-01-05 09:54:10 -08:00
Steffen Mauch 362eedc510 pcbnew: EAGLE plugin is case sensitive to >VALUE / >NAME
Fixes https://gitlab.com/kicad/code/kicad/issues/10253

(cherry picked from commit 82f147ecef)
2022-01-05 08:07:41 -05:00
Steffen Mauch 11402e2db1 pcbnew: fixing eagle_plugin with empty class names
Fixes #10229
https://gitlab.com/kicad/code/kicad/issues/10229

(cherry picked from commit a5307c6f59)
2022-01-05 07:22:01 -05:00
Seth Hillbrand b1658fdf9a Don't rename existing schematic file
We should never leave a situation where the schematic file may no longer
exist (if the first rename succeeds and the second fails).  So, make a
backup copy of the original schematic file and then attempt to rename
the autosave over the first file.  In this case, if either attempt
fails, we do not lose the original file

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

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

Fixes https://gitlab.com/kicad/code/kicad/issues/10219
2022-01-04 20:27:43 -08:00
Jon Evans f9d8ec6137 Handle footprint shapes in polygon creation
Fixes https://gitlab.com/kicad/code/kicad/-/issues/10259
2022-01-04 21:31:22 -05:00
Jon Evans e9b91b6fab Fix creating polygons from footprint rule areas
Fixes https://gitlab.com/kicad/code/kicad/-/issues/10257
2022-01-04 21:28:04 -05:00
Seth Hillbrand 873353d8d7 Prevent clipping by default
The text bbox inflation from fb4343bc clips dimensions by default.  This
restores the default size to not clip the dimension line.  It is still a
bit larger than I'd like it to be but is usable

Fixes https://gitlab.com/kicad/code/kicad/issues/10033
2022-01-04 12:11:23 -08:00
Seth Hillbrand a326d777f0 Don't split legacy paths
The '.' is a valid character in the legacy preferences, not a separator.
Also adds fail-safe catch for JSON throws

Fixes https://gitlab.com/kicad/code/kicad/issues/10211
2022-01-04 19:08:12 +00:00
Thomas Pointhuber dec310f7f8 altium: Fix board outline import with arcs using SHAPE_LINE_CHAIN instead of a hack 2022-01-04 19:57:26 +01:00
Seth Hillbrand ca8cf14dff Fix missing FOOTPRINT cast in swig
Fixes https://gitlab.com/kicad/code/kicad/issues/10236
2022-01-04 10:49:29 -08:00
Seth Hillbrand ed9a3deb57 Fix pad snapping in renumber pads
Snap shouldn't be looking for other items in this routine or using the
grid

Fixes https://gitlab.com/kicad/code/kicad/issues/10238
2022-01-03 17:18:03 -08:00
Wayne Stambaugh 58b07efd99 Make footprint and symbol editors use MRU path for new libraries.
Fixes https://gitlab.com/kicad/code/kicad/-/issues/10216

(cherry picked from commit ff38853886)
2022-01-03 18:36:46 -05:00
Seth Hillbrand 1874ad2f7e Catch errors from load()
Loading footprints may throw in some cases.  We need to catch these
nicely without breaking out of the full loading process

Fixes https://gitlab.com/kicad/code/kicad/issues/10213
2022-01-03 15:30:20 -08:00
Marco Ciampa b115aec42b Updated Italian translation 2022-01-03 12:02:20 +01:00
Roberto Fernandez Bautista 5e884d14c7 Rename ComparePageNumAndName -> ComparePageNum 2022-01-02 23:27:15 +00:00
Mike Williams e36381bdd2 Gerbview: Fix diff mode issues with OpenGL transparency
Fixes: https://gitlab.com/kicad/code/kicad/-/issues/10121
(cherry picked from commit 404659d275)
2022-01-02 18:18:00 -05:00
Jon Evans 45182febaf Exit router and invoke edit tool when attempting to drag an arc track
Fixes https://gitlab.com/kicad/code/kicad/-/issues/10208
2022-01-02 16:10:26 -05:00
Jon Evans ea99c42df6 Move duplicate field handling into field parser
Fixes https://gitlab.com/kicad/code/kicad/-/issues/10130
2022-01-02 13:19:31 -05:00
Jon Evans 0065036899 Load local settings even when not setting project active
Fixes https://gitlab.com/kicad/code/kicad/-/issues/10179
2022-01-02 12:40:25 -05:00
Jon Evans bb388d47fc Fix undo/redo sample action plugin for latest API
Fixes https://gitlab.com/kicad/code/kicad/-/issues/10212
2022-01-02 12:26:27 -05:00
Jon Evans 134b09004b Fix highlighting color logic when net colors are active
Fixes https://gitlab.com/kicad/code/kicad/-/issues/10157
2022-01-02 12:11:24 -05:00
Jon Evans c52421869a Fix saving of existing appearance presets
Fixes https://gitlab.com/kicad/code/kicad/-/issues/10166
2022-01-02 11:59:19 -05:00
Seth Hillbrand addc5574b4 Ensure merged line gets selected if either parent is
We were only checking for the selection of a single line that gets
merged.  This prevents the merged line from being highlighted but not
selected after merging

Fixes https://gitlab.com/kicad/code/kicad/issues/10202
2022-01-01 16:53:31 -08:00
Seth Hillbrand bd75cffff3 Prevent ops on empty selection
Fixes https://gitlab.com/kicad/code/kicad/issues/10164
2022-01-01 15:28:47 -08:00
Marco Ciampa 3453bf3f88 Updated Italian translation 2022-01-01 22:06:16 +01:00
Marek Roszko f139cc2d9f Add kicad_3dsg copy for qa_pcbnew to run out of build dir
Mirror of the pcbnew step for the same reason


(cherry picked from commit b85fb9137f)
2022-01-01 19:54:30 +00:00
Marek Roszko 6fd93eaa1e Silence MSVC warnings about type mismatch and unused var
(cherry picked from commit 34e90e5045)
2022-01-01 19:50:11 +00:00
Roberto Fernandez Bautista cf8c614a02 Use virtual page number when real page numbers are blank
Fixes https://gitlab.com/kicad/code/kicad/-/issues/10158

(cherry picked from commit a0d708e04d)
2022-01-01 18:39:49 +00:00
Marco Ciampa 9fd1ad9b7b Updated Italian translation 2022-01-01 17:10:10 +01:00
jean-pierre charras d45472adcd French translation update 2021-12-31 13:23:17 +01:00
jean-pierre charras f67c0ea8c7 fix missing line breaks and non printable html char on Windows 2021-12-31 13:21:43 +01:00
jean-pierre charras 3c2bb97eae PANEL_PREVIEW_3D_MODEL: fix incorrect values of offset for unit inch and mil.
From master commit 49cb9586
2021-12-31 10:05:56 +01:00
Marek Roszko cbdfb5d396 Remove the unused updateui in the selection filter base
(cherry picked from commit e75d283007)
2021-12-30 17:18:38 +00:00
Roberto Fernandez Bautista e19acb4632 Correctly handle excluding an ERC marker in eeschema when right clicking
In addition, hide the option to exclude a marker if the selected marker
is already excluded.

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

(cherry picked from commit 701e256b3f)
2021-12-30 17:16:04 +00:00
Erwan Rouault 11c967b259 pcbnew: Add via height support in drc length
Fixes https://gitlab.com/kicad/code/kicad/-/issues/10135
2021-12-30 14:34:44 +00:00
Jon Evans 517e44e917 3D viewer: Disable copper thickness in OpenGL mode
Fixes https://gitlab.com/kicad/code/kicad/-/issues/10153
2021-12-30 09:20:09 -05:00
Jon Evans 0ec440805d Tune connectivity progress reporter
We don't need quite as many updates, this helps speed a little

See https://gitlab.com/kicad/code/kicad/-/issues/10154
2021-12-30 09:16:19 -05:00
Marek Roszko 67fe8904c0 Add win32 VERSION_INFO resource blocks for the DLLs
(cherry picked from commit 3f711b8958)
2021-12-29 04:56:26 +00:00
Marek Roszko da850036e3 Append product version to task manager titlebar (effectively)
(cherry picked from commit 426f6dd485)
2021-12-29 01:27:40 +00:00
Mike Williams b80595903c Eeschema: draw dangling end shadows
(cherry picked from commit bf2c4c1584)
2021-12-28 16:10:40 -08:00
Steven A. Falco c83880428c Add python 3.11 support
(Cherry-picked from commit 40589d2c33)
2021-12-28 14:53:31 +00:00
Jacob Mealey cc84344499 fix in pcbnew/python/swig/units.i ... added error handling
Added error handling in unit conversions for the pcbnew python bindings.

Fixes https://gitlab.com/kicad/code/kicad/-/issues/10081
2021-12-28 07:21:35 +00:00
Marek Roszko 32be48222a Fix parent of schematic setup parent nodes
(cherry picked from commit 705aa64c24)
2021-12-28 01:16:18 +00:00
Marek Roszko b7ec594c0a Use the correct parent for the root node placeholders of board setup
(cherry picked from commit 38842647b8)
2021-12-28 01:16:05 +00:00
Wayne Stambaugh 2481b21d80 Don't treat project Save As path as a path and file name.
The single string ctor of wxFileName treats the string as a path and file
name.  If there is a dot in the last path name, it assumes that the last
path is actually a file name and extension.

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

(cherry picked from commit fcc497509a)
2021-12-26 17:04:45 -05:00
Marek Roszko ceb4d08ce9 Fix race condition with ShowEventCounters on Windows
(cherry picked from commit 3dd8c57bdd)
2021-12-26 13:33:18 +00:00
Steven A. Falco 6edc605cab Several scripting options are no longer valid
Remove invalid scripting options from the yml file.
2021-12-25 11:14:26 -05:00
Mikolaj Wielgus d913e6a8f7 Restore Translators-Other section in credits 2021-12-24 20:36:10 +01:00
jean-pierre charras bde0c3e879 DIALOG_TEMPLATE_SELECTOR: Force display refresh after selecting a path
For some reason the panel showing the templates did not show the new selection
Fixes #10106
From Master branch
2021-12-24 11:51:26 +01:00
jean-pierre charras b95032901e pcbnew print: minor fix: option edge.cut on all layers not stored. Fixes #10046 https://gitlab.com/kicad/code/kicad/issues/10046 2021-12-23 18:36:42 +01:00
jean-pierre charras 753e08a944 Use ChangeValue() instead of SetValue() in some wxTextCtrl (It avoids generating unused events) 2021-12-23 18:36:42 +01:00
jean-pierre charras ee1b327162 3D viewer: fix a minor cosmetic issue. Fixes #10002 https://gitlab.com/kicad/code/kicad/issues/10002 2021-12-23 18:36:24 +01:00
jean-pierre charras da5f2366f9 PANEL_SETUP_BOARD_STACKUP: fix a typo that prevent displaying a color swatch. Fixes #10027 https://gitlab.com/kicad/code/kicad/issues/10027 2021-12-23 18:36:24 +01:00
Jeff Young e7cc177d94 Allow a 0 pin-symbol-size.
This is particularly important when reading legacy projects as 0 is
what signals the painter to use the old algorithm (1/2 pin name/number
size).

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

(cherry picked from commit f089cf44a7)
2021-12-23 17:01:48 +00:00
Jeff Young 93c48b9d46 Hot-update units in track editing dialogs.
Fixes https://gitlab.com/kicad/code/kicad/issues/10099

(cherry picked from commit 4e8a7fc911)
2021-12-23 17:01:44 +00:00
Jeff Young 1b033d56a7 Improve clean up tracks & vias algorithm for neck-downs.
Fixes https://gitlab.com/kicad/code/kicad/issues/10098

(cherry picked from commit d5a5928e5a)
2021-12-23 17:01:39 +00:00
Jeff Young ad583eab13 Add hot-updating of units in common wxGrids.
Fixes https://gitlab.com/kicad/code/kicad/issues/10020

(cherry picked from commit 6e2460ad37)
2021-12-23 17:01:34 +00:00
Jeff Young 0d3246e3ab Don't commit zone refill if there were no changes.
Fixes https://gitlab.com/kicad/code/kicad/issues/10085

(cherry picked from commit 77239591c0)
2021-12-23 17:01:31 +00:00
Jeff Young 76fd029cd6 Don't leave stranded symbols/footprints in editors when doc closes.
Fixes https://gitlab.com/kicad/code/kicad/issues/10026

(cherry picked from commit 9af33cdfe8)
2021-12-23 17:01:25 +00:00
Jeff Young 2efa878287 Use a bigger hammer to update adjacent segments.
Fixes https://gitlab.com/kicad/code/kicad/issues/9927

(cherry picked from commit ee5db73113)
2021-12-23 17:01:22 +00:00
Jeff Young 1dc78c4adc Tidy up pad & parent footprint selection corner cases.
Fixes https://gitlab.com/kicad/code/kicad/issues/9923

(cherry picked from commit d9dba2edb2)
2021-12-23 17:01:19 +00:00
Jeff Young 34d855cd53 Make sure undo/redo of pagesetup is done to correct sheet.
Fixes https://gitlab.com/kicad/code/kicad/issues/9999

(cherry picked from commit aa4dcb2bf1)
2021-12-23 17:01:15 +00:00
Jeff Young 9cb36e5bc5 Restore units to a bunch of wxGrids.
Fixes https://gitlab.com/kicad/code/kicad/issues/10063

(cherry picked from commit 8b52e969d6)
2021-12-23 17:01:10 +00:00
Jeff Young b6ff44cccf Fix failure to remove hover selection after rotate operation.
Fixes https://gitlab.com/kicad/code/kicad/issues/10058

(cherry picked from commit f696c4ddfc)
2021-12-23 17:01:06 +00:00
Jeff Young e9e742816d Scale markers somewhat proportionally to zoom.
Fixes https://gitlab.com/kicad/code/kicad/issues/10048

(cherry picked from commit a1c8e36c99)
2021-12-23 17:01:01 +00:00
Wayne Stambaugh b403930601 Begin version 6.0.1 development. 2021-12-22 08:44:30 -05:00
14032 changed files with 1832837 additions and 9161319 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"
+10 -15
View File
@@ -1,9 +1,8 @@
.downloads-by-cmake
.gdb_history
boost_root
/Build*
/build*
/cmake-build-*
Build*
build*
common/fp_lib_table_keywords.cpp
common/drc_rules_keywords.cpp
common/drc_rules_lexer.h
@@ -24,17 +23,19 @@ eeschema/dialogs/dialog_bom_cfg_lexer.h
common/template_fieldnames_keywords.cpp
common/template_fieldnames_lexer.h
eeschema/schematic_keywords.*
eeschema/sch_text_help_md.h
pcbnew/pcb_plot_params_keywords.cpp
pcbnew/pcb_plot_params_lexer.h
pcbnew/dialogs/panel_setup_rules_help_md.h
Makefile
CMakeUserPresets.json
CMakeCache.txt
.cache/
auto_renamed_to_cpp
Testing
version.h
config.h
install_manifest.txt
doxygen/out
Documentation/doxygen
Documentation/development/doxygen
*.bak
*.pyc
common/pcb_plot_params_keywords.cpp
@@ -52,7 +53,6 @@ bitmaps_png/tmp
common/pcb_keywords.cpp
include/pcb_lexer.h
fp-info-cache
qa/tests/output/**
# demo project auxiliary files
demos/**/*-bak
@@ -80,6 +80,7 @@ pcbnew/Info.plist
*.o.*
*.a
*.a.*
*.cmake
*.orig
*.rej
*.so
@@ -89,7 +90,7 @@ pcbnew/Info.plist
*.patch
# These CMake files are wanted
!cmake/**/*.cmake
!CMakeModules/*.cmake
# Eclipse IDE
.settings/
@@ -102,8 +103,6 @@ __pycache__
.vs/
.editorconfig
CMakeSettings.json
.vscode/
/vcpkg_installed
# Sublime Text
*.sublime-*
@@ -121,14 +120,10 @@ i18n_status.csv
*.kicad_prl
*-backups
# QA dataoutput
qa/data/**/*.csv
# Don't actually ignore any of these files, since we need them in the tree
!resources/linux/icons/hicolor/**/**/*
!resources/linux/icons-nightly/hicolor/**/**/*
!CMakeModules/**/*
!resources/bitmaps_png/png/**/*
!bitmaps_png/png/**/*
# Junk temp files generated by MSVC for resource files
/resources/msw/RC*
+29 -4
View File
@@ -5,16 +5,41 @@ stages:
default:
image:
name: registry.gitlab.com/kicad/kicad-ci/source_containers/master/fedora:36
name: registry.gitlab.com/kicad/kicad-ci/source_containers/master/fedora:34
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'
+18 -98
View File
@@ -1,12 +1,11 @@
##########################################################################
# Build KiCad on Fedora and save the results
##########################################################################
.fedora_build_linux_base:
fedora_build_linux:
stage: build
# 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
tags:
- kicad-fedora
image: registry.gitlab.com/kicad/kicad-ci/source_containers/master/fedora:34
extends: .only_code
interruptible: false
cache:
@@ -23,11 +22,11 @@
- cd build/linux
- cmake
-G Ninja
-DCMAKE_BUILD_TYPE=QABUILD
-DCMAKE_BUILD_TYPE=Debug
-DKICAD_STDLIB_LIGHT_DEBUG=ON
-DKICAD_USE_OCC=ON
-DKICAD_SPICE=ON
-DKICAD_BUILD_I18N=ON
-DKICAD_TEST_XML_OUTPUT=ON
-DKICAD_BUILD_PNS_DEBUG_TOOL=ON
../../
- ninja 2>&1 | tee compilation_log.txt
- cd ../../
@@ -39,40 +38,19 @@
when: always
paths:
- build/linux/3d-viewer/
- 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
- build/linux/qa/
- build/linux/compilation_log.txt
exclude:
- build/linux/**/*.o
- build/linux/**/*.a
# This split is to ensure we can always use our runner for our jobs
fedora_build_linux_kicad:
extends: .fedora_build_linux_base
tags:
- kicad-fedora
only:
variables:
- $CI_PROJECT_ROOT_NAMESPACE == "kicad"
fedora_build_linux_public:
extends: .fedora_build_linux_base
except:
variables:
- $CI_PROJECT_ROOT_NAMESPACE == "kicad"
# Upload the compilation log in an easily downloadable form
.fedora_report_build_warn:
fedora_report_build_warn:
stage: report
extends: .only_code
when: always
needs:
- job: fedora_build_linux
artifacts: true
script:
- echo "Uploading compilation log"
- cp build/linux/compilation_log.txt compilation_log.txt
@@ -83,32 +61,14 @@ fedora_build_linux_public:
paths:
- compilation_log.txt
fedora_report_build_warn_kicad:
extends: .fedora_report_build_warn
tags:
- kicad-fedora
needs:
- job: fedora_build_linux_kicad
artifacts: true
only:
variables:
- $CI_PROJECT_ROOT_NAMESPACE == "kicad"
fedora_report_build_warn_public:
extends: .fedora_report_build_warn
needs:
- job: fedora_build_linux_public
artifacts: true
except:
variables:
- $CI_PROJECT_ROOT_NAMESPACE == "kicad"
# Report on the metrics of the code
.fedora_report_metrics:
fedora_report_metrics:
stage: report
extends: .only_code
when: always
needs:
- job: fedora_build_linux
artifacts: true
script:
- cat build/linux/compilation_log.txt | { grep "warning:" || test $? = 1; } | awk 'END{print "number_of_fedora_warnings "NR}' > metrics.txt
- cat metrics.txt
@@ -116,58 +76,18 @@ fedora_report_build_warn_public:
reports:
metrics: metrics.txt
fedora_report_metrics_kicad:
extends: .fedora_report_metrics
tags:
- kicad-fedora
needs:
- job: fedora_build_linux_kicad
artifacts: true
only:
variables:
- $CI_PROJECT_ROOT_NAMESPACE == "kicad"
fedora_report_metrics_public:
extends: .fedora_report_metrics
needs:
- job: fedora_build_linux_public
artifacts: true
except:
variables:
- $CI_PROJECT_ROOT_NAMESPACE == "kicad"
##########################################################################
# Run the code unit tests.
##########################################################################
.fedora_qa:
image: registry.gitlab.com/kicad/kicad-ci/source_containers/master/fedora:38
fedora_qa:
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]
fedora_qa_kicad:
extends: .fedora_qa
tags:
- kicad-fedora
- TEST: [python, common, gerbview, pcbnew, eeschema, kimath, sexpr, kicad2step]
needs:
- job: fedora_build_linux_kicad
- job: fedora_build_linux
artifacts: true
only:
variables:
- $CI_PROJECT_ROOT_NAMESPACE == "kicad"
fedora_qa_public:
extends: .fedora_qa
needs:
- job: fedora_build_linux_public
artifacts: true
except:
variables:
- $CI_PROJECT_ROOT_NAMESPACE == "kicad"
+3 -6
View File
@@ -28,10 +28,11 @@
-G Ninja
-DCMAKE_C_COMPILER_LAUNCHER=ccache
-DCMAKE_CXX_COMPILER_LAUNCHER=ccache
-DCMAKE_BUILD_TYPE=Release
-DCMAKE_BUILD_TYPE=Debug
-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
../../
@@ -46,13 +47,9 @@
paths:
- build/linux/3d-viewer/
- build/linux/pcbnew/pcbnew.py
- build/linux/pcbnew/_pcbnew.kiface
- build/linux/pcbnew/_pcbnew.so
- build/linux/qa/
- build/linux/compilation_log.txt
exclude:
- build/linux/**/*.o
- build/linux/**/*.a
# Upload the compilation log in an easily downloadable form
.ubuntu20.04_report_build_warn:
@@ -115,4 +112,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]
+7 -21
View File
@@ -5,37 +5,23 @@ 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"
image: registry.gitlab.com/kicad/kicad-ci/source_containers/win64:msvc1809
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
- nuget.exe sources add -Name kicad -Source "https://nuget.kicad.org:443/v3/index.json"
- nuget.exe setapikey $env:KICAD_NUGET_KEY -Source "https://nuget.kicad.org:443/v3/index.json"
- mkdir -p build/windows -Force
- cd build/windows
- cmake `
-G "Ninja" `
-DCMAKE_TOOLCHAIN_FILE=C:\builder\vcpkg\scripts\buildsystems\vcpkg.cmake `
-DCMAKE_TOOLCHAIN_FILE=C:\build\vcpkg\scripts\buildsystems\vcpkg.cmake `
-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 `
../../
- cmake --build . 2>&1 | tee compilation_log.txt
- cd ../../
+15 -18
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 \
curl -v 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,13 @@ 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"
# Use Fedora 33 because Coverity needs GCC 10 still (as of 06/16/2021)
image: registry.gitlab.com/kicad/kicad-ci/source_containers/master/fedora:33
only:
refs:
- schedules
variables:
- $SCHEDULED_JOB_NAME == "coverity"
cache:
key: coverity
paths:
@@ -53,23 +54,19 @@ 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_USE_OCC=ON
-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
-15
View File
@@ -1,15 +0,0 @@
build_doxygen_docker:
image: docker:stable
services:
- docker:dind
stage: build
rules:
- if: $CI_PIPELINE_SOURCE == "schedule" && $SCHEDULED_JOB_NAME == "doxygen"
tags:
- docker
before_script:
- docker info
- docker login -u gitlab-ci-token -p "$CI_JOB_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"
-20
View File
@@ -1,20 +0,0 @@
<!-- --------Before Creating a New Issue-----------
* Limit report to a single issue.
* Search the issue tracker to verify the issue has not already been reported.
* Complete all instructions between `template comment markers <>.
* Keep report contents limited to the necessary information required to fix the issue.
* When creating an issue against the stable version of KiCad, make sure the latest available stable version is installed as issues may have already been resolved in later stable versions. -->
# Description
<!-- What is the current behavior and what is the expected behavior? -->
<!-- If the issue is visual/graphical, please attach screenshots of the problem. -->
<!-- Add the issue details below this line and before the "Steps to reproduce" heading. -->
# Steps to reproduce
<!-- If there are multiple steps to reproduce it or it is a visual issue, then providing a screen recording as an attachment to this report is recommended. -->
<!-- If this issue is specific to a project, please attach the necessary files to this issue. -->
<!-- Add the steps to reproduce using the numbers below -->
<!-- Add new step numbers before the "KiCad Version" heading. -->
1.
# KiCad Version
+16 -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:34
# 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,8 @@ validate_linux_metadata:
-DCMAKE_BUILD_TYPE=Debug
-DKICAD_STDLIB_LIGHT_DEBUG=ON
-DKICAD_SCRIPTING_WXPYTHON=ON
-DKICAD_USE_OCC=ON
-DKICAD_SPICE=ON
-DKICAD_BUILD_I18N=ON
../../
- make metadata
-47
View File
@@ -1,47 +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_BUILD_TYPE=RelWithDebInfo
-DDEFAULT_INSTALL_PATH=/Library/Application\ Support /kicad
-DOCC_INCLUDE_DIR=/opt/homebrew/Cellar/opencascade/7.7.2_2/include/opencascade
-DOCC_LIBRARY_DIR=/opt/homebrew/Cellar/opencascade/7.7.2_2/Lib
-DCMAKE_INSTALL_PREFIX=/Users/ci/kicad-mac-builder/build/kicad-dest
-DCMAKE_C_COMPILER=/usr/bin/clang
-DCMAKE_CXX_COMPILER=/usr/bin/clang++
-DwxWidgets_CONFIG_EXECUTABLE=/Users/ci/kicad-mac-builder/build/wxwidgets-dest/bin/wx-config
-DKICAD_BUILD_I18N=ON
-DKICAD_SCRIPTING_WXPYTHON=ON
-DKICAD_BUILD_PNS_DEBUG_TOOL=ON
-DPYTHON_EXECUTABLE=/Users/ci/kicad-mac-builder/build/python-dest/Library/Frameworks/Python.framework/Versions/Current/bin/python3
-DPYTHON_INCLUDE_DIR=/Users/ci/kicad-mac-builder/build/python-dest/Library/Frameworks/Python.framework/Versions/Current/include/python3.9/
-DPYTHON_LIBRARY=/Users/ci/kicad-mac-builder/build/python-dest/Library/Frameworks/Python.framework/Versions/Current/lib/libpython3.9.dylib
-DPYTHON_SITE_PACKAGE_PATH=/Users/ci/kicad-mac-builder/build/python-dest/Library/Frameworks/Python.framework/Versions/Current/lib/python3.9/site-packages
-DPYTHON_FRAMEWORK=/Users/ci/kicad-mac-builder/build/python-dest/Library/Frameworks/Python.framework
-DNGSPICE_INCLUDE_DIR=/Users/ci/kicad-mac-builder/build/ngspice-dest/include
-DNGSPICE_LIBRARY=/Users/ci/kicad-mac-builder/build/ngspice-dest/lib/libngspice.dylib
-DKICAD_USE_3DCONNEXION=ON
../../
- 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}
+11 -11
View File
@@ -11,27 +11,27 @@
- schedules
##########################################################################
# Define a template for all the unit tests, since each one is run in a separate
# Define a template for all the unit tests, since each one is run in a separate
# job to make the display nicer.
##########################################################################
.unit_test:
stage: test
when: on_success
variables:
BOOST_TEST_LOGGER: 'JUNIT,warning,test_results.${TEST}.xml:HRF,warning'
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 -14
View File
@@ -2,8 +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) 2018-2022 KiCad Developers, see AUTHORS.txt for contributors.
* Copyright (C) 2022 CERN
* Copyright (C) 2018-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,6 +29,7 @@
#include <wx/datetime.h>
#include <wx/dir.h>
#include <wx/filename.h>
#include <wx/log.h>
#include <wx/stdpaths.h>
@@ -55,12 +55,12 @@
#include <project.h>
#include <settings/common_settings.h>
#include <settings/settings_manager.h>
#include <wx_filename.h>
#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
@@ -194,20 +194,29 @@ S3D_CACHE::S3D_CACHE()
S3D_CACHE::~S3D_CACHE()
{
COMMON_SETTINGS* commonSettings = Pgm().GetCommonSettings();
FlushCache();
// We'll delete ".3dc" cache files older than this many days
int clearCacheInterval = commonSettings->m_System.clear_3d_cache_interval;
// An interval of zero means the user doesn't want to ever clear the cache
if( clearCacheInterval > 0 )
CleanCacheDir( clearCacheInterval );
delete m_FNResolver;
delete m_Plugins;
}
SCENEGRAPH* S3D_CACHE::load( const wxString& aModelFile, const wxString& aBasePath,
S3D_CACHE_ENTRY** aCachePtr )
SCENEGRAPH* S3D_CACHE::load( const wxString& aModelFile, S3D_CACHE_ENTRY** aCachePtr )
{
if( aCachePtr )
*aCachePtr = nullptr;
wxString full3Dpath = m_FNResolver->ResolvePath( aModelFile, aBasePath );
wxString full3Dpath = m_FNResolver->ResolvePath( aModelFile );
if( full3Dpath.empty() )
{
@@ -272,9 +281,9 @@ SCENEGRAPH* S3D_CACHE::load( const wxString& aModelFile, const wxString& aBasePa
}
SCENEGRAPH* S3D_CACHE::Load( const wxString& aModelFile, const wxString& aBasePath )
SCENEGRAPH* S3D_CACHE::Load( const wxString& aModelFile )
{
return load( aModelFile, aBasePath );
return load( aModelFile );
}
@@ -295,7 +304,8 @@ SCENEGRAPH* S3D_CACHE::checkCache( const wxString& aFileName, S3D_CACHE_ENTRY**
// or we do not have a configured cache file directory, we create an
// entry to prevent further attempts at loading the file
if( m_CacheMap.emplace( aFileName, ep ).second == false )
if( m_CacheMap.insert( std::pair< wxString, S3D_CACHE_ENTRY* >
( aFileName, ep ) ).second == false )
{
wxLogTrace( MASK_3D_CACHE,
wxT( "%s:%s:%d\n * [BUG] duplicate entry in map file; key = '%s'" ),
@@ -313,7 +323,8 @@ SCENEGRAPH* S3D_CACHE::checkCache( const wxString& aFileName, S3D_CACHE_ENTRY**
return nullptr;
}
if( m_CacheMap.emplace( aFileName, ep ).second == false )
if( m_CacheMap.insert( std::pair< wxString, S3D_CACHE_ENTRY* >
( aFileName, ep ) ).second == false )
{
wxLogTrace( MASK_3D_CACHE,
wxT( "%s:%s:%d\n * [BUG] duplicate entry in map file; key = '%s'" ),
@@ -502,7 +513,7 @@ bool S3D_CACHE::Set3DConfigDir( const wxString& aConfigDir )
wxFileName cfgdir( ExpandEnvVarSubstitutions( aConfigDir, m_project ), wxEmptyString );
cfgdir.Normalize( FN_NORMALIZE_FLAGS );
cfgdir.Normalize();
if( !cfgdir.DirExists() )
{
@@ -631,10 +642,10 @@ void S3D_CACHE::ClosePlugins()
}
S3DMODEL* S3D_CACHE::GetModel( const wxString& aModelFileName, const wxString& aBasePath )
S3DMODEL* S3D_CACHE::GetModel( const wxString& aModelFileName )
{
S3D_CACHE_ENTRY* cp = nullptr;
SCENEGRAPH* sp = load( aModelFileName, aBasePath,&cp );
SCENEGRAPH* sp = load( aModelFileName, &cp );
if( !sp )
return nullptr;
@@ -696,4 +707,40 @@ void S3D_CACHE::CleanCacheDir( int aNumDaysOld )
}
}
}
}
}
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();
}
+3 -4
View File
@@ -92,10 +92,9 @@ public:
*
* @param aModelFile is the partial or full path to the model to be loaded.
* @param aBasePath is the path to search for any relative files
* @return true if the model was successfully loaded, otherwise false.
*/
SCENEGRAPH* Load( const wxString& aModelFile, const wxString& aBasePath );
SCENEGRAPH* Load( const wxString& aModelFile );
FILENAME_RESOLVER* GetResolver() noexcept;
@@ -125,7 +124,7 @@ public:
* @param aModelFileName is the full path to the model to be loaded.
* @return is a pointer to the render data or NULL if not available.
*/
S3DMODEL* GetModel( const wxString& aModelFileName, const wxString& aBasePath );
S3DMODEL* GetModel( const wxString& aModelFileName );
/**
* Delete up old cache files in cache directory.
@@ -165,7 +164,7 @@ private:
bool saveCacheData( S3D_CACHE_ENTRY* aCacheItem );
// the real load function (can supply a cache entry pointer to member functions)
SCENEGRAPH* load( const wxString& aModelFile, const wxString& aBasePath, S3D_CACHE_ENTRY** aCachePtr = nullptr );
SCENEGRAPH* load( const wxString& aModelFile, S3D_CACHE_ENTRY** aCachePtr = nullptr );
/// cache entries
std::list< S3D_CACHE_ENTRY* > m_CacheList;
+51 -46
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 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,13 +29,13 @@
#include <wx/dir.h>
#include <wx/dynlib.h>
#include <wx/filename.h>
#include <wx/log.h>
#include <wx/stdpaths.h>
#include <wx/string.h>
#include <common.h>
#include <paths.h>
#include <wx_filename.h>
#include "3d_plugin_manager.h"
#include "plugins/3d/3d_plugin.h"
#include "3d_cache/sg/scenegraph.h"
@@ -55,7 +55,7 @@
S3D_PLUGIN_MANAGER::S3D_PLUGIN_MANAGER()
{
// create the initial file filter list entry
m_FileFilters.emplace_back( _( "All Files" ) + wxT( " (*.*)|*.*" ) );
m_FileFilters.push_back( _( "All Files" ) + wxT( " (*.*)|*.*" ) );
// discover and load plugins
loadPlugins();
@@ -120,48 +120,57 @@ S3D_PLUGIN_MANAGER::~S3D_PLUGIN_MANAGER()
void S3D_PLUGIN_MANAGER::loadPlugins( void )
{
std::list<wxString> searchpaths;
std::list<wxString> pluginlist;
wxFileName fn;
std::list< wxString > searchpaths;
std::list< wxString > pluginlist;
wxFileName fn;
#ifndef __WXMAC__
if( wxGetEnv( wxT( "KICAD_RUN_FROM_BUILD_DIR" ), nullptr ) )
#ifdef DEBUG
// set up to work from the build directory
fn.Assign( wxStandardPaths::Get().GetExecutablePath() );
fn.AppendDir( wxT( ".." ) );
fn.AppendDir( wxT( "plugins" ) );
fn.AppendDir( wxT( "3d" ) );
std::string testpath = std::string( fn.GetPathWithSep().ToUTF8() );
checkPluginPath( testpath, searchpaths );
// add subdirectories too
wxDir debugPluginDir;
wxString subdir;
debugPluginDir.Open( testpath );
if( debugPluginDir.IsOpened() && debugPluginDir.GetFirst( &subdir, wxEmptyString, wxDIR_DIRS ) )
{
// set up to work from the build directory
fn.Assign( wxStandardPaths::Get().GetExecutablePath() );
fn.AppendDir( wxT( ".." ) );
fn.AppendDir( wxT( "plugins" ) );
fn.AppendDir( wxT( "3d" ) );
checkPluginPath( testpath + subdir, searchpaths );
std::string testpath = std::string( fn.GetPathWithSep().ToUTF8() );
checkPluginPath( testpath, searchpaths );
// add subdirectories too
wxDir debugPluginDir;
wxString subdir;
debugPluginDir.Open( testpath );
if( debugPluginDir.IsOpened()
&& debugPluginDir.GetFirst( &subdir, wxEmptyString, wxDIR_DIRS ) )
{
while( debugPluginDir.GetNext( &subdir ) )
checkPluginPath( testpath + subdir, searchpaths );
while( debugPluginDir.GetNext( &subdir ) )
checkPluginPath( testpath + subdir, searchpaths );
}
}
#endif
fn.AssignDir( PATHS::GetStockPlugins3DPath() );
checkPluginPath( std::string( fn.GetPathWithSep().ToUTF8() ), searchpaths );
// check for per-user third party plugins
// note: GetUserDataDir() gives '.pcbnew' rather than '.kicad' since it uses the exe name;
fn.AssignDir( PATHS::GetUserPlugins3DPath() );
checkPluginPath( fn.GetPathWithSep(), searchpaths );
#else
// Search path on OS X is
// (1) Machine /Library/Application Support/kicad/PlugIns/3d
// (1) User ~/Library/Application Support/kicad/PlugIns/3d
checkPluginPath( PATHS::GetOSXKicadUserDataDir() + wxT( "/PlugIns/3d" ), searchpaths );
// (2) Machine /Library/Application Support/kicad/PlugIns/3d
checkPluginPath( PATHS::GetOSXKicadMachineDataDir() + wxT( "/PlugIns/3d" ), searchpaths );
// (2) Bundle kicad.app/Contents/PlugIns/3d
// (3) Bundle kicad.app/Contents/PlugIns/3d
fn.AssignDir( PATHS::GetStockPlugins3DPath() );
checkPluginPath( fn.GetPathWithSep(), searchpaths );
#endif
std::list< wxString >::iterator sPL = searchpaths.begin();
@@ -248,7 +257,7 @@ void S3D_PLUGIN_MANAGER::listPlugins( const wxString& aPath, std::list< wxString
// Per definition a loadable "xxx.bundle" is similar to an "xxx.app" app
// bundle being a folder with some special content in it. We obviously don't
// want to have that here for our loadable module, so just use ".so".
nameFilter.Append( wxS( ".so" ) );
nameFilter.Append( ".so" );
#endif
wxString lp = wd.GetNameWithSep();
@@ -279,7 +288,7 @@ void S3D_PLUGIN_MANAGER::checkPluginName( const wxString& aPath,
wxFileName path( ExpandEnvVarSubstitutions( aPath, nullptr ) );
path.Normalize( FN_NORMALIZE_FLAGS );
path.Normalize();
// determine if the path is already in the list
wxString wxpath = path.GetFullPath();
@@ -294,16 +303,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() );
@@ -313,15 +312,21 @@ void S3D_PLUGIN_MANAGER::checkPluginName( const wxString& aPath,
void S3D_PLUGIN_MANAGER::checkPluginPath( const wxString& aPath,
std::list< wxString >& aSearchList )
{
// check the existence of a path and add it to the path search list
if( aPath.empty() )
return;
wxLogTrace( MASK_3D_PLUGINMGR, wxT( " * [INFO] checking if valid plugin directory '%s'\n" ),
wxLogTrace( MASK_3D_PLUGINMGR, wxT( " * [INFO] checking for 3D plugins in '%s'\n" ),
aPath.GetData() );
wxFileName path;
path.AssignDir( aPath );
path.Normalize( FN_NORMALIZE_FLAGS );
if( aPath.StartsWith( wxT( "${" ) ) || aPath.StartsWith( wxT( "$(" ) ) )
path.Assign( ExpandEnvVarSubstitutions( aPath, nullptr ), wxEmptyString );
else
path.Assign( aPath, wxEmptyString );
path.Normalize();
if( !wxFileName::DirExists( path.GetFullPath() ) )
return;
@@ -386,7 +391,7 @@ void S3D_PLUGIN_MANAGER::addExtensionMap( KICAD_PLUGIN_LDR_3D* aPlugin )
if( !ws.empty() )
{
m_ExtMap.emplace( ws, aPlugin );
m_ExtMap.insert( std::pair< const wxString, KICAD_PLUGIN_LDR_3D* >( ws, aPlugin ) );
}
}
+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
@@ -359,7 +359,7 @@ S3DMODEL* S3D::GetModel( SCENEGRAPH* aNode )
app.transparency = 0.0f;
materials.matorder.push_back( &app );
materials.matmap.emplace( &app, 0 );
materials.matmap.insert( std::pair< SGAPPEARANCE const*, int >( &app, 0 ) );
if( aNode->Prepare( nullptr, materials, meshes ) )
{
+6 -3
View File
@@ -420,7 +420,8 @@ bool S3D::CalcTriangleNormals( std::vector< SGPOINT > coords, std::vector< int >
}
else
{
vmap.emplace( p1, std::list < glm::dvec3 >( 1, tri ) );
vmap.insert( std::pair < int, std::list < glm::dvec3 > >
( p1, std::list < glm::dvec3 >( 1, tri ) ) );
}
ip = vmap.find( p2 );
@@ -431,7 +432,8 @@ bool S3D::CalcTriangleNormals( std::vector< SGPOINT > coords, std::vector< int >
}
else
{
vmap.emplace( p2, std::list < glm::dvec3 >( 1, tri ) );
vmap.insert( std::pair < int, std::list < glm::dvec3 > >
( p2, std::list < glm::dvec3 >( 1, tri ) ) );
}
ip = vmap.find( p3 );
@@ -442,7 +444,8 @@ bool S3D::CalcTriangleNormals( std::vector< SGPOINT > coords, std::vector< int >
}
else
{
vmap.emplace( p3, std::list < glm::dvec3 >( 1, tri ) );
vmap.insert( std::pair < int, std::list < glm::dvec3 > >
( p3, std::list < glm::dvec3 >( 1, tri ) ) );
}
}
+1 -1
View File
@@ -260,7 +260,7 @@ bool S3D::GetMatIndex( MATLIST& aList, SGNODE* aNode, int& aIndex )
int idx = (int)aList.matorder.size();
aList.matorder.push_back( node );
aList.matmap.emplace( node, idx );
aList.matmap.insert( std::pair< SGAPPEARANCE const*, int >( node, idx ) );
aIndex = idx;
return true;
+1 -1
View File
@@ -699,7 +699,7 @@ bool SGSHAPE::Prepare( const glm::dmat4* aTransform, S3D::MATLIST& materials,
if( mit == indexmap.end() )
{
indexmap.emplace( lv[i], vertices.size() );
indexmap.insert( std::pair< int, unsigned int >( lv[i], vertices.size() ) );
vertices.push_back( lv[i] );
}
}
+262 -459
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-2016 Mario Luzeiro <mrluzeiro@ua.pt>
* 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
@@ -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>
@@ -34,23 +33,13 @@
#include <3d_math.h>
#include "3d_fastmath.h"
#include <geometry/geometry_utils.h>
#include <convert_to_biu.h>
#include <pgm_base.h>
#include <settings/settings_manager.h>
#include <wx/log.h>
#include <pcbnew_settings.h>
#include <advanced_config.h>
#define DEFAULT_BOARD_THICKNESS pcbIUScale.mmToIU( 1.6 )
#define DEFAULT_COPPER_THICKNESS pcbIUScale.mmToIU( 0.035 ) // for 35 um
// The solder mask layer (and silkscreen) thickness
#define DEFAULT_TECH_LAYER_THICKNESS pcbIUScale.mmToIU( 0.025 )
// The solder paste thickness is chosen bigger than the solder mask layer
// to be sure is covers the mask when overlapping.
#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,11 +52,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;
static bool g_ColorsLoaded = false;
@@ -83,10 +67,6 @@ const wxChar *BOARD_ADAPTER::m_logTrace = wxT( "KI_TRACE_EDA_CINFO3D_VISU" );
BOARD_ADAPTER::BOARD_ADAPTER() :
m_Cfg( nullptr ),
m_IsBoardView( true ),
m_MousewheelPanning( true ),
m_IsPreviewer( false ),
m_board( nullptr ),
m_3dModelManager( nullptr ),
m_colors( nullptr ),
@@ -95,26 +75,32 @@ BOARD_ADAPTER::BOARD_ADAPTER() :
{
wxLogTrace( m_logTrace, wxT( "BOARD_ADAPTER::BOARD_ADAPTER" ) );
ReloadColorSettings();
m_gridType = GRID3D_TYPE::NONE;
m_antiAliasingMode = ANTIALIASING_MODE::AA_8X;
m_drawFlags.resize( FL_LAST, false );
m_boardPos = VECTOR2I();
m_boardSize = VECTOR2I();
if( PgmOrNull() )
m_colors = Pgm().GetSettingsManager().GetColorSettings();
m_renderEngine = RENDER_ENGINE::OPENGL;
m_materialMode = MATERIAL_MODE::NORMAL;
m_boardPos = wxPoint();
m_boardSize = wxSize();
m_boardCenter = SFVEC3F( 0.0f );
m_boardBoundingBox.Reset();
m_TH_IDs.Clear();
m_TH_ODs.Clear();
m_viaAnnuli.Clear();
m_copperLayersCount = 2;
m_throughHoleIds.Clear();
m_throughHoleOds.Clear();
m_throughHoleAnnularRings.Clear();
m_copperLayersCount = -1;
m_epoxyThickness3DU = 0.0f;
m_copperThickness3DU = 0.0f;
m_nonCopperLayerThickness3DU = 0.0f;
m_solderPasteLayerThickness3DU = 0.0f;
m_biuTo3Dunits = 1.0;
m_boardBodyThickness3DU = DEFAULT_BOARD_THICKNESS * m_biuTo3Dunits;
m_frontCopperThickness3DU = DEFAULT_COPPER_THICKNESS * m_biuTo3Dunits;
m_backCopperThickness3DU = DEFAULT_COPPER_THICKNESS * m_biuTo3Dunits;
m_nonCopperLayerThickness3DU = DEFAULT_TECH_LAYER_THICKNESS * m_biuTo3Dunits;
m_solderPasteLayerThickness3DU = SOLDERPASTE_LAYER_THICKNESS * m_biuTo3Dunits;
m_trackCount = 0;
m_viaCount = 0;
@@ -123,6 +109,27 @@ BOARD_ADAPTER::BOARD_ADAPTER() :
m_averageHoleDiameter = 0.0f;
m_averageTrackWidth = 0.0f;
SetFlag( FL_USE_REALISTIC_MODE, true );
SetFlag( FL_FP_ATTRIBUTES_NORMAL, true );
SetFlag( FL_SHOW_BOARD_BODY, true );
SetFlag( FL_CLIP_SILK_ON_VIA_ANNULUS, false );
SetFlag( FL_FP_ATTRIBUTES_NORMAL, true );
SetFlag( FL_FP_ATTRIBUTES_NORMAL_INSERT, true );
SetFlag( FL_FP_ATTRIBUTES_VIRTUAL, true );
SetFlag( FL_ZONE, true );
SetFlag( FL_SILKSCREEN, true );
SetFlag( FL_SOLDERMASK, true );
SetFlag( FL_SUBTRACT_MASK_FROM_SILK, false );
SetFlag( FL_RENDER_OPENGL_COPPER_THICKNESS, true );
SetFlag( FL_RENDER_OPENGL_AA_DISABLE_ON_MOVE, false );
SetFlag( FL_RENDER_OPENGL_THICKNESS_DISABLE_ON_MOVE, false );
SetFlag( FL_RENDER_OPENGL_VIAS_DISABLE_ON_MOVE, false );
SetFlag( FL_RENDER_OPENGL_HOLES_DISABLE_ON_MOVE, false );
SetFlag( FL_USE_SELECTION, true );
SetFlag( FL_HIGHLIGHT_ROLLOVER_ITEM, true );
m_BgColorBot = SFVEC4F( 0.4, 0.4, 0.5, 1.0 );
m_BgColorTop = SFVEC4F( 0.8, 0.8, 0.9, 1.0 );
m_BoardBodyColor = SFVEC4F( 0.4, 0.4, 0.5, 0.9 );
@@ -132,34 +139,38 @@ 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;
// Avoid raytracing options not initialized:
m_RtShadowSampleCount = 0;
m_RtReflectionSampleCount = 0;
m_RtRefractionSampleCount = 0;
m_RtSpreadShadows = 0.0;
m_RtSpreadReflections = 0.0;
m_RtSpreadRefractions = 0.0;
m_RtRecursiveReflectionCount = 0;
m_RtRecursiveRefractionCount = 0;
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 )
list.push_back( CUSTOM_COLOR_ITEM( 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 +217,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,88 +229,110 @@ 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 GetFlag( FL_ADHESIVE );
case B_Paste:
case F_Paste:
return GetFlag( FL_SOLDERPASTE );
case B_SilkS:
case F_SilkS:
return GetFlag( FL_SILKSCREEN );
case B_Mask:
case F_Mask:
return GetFlag( FL_SOLDERMASK );
case Dwgs_User:
case Cmts_User:
if( GetFlag( FL_USE_REALISTIC_MODE ) )
return false;
return GetFlag( FL_COMMENTS );
case Eco1_User:
case Eco2_User:
if( GetFlag( FL_USE_REALISTIC_MODE ) )
return false;
return GetFlag( FL_ECO );
case Edge_Cuts:
if( GetFlag( FL_SHOW_BOARD_BODY ) || GetFlag( FL_USE_REALISTIC_MODE ) )
return false;
return true;
case Margin:
if( GetFlag( FL_USE_REALISTIC_MODE ) )
return false;
return true;
case B_Cu:
case F_Cu:
return m_board ? m_board->IsLayerVisible( aLayer ) || GetFlag( FL_USE_REALISTIC_MODE )
: true;
default:
// the layer is an internal copper layer, used the visibility
return m_board && m_board->IsLayerVisible( aLayer );
}
}
bool BOARD_ADAPTER::GetFlag( DISPLAY3D_FLG aFlag ) const
{
wxASSERT( aFlag < FL_LAST );
return m_drawFlags[aFlag];
}
void BOARD_ADAPTER::SetFlag( DISPLAY3D_FLG aFlag, bool aState )
{
wxASSERT( aFlag < FL_LAST );
m_drawFlags[aFlag] = aState;
}
bool BOARD_ADAPTER::IsFootprintShown( FOOTPRINT_ATTR_T aFPAttributes ) const
{
if( m_IsPreviewer ) // In panel Preview, footprints are always shown, of course
return true;
if( aFPAttributes & FP_EXCLUDE_FROM_POS_FILES )
{
if( !m_Cfg->m_Render.show_footprints_not_in_posfile )
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;
if( aFPAttributes & FP_THROUGH_HOLE )
return m_Cfg->m_Render.show_footprints_normal;
return m_Cfg->m_Render.show_footprints_virtual;
return GetFlag( FL_FP_ATTRIBUTES_NORMAL_INSERT );
else if( aFPAttributes & FP_THROUGH_HOLE )
return GetFlag( FL_FP_ATTRIBUTES_NORMAL );
else
return GetFlag( FL_FP_ATTRIBUTES_VIRTUAL );
}
// !TODO: define the actual copper thickness by user from board stackup
#define COPPER_THICKNESS Millimeter2iu( 0.035 ) // for 35 um
// The solder mask layer (and silkscreen) thickness
#define TECH_LAYER_THICKNESS Millimeter2iu( 0.025 )
// The solder paste thickness is chosen bigger than the solder mask layer
// to be sure is covers the mask when overlapping.
#define SOLDERPASTE_LAYER_THICKNESS Millimeter2iu( 0.04 )
int BOARD_ADAPTER::GetHolePlatingThickness() const noexcept
{
return m_board ? m_board->GetDesignSettings().GetHolePlatingThickness()
: DEFAULT_COPPER_THICKNESS;
: 0.035 * PCB_IU_PER_MM;
}
@@ -318,7 +348,7 @@ unsigned int BOARD_ADAPTER::GetCircleSegmentCount( int aDiameterBIU ) const
{
wxASSERT( aDiameterBIU > 0 );
return GetArcToSegmentCount( aDiameterBIU / 2, ARC_HIGH_DEF, FULL_CIRCLE );
return GetArcToSegmentCount( aDiameterBIU / 2, ARC_HIGH_DEF, 360.0 );
}
@@ -331,24 +361,34 @@ void BOARD_ADAPTER::InitSettings( REPORTER* aStatusReporter, REPORTER* aWarningR
wxString msg;
const bool haveOutline = createBoardPolygon( &msg );
const bool succeedToGetBoardPolygon = createBoardPolygon( &msg );
if( aWarningReporter )
{
if( !haveOutline )
if( !succeedToGetBoardPolygon )
aWarningReporter->Report( msg, RPT_SEVERITY_WARNING );
else
aWarningReporter->Report( wxEmptyString );
}
BOX2I bbbox;
// Calculates the board bounding box (board outlines + items)
// to ensure any item, even outside the board outlines can be seen
bool boardEdgesOnly = true;
if( ( m_board && m_board->IsFootprintHolder() ) || !GetFlag( FL_USE_REALISTIC_MODE )
|| !succeedToGetBoardPolygon )
{
boardEdgesOnly = false;
}
EDA_RECT bbbox;
if( m_board )
bbbox = m_board->ComputeBoundingBox( !m_board->IsFootprintHolder() && haveOutline );
bbbox = m_board->ComputeBoundingBox( boardEdgesOnly );
// Gives a non null size to avoid issues in zoom / scale calculations
if( ( bbbox.GetWidth() == 0 ) && ( bbbox.GetHeight() == 0 ) )
bbbox.Inflate( pcbIUScale.mmToIU( 10 ) );
bbbox.Inflate( Millimeter2iu( 10 ) );
m_boardSize = bbbox.GetSize();
m_boardPos = bbbox.Centre();
@@ -367,63 +407,20 @@ 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_epoxyThickness3DU = m_board
? m_board->GetDesignSettings().GetBoardThickness() * m_biuTo3Dunits
: 1.6 * PCB_IU_PER_MM * m_biuTo3Dunits;
m_boardBodyThickness3DU = DEFAULT_BOARD_THICKNESS * m_biuTo3Dunits;
m_frontCopperThickness3DU = DEFAULT_COPPER_THICKNESS * m_biuTo3Dunits;
m_backCopperThickness3DU = DEFAULT_COPPER_THICKNESS * m_biuTo3Dunits;
m_nonCopperLayerThickness3DU = DEFAULT_TECH_LAYER_THICKNESS * m_biuTo3Dunits;
m_solderPasteLayerThickness3DU = SOLDERPASTE_LAYER_THICKNESS * m_biuTo3Dunits;
g_BevelThickness3DU = pcbIUScale.mmToIU( ADVANCED_CFG::GetCfg().m_3DRT_BevelHeight_um / 1000.0 ) * m_biuTo3Dunits;
if( m_board )
{
const BOARD_DESIGN_SETTINGS& bds = m_board->GetDesignSettings();
if( bds.GetStackupDescriptor().GetCount() )
{
int thickness = 0;
for( BOARD_STACKUP_ITEM* item : bds.GetStackupDescriptor().GetList() )
{
switch( item->GetType() )
{
case BS_ITEM_TYPE_DIELECTRIC:
for( int sublayer = 0; sublayer < item->GetSublayersCount(); sublayer++ )
thickness += item->GetThickness( sublayer );
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;
else if( item->GetBrdLayerId() == B_Cu )
m_backCopperThickness3DU = copper_thickness * m_biuTo3Dunits;
else if( item->IsEnabled() )
thickness += copper_thickness;
}
break;
default:
break;
}
}
m_boardBodyThickness3DU = thickness * m_biuTo3Dunits;
}
}
// !TODO: use value defined by user (currently use default values by ctor
m_copperThickness3DU = COPPER_THICKNESS * m_biuTo3Dunits;
m_nonCopperLayerThickness3DU = TECH_LAYER_THICKNESS * m_biuTo3Dunits;
m_solderPasteLayerThickness3DU = SOLDERPASTE_LAYER_THICKNESS * m_biuTo3Dunits;
// Init Z position of each layer
// calculate z position for each copper layer
// Zstart = -m_epoxyThickness / 2.0 is the z position of the back (bottom layer) (layer id = 31)
// Zstart = +m_epoxyThickness / 2.0 is the z position of the front (top layer) (layer id = 0)
// all unused copper layer z position are set to 0
// ____==__________==________==______ <- Bottom = +m_epoxyThickness / 2.0,
// | | Top = Bottom + m_copperThickness
@@ -435,26 +432,24 @@ void BOARD_ADAPTER::InitSettings( REPORTER* aStatusReporter, REPORTER* aWarningR
for( layer = 0; layer < m_copperLayersCount; ++layer )
{
// This approximates internal layer positions (because we're treating all the dielectric
// layers as having the same thickness). But we don't render them anyway so it doesn't
// really matter.
m_layerZcoordBottom[layer] = m_boardBodyThickness3DU / 2.0f -
(m_boardBodyThickness3DU * layer / (m_copperLayersCount - 1) );
m_layerZcoordBottom[layer] = m_epoxyThickness3DU / 2.0f -
(m_epoxyThickness3DU * layer / (m_copperLayersCount - 1) );
if( layer < (m_copperLayersCount / 2) )
m_layerZcoordTop[layer] = m_layerZcoordBottom[layer] + m_frontCopperThickness3DU;
m_layerZcoordTop[layer] = m_layerZcoordBottom[layer] + m_copperThickness3DU;
else
m_layerZcoordTop[layer] = m_layerZcoordBottom[layer] - m_backCopperThickness3DU;
m_layerZcoordTop[layer] = m_layerZcoordBottom[layer] - m_copperThickness3DU;
}
#define layerThicknessMargin 1.1
const float zpos_offset = m_nonCopperLayerThickness3DU * layerThicknessMargin;
// Fill remaining unused copper layers and back layer zpos with -m_boardBodyThickness / 2.0
// Fill remaining unused copper layers and back layer zpos
// with -m_epoxyThickness / 2.0
for( ; layer < MAX_CU_LAYERS; layer++ )
{
m_layerZcoordBottom[layer] = -( m_boardBodyThickness3DU / 2.0f );
m_layerZcoordTop[layer] = m_layerZcoordBottom[layer] - m_backCopperThickness3DU;
m_layerZcoordBottom[layer] = -(m_epoxyThickness3DU / 2.0f);
m_layerZcoordTop[layer] = -(m_epoxyThickness3DU / 2.0f) - m_copperThickness3DU;
}
// This is the top of the copper layer thickness.
@@ -510,6 +505,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 +531,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 +539,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 +575,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,23 +590,47 @@ 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;
case BS_ITEM_TYPE_DIELECTRIC:
{
KIGFX::COLOR4D layerColor = findColor( colorName, g_BoardColors );
KIGFX::COLOR4D layerColor = COLOR4D::UNSPECIFIED;
const wxString& materialName = stackupItem->GetMaterial();
if( materialName.StartsWith( wxT( "FR4" ) ) )
{
layerColor = findColor( wxT( "FR4 natural" ), g_BoardColors );
}
else if( materialName.IsSameAs( wxT( "PTFE" ) )
|| materialName.IsSameAs( wxT( "Teflon" ) ) )
{
layerColor = findColor( wxT( "PTFE natural" ), g_BoardColors );
}
else if( materialName.IsSameAs( wxT( "Polyimide" ) )
|| materialName.IsSameAs( wxT( "Kapton" ) ) )
{
layerColor = findColor( wxT( "Polyimide" ), g_BoardColors );
}
else if( materialName.IsSameAs( wxT( "Al" ) ) )
{
layerColor = findColor( wxT( "Aluminum" ), g_BoardColors );
}
else // A default color value for unknown dielectric material
// (i.e. an exotic name entered by hand)
{
layerColor = findColor( wxT( "FR4 natural" ), g_BoardColors );
}
if( bodyColor == COLOR4D( 0, 0, 0, 0 ) )
bodyColor = layerColor;
@@ -671,221 +647,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 ];
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 );
}
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 )
@@ -907,8 +714,7 @@ bool BOARD_ADAPTER::createBoardPolygon( wxString* aErrorMsg )
return false;
}
// max dist from one endPt to next startPt
int chainingEpsilon = m_board->GetOutlinesChainingEpsilon();
int chainingEpsilon = Millimeter2iu( 0.02 ); // max dist from one endPt to next startPt
success = BuildFootprintPolygonOutlines( m_board, m_board_poly,
m_board->GetDesignSettings().m_MaxError,
@@ -925,7 +731,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." );
@@ -938,9 +744,19 @@ bool BOARD_ADAPTER::createBoardPolygon( wxString* aErrorMsg )
float BOARD_ADAPTER::GetFootprintZPos( bool aIsFlipped ) const
{
if( aIsFlipped )
return m_layerZcoordBottom[B_Paste];
{
if( GetFlag( FL_SOLDERPASTE ) )
return m_layerZcoordBottom[B_SilkS];
else
return m_layerZcoordBottom[B_Paste];
}
else
return m_layerZcoordTop[F_Paste];
{
if( GetFlag( FL_SOLDERPASTE ) )
return m_layerZcoordTop[F_SilkS];
else
return m_layerZcoordTop[F_Paste];
}
}
@@ -964,16 +780,3 @@ SFVEC4F BOARD_ADAPTER::GetColor( const COLOR4D& aColor ) const
{
return SFVEC4F( aColor.r, aColor.g, aColor.b, aColor.a );
}
SFVEC2F BOARD_ADAPTER::GetSphericalCoord( int i ) const
{
SFVEC2F sphericalCoord =
SFVEC2F( ( m_Cfg->m_Render.raytrace_lightElevation[i] + 90.0f ) / 180.0f,
m_Cfg->m_Render.raytrace_lightAzimuth[i] / 180.0f );
sphericalCoord.x = glm::clamp( sphericalCoord.x, 0.0f, 1.0f );
sphericalCoord.y = glm::clamp( sphericalCoord.y, 0.0f, 2.0f );
return sphericalCoord;
}
+443 -167
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-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
@@ -31,15 +30,15 @@
#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_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"
#include <layer_ids.h>
#include <pad.h>
#include <pcb_track.h>
#include <wx/gdicmn.h>
#include <pcb_base_frame.h>
#include <pcb_text.h>
#include <pcb_shape.h>
@@ -50,13 +49,12 @@
#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;
typedef std::map< PCB_LAYER_ID, BVH_CONTAINER_2D *> MAP_CONTAINER_2D_BASE;
/// A type that stores polysets for each layer id
typedef std::map<PCB_LAYER_ID, SHAPE_POLY_SET*> MAP_POLY;
typedef std::map< PCB_LAYER_ID, SHAPE_POLY_SET *> MAP_POLY;
/// This defines the range that all coord will have to be rendered.
/// It will use this value to convert to a normalized value between
@@ -79,16 +77,41 @@ public:
*
* @param aCachePointer: the pointer to the 3D cache manager.
*/
void Set3dCacheManager( S3D_CACHE* aCacheMgr ) noexcept { m_3dModelManager = aCacheMgr; }
S3D_CACHE* Get3dCacheManager() const noexcept { return m_3dModelManager; }
void Set3dCacheManager( S3D_CACHE* aCachePointer ) noexcept
{
m_3dModelManager = aCachePointer;
}
/**
* Return the 3D cache manager pointer.
*/
S3D_CACHE* Get3dCacheManager() const noexcept
{
return m_3dModelManager;
}
/**
* Get a configuration status of a flag.
*
* @param aFlag the flag to get the status.
* @return true if flag is set, false if not.
*/
bool GetFlag( DISPLAY3D_FLG aFlag ) const ;
/**
* Set the status of a flag.
*
* @param aFlag the flag to set the status
* @param aState status to set.
*/
void SetFlag( DISPLAY3D_FLG aFlag, bool aState );
/**
* Check if a layer is enabled.
*
* @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.
@@ -100,18 +123,25 @@ public:
*
* @param aBoard board to process.
*/
void SetBoard( BOARD* aBoard ) noexcept { m_board = aBoard; }
const BOARD* GetBoard() const noexcept { return m_board; }
void SetBoard( BOARD* aBoard ) noexcept
{
m_board = aBoard;
}
void ReloadColorSettings() noexcept;
/**
* Get current board to be rendered.
*
* @return BOARD pointer
*/
const BOARD* GetBoard() const noexcept
{
return m_board;
}
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.
@@ -126,33 +156,55 @@ public:
*
* @return the conversion factor to transform a position from the board to 3D units.
*/
double BiuTo3dUnits() const noexcept { return m_biuTo3Dunits; }
double BiuTo3dUnits() const noexcept
{
return m_biuTo3Dunits;
}
/**
* Get the board outling bounding box.
*
* @return the board bounding box in 3D units.
*/
const BBOX_3D& GetBBox() const noexcept { return m_boardBoundingBox; }
const BBOX_3D& GetBBox() const noexcept
{
return m_boardBoundingBox;
}
/**
* Get the board body thickness, including internal copper layers (in 3D units).
* Get the current epoxy thickness.
*
* @return epoxy thickness in 3D units.
*/
float GetBoardBodyThickness() const noexcept { return m_boardBodyThickness3DU; }
float GetEpoxyThickness() const noexcept
{
return m_epoxyThickness3DU;
}
/**
* Get the non copper layers thickness (in 3D units).
* Get the current non copper layers thickness.
*
* @return thickness in 3D units of non copper layers.
*/
float GetNonCopperLayerThickness() const noexcept { return m_nonCopperLayerThickness3DU; }
float GetNonCopperLayerThickness() const noexcept
{
return m_nonCopperLayerThickness3DU;
}
/**
* Get the copper layer thicknesses (in 3D units).
* Get the current copper layer thickness.
*
* @return thickness in 3D units of copper layers.
*/
float GetFrontCopperThickness() const noexcept { return m_frontCopperThickness3DU; }
float GetBackCopperThickness() const noexcept { return m_backCopperThickness3DU; }
float GetCopperThickness() const noexcept
{
return m_copperThickness3DU;
}
/**
* Get the hole plating thickness (NB: in BOARD UNITS!).
* Get the current copper layer thickness.
*
* @return thickness in board units.
*/
int GetHolePlatingThickness() const noexcept;
@@ -161,21 +213,30 @@ public:
*
* @return size in BIU units.
*/
VECTOR2I GetBoardSize() const noexcept { return m_boardSize; }
wxSize GetBoardSize() const noexcept
{
return m_boardSize;
}
/**
* Get the board center.
*
* @return position in BIU units.
*/
VECTOR2I GetBoardPos() const noexcept { return m_boardPos; }
wxPoint GetBoardPos() const noexcept
{
return m_boardPos;
}
/**
* The board center position in 3D units.
*
* @return board center vector position in 3D units.
*/
const SFVEC3F& GetBoardCenter() const noexcept { return m_boardCenter; }
const SFVEC3F& GetBoardCenter() const noexcept
{
return m_boardCenter;
}
/**
* Get the position of the footprint in 3d integer units considering if it is flipped or not.
@@ -186,12 +247,81 @@ public:
*/
float GetFootprintZPos( bool aIsFlipped ) const ;
/**
* Get the current grid.
*
* @return space type of the grid.
*/
GRID3D_TYPE GetGridType() const noexcept
{
return m_gridType;
}
/**
* Set the current grid.
*
* @param aGridType the type space of the grid.
*/
void SetGridType( GRID3D_TYPE aGridType ) noexcept
{
m_gridType = aGridType;
}
/**
* Get the current antialiasing mode value.
*
* @return antialiasing mode value
*/
ANTIALIASING_MODE GetAntiAliasingMode() const { return m_antiAliasingMode; }
/**
* Set the current antialiasing mode value.
*
* @param aAAmode antialiasing mode value.
*/
void SetAntiAliasingMode( ANTIALIASING_MODE aAAmode ) { m_antiAliasingMode = aAAmode; }
/**
* @param aRenderEngine the render engine mode selected.
*/
void SetRenderEngine( RENDER_ENGINE aRenderEngine ) noexcept
{
m_renderEngine = aRenderEngine;
}
/**
* @return render engine on use.
*/
RENDER_ENGINE GetRenderEngine() const noexcept
{
return m_renderEngine;
}
/**
* @param aMaterialMode the render material mode.
*/
void SetMaterialMode( MATERIAL_MODE aMaterialMode ) noexcept
{
m_materialMode = aMaterialMode;
}
/**
* @return material rendering mode.
*/
MATERIAL_MODE GetMaterialMode() const noexcept
{
return m_materialMode;
}
/**
* Get the current polygon of the epoxy board.
*
* @return the shape polygon
*/
const SHAPE_POLY_SET& GetBoardPoly() const noexcept { return m_board_poly; }
const SHAPE_POLY_SET& GetBoardPoly() const noexcept
{
return m_board_poly;
}
/**
* Get the technical color of a layer.
@@ -215,8 +345,6 @@ public:
*/
SFVEC4F GetColor( const COLOR4D& aColor ) const;
SFVEC2F GetSphericalCoord( int i ) const;
/**
* Get the top z position.
*
@@ -244,15 +372,50 @@ public:
*
* @return the map containers of this board.
*/
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& GetLayerMap() const noexcept
{
return m_layerMap;
}
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* GetPlatedPadsFront() const noexcept
{
return m_platedPadsFront;
}
const BVH_CONTAINER_2D* GetPlatedPadsBack() const noexcept
{
return m_platedPadsBack;
}
/**
* Get the map of container that have the holes per layer.
*
* @return the map containers of holes from this board.
*/
const MAP_CONTAINER_2D_BASE& GetLayerHoleMap() const noexcept
{
return m_layerHoleMap;
}
/**
* Get the inflated through hole outside diameters container.
*
* @return a container with holes.
*/
const BVH_CONTAINER_2D& GetThroughHoleOds() const noexcept
{
return m_throughHoleOds;
}
/**
* Get the through hole annular rings container.
*
* @return a container with through hole annular rings.
*/
const BVH_CONTAINER_2D& GetThroughHoleAnnularRings() const noexcept
{
return m_throughHoleAnnularRings;
}
/**
* Get through hole outside diameter 2D polygons.
@@ -261,56 +424,93 @@ 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 SHAPE_POLY_SET& GetThroughHoleAnnularRingPolys() const noexcept
{
return m_viaAnnuli;
return m_throughHoleAnnularRingPolys;
}
const SHAPE_POLY_SET& GetViaAnnuliPolys() const noexcept
const SHAPE_POLY_SET& GetOuterNonPlatedThroughHolePoly() const noexcept
{
return m_viaAnnuliPolys;
}
const SHAPE_POLY_SET& GetNPTH_ODPolys() 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; }
unsigned int GetHoleCount() const noexcept { return m_holeCount; }
/**
* Get the through hole inner diameter container.
*
* @return a container with holes inner diameters.
*/
const BVH_CONTAINER_2D& GetThroughHoleIds() const noexcept
{
return m_throughHoleIds;
}
/**
* Get number of vias in this board.
*
* @return number of vias.
*/
unsigned int GetViaCount() const noexcept
{
return m_viaCount;
}
/**
* Get number of holes in this board.
*
* @return number of holes.
*/
unsigned int GetHoleCount() const noexcept
{
return m_holeCount;
}
/**
* Thee average diameter of the via holes.
*
* @return via hole average diameter dimension in 3D units.
*/
float GetAverageViaHoleDiameter() const noexcept { return m_averageViaHoleDiameter; }
float GetAverageViaHoleDiameter() const noexcept
{
return m_averageViaHoleDiameter;
}
/**
* Average diameter of through holes.
*
* @return the average diameter of through holes in 3D units.
*/
float GetAverageHoleDiameter() const noexcept { return m_averageHoleDiameter; }
float GetAverageHoleDiameter() const noexcept
{
return m_averageHoleDiameter;
}
/**
* Average width of the tracks.
*
* @return average track width in 3D units.
*/
float GetAverageTrackWidth() const noexcept { return m_averageTrackWidth; }
float GetAverageTrackWidth() const noexcept
{
return m_averageTrackWidth;
}
/**
* @param aDiameter3DU diameter in 3DU.
@@ -329,12 +529,30 @@ public:
*
* @return the map with polygon's layers.
*/
const MAP_POLY& GetPolyMap() const noexcept { return m_layers_poly; }
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 MAP_POLY& GetHoleIdPolysMap() const noexcept { return m_layerHoleIdPolys; }
const MAP_POLY& GetHoleOdPolysMap() const noexcept { return m_layerHoleOdPolys; }
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;
}
private:
/**
@@ -347,47 +565,51 @@ 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,
int aClearanceValue );
void createTrack( const PCB_TRACK* aTrack, CONTAINER_2D_BASE* aDstContainer );
void createPadWithClearance( const PAD *aPad, CONTAINER_2D_BASE* aDstContainer,
PCB_LAYER_ID aLayer, const wxSize& aClearanceValue ) const;
void createPadWithMargin( const PAD *aPad, CONTAINER_2D_BASE* aDstContainer,
PCB_LAYER_ID aLayer, const VECTOR2I& aMargin ) const;
OBJECT_2D* createPadWithDrill( const PAD* aPad, int aInflateValue );
void createPadWithHole( const PAD* aPad, CONTAINER_2D_BASE* aDstContainer,
int aInflateValue );
void addPadsWithClearance( const FOOTPRINT* aFootprint, CONTAINER_2D_BASE* aDstContainer,
PCB_LAYER_ID aLayerId, int aInflateValue,
bool aSkipNPTHPadsWihNoCopper, bool aSkipPlatedPads,
bool aSkipNonPlatedPads );
void addPads( const FOOTPRINT* aFootprint, CONTAINER_2D_BASE* aDstContainer,
PCB_LAYER_ID aLayerId, bool aSkipPlatedPads, bool aSkipNonPlatedPads );
void addFootprintShapesWithClearance( const FOOTPRINT* aFootprint,
CONTAINER_2D_BASE* aDstContainer,
PCB_LAYER_ID aLayerId, int aInflateValue );
void addFootprintShapes( const FOOTPRINT* aFootprint, CONTAINER_2D_BASE* aDstContainer,
PCB_LAYER_ID aLayerId,
const std::bitset<LAYER_3D_END>& aVisibilityFlags );
void addShapeWithClearance( const PCB_TEXT* aText, CONTAINER_2D_BASE* aDstContainer,
PCB_LAYER_ID aLayerId, int aClearanceValue );
void addText( const EDA_TEXT* aText, CONTAINER_2D_BASE* aDstContainer,
const BOARD_ITEM* aOwner );
void addShapeWithClearance( const PCB_SHAPE* aShape, CONTAINER_2D_BASE* aDstContainer,
PCB_LAYER_ID aLayerId, int aClearanceValue );
void addShape( const PCB_SHAPE* aShape, CONTAINER_2D_BASE* aContainer,
const BOARD_ITEM* aOwner );
void addShapeWithClearance( const PCB_DIMENSION_BASE* aDimension,
CONTAINER_2D_BASE* aDstContainer, PCB_LAYER_ID aLayerId,
int aClearanceValue );
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 addSolidAreasShapes( const ZONE* aZone, CONTAINER_2D_BASE* aDstContainer,
void addSolidAreasShapes( const ZONE* aZoneContainer, CONTAINER_2D_BASE* aDstContainer,
PCB_LAYER_ID aLayerId );
void createArcSegments( const VECTOR2I& aCentre, const VECTOR2I& aStart,
const EDA_ANGLE& aArcAngle, int aCircleToSegmentsCount, int aWidth,
CONTAINER_2D_BASE* aContainer, const BOARD_ITEM& aOwner );
void transformArcToSegments( const wxPoint& aCentre, const wxPoint& aStart, double aArcAngle,
int aCircleToSegmentsCount, int aWidth,
CONTAINER_2D_BASE* aDstContainer, const BOARD_ITEM& aBoardItem );
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& aCornerBuffer,
int aWidth) const;
void transformFPShapesToPolygon( const FOOTPRINT* aFootprint, PCB_LAYER_ID aLayer,
SHAPE_POLY_SET& aCornerBuffer ) 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;
@@ -400,100 +622,154 @@ 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;
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
bool m_IsBoardView;
bool m_MousewheelPanning;
bool m_IsPreviewer; ///< true if we're in a 3D preview panel, false
///< for the standard 3D viewer
SFVEC3F m_OpenGlSelectionColor;
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;
// Raytracing light colors
SFVEC3F m_RtCameraLightColor;
SFVEC3F m_RtLightColorTop;
SFVEC3F m_RtLightColorBottom;
std::vector<SFVEC3F> m_RtLightColor;
std::vector<SFVEC2F> m_RtLightSphericalCoords;
// Raytracing options
int m_RtShadowSampleCount;
int m_RtReflectionSampleCount;
int m_RtRefractionSampleCount;
int m_RtRecursiveReflectionCount;
int m_RtRecursiveRefractionCount;
float m_RtSpreadShadows;
float m_RtSpreadReflections;
float m_RtSpreadRefractions;
private:
BOARD* m_board;
S3D_CACHE* m_3dModelManager;
COLOR_SETTINGS* m_colors;
BOARD* m_board;
S3D_CACHE* m_3dModelManager;
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.
std::vector< bool > m_drawFlags;
GRID3D_TYPE m_gridType;
RENDER_ENGINE m_renderEngine;
MATERIAL_MODE m_materialMode;
ANTIALIASING_MODE m_antiAliasingMode;
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;
wxPoint m_boardPos; ///< Board center position in board internal units.
wxSize 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_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
///< Polygon contours for each layer.
MAP_POLY m_layers_poly;
SHAPE_POLY_SET m_board_poly; ///< Board outline polygon.
SHAPE_POLY_SET* m_frontPlatedPadPolys;
SHAPE_POLY_SET* m_backPlatedPadPolys;
///< Polygon contours for hole outer diameters for each layer.
MAP_POLY m_layerHoleOdPolys;
///< Polygon contours for hole inner diameters for each layer.
MAP_POLY m_layerHoleIdPolys;
///< Polygon contours for non plated through hole outer diameters.
SHAPE_POLY_SET m_nonPlatedThroughHoleOdPolys;
///< Polygon contours for through hole outer diameters.
SHAPE_POLY_SET m_throughHoleOdPolys;
///< Polygon contours for through holes via outer diameters.
SHAPE_POLY_SET m_throughHoleViaOdPolys;
///< Polygon contours for through hole via annular rings.
SHAPE_POLY_SET m_throughHoleAnnularRingPolys;
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_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
///< The holes per each layer.
MAP_CONTAINER_2D_BASE m_layerHoleMap;
unsigned int m_copperLayersCount;
///< List of through holes with the radius of the hole inflated with the copper thickness.
BVH_CONTAINER_2D m_throughHoleOds;
double m_biuTo3Dunits; ///< Scale factor to convert board internal units
///< to 3D units normalized between -1.0 and 1.0.
///< List of plated through hole annular rings.
BVH_CONTAINER_2D m_throughHoleAnnularRings;
std::array<float, PCB_LAYER_ID_COUNT> m_layerZcoordTop; ///< Top (End) Z position of each
///< layer in 3D units.
///< List of through hole inner diameters.
BVH_CONTAINER_2D m_throughHoleIds;
std::array<float, PCB_LAYER_ID_COUNT> m_layerZcoordBottom; ///< Bottom (Start) Z position of
///< each layer in 3D units.
///< List of through hole vias with the radius of the hole inflated with the copper thickness.
BVH_CONTAINER_2D m_throughHoleViaOds;
float m_frontCopperThickness3DU;
float m_backCopperThickness3DU;
float m_boardBodyThickness3DU;
float m_nonCopperLayerThickness3DU;
float m_solderPasteLayerThickness3DU;
///< List of through hole via inner diameters.
BVH_CONTAINER_2D m_throughHoleViaIds;
unsigned int m_trackCount;
float m_averageTrackWidth;
unsigned int m_viaCount;
float m_averageViaHoleDiameter;
unsigned int m_holeCount;
float m_averageHoleDiameter;
///< Number of copper layers actually used by the board.
unsigned int m_copperLayersCount;
///< Scale factor to convert board internal units to 3D units normalized between -1.0 and 1.0.
double m_biuTo3Dunits;
///< Top (End) Z position of each layer in 3D units.
std::array<float, PCB_LAYER_ID_COUNT> m_layerZcoordTop;
///< Bottom (Start) Z position of each layer in 3D units.
std::array<float, PCB_LAYER_ID_COUNT> m_layerZcoordBottom;
///< Copper thickness in 3D units.
float m_copperThickness3DU;
///< Epoxy thickness in 3D units.
float m_epoxyThickness3DU;
///< Non copper layers thickness in 3D units.
float m_nonCopperLayerThickness3DU;
///< solder paste layers thickness in 3D units.
float m_solderPasteLayerThickness3DU;
///< Number of tracks in the board.
unsigned int m_trackCount;
///< Track average width.
float m_averageTrackWidth;
///< Number of through hole vias in the board.
unsigned int m_viaCount;
///< Computed average diameter of the via holes in 3D units.
float m_averageViaHoleDiameter;
///< Number of holes in the board.
unsigned int m_holeCount;
///< Computed average diameter of the holes in 3D units.
float m_averageHoleDiameter;
/**
* Trace mask used to enable or disable debug output for this class. Output can be turned
* on by setting the WXTRACE environment variable to "KI_TRACE_EDA_CINFO3D_VISU". See the
* wxWidgets documentation on wxLogTrace for more information.
* 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
* "KI_TRACE_EDA_CINFO3D_VISU". See the wxWidgets documentation on wxLogTrace for
* more information.
*/
static const wxChar* m_logTrace;
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
+78
View File
@@ -0,0 +1,78 @@
/*
* 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-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 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 <convert_basic_shapes_to_polygon.h>
#include <fp_shape.h>
#include <footprint.h>
void BOARD_ADAPTER::buildPadOutlineAsPolygon( const PAD* aPad, SHAPE_POLY_SET& aCornerBuffer,
int aWidth ) const
{
if( aPad->GetShape() == PAD_SHAPE::CIRCLE ) // Draw a ring
{
TransformRingToPolygon( aCornerBuffer, aPad->ShapePos(), aPad->GetSize().x / 2,
aWidth, ARC_HIGH_DEF, 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( aCornerBuffer, (wxPoint) a, (wxPoint) b, aWidth, ARC_HIGH_DEF,
ERROR_INSIDE );
}
}
void BOARD_ADAPTER::transformFPShapesToPolygon( const FOOTPRINT* aFootprint, PCB_LAYER_ID aLayer,
SHAPE_POLY_SET& aCornerBuffer ) const
{
for( BOARD_ITEM* item : aFootprint->GraphicalItems() )
{
if( item->Type() == PCB_FP_SHAPE_T )
{
FP_SHAPE* outline = (FP_SHAPE*) item;
if( outline->GetLayer() == aLayer )
{
outline->TransformShapeWithClearanceToPolygon( aCornerBuffer, aLayer, 0,
ARC_HIGH_DEF, ERROR_INSIDE );
}
}
}
}
+229 -167
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
@@ -23,7 +23,7 @@
*/
#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"
@@ -32,13 +32,13 @@
#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 <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>
@@ -55,12 +55,14 @@
*/
const wxChar* EDA_3D_CANVAS::m_logTrace = wxT( "KI_TRACE_EDA_3D_CANVAS" );
const float EDA_3D_CANVAS::m_delta_move_step_factor = 0.7f;
// A custom event, used to call DoRePaint during an idle time
wxDEFINE_EVENT( wxEVT_REFRESH_CUSTOM_COMMAND, wxEvent );
wxDEFINE_EVENT( wxEVT_REFRESH_CUSTOM_COMMAND, wxEvent);
BEGIN_EVENT_TABLE( EDA_3D_CANVAS, HIDPI_GL_3D_CANVAS )
BEGIN_EVENT_TABLE( EDA_3D_CANVAS, wxGLCanvas )
EVT_PAINT( EDA_3D_CANVAS::OnPaint )
// mouse events
@@ -70,10 +72,14 @@ 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 )
#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 )
//EVT_REFRESH_CUSTOM_COMMAND( ID_CUSTOM_EVENT_1, EDA_3D_CANVAS::OnRefreshRequest )
EVT_CUSTOM(wxEVT_REFRESH_CUSTOM_COMMAND, ID_CUSTOM_EVENT_1, EDA_3D_CANVAS::OnRefreshRequest )
EVT_CLOSE( EDA_3D_CANVAS::OnCloseWindow )
@@ -83,29 +89,30 @@ END_EVENT_TABLE()
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, wxID_ANY,
aAttribList, wxDefaultPosition,
wxDefaultSize, wxFULL_REPAINT_ON_RESIZE ),
m_eventDispatcher( nullptr ),
m_parentStatusBar( nullptr ),
m_parentInfoBar( nullptr ),
m_glRC( nullptr ),
m_is_opengl_initialized( false ),
m_is_opengl_version_supported( true ),
m_editing_timeout_timer( this, wxID_HIGHEST + 1 ),
m_redraw_trigger_timer( this, wxID_HIGHEST + 2 ),
m_render_pivot( false ),
m_camera_moving_speed( 1.0f ),
m_strtime_camera_movement( 0 ),
m_animation_enabled( true ),
m_moving_speed_multiplier( 3 ),
m_boardAdapter( aBoardAdapter ),
m_3d_render( nullptr ),
m_opengl_supports_raytracing( true ),
m_render_raytracing_was_requested( false ),
m_accelerator3DShapes( nullptr ),
m_currentRollOverItem( nullptr )
S3D_CACHE* a3DCachePointer )
: HIDPI_GL_CANVAS( aParent, wxID_ANY, aAttribList, wxDefaultPosition, wxDefaultSize,
wxFULL_REPAINT_ON_RESIZE ),
m_eventDispatcher( nullptr ),
m_parentStatusBar( nullptr ),
m_parentInfoBar( nullptr ),
m_glRC( nullptr ),
m_is_opengl_initialized( false ),
m_is_opengl_version_supported( true ),
m_mouse_is_moving( false ),
m_mouse_was_moved( false ),
m_camera_is_moving( false ),
m_render_pivot( false ),
m_camera_moving_speed( 1.0f ),
m_strtime_camera_movement( 0 ),
m_animation_enabled( true ),
m_moving_speed_multiplier( 3 ),
m_boardAdapter( aBoardAdapter ),
m_camera( aCamera ),
m_3d_render( nullptr ),
m_opengl_supports_raytracing( true ),
m_render_raytracing_was_requested( false ),
m_accelerator3DShapes( nullptr ),
m_currentRollOverItem( nullptr )
{
wxLogTrace( m_logTrace, wxT( "EDA_3D_CANVAS::EDA_3D_CANVAS" ) );
@@ -125,20 +132,14 @@ EDA_3D_CANVAS::EDA_3D_CANVAS( wxWindow* aParent, const int* aAttribList,
wxASSERT( m_3d_render_raytracing != nullptr );
wxASSERT( m_3d_render_opengl != nullptr );
auto busy_indicator_factory =
[]()
{
return std::make_unique<WX_BUSY_INDICATOR>();
};
auto busy_indicator_factory = []() { return std::make_unique<WX_BUSY_INDICATOR>(); };
m_3d_render_raytracing->SetBusyIndicatorFactory( busy_indicator_factory );
m_3d_render_opengl->SetBusyIndicatorFactory( busy_indicator_factory );
// We always start with the opengl engine (raytracing is avoided due to very
// long calculation time)
m_3d_render = m_3d_render_opengl;
RenderEngineChanged();
m_boardAdapter.ReloadColorSettings();
m_boardAdapter.SetColorSettings( Pgm().GetSettingsManager().GetColorSettings() );
wxASSERT( a3DCachePointer != nullptr );
m_boardAdapter.Set3dCacheManager( a3DCachePointer );
@@ -153,7 +154,9 @@ EDA_3D_CANVAS::EDA_3D_CANVAS( wxWindow* aParent, const int* aAttribList,
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
};
@@ -205,7 +208,7 @@ void EDA_3D_CANVAS::OnCloseWindow( wxCloseEvent& event )
void EDA_3D_CANVAS::OnResize( wxSizeEvent& event )
{
Request_refresh();
this->Request_refresh();
}
@@ -226,10 +229,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 ) ) );
}
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 );
@@ -299,7 +302,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();
@@ -330,9 +333,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 ) );
}
}
@@ -363,13 +363,17 @@ 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();
STATUSBAR_REPORTER activityReporter( m_parentStatusBar,
(int) EDA_3D_VIEWER_STATUSBAR::ACTIVITY );
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.
@@ -379,15 +383,6 @@ void EDA_3D_CANVAS::DoRePaint()
if( m_glRC == nullptr )
m_glRC = GL_CONTEXT_MANAGER::Get().CreateCtx( this );
// CreateCtx could and does fail per sentry crash events, lets be graceful
if( m_glRC == nullptr )
{
warningReporter.Report( _( "OpenGL context creation error" ), RPT_SEVERITY_ERROR );
warningReporter.Finalize();
m_is_currently_painting.clear();
return;
}
GL_CONTEXT_MANAGER::Get().LockCtx( m_glRC, this );
// Set the OpenGL viewport according to the client size of this canvas.
@@ -438,11 +433,11 @@ void EDA_3D_CANVAS::DoRePaint()
{
m_3d_render = m_3d_render_opengl;
m_render_raytracing_was_requested = false;
m_boardAdapter.m_Cfg->m_Render.engine = RENDER_ENGINE::OPENGL;
m_boardAdapter.SetRenderEngine( RENDER_ENGINE::OPENGL );
}
// Check if a raytacing was requested and need to switch to raytracing mode
if( m_boardAdapter.m_Cfg->m_Render.engine == RENDER_ENGINE::OPENGL )
if( m_boardAdapter.GetRenderEngine() == RENDER_ENGINE::OPENGL )
{
const bool was_camera_changed = m_camera.ParametersChanged();
@@ -461,7 +456,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 );
@@ -491,7 +486,7 @@ void EDA_3D_CANVAS::DoRePaint()
bool reloadRaytracingForCalculations = false;
if( m_boardAdapter.m_Cfg->m_Render.engine == RENDER_ENGINE::OPENGL
if( m_boardAdapter.GetRenderEngine() == RENDER_ENGINE::OPENGL
&& m_3d_render_opengl->IsReloadRequestPending() )
{
reloadRaytracingForCalculations = true;
@@ -527,14 +522,6 @@ 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( m_render3dmousePivot )
{
const float scale = glm::min( m_camera.GetZoom(), 1.0f );
render3dmousePivot( scale );
}
// "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
// commands is displayed on the window."
@@ -542,13 +529,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
@@ -595,19 +585,72 @@ void EDA_3D_CANVAS::OnEraseBackground( wxEraseEvent& event )
void EDA_3D_CANVAS::OnMouseWheel( wxMouseEvent& event )
{
bool mouseActivity = false;
wxLogTrace( m_logTrace, wxT( "EDA_3D_CANVAS::OnMouseWheel" ) );
OnMouseWheelCamera( event, m_boardAdapter.m_MousewheelPanning );
if( m_camera_is_moving )
return;
if( m_mouse_was_moved )
float delta_move = m_delta_move_step_factor * m_camera.GetZoom();
if( m_boardAdapter.GetFlag( FL_MOUSEWHEEL_PANNING ) )
delta_move *= 0.01f * event.GetWheelRotation();
else
if( event.GetWheelRotation() < 0 )
delta_move = -delta_move;
// mousewheel_panning enabled:
// wheel -> pan;
// wheel + shift -> horizontal scrolling;
// wheel + ctrl -> zooming;
// mousewheel_panning disabled:
// wheel + shift -> vertical scrolling;
// wheel + ctrl -> horizontal scrolling;
// wheel -> zooming.
if( m_boardAdapter.GetFlag( FL_MOUSEWHEEL_PANNING ) && !event.ControlDown() )
{
if( event.GetWheelAxis() == wxMOUSE_WHEEL_HORIZONTAL || event.ShiftDown() )
m_camera.Pan( SFVEC3F( -delta_move, 0.0f, 0.0f ) );
else
m_camera.Pan( SFVEC3F( 0.0f, -delta_move, 0.0f ) );
mouseActivity = true;
}
else if( event.ShiftDown() && !m_boardAdapter.GetFlag( FL_MOUSEWHEEL_PANNING ) )
{
m_camera.Pan( SFVEC3F( 0.0f, -delta_move, 0.0f ) );
mouseActivity = true;
}
else if( event.ControlDown() && !m_boardAdapter.GetFlag( FL_MOUSEWHEEL_PANNING ) )
{
m_camera.Pan( SFVEC3F( delta_move, 0.0f, 0.0f ) );
mouseActivity = true;
}
else
{
mouseActivity = m_camera.Zoom( event.GetWheelRotation() > 0 ? 1.1f : 1/1.1f );
}
// If it results on a camera movement
if( mouseActivity )
{
DisplayStatus();
Request_refresh();
m_mouse_is_moving = true;
m_mouse_was_moved = true;
restart_editingTimeOut_Timer();
}
// Update the cursor current mouse position on the camera
m_camera.SetCurMousePosition( GetNativePosition( event.GetPosition() ) );
}
#if wxCHECK_VERSION( 3, 1, 0 ) || defined( USE_OSX_MAGNIFY_EVENT )
void EDA_3D_CANVAS::OnMagnify( wxMouseEvent& event )
{
SetFocus();
@@ -625,44 +668,49 @@ void EDA_3D_CANVAS::OnMagnify( wxMouseEvent& event )
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
//wxLogTrace( m_logTrace, wxT( "EDA_3D_CANVAS::OnMouseMove" ) );
if( m_camera_is_moving )
return;
OnMouseMoveCamera( event );
const wxSize& nativeWinSize = GetNativePixelSize();
const wxPoint& nativePosition = GetNativePosition( event.GetPosition() );
if( m_mouse_was_moved )
m_camera.SetCurWindowSize( nativeWinSize );
if( event.Dragging() )
{
if( event.LeftIsDown() ) // Drag
m_camera.Drag( nativePosition );
else if( event.MiddleIsDown() ) // Pan
m_camera.Pan( nativePosition );
m_mouse_is_moving = true;
m_mouse_was_moved = true;
// orientation has changed, redraw mesh
DisplayStatus();
Request_refresh();
// *Do not* reactivate the timer here during the mouse move command:
// OnMiddleUp() will do it at the end of mouse drag/move command
}
if( !event.Dragging() && m_boardAdapter.m_Cfg->m_Render.engine == RENDER_ENGINE::OPENGL )
{
STATUSBAR_REPORTER reporter( m_parentStatusBar, EDA_3D_VIEWER_STATUSBAR::HOVERED_ITEM );
RAY mouseRay = getRayAtCurrentMousePosition();
BOARD_ITEM* rollOverItem = m_3d_render_raytracing->IntersectBoardItem( mouseRay );
m_camera.SetCurMousePosition( nativePosition );
auto printNetInfo =
[]( BOARD_CONNECTED_ITEM* aItem )
{
return wxString::Format( _( "Net %s\tNet class %s" ),
aItem->GetNet()->GetNetname(),
aItem->GetNet()->GetNetClass()->GetName() );
};
if( !event.Dragging() && m_boardAdapter.GetRenderEngine() == RENDER_ENGINE::OPENGL )
{
STATUSBAR_REPORTER reporter( m_parentStatusBar,
static_cast<int>( EDA_3D_VIEWER_STATUSBAR::HOVERED_ITEM ) );
RAY mouseRay = getRayAtCurrrentMousePosition();
BOARD_ITEM *rollOverItem = m_3d_render_raytracing->IntersectBoardItem( mouseRay );
if( rollOverItem )
{
wxString msg;
if( rollOverItem != m_currentRollOverItem )
{
m_3d_render_opengl->SetCurrentRollOverItem( rollOverItem );
@@ -675,61 +723,62 @@ void EDA_3D_CANVAS::OnMouseMove( wxMouseEvent& event )
{
case PCB_PAD_T:
{
PAD* pad = static_cast<PAD*>( rollOverItem );
PAD* pad = dynamic_cast<PAD*>( rollOverItem );
if( !pad->GetNumber().IsEmpty() )
msg += wxString::Format( _( "Pad %s\t" ), pad->GetNumber() );
if( pad->IsOnCopperLayer() )
msg += printNetInfo( pad );
break;
if( pad && pad->IsOnCopperLayer() )
{
reporter.Report( wxString::Format( _( "Net %s\tNetClass %s\tPadName %s" ),
pad->GetNet()->GetNetname(),
pad->GetNet()->GetNetClassName(),
pad->GetNumber() ) );
}
}
break;
case PCB_FOOTPRINT_T:
{
FOOTPRINT* footprint = static_cast<FOOTPRINT*>( rollOverItem );
msg += footprint->GetReference();
break;
FOOTPRINT* footprint = dynamic_cast<FOOTPRINT*>( rollOverItem );
if( footprint )
reporter.Report( footprint->GetReference() );
}
break;
case PCB_TRACE_T:
case PCB_VIA_T:
case PCB_ARC_T:
{
PCB_TRACK* track = static_cast<PCB_TRACK*>( rollOverItem );
msg += printNetInfo( track );
break;
PCB_TRACK* track = dynamic_cast<PCB_TRACK*>( rollOverItem );
if( track )
{
reporter.Report( wxString::Format( _( "Net %s\tNetClass %s" ),
track->GetNet()->GetNetname(),
track->GetNet()->GetNetClassName() ) );
}
}
break;
case PCB_ZONE_T:
{
ZONE* zone = static_cast<ZONE*>( rollOverItem );
ZONE* zone = dynamic_cast<ZONE*>( rollOverItem );
if( !zone->GetZoneName().IsEmpty() )
if( zone && zone->IsOnCopperLayer() )
{
if( zone->GetIsRuleArea() )
msg += wxString::Format( _( "Rule area %s\t" ), zone->GetZoneName() );
else
msg += wxString::Format( _( "Zone %s\t" ), zone->GetZoneName() );
reporter.Report( wxString::Format( _( "Net %s\tNetClass %s" ),
zone->GetNet()->GetNetname(),
zone->GetNet()->GetNetClassName() ) );
}
if( zone->IsOnCopperLayer() )
msg += printNetInfo( zone );
break;
}
break;
default:
break;
}
reporter.Report( msg );
}
else
{
if( m_currentRollOverItem
&& m_boardAdapter.m_Cfg->m_Render.engine == RENDER_ENGINE::OPENGL )
if( m_currentRollOverItem && m_boardAdapter.GetRenderEngine() == RENDER_ENGINE::OPENGL )
{
m_3d_render_opengl->SetCurrentRollOverItem( nullptr );
Request_refresh();
@@ -750,7 +799,7 @@ void EDA_3D_CANVAS::OnLeftDown( wxMouseEvent& event )
if( !event.Dragging() && ( m_3d_render_raytracing != nullptr ) )
{
RAY mouseRay = getRayAtCurrentMousePosition();
RAY mouseRay = getRayAtCurrrentMousePosition();
BOARD_ITEM *intersectedBoardItem = m_3d_render_raytracing->IntersectBoardItem( mouseRay );
@@ -796,14 +845,8 @@ void EDA_3D_CANVAS::OnMiddleUp( wxMouseEvent& event )
}
void EDA_3D_CANVAS::OnTimerTimeout_Editing( wxTimerEvent& aEvent )
void EDA_3D_CANVAS::OnTimerTimeout_Editing( wxTimerEvent& /* event */ )
{
if( aEvent.GetId() != m_editing_timeout_timer.GetId() )
{
aEvent.Skip();
return;
}
m_mouse_is_moving = false;
m_mouse_was_moved = false;
@@ -824,21 +867,15 @@ void EDA_3D_CANVAS::restart_editingTimeOut_Timer()
}
void EDA_3D_CANVAS::OnTimerTimeout_Redraw( wxTimerEvent& aEvent )
void EDA_3D_CANVAS::OnTimerTimeout_Redraw( wxTimerEvent& event )
{
if( aEvent.GetId() != m_redraw_trigger_timer.GetId() )
{
aEvent.Skip();
return;
}
Request_refresh( true );
}
void EDA_3D_CANVAS::OnRefreshRequest( wxEvent& aEvent )
{
Refresh();
DoRePaint();
}
@@ -894,7 +931,7 @@ void EDA_3D_CANVAS::request_start_moving_camera( float aMovingSpeed, bool aRende
void EDA_3D_CANVAS::move_pivot_based_on_cur_mouse_position()
{
RAY mouseRay = getRayAtCurrentMousePosition();
RAY mouseRay = getRayAtCurrrentMousePosition();
float hit_t;
@@ -911,56 +948,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();
@@ -969,7 +1018,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();
@@ -978,7 +1027,14 @@ bool EDA_3D_CANVAS::SetView3D( VIEW3D_TYPE aRequestedView )
return true;
case VIEW3D_TYPE::VIEW3D_RIGHT:
case ID_VIEW3D_RESET:
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_RIGHT:
m_camera.SetInterpolateMode( CAMERA_INTERPOLATION::BEZIER );
m_camera.SetT0_and_T1_current_T();
m_camera.Reset_T1();
@@ -987,7 +1043,7 @@ bool EDA_3D_CANVAS::SetView3D( VIEW3D_TYPE aRequestedView )
request_start_moving_camera();
return true;
case VIEW3D_TYPE::VIEW3D_LEFT:
case ID_VIEW3D_LEFT:
m_camera.SetInterpolateMode( CAMERA_INTERPOLATION::BEZIER );
m_camera.SetT0_and_T1_current_T();
m_camera.Reset_T1();
@@ -996,7 +1052,7 @@ bool EDA_3D_CANVAS::SetView3D( VIEW3D_TYPE aRequestedView )
request_start_moving_camera();
return true;
case VIEW3D_TYPE::VIEW3D_FRONT:
case ID_VIEW3D_FRONT:
m_camera.SetInterpolateMode( CAMERA_INTERPOLATION::BEZIER );
m_camera.SetT0_and_T1_current_T();
m_camera.Reset_T1();
@@ -1004,7 +1060,7 @@ bool EDA_3D_CANVAS::SetView3D( VIEW3D_TYPE aRequestedView )
request_start_moving_camera();
return true;
case VIEW3D_TYPE::VIEW3D_BACK:
case ID_VIEW3D_BACK:
m_camera.SetInterpolateMode( CAMERA_INTERPOLATION::BEZIER );
m_camera.SetT0_and_T1_current_T();
m_camera.Reset_T1();
@@ -1017,14 +1073,14 @@ bool EDA_3D_CANVAS::SetView3D( VIEW3D_TYPE aRequestedView )
request_start_moving_camera();
return true;
case VIEW3D_TYPE::VIEW3D_TOP:
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 VIEW3D_TYPE::VIEW3D_BOTTOM:
case ID_VIEW3D_BOTTOM:
m_camera.SetInterpolateMode( CAMERA_INTERPOLATION::BEZIER );
m_camera.SetT0_and_T1_current_T();
m_camera.Reset_T1();
@@ -1032,7 +1088,7 @@ bool EDA_3D_CANVAS::SetView3D( VIEW3D_TYPE aRequestedView )
request_start_moving_camera( glm::min( glm::max( m_camera.GetZoom(), 0.5f ), 1.125f ) );
return true;
case VIEW3D_TYPE::VIEW3D_FLIP:
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 ) );
@@ -1042,15 +1098,21 @@ bool EDA_3D_CANVAS::SetView3D( VIEW3D_TYPE aRequestedView )
default:
return false;
}
m_mouse_was_moved = true;
restart_editingTimeOut_Timer();
DisplayStatus();
Request_refresh();
return handled;
}
void EDA_3D_CANVAS::RenderEngineChanged()
{
SETTINGS_MANAGER& mgr = Pgm().GetSettingsManager();
EDA_3D_VIEWER_SETTINGS* cfg = mgr.GetAppSettings<EDA_3D_VIEWER_SETTINGS>();
switch( cfg->m_Render.engine )
switch( m_boardAdapter.GetRenderEngine() )
{
case RENDER_ENGINE::OPENGL: m_3d_render = m_3d_render_opengl; break;
case RENDER_ENGINE::RAYTRACING: m_3d_render = m_3d_render_raytracing; break;
@@ -1066,13 +1128,13 @@ void EDA_3D_CANVAS::RenderEngineChanged()
}
RAY EDA_3D_CANVAS::getRayAtCurrentMousePosition()
RAY EDA_3D_CANVAS::getRayAtCurrrentMousePosition()
{
SFVEC3F rayOrigin;
SFVEC3F rayDir;
// Generate a ray origin and direction based on current mouser position and camera
m_camera.MakeRayAtCurrentMousePosition( rayOrigin, rayDir );
m_camera.MakeRayAtCurrrentMousePosition( rayOrigin, rayDir );
RAY mouseRay;
mouseRay.Init( rayOrigin, rayDir );
+21 -66
View File
@@ -30,7 +30,7 @@
#include "3d_rendering/raytracing/accelerators/accelerator_3d.h"
#include "3d_rendering/render_3d_base.h"
#include "3d_cache/3d_cache.h"
#include <gal/hidpi_gl_3D_canvas.h>
#include <gal/hidpi_gl_canvas.h>
#include <wx/image.h>
#include <wx/timer.h>
@@ -45,7 +45,7 @@ class RENDER_3D_OPENGL;
/**
* Implement a canvas based on a wxGLCanvas
*/
class EDA_3D_CANVAS : public HIDPI_GL_3D_CANVAS
class EDA_3D_CANVAS : public HIDPI_GL_CANVAS
{
public:
/**
@@ -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.
@@ -161,52 +161,11 @@ public:
*/
void OnEvent( wxEvent& aEvent );
private:
/**
* Get information used to display 3D board.
* Called by a wxPaintEvent event
*/
const BOARD_ADAPTER& GetBoardAdapter() const { return m_boardAdapter; }
/**
* Get a value indicating whether to render the pivot.
*/
bool GetRenderPivot() { return m_render_pivot; }
/**
* Set aValue indicating whether to render the pivot.
*
* @param aValue true will cause the pivot to be rendered on the next redraw.
*/
void SetRenderPivot( bool aValue ) { m_render_pivot = aValue; }
/**
* Get a value indicating whether to render the 3dmouse pivot.
*/
bool GetRender3dmousePivot()
{
return m_render3dmousePivot;
}
/**
* Set aValue indicating whether to render the 3dmouse pivot.
*
* @param aValue true will cause the pivot to be rendered on the next redraw.
*/
void SetRender3dmousePivot( bool aValue )
{
m_render3dmousePivot = aValue;
}
/**
* Set the position of the the 3dmouse pivot.
*
* @param aPos is the position of the 3dmouse rotation pivot
*/
void Set3dmousePivotPos( const SFVEC3F& aPos )
{
m_3dmousePivotPos = aPos;
}
void OnPaint( wxPaintEvent& aEvent );
/**
* The actual function to repaint the canvas.
@@ -216,17 +175,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 );
@@ -270,13 +228,6 @@ private:
*/
void render_pivot( float t, float aScale );
/**
* Render the 3dmouse pivot cursor.
*
* @param aScale scale to apply on the cursor.
*/
void render3dmousePivot( float aScale );
/**
* @return true if OpenGL initialization succeeded.
*/
@@ -287,7 +238,7 @@ private:
*/
void releaseOpenGL();
RAY getRayAtCurrentMousePosition();
RAY getRayAtCurrrentMousePosition();
private:
TOOL_DISPATCHER* m_eventDispatcher;
@@ -303,17 +254,24 @@ private:
wxTimer m_redraw_trigger_timer; // Used to schedule a redraw event
std::atomic_flag m_is_currently_painting; // Avoid drawing twice at the same time
bool m_mouse_is_moving; // Mouse activity is in progress
bool m_mouse_was_moved;
bool m_camera_is_moving; // Camera animation is ongoing
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
CAMERA& m_camera;
RENDER_3D_BASE* m_3d_render;
RENDER_3D_RAYTRACE* m_3d_render_raytracing;
RENDER_3D_OPENGL* m_3d_render_opengl;
static const float m_delta_move_step_factor; // Step factor to used with cursor on
// relation to the current zoom
bool m_opengl_supports_raytracing;
bool m_render_raytracing_was_requested;
@@ -321,9 +279,6 @@ private:
BOARD_ITEM* m_currentRollOverItem;
bool m_render3dmousePivot = false; // Render the 3dmouse pivot
SFVEC3F m_3dmousePivotPos; // The position of the 3dmouse pivot
/**
* 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
+1 -42
View File
@@ -73,7 +73,7 @@ static void pivot_render_triangles( float t )
}
void EDA_3D_CANVAS::render_pivot( float t, float aScale )
void EDA_3D_CANVAS::render_pivot( float t , float aScale )
{
wxASSERT( aScale >= 0.0f );
wxASSERT( t >= 0.0f );
@@ -118,44 +118,3 @@ void EDA_3D_CANVAS::render_pivot( float t, float aScale )
pivot_render_triangles( t * 0.5f );
glPopMatrix();
}
void EDA_3D_CANVAS::render3dmousePivot( float aScale )
{
wxASSERT( aScale >= 0.0f );
glDisable( GL_LIGHTING );
glDisable( GL_DEPTH_TEST );
glDisable( GL_CULL_FACE );
// Set projection and modelview matrixes
glMatrixMode( GL_PROJECTION );
glLoadMatrixf( glm::value_ptr( m_camera.GetProjectionMatrix() ) );
glMatrixMode( GL_MODELVIEW );
glLoadIdentity();
glLoadMatrixf( glm::value_ptr( m_camera.GetViewMatrix() ) );
glEnable( GL_COLOR_MATERIAL );
glColor4f( 0.0f, 0.667f, 0.902f, 0.75f );
// Translate to the look at position
glTranslatef( m_3dmousePivotPos.x, m_3dmousePivotPos.y, m_3dmousePivotPos.z );
glPointSize( 16.0f );
glEnable( GL_POINT_SMOOTH );
glHint( GL_POINT_SMOOTH_HINT, GL_NICEST );
glEnable( GL_BLEND );
glBlendFunc( GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA );
glScalef( aScale, aScale, aScale );
// Draw a point at the look at position.
glBegin( GL_POINTS );
glVertex3f( 0, 0, 0 );
glEnd();
glDisable( GL_BLEND );
glDisable( GL_POINT_SMOOTH );
}
+59 -35
View File
@@ -30,6 +30,52 @@
#ifndef _3D_ENUMS_H_
#define _3D_ENUMS_H_
/// Flags used in rendering options
enum DISPLAY3D_FLG
{
FL_AXIS = 0,
FL_ZONE,
FL_ADHESIVE,
FL_SILKSCREEN,
FL_SOLDERMASK,
FL_SOLDERPASTE,
FL_COMMENTS,
FL_ECO,
FL_FP_ATTRIBUTES_NORMAL,
FL_FP_ATTRIBUTES_NORMAL_INSERT,
FL_FP_ATTRIBUTES_VIRTUAL,
FL_USE_SELECTION,
FL_HIGHLIGHT_ROLLOVER_ITEM,
FL_SHOW_BOARD_BODY,
FL_MOUSEWHEEL_PANNING,
FL_USE_REALISTIC_MODE,
FL_SUBTRACT_MASK_FROM_SILK,
FL_CLIP_SILK_ON_VIA_ANNULUS,
FL_RENDER_PLATED_PADS_AS_PLATED,
// OpenGL options
FL_RENDER_OPENGL_SHOW_MODEL_BBOX,
FL_RENDER_OPENGL_COPPER_THICKNESS,
FL_RENDER_OPENGL_AA_DISABLE_ON_MOVE,
FL_RENDER_OPENGL_THICKNESS_DISABLE_ON_MOVE,
FL_RENDER_OPENGL_VIAS_DISABLE_ON_MOVE,
FL_RENDER_OPENGL_HOLES_DISABLE_ON_MOVE,
// Raytracing options
FL_RENDER_RAYTRACING_SHADOWS,
FL_RENDER_RAYTRACING_BACKFLOOR,
FL_RENDER_RAYTRACING_REFRACTIONS,
FL_RENDER_RAYTRACING_REFLECTIONS,
FL_RENDER_RAYTRACING_POST_PROCESSING,
FL_RENDER_RAYTRACING_ANTI_ALIASING,
FL_RENDER_RAYTRACING_PROCEDURAL_TEXTURES,
FL_LAST
};
/// Rotation direction for the 3d canvas
enum class ROTATION_DIR
{
@@ -41,61 +87,39 @@ enum class ROTATION_DIR
Z_CCW
};
/// Camera types
enum class CAMERA_TYPE
{
TRACKBALL
};
// Do not modify the following enum numbers, they are saved in the config file and used in the UI
/// Grid types
enum class GRID3D_TYPE
{
NONE = 0,
GRID_1MM = 1,
GRID_2P5MM = 2,
GRID_5MM = 3,
GRID_10MM = 4
NONE,
GRID_1MM,
GRID_2P5MM,
GRID_5MM,
GRID_10MM
};
/// Render engine mode
enum class RENDER_ENGINE
{
OPENGL = 0,
RAYTRACING = 1,
OPENGL,
RAYTRACING,
};
/// Render 3d model shape materials mode
enum class MATERIAL_MODE
{
NORMAL = 0, ///< Use all material properties from model file
DIFFUSE_ONLY = 1, ///< Use only diffuse material properties
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
NORMAL, ///< Use all material properties from model file
DIFFUSE_ONLY, ///< Use only diffuse material properties
CAD_MODE ///< Use a gray shading based on diffuse material
};
#endif // _3D_ENUMS_H_
@@ -27,7 +27,6 @@
* 3d models that come in the original data from the files without any transformations.
*/
#include <gal/opengl/kiglew.h> // Must be included first
#include <iostream>
#include "3d_rendering/opengl/3d_model.h"
#include "eda_3d_model_viewer.h"
@@ -35,17 +34,15 @@
#include "../3d_cache/3d_cache.h"
#include <wx/dcclient.h>
#include <base_units.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 <macros.h>
#include <gal/dpi_scaling.h>
/**
* Scale conversion from 3d model units to pcb units
*/
#define UNITS3D_TO_UNITSPCB ( pcbIUScale.IU_PER_MM )
#define UNITS3D_TO_UNITSPCB (IU_PER_MM)
/**
* Trace mask used to enable or disable the trace output of this class.
@@ -87,8 +84,7 @@ END_EVENT_TABLE()
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, wxID_ANY, aAttribList,
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 )
@@ -105,7 +101,7 @@ EDA_3D_MODEL_VIEWER::EDA_3D_MODEL_VIEWER( wxWindow* aParent, const int* aAttribL
COMMON_SETTINGS* settings = Pgm().GetCommonSettings();
const DPI_SCALING_COMMON dpi{ settings, this };
const DPI_SCALING dpi{ settings, this };
SetScaleFactor( dpi.GetScaleFactor() );
}
@@ -160,7 +156,7 @@ void EDA_3D_MODEL_VIEWER::Set3DModel( const wxString& aModelPathName)
if( m_cacheManager )
{
const S3DMODEL* model = m_cacheManager->GetModel( aModelPathName, wxEmptyString );
const S3DMODEL* model = m_cacheManager->GetModel( aModelPathName );
if( model )
Set3DModel( (const S3DMODEL &)*model );
@@ -186,20 +182,6 @@ void EDA_3D_MODEL_VIEWER::Clear3DModel()
void EDA_3D_MODEL_VIEWER::ogl_initialize()
{
const GLenum err = glewInit();
if( GLEW_OK != err )
{
const wxString msgError = (const char*) glewGetErrorString( err );
wxLogMessage( msgError );
}
else
{
wxLogTrace( m_logTrace, wxT( "EDA_3D_MODEL_VIEWER::ogl_initialize Using GLEW version %s" ),
From_UTF8( (char*) glewGetString( GLEW_VERSION ) ) );
}
glHint( GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST );
glHint( GL_LINE_SMOOTH_HINT, GL_NICEST );
glHint( GL_POLYGON_SMOOTH_HINT, GL_NICEST );
@@ -259,13 +241,6 @@ void EDA_3D_MODEL_VIEWER::OnPaint( wxPaintEvent& event )
if( m_glRC == nullptr )
m_glRC = GL_CONTEXT_MANAGER::Get().CreateCtx( this );
// CreateCtx could and does fail per sentry crash events, lets be graceful
if( m_glRC == nullptr )
{
wxLogTrace( m_logTrace, wxT( "EDA_3D_MODEL_VIEWER::OnPaint creating gl context failed" ) );
return;
}
GL_CONTEXT_MANAGER::Get().LockCtx( m_glRC, this );
// Set the OpenGL viewport according to the client size of this canvas.
@@ -332,16 +307,8 @@ void EDA_3D_MODEL_VIEWER::OnPaint( wxPaintEvent& event )
m_ogl_3dmodel->BeginDrawMulti( true );
m_ogl_3dmodel->DrawOpaque( false );
glDepthMask( GL_FALSE );
glEnable( GL_BLEND );
glBlendFunc( GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA );
m_ogl_3dmodel->DrawTransparent( 1.0f, false );
glDisable( GL_BLEND );
glDepthMask( GL_TRUE );
m_ogl_3dmodel->EndDrawMulti();
glPopMatrix();
@@ -402,16 +369,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
-25
View File
@@ -1,25 +0,0 @@
add_library(3d-viewer_navlib STATIC
"nl_3d_viewer_plugin.cpp"
"nl_3d_viewer_plugin_impl.cpp"
)
# 3d-viewer_navlib depends on make_lexer outputs in common
add_dependencies( 3d-viewer_navlib pcbcommon )
# Find the 3DxWare SDK component 3DxWare::NlClient
# find_package(TDxWare_SDK 4.0 REQUIRED COMPONENTS 3DxWare::Navlib)
target_compile_definitions(3d-viewer_navlib PRIVATE
$<TARGET_PROPERTY:3DxWare::Navlib,INTERFACE_COMPILE_DEFINITIONS>
)
target_compile_options(3d-viewer_navlib PRIVATE
$<TARGET_PROPERTY:3DxWare::Navlib,INTERFACE_COMPILE_OPTIONS>
)
target_include_directories(3d-viewer_navlib PRIVATE
$<TARGET_PROPERTY:3DxWare::Navlib,INTERFACE_INCLUDE_DIRECTORIES>
$<TARGET_PROPERTY:pcbnew_kiface_objects,INCLUDE_DIRECTORIES>
)
target_link_libraries(3d-viewer_navlib
$<TARGET_PROPERTY:3DxWare::Navlib,INTERFACE_LINK_LIBRARIES>
3DxWare::Navlib
)
@@ -1,48 +0,0 @@
/*
* This program source code file is part of KiCad, a free EDA CAD application.
*
* Copyright (C) 2021 3Dconnexion
* 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 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 "nl_3d_viewer_plugin.h"
#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 )
{
if( ADVANCED_CFG::GetCfg().m_Use3DConnexionDriver
&& KIPLATFORM::DRIVERS::Valid3DConnexionDriverVersion() )
{
m_impl = new NL_3D_VIEWER_PLUGIN_IMPL( aViewport );
}
}
NL_3D_VIEWER_PLUGIN::~NL_3D_VIEWER_PLUGIN()
{
delete m_impl;
}
void NL_3D_VIEWER_PLUGIN::SetFocus( bool focus )
{
if( m_impl )
m_impl->SetFocus( focus );
}
-60
View File
@@ -1,60 +0,0 @@
/*
* This program source code file is part of KiCad, a free EDA CAD application.
*
* Copyright (C) 2021 3Dconnexion
* 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 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 nl_3d_viewer_plugin.h
* @brief Declaration of the NL_3D_VIEWER_PLUGIN class
*/
#ifndef NL_3D_VIEWER_PLUGIN_H_
#define NL_3D_VIEWER_PLUGIN_H_
// Forward declarations.
class EDA_3D_CANVAS;
class NL_3D_VIEWER_PLUGIN_IMPL;
/**
* The class that implements the public interface to the SpaceMouse plug-in.
*/
class NL_3D_VIEWER_PLUGIN
{
public:
/**
* Initializes a new instance of the NL_3D_VIEWER_PLUGIN.
*
* @param aViewport is the viewport to be navigated.
*/
NL_3D_VIEWER_PLUGIN( EDA_3D_CANVAS* aViewport );
virtual ~NL_3D_VIEWER_PLUGIN();
/**
* Set the connection to the 3Dconnexion driver to the focus state so that
* 3DMouse data is routed here.
*
* @param aFocus is true to set the connection active.
*/
void SetFocus( bool aFocus = true );
private:
NL_3D_VIEWER_PLUGIN_IMPL* m_impl;
};
#endif // NL_3D_VIEWER_PLUGIN_H_
@@ -1,662 +0,0 @@
/*
* This program source code file is part of KiCad, a free EDA CAD application.
*
* Copyright (C) 2021 3Dconnexion
* 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 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 "nl_3d_viewer_plugin_impl.h"
// 3d-viewer
#include <3d-viewer/3d_rendering/track_ball.h>
#include <3d-viewer/3d_canvas/eda_3d_canvas.h>
// KiCAD includes
#include <tool/action_manager.h>
#include <tool/tool_manager.h>
// stdlib
#include <map>
#include <string>
#include <vector>
#include <wx/mstream.h>
/**
* Flag to enable the NL_3D_VIEWER_PLUGIN debug tracing.
*
* Use "KI_TRACE_NL_3D_VIEWER_PLUGIN" to enable.
*
* @ingroup trace_env_vars
*/
const wxChar* NL_3D_VIEWER_PLUGIN_IMPL::m_logTrace = wxT( "KI_TRACE_NL_3D_VIEWER_PLUGIN" );
/**
* Template to compare two glm::mat<T> values for equality within a required epsilon.
*
* @param aFirst value to compare.
* @param aSecond value to compare.
* @param aEpsilon allowed error.
* @return true if the values considered equal within the specified epsilon, otherwise false.
*/
template <glm::length_t L, glm::length_t C, class T, glm::qualifier Q>
bool equals( glm::mat<L, C, T, Q> const& aFirst, glm::mat<L, C, T, Q> const& aSecond,
T aEpsilon = static_cast<T>( FLT_EPSILON * 10 ) )
{
T const* first = glm::value_ptr( aFirst );
T const* second = glm::value_ptr( aSecond );
for( glm::length_t j = 0; j < L * C; ++j )
{
if( !equals( first[j], second[j], aEpsilon ) )
{
return false;
}
}
return true;
}
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 )
{
m_camera = dynamic_cast<TRACK_BALL*>( m_canvas->GetCamera() );
PutProfileHint( "KiCAD 3D" );
EnableNavigation( true );
PutFrameTimingSource( TimingSource::SpaceMouse );
exportCommandsAndImages();
}
NL_3D_VIEWER_PLUGIN_IMPL::~NL_3D_VIEWER_PLUGIN_IMPL()
{
EnableNavigation( false );
}
void NL_3D_VIEWER_PLUGIN_IMPL::SetFocus( bool aFocus )
{
wxLogTrace( m_logTrace, wxT( "NL_3D_VIEWER_PLUGIN_IMPL::SetFocus %d" ), aFocus );
NAV_3D::Write( navlib::focus_k, aFocus );
}
// temporary store for the categories
typedef std::map<std::string, TDx::CCommandTreeNode*> CATEGORY_STORE;
/**
* Add a category to the store.
*
* The function adds category paths of the format "A.B" where B is a sub-category of A.
*
* @param aCategoryPath is the std::string representation of the category.
* @param aCategoryStore is the CATEGORY_STORE instance to add to.
* @return a CATEGORY_STORE::iterator where the category was added.
*/
CATEGORY_STORE::iterator add_category( std::string aCategoryPath, CATEGORY_STORE& aCategoryStore )
{
using TDx::SpaceMouse::CCategory;
CATEGORY_STORE::iterator parent_iter = aCategoryStore.begin();
std::string::size_type pos = aCategoryPath.find_last_of( '.' );
if( pos != std::string::npos )
{
std::string parentPath = aCategoryPath.substr( 0, pos );
parent_iter = aCategoryStore.find( parentPath );
if( parent_iter == aCategoryStore.end() )
{
parent_iter = add_category( parentPath, aCategoryStore );
}
}
std::string name = aCategoryPath.substr( pos + 1 );
std::unique_ptr<CCategory> categoryNode =
std::make_unique<CCategory>( aCategoryPath.c_str(), name.c_str() );
CATEGORY_STORE::iterator iter = aCategoryStore.insert(
aCategoryStore.end(), CATEGORY_STORE::value_type( aCategoryPath, categoryNode.get() ) );
parent_iter->second->push_back( std::move( categoryNode ) );
return iter;
}
void NL_3D_VIEWER_PLUGIN_IMPL::exportCommandsAndImages()
{
wxLogTrace( m_logTrace, wxT( "NL_3D_VIEWER_PLUGIN_IMPL::exportCommandsAndImages" ) );
std::list<TOOL_ACTION*> actions = ACTION_MANAGER::GetActionList();
if( actions.size() == 0 )
{
return;
}
using TDx::SpaceMouse::CCommand;
using TDx::SpaceMouse::CCommandSet;
// The root action set node
CCommandSet commandSet( "EDA_3D_CANVAS", "3D Viewer" );
// Activate the command set
NAV_3D::PutActiveCommands( commandSet.GetId() );
// temporary store for the categories
CATEGORY_STORE categoryStore;
std::vector<TDx::CImage> vImages;
// add the action set to the category_store
categoryStore.insert( categoryStore.end(), CATEGORY_STORE::value_type( ".", &commandSet ) );
std::list<TOOL_ACTION*>::const_iterator it;
for( it = actions.begin(); it != actions.end(); ++it )
{
const TOOL_ACTION* action = *it;
std::string label = action->GetMenuLabel().ToStdString();
if( label.empty() )
{
continue;
}
std::string name = action->GetName();
// Do no export commands for the pcbnew app.
if( name.rfind( "pcbnew.", 0 ) == 0 )
{
continue;
}
std::string strCategory = action->GetToolName();
CATEGORY_STORE::iterator iter = categoryStore.find( strCategory );
if( iter == categoryStore.end() )
{
iter = add_category( std::move( strCategory ), categoryStore );
}
std::string description = action->GetDescription().ToStdString();
// Arbitrary 8-bit data stream
wxMemoryOutputStream imageStream;
if( action->GetIcon() != BITMAPS::INVALID_BITMAP )
{
wxImage image = KiBitmap( action->GetIcon() ).ConvertToImage();
image.SaveFile( imageStream, wxBitmapType::wxBITMAP_TYPE_PNG );
image.Destroy();
if( imageStream.GetSize() )
{
wxStreamBuffer* streamBuffer = imageStream.GetOutputStreamBuffer();
TDx::CImage tdxImage = TDx::CImage::FromData( "", 0, name.c_str() );
tdxImage.AssignImage( std::string( reinterpret_cast<const char*>(
streamBuffer->GetBufferStart() ),
streamBuffer->GetBufferSize() ),
0 );
wxLogTrace( m_logTrace, wxT( "Adding image for : %s" ), name );
vImages.push_back( std::move( tdxImage ) );
}
}
wxLogTrace( m_logTrace, wxT( "Inserting command: %s, description: %s, in category: %s" ),
name, description, iter->first );
iter->second->push_back(
CCommand( std::move( name ), std::move( label ), std::move( description ) ) );
}
NAV_3D::AddCommandSet( commandSet );
NAV_3D::AddImages( vImages );
}
long NL_3D_VIEWER_PLUGIN_IMPL::GetCameraMatrix( navlib::matrix_t& matrix ) const
{
// cache the camera matrix so that we can tell if the view has been moved and
// calculate a delta transform if required.
m_cameraMatrix = m_camera->GetViewMatrix();
std::copy_n( glm::value_ptr( glm::inverse( m_cameraMatrix ) ), 16, matrix.m );
return 0;
}
long NL_3D_VIEWER_PLUGIN_IMPL::GetPointerPosition( navlib::point_t& position ) const
{
SFVEC3F origin, direction;
m_camera->MakeRayAtCurrentMousePosition( origin, direction );
position = { origin.x, origin.y, origin.z };
return 0;
}
long NL_3D_VIEWER_PLUGIN_IMPL::GetViewExtents( navlib::box_t& extents ) const
{
if( m_camera->GetProjection() == PROJECTION_TYPE::PERSPECTIVE )
{
return navlib::make_result_code( navlib::navlib_errc::invalid_operation );
}
const CAMERA_FRUSTUM& f = m_camera->GetFrustum();
double half_width = f.fw / 2.;
double half_height = f.fh / 2.;
extents = { -half_width, -half_height, f.nearD, half_width, half_height, f.farD };
return 0;
}
long NL_3D_VIEWER_PLUGIN_IMPL::GetViewFOV( double& aFov ) const
{
const CAMERA_FRUSTUM& f = m_camera->GetFrustum();
aFov = glm::radians( f.angle );
return 0;
}
long NL_3D_VIEWER_PLUGIN_IMPL::GetViewFrustum( navlib::frustum_t& aFrustum ) const
{
if( m_camera->GetProjection() != PROJECTION_TYPE::PERSPECTIVE )
{
return navlib::make_result_code( navlib::navlib_errc::invalid_operation );
}
const CAMERA_FRUSTUM& f = m_camera->GetFrustum();
double half_width = f.nw / 2.;
double half_height = f.nh / 2.;
aFrustum = { -half_width, half_width, -half_height, half_height, f.nearD, f.farD };
return 0;
}
long NL_3D_VIEWER_PLUGIN_IMPL::GetIsViewPerspective( navlib::bool_t& perspective ) const
{
perspective = m_camera->GetProjection() == PROJECTION_TYPE::PERSPECTIVE ? 1 : 0;
return 0;
}
long NL_3D_VIEWER_PLUGIN_IMPL::SetCameraMatrix( const navlib::matrix_t& aCameraMatrix )
{
long result = 0;
glm::mat4 cam, viewMatrix;
std::copy_n( aCameraMatrix.m, 16, glm::value_ptr( cam ) );
viewMatrix = glm::inverse( cam );
glm::mat4 camera = m_camera->GetViewMatrix();
// The navlib does not move the camera in its z-axis in an orthographic projection
// as this does not change the viewed object size. However ...
if( m_camera->GetProjection() == PROJECTION_TYPE::ORTHO )
{
// ... the CAMERA class couples zoom and distance to the object: we need to
// ensure that The CAMERA's z position relative to the lookat_pos is not changed
// in an orthographic projection.
glm::vec4 lookat( m_camera->GetLookAtPos(), 1.0f );
glm::vec4 lookat_new = viewMatrix * lookat;
glm::vec4 lookat_old = camera * lookat;
viewMatrix[3].z += lookat_old.z - lookat_new.z;
}
if( !equals( camera, m_cameraMatrix ) )
{
// Some other input device has moved the camera. Apply only the intended delta
// transform ...
m_camera->SetViewMatrix( viewMatrix * glm::inverse( m_cameraMatrix ) * camera );
m_camera->Update();
// .., cache the intended camera matrix so that we can calculate the delta
// transform when needed ...
m_cameraMatrix = viewMatrix;
// ... and let the 3DMouse controller know, that something is amiss.
return navlib::make_result_code( navlib::navlib_errc::error );
}
m_camera->SetViewMatrix( viewMatrix );
m_camera->Update();
// cache the view matrix so that we know when it has changed.
m_cameraMatrix = m_camera->GetViewMatrix();
// The camera has a constraint on the z position so we need to check that ...
if( !equals( m_cameraMatrix[3].z, viewMatrix[3].z ) )
{
// ... and let the 3DMouse controller know, when something is amiss.
return navlib::make_result_code( navlib::navlib_errc::error );
}
return 0;
}
long NL_3D_VIEWER_PLUGIN_IMPL::SetViewExtents( const navlib::box_t& extents )
{
const CAMERA_FRUSTUM& f = m_camera->GetFrustum();
float factor = f.nw / ( extents.max_x - extents.min_x );
float zoom = m_camera->GetZoom() / factor;
m_camera->Zoom( factor );
// The camera auto positions the camera to match the zoom values. We need to
// update our cached camera matrix to match the new z value
m_cameraMatrix[3].z = m_camera->GetViewMatrix()[3].z;
// The camera has a constraint on the zoom factor so we need to check that ...
if( zoom != m_camera->GetZoom() )
{
// ... and let the 3DMouse controller know, when something is amiss.
return navlib::make_result_code( navlib::navlib_errc::error );
}
return 0;
}
long NL_3D_VIEWER_PLUGIN_IMPL::SetViewFOV( double fov )
{
return navlib::make_result_code( navlib::navlib_errc::function_not_supported );
}
long NL_3D_VIEWER_PLUGIN_IMPL::SetViewFrustum( const navlib::frustum_t& frustum )
{
return navlib::make_result_code( navlib::navlib_errc::permission_denied );
}
long NL_3D_VIEWER_PLUGIN_IMPL::GetModelExtents( navlib::box_t& extents ) const
{
SFVEC3F min = m_canvas->GetBoardAdapter().GetBBox().Min();
SFVEC3F max = m_canvas->GetBoardAdapter().GetBBox().Max();
extents = { min.x, min.y, min.z, max.x, max.y, max.z };
return 0;
}
long NL_3D_VIEWER_PLUGIN_IMPL::GetSelectionExtents( navlib::box_t& extents ) const
{
return navlib::make_result_code( navlib::navlib_errc::no_data_available );
}
long NL_3D_VIEWER_PLUGIN_IMPL::GetSelectionTransform( navlib::matrix_t& transform ) const
{
return navlib::make_result_code( navlib::navlib_errc::no_data_available );
}
long NL_3D_VIEWER_PLUGIN_IMPL::GetIsSelectionEmpty( navlib::bool_t& empty ) const
{
empty = true;
return 0;
}
long NL_3D_VIEWER_PLUGIN_IMPL::SetSelectionTransform( const navlib::matrix_t& matrix )
{
return navlib::make_result_code( navlib::navlib_errc::invalid_operation );
}
long NL_3D_VIEWER_PLUGIN_IMPL::GetPivotPosition( navlib::point_t& position ) const
{
SFVEC3F lap = m_camera->GetLookAtPos();
position = { lap.x, lap.y, lap.z };
return 0;
}
long NL_3D_VIEWER_PLUGIN_IMPL::IsUserPivot( navlib::bool_t& userPivot ) const
{
userPivot = false;
return 0;
}
long NL_3D_VIEWER_PLUGIN_IMPL::SetPivotPosition( const navlib::point_t& position )
{
SFVEC3F pivotPos = SFVEC3F( position.x, position.y, position.z );
// Set the 3dmouse pivot position.
m_canvas->Set3dmousePivotPos( pivotPos );
// Set the camera lookat pos.
m_camera->SetLookAtPos_T1( pivotPos );
m_canvas->Request_refresh();
return 0;
}
long NL_3D_VIEWER_PLUGIN_IMPL::GetPivotVisible( navlib::bool_t& visible ) const
{
visible = m_canvas->GetRender3dmousePivot();
return 0;
}
long NL_3D_VIEWER_PLUGIN_IMPL::SetPivotVisible( bool visible )
{
m_canvas->SetRender3dmousePivot( visible );
m_canvas->Request_refresh();
return 0;
}
long NL_3D_VIEWER_PLUGIN_IMPL::GetHitLookAt( navlib::point_t& position ) const
{
RAY mouseRay;
mouseRay.Init( m_rayOrigin, m_rayDirection );
float hit;
glm::vec3 vec;
// Test it with the board bounding box
if( m_canvas->GetBoardAdapter().GetBBox().Intersect( mouseRay, &hit ) )
{
vec = mouseRay.at( hit );
position = { vec.x, vec.y, vec.z };
return 0;
}
return navlib::make_result_code( navlib::navlib_errc::no_data_available );
}
long NL_3D_VIEWER_PLUGIN_IMPL::SetHitAperture( double aperture )
{
return navlib::make_result_code( navlib::navlib_errc::function_not_supported );
}
long NL_3D_VIEWER_PLUGIN_IMPL::SetHitDirection( const navlib::vector_t& direction )
{
m_rayDirection = { direction.x, direction.y, direction.z };
return 0;
}
long NL_3D_VIEWER_PLUGIN_IMPL::SetHitLookFrom( const navlib::point_t& eye )
{
m_rayOrigin = { eye.x, eye.y, eye.z };
return 0;
}
long NL_3D_VIEWER_PLUGIN_IMPL::SetHitSelectionOnly( bool onlySelection )
{
return navlib::make_result_code( navlib::navlib_errc::function_not_supported );
}
long NL_3D_VIEWER_PLUGIN_IMPL::SetActiveCommand( std::string commandId )
{
if( commandId.empty() )
{
return 0;
}
std::list<TOOL_ACTION*> actions = ACTION_MANAGER::GetActionList();
TOOL_ACTION* context = nullptr;
for( std::list<TOOL_ACTION*>::const_iterator it = actions.begin(); it != actions.end(); it++ )
{
TOOL_ACTION* action = *it;
std::string nm = action->GetName();
if( commandId == nm )
{
context = action;
}
}
if( context != nullptr )
{
wxWindow* parent = m_canvas->GetParent();
// Only allow command execution if the window is enabled. i.e. there is not a modal dialog
// currently active.
if( parent->IsEnabled() )
{
TOOL_MANAGER* tool_manager = static_cast<PCB_BASE_FRAME*>( parent )->GetToolManager();
if( tool_manager == nullptr )
{
return navlib::make_result_code( navlib::navlib_errc::invalid_operation );
}
// Get the selection to use to test if the action is enabled
SELECTION& sel = tool_manager->GetToolHolder()->GetCurrentSelection();
bool runAction = true;
if( const ACTION_CONDITIONS* aCond =
tool_manager->GetActionManager()->GetCondition( *context ) )
{
runAction = aCond->enableCondition( sel );
}
if( runAction )
{
tool_manager->RunAction( *context );
m_canvas->Request_refresh();
}
}
else
{
return navlib::make_result_code( navlib::navlib_errc::invalid_operation );
}
}
return 0;
}
long NL_3D_VIEWER_PLUGIN_IMPL::SetSettingsChanged( long change )
{
return 0;
}
long NL_3D_VIEWER_PLUGIN_IMPL::SetMotionFlag( bool value )
{
m_capIsMoving = value;
return 0;
}
long NL_3D_VIEWER_PLUGIN_IMPL::SetTransaction( long value )
{
if( value != 0L )
{
}
else
{
m_canvas->Request_refresh( true );
wxLogTrace( m_logTrace, wxT( "End of transaction" ) );
}
return 0;
}
long NL_3D_VIEWER_PLUGIN_IMPL::SetCameraTarget( const navlib::point_t& position )
{
return navlib::make_result_code( navlib::navlib_errc::function_not_supported );
}
long NL_3D_VIEWER_PLUGIN_IMPL::GetFrontView( navlib::matrix_t& matrix ) const
{
matrix = { 1, 0, 0, 0, 0, 0, 1, 0, 0, -1, 0, 0, 0, 0, 0, 1 };
return 0;
}
long NL_3D_VIEWER_PLUGIN_IMPL::GetCoordinateSystem( navlib::matrix_t& matrix ) const
{
// Use the right-handed coordinate system X-right, Z-up, Y-in (row vectors)
matrix = { 1, 0, 0, 0, 0, 0, -1, 0, 0, 1, 0, 0, 0, 0, 0, 1 };
return 0;
}
long NL_3D_VIEWER_PLUGIN_IMPL::GetIsViewRotatable( navlib::bool_t& isRotatable ) const
{
isRotatable = true;
return 0;
}
@@ -1,136 +0,0 @@
/*
* This program source code file is part of KiCad, a free EDA CAD application.
*
* Copyright (C) 2021 3Dconnexion
* 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 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 nl_3d_viewer_plugin_impl.h
* @brief Declaration of the NL_3D_VIEWER_PLUGIN_IMPL class
*/
#ifndef NL_3D_VIEWER_PLUGIN_IMPL_H_
#define NL_3D_VIEWER_PLUGIN_IMPL_H_
// TDxWare SDK.
#include <SpaceMouse/CNavigation3D.hpp>
// KiCAD
#include <include/plugins/3dapi/xv3d_types.h>
// wx
#include <wx/chartype.h>
// glm
#include <glm/glm.hpp>
// Forward declarations.
class EDA_3D_CANVAS;
class TRACK_BALL;
// Convenience typedef.
typedef TDx::SpaceMouse::Navigation3D::CNavigation3D NAV_3D;
/**
* The class that implements the accessors and mutators required for
* 3D navigation in an EDA_3D_CANVAS using a SpaceMouse.
*/
class NL_3D_VIEWER_PLUGIN_IMPL : public NAV_3D
{
public:
/**
* Initializes a new instance of the NL_3DVIEWER_PLUGIN.
*
* @param aCanvas is the viewport to be navigated.
*/
NL_3D_VIEWER_PLUGIN_IMPL( EDA_3D_CANVAS* aCanvas );
virtual ~NL_3D_VIEWER_PLUGIN_IMPL();
/**
* Set the connection to the 3Dconnexion driver to the focus state so that
* 3DMouse data is routed here.
*
* @param aFocus is true to set the connection active.
*/
void SetFocus( bool aFocus = true );
private:
/**
* Export the invocable actions and images to the 3Dconnexion UI.
*/
void exportCommandsAndImages();
long GetCameraMatrix( navlib::matrix_t& aMatrix ) const override;
long GetPointerPosition( navlib::point_t& aPosition ) const override;
long GetViewExtents( navlib::box_t& aExtents ) const override;
long GetViewFOV( double& aFov ) const override;
long GetViewFrustum( navlib::frustum_t& aFrustum ) const override;
long GetIsViewPerspective( navlib::bool_t& aPerspective ) const override;
long SetCameraMatrix( const navlib::matrix_t& aMatrix ) override;
long SetViewExtents( const navlib::box_t& aExtents ) override;
long SetViewFOV( double aFov ) override;
long SetViewFrustum( const navlib::frustum_t& aFrustum ) override;
long GetModelExtents( navlib::box_t& aExtents ) const override;
long GetSelectionExtents( navlib::box_t& aExtents ) const override;
long GetSelectionTransform( navlib::matrix_t& aTransform ) const override;
long GetIsSelectionEmpty( navlib::bool_t& aEmpty ) const override;
long SetSelectionTransform( const navlib::matrix_t& aMatrix ) override;
long GetPivotPosition( navlib::point_t& aPosition ) const override;
long IsUserPivot( navlib::bool_t& aUserPivot ) const override;
long SetPivotPosition( const navlib::point_t& aPosition ) override;
long GetPivotVisible( navlib::bool_t& aVisible ) const override;
long SetPivotVisible( bool aVisible ) override;
long GetHitLookAt( navlib::point_t& aPosition ) const override;
long SetHitAperture( double aAperture ) override;
long SetHitDirection( const navlib::vector_t& aDirection ) override;
long SetHitLookFrom( const navlib::point_t& aPosition ) override;
long SetHitSelectionOnly( bool aSelectionOnly ) override;
long SetActiveCommand( std::string aCommandId ) override;
long SetSettingsChanged( long aChangeNumber ) override;
long SetMotionFlag( bool aValue ) override;
long SetTransaction( long aValue ) override;
long SetCameraTarget( const navlib::point_t& aPosition ) override;
long GetFrontView( navlib::matrix_t& aMatrix ) const override;
long GetCoordinateSystem( navlib::matrix_t& aMatrix ) const override;
long GetIsViewRotatable( navlib::bool_t& isRotatable ) const override;
private:
EDA_3D_CANVAS* m_canvas;
TRACK_BALL* m_camera;
bool m_capIsMoving;
double m_newWidth;
SFVEC3F m_rayOrigin;
SFVEC3F m_rayDirection;
// The cached CAMERA affine matrix. This is used to determine if the camera has been
// moved. The camera matrix is the world to camera affine.
mutable glm::mat4 m_cameraMatrix;
/**
* 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
* "KI_TRACE_NL_3DVIEWER_PLUGIN". See the wxWidgets documentation on wxLogTrace for
* more information.
*/
static const wxChar* m_logTrace;
};
#endif // NL_3D_VIEWER_PLUGIN_IMPL_H_
@@ -26,9 +26,9 @@
* @file camera.cpp
*/
#include <gal/3d/camera.h>
#include "camera.h"
#include <wx/log.h>
#include <algorithm>
// A helper function to normalize aAngle between -2PI and +2PI
inline void normalise2PI( float& aAngle )
@@ -46,8 +46,9 @@ inline void normalise2PI( float& aAngle )
*/
const wxChar *CAMERA::m_logTrace = wxT( "KI_TRACE_CAMERA" );
const float CAMERA::DEFAULT_MIN_ZOOM = 0.020f;
const float CAMERA::DEFAULT_MAX_ZOOM = 2.0f;
#define DEFAULT_MIN_ZOOM 0.10f
#define DEFAULT_MAX_ZOOM 1.20f
CAMERA::CAMERA( float aInitialDistance )
@@ -120,21 +121,6 @@ void CAMERA::Reset_T1()
}
void CAMERA::SetBoardLookAtPos( const SFVEC3F& aBoardPos )
{
if( m_board_lookat_pos_init != aBoardPos )
{
m_board_lookat_pos_init = aBoardPos;
m_lookat_pos = aBoardPos;
m_parametersChanged = true;
updateViewMatrix();
updateFrustum();
}
}
void CAMERA::zoomChanged()
{
if( m_zoom < m_minZoom )
@@ -179,20 +165,12 @@ void CAMERA::updateRotationMatrix()
}
glm::mat4 CAMERA::GetRotationMatrix() const
const glm::mat4 CAMERA::GetRotationMatrix() const
{
return m_rotationMatrix * m_rotationMatrixAux;
}
void CAMERA::SetRotationMatrix( const glm::mat4& aRotation )
{
m_parametersChanged = true;
std::copy_n( glm::value_ptr( aRotation * glm::inverse( m_rotationMatrixAux ) ), 12,
glm::value_ptr( m_rotationMatrix ) );
}
void CAMERA::rebuildProjection()
{
if( ( m_windowSize.x == 0 ) || ( m_windowSize.y == 0 ) )
@@ -208,6 +186,7 @@ void CAMERA::rebuildProjection()
m_frustum.nearD = 0.10f;
// Ratio width / height of the window display
m_frustum.angle = 45.0f;
m_projectionMatrix = glm::perspective( glm::radians( m_frustum.angle ), m_frustum.ratio,
@@ -220,22 +199,19 @@ void CAMERA::rebuildProjection()
m_focalLen.x = ( (float)m_windowSize.y / (float)m_windowSize.x ) / m_frustum.tang;
m_focalLen.y = 1.0f / m_frustum.tang;
m_frustum.nh = 2.0f * m_frustum.nearD * m_frustum.tang;
m_frustum.nh = m_frustum.nearD * m_frustum.tang;
m_frustum.nw = m_frustum.nh * m_frustum.ratio;
m_frustum.fh = 2.0f * m_frustum.farD * m_frustum.tang;
m_frustum.fh = m_frustum.farD * m_frustum.tang;
m_frustum.fw = m_frustum.fh * m_frustum.ratio;
break;
case PROJECTION_TYPE::ORTHO:
// Keep the viewed plane at (m_camera_pos_init * m_zoom) the same dimensions in both projections.
m_frustum.angle = 45.0f;
m_frustum.tang = glm::tan( glm::radians( m_frustum.angle ) * 0.5f );
m_frustum.nearD = -m_frustum.farD; // Use a symmetrical clip plane for ortho projection
const float orthoReductionFactor =
glm::length( m_camera_pos_init ) * m_zoom * m_frustum.tang;
// This formula was found by trial and error
const float orthoReductionFactor = glm::length( m_camera_pos_init ) *
m_zoom * m_zoom * 0.5f;
// Initialize Projection Matrix for Orthographic View
m_projectionMatrix = glm::ortho( -m_frustum.ratio * orthoReductionFactor,
@@ -307,26 +283,21 @@ void CAMERA::updateFrustum()
* http://www.lighthouse3d.com/tutorials/view-frustum-culling/
*/
const SFVEC3F half_right_nw = m_right * m_frustum.nw * 0.5f;
const SFVEC3F half_right_fw = m_right * m_frustum.fw * 0.5f;
const SFVEC3F half_up_nh = m_up * m_frustum.nh * 0.5f;
const SFVEC3F half_up_fh = m_up * m_frustum.fh * 0.5f;
// compute the centers of the near and far planes
m_frustum.nc = m_pos - m_dir * m_frustum.nearD;
m_frustum.fc = m_pos - m_dir * m_frustum.farD;
// compute the 4 corners of the frustum on the near plane
m_frustum.ntl = m_frustum.nc + half_up_nh - half_right_nw;
m_frustum.ntr = m_frustum.nc + half_up_nh + half_right_nw;
m_frustum.nbl = m_frustum.nc - half_up_nh - half_right_nw;
m_frustum.nbr = m_frustum.nc - half_up_nh + half_right_nw;
m_frustum.ntl = m_frustum.nc + m_up * m_frustum.nh - m_right * m_frustum.nw;
m_frustum.ntr = m_frustum.nc + m_up * m_frustum.nh + m_right * m_frustum.nw;
m_frustum.nbl = m_frustum.nc - m_up * m_frustum.nh - m_right * m_frustum.nw;
m_frustum.nbr = m_frustum.nc - m_up * m_frustum.nh + m_right * m_frustum.nw;
// compute the 4 corners of the frustum on the far plane
m_frustum.ftl = m_frustum.fc + half_up_fh - half_right_fw;
m_frustum.ftr = m_frustum.fc + half_up_fh + half_right_fw;
m_frustum.fbl = m_frustum.fc - half_up_fh - half_right_fw;
m_frustum.fbr = m_frustum.fc - half_up_fh + half_right_fw;
m_frustum.ftl = m_frustum.fc + m_up * m_frustum.fh - m_right * m_frustum.fw;
m_frustum.ftr = m_frustum.fc + m_up * m_frustum.fh + m_right * m_frustum.fw;
m_frustum.fbl = m_frustum.fc - m_up * m_frustum.fh - m_right * m_frustum.fw;
m_frustum.fbr = m_frustum.fc - m_up * m_frustum.fh + m_right * m_frustum.fw;
if( ( m_windowSize.x > 0 ) && ( m_windowSize.y > 0 ) )
{
@@ -335,12 +306,16 @@ void CAMERA::updateFrustum()
m_up_nY.resize( m_windowSize.y + 1 );
// Precalc X values for camera -> ray generation
const SFVEC3F right_nw = m_right * m_frustum.nw;
for( unsigned int x = 0; x < ( (unsigned int) m_windowSize.x + 1 ); ++x )
m_right_nX[x] = half_right_nw * m_scr_nX[x];
m_right_nX[x] = right_nw * m_scr_nX[x];
// Precalc Y values for camera -> ray generation
const SFVEC3F up_nh = m_up * m_frustum.nh;
for( unsigned int y = 0; y < ( (unsigned int) m_windowSize.y + 1 ); ++y )
m_up_nY[y] = half_up_nh * m_scr_nY[y];
m_up_nY[y] = up_nh * m_scr_nY[y];
}
}
@@ -351,16 +326,18 @@ void CAMERA::MakeRay( const SFVEC2I& aWindowPos, SFVEC3F& aOutOrigin,
wxASSERT( aWindowPos.x < m_windowSize.x );
wxASSERT( aWindowPos.y < m_windowSize.y );
aOutOrigin = m_frustum.nc + m_up_nY[aWindowPos.y] + m_right_nX[aWindowPos.x];
const SFVEC3F up_plus_right = m_up_nY[aWindowPos.y] + m_right_nX[aWindowPos.x];
switch( m_projectionType )
{
default:
case PROJECTION_TYPE::PERSPECTIVE:
aOutOrigin = up_plus_right + m_frustum.nc;
aOutDirection = glm::normalize( aOutOrigin - m_pos );
break;
case PROJECTION_TYPE::ORTHO:
aOutOrigin = up_plus_right * 0.5f + m_frustum.nc;
aOutDirection = -m_dir + SFVEC3F( FLT_EPSILON );
break;
}
@@ -383,23 +360,23 @@ void CAMERA::MakeRay( const SFVEC2F& aWindowPos, SFVEC3F& aOutOrigin,
m_right_nX[floorWinPos_i.x] * (1.0f - relativeWinPos.x) +
m_right_nX[floorWinPos_i.x + 1] * relativeWinPos.x;
aOutOrigin = up_plus_right + m_frustum.nc;
switch( m_projectionType )
{
default:
case PROJECTION_TYPE::PERSPECTIVE:
aOutOrigin = up_plus_right + m_frustum.nc;
aOutDirection = glm::normalize( aOutOrigin - m_pos );
break;
case PROJECTION_TYPE::ORTHO:
aOutOrigin = up_plus_right * 0.5f + m_frustum.nc;
aOutDirection = -m_dir + SFVEC3F( FLT_EPSILON );
break;
}
}
void CAMERA::MakeRayAtCurrentMousePosition( SFVEC3F& aOutOrigin, SFVEC3F& aOutDirection ) const
void CAMERA::MakeRayAtCurrrentMousePosition( SFVEC3F& aOutOrigin, SFVEC3F& aOutDirection ) const
{
const SFVEC2I windowPos = SFVEC2I( m_lastPosition.x, m_windowSize.y - m_lastPosition.y );
@@ -453,38 +430,6 @@ const glm::mat4& CAMERA::GetViewMatrix() const
}
void CAMERA::SetViewMatrix( glm::mat4 aViewMatrix )
{
SetRotationMatrix( aViewMatrix );
// The look at position in the view frame.
glm::vec4 lookat = aViewMatrix * glm::vec4( m_lookat_pos, 1.0f );
wxLogTrace( m_logTrace,
wxT( "CAMERA::SetViewMatrix aViewMatrix[3].z =%f, old_zoom=%f, new_zoom=%f, "
"m[3].z=%f" ),
aViewMatrix[3].z, m_zoom, lookat.z / m_camera_pos_init.z, lookat.z );
m_zoom = lookat.z / m_camera_pos_init.z;
if( m_zoom > m_maxZoom )
{
m_zoom = m_maxZoom;
aViewMatrix[3].z += -lookat.z + m_maxZoom * m_camera_pos_init.z;
}
else if( m_zoom < m_minZoom )
{
m_zoom = m_minZoom;
aViewMatrix[3].z += -lookat.z + m_minZoom * m_camera_pos_init.z;
}
m_viewMatrix = std::move( aViewMatrix );
m_camera_pos = m_viewMatrix
* glm::inverse( m_rotationMatrix * m_rotationMatrixAux
* glm::translate( glm::mat4( 1.0f ), -m_lookat_pos ) )[3];
}
const glm::mat4& CAMERA::GetViewMatrix_Inv() const
{
return m_viewMatrixInverse;
@@ -534,41 +479,24 @@ void CAMERA::ZoomReset()
rebuildProjection();
}
bool CAMERA::Zoom( float aFactor )
{
if( ( m_zoom <= m_minZoom && aFactor > 1 ) || ( m_zoom >= m_maxZoom && aFactor < 1 )
if( ( m_zoom == m_minZoom && aFactor > 1 ) || ( m_zoom == m_maxZoom && aFactor < 1 )
|| aFactor == 1 )
{
return false;
}
float zoom = m_zoom;
m_zoom /= aFactor;
if( m_zoom <= m_minZoom && aFactor > 1 )
{
aFactor = zoom / m_minZoom;
m_zoom = m_minZoom;
}
else if( m_zoom >= m_maxZoom && aFactor < 1 )
{
aFactor = zoom / m_maxZoom;
m_zoom = m_maxZoom;
}
m_camera_pos.z /= aFactor;
updateViewMatrix();
rebuildProjection();
zoomChanged();
return true;
}
bool CAMERA::Zoom_T1( float aFactor )
{
if( ( m_zoom <= m_minZoom && aFactor > 1 ) || ( m_zoom >= m_maxZoom && aFactor < 1 )
if( ( m_zoom == m_minZoom && aFactor > 1 ) || ( m_zoom == m_maxZoom && aFactor < 1 )
|| aFactor == 1 )
{
return false;
@@ -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-2023 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,8 +30,7 @@
#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>
@@ -59,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 )
{
}
};
@@ -98,12 +74,9 @@ 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;
static const float DEFAULT_MAX_ZOOM;
/**
* Initialize a camera.
*
@@ -120,7 +93,7 @@ public:
*
* @return the rotation matrix of the camera
*/
glm::mat4 GetRotationMatrix() const;
const glm::mat4 GetRotationMatrix() const;
const glm::mat4& GetViewMatrix() const;
const glm::mat4& GetViewMatrix_Inv() const;
@@ -135,27 +108,17 @@ public:
const SFVEC2F& GetFocalLen() const { return m_focalLen; }
float GetNear() const { return m_frustum.nearD; }
float GetFar() const { return m_frustum.farD; }
const CAMERA_FRUSTUM& GetFrustum() const { return m_frustum; }
const SFVEC3F& GetLookAtPos() const { return m_lookat_pos; }
/**
* Set the rotation matrix to be applied in a transformation camera, without
* making any new calculations on camera.
*
* @param aRotation is the total rotation matrix of the camera.
*/
void SetRotationMatrix( const glm::mat4& aRotation );
void SetBoardLookAtPos( const SFVEC3F& aBoardPos )
{
if( m_board_lookat_pos_init != aBoardPos )
{
m_board_lookat_pos_init = aBoardPos;
SetLookAtPos( aBoardPos );
}
}
/**
* Set the affine matrix to be applied to a transformation camera.
*
* @param aViewMatrix is the affine matrix of the camera. The affine matrix
* maps coordinates in the world frame to those in the
* camera frame.
*/
void SetViewMatrix( glm::mat4 aViewMatrix );
void SetBoardLookAtPos( const SFVEC3F& aBoardPos );
virtual void SetLookAtPos( const SFVEC3F& aLookAtPos ) = 0;
void SetLookAtPos_T1( const SFVEC3F& aLookAtPos )
{
@@ -189,11 +152,6 @@ public:
void ResetXYpos();
void ResetXYpos_T1();
/**
* Get the current mouse position.
*/
const wxPoint& GetCurMousePosition() { return m_lastPosition; }
/**
* Update the current mouse position without make any new calculations on camera.
*/
@@ -292,12 +250,7 @@ public:
* @param aOutOrigin out origin position of the ray.
* @param aOutDirection out direction.
*/
void MakeRayAtCurrentMousePosition( SFVEC3F& aOutOrigin, SFVEC3F& aOutDirection ) const;
/**
* Update the camera.
*/
void Update() { updateFrustum(); }
void MakeRayAtCurrrentMousePosition( SFVEC3F& aOutOrigin, SFVEC3F& aOutDirection ) const;
protected:
void zoomChanged();
+45 -122
View File
@@ -24,16 +24,16 @@
*/
/**
* @file 3d_model.cpp
* @file c_ogl_3dmodel.cpp
* @brief
*/
#include <algorithm>
#include <stdexcept>
#include <gal/opengl/kiglew.h> // Must be included first
#include "3d_model.h"
#include "opengl_utils.h"
#include "../common_ogl/ogl_utils.h"
#include "../3d_math.h"
#include <utility>
#include <wx/debug.h>
#include <wx/log.h>
#include <chrono>
@@ -149,25 +149,24 @@ MODEL_3D::MODEL_3D( const S3DMODEL& a3DModel, MATERIAL_MODE aMaterialMode )
for( unsigned int mesh_i = 0; mesh_i < a3DModel.m_MeshesSize; ++mesh_i )
{
const SMESH& mesh = a3DModel.m_Meshes[mesh_i];
const auto& mesh = a3DModel.m_Meshes[mesh_i];
// silently ignore meshes that have invalid material references or invalid geometry.
if( mesh.m_MaterialIdx >= m_materials.size()
|| mesh.m_Positions == nullptr
|| mesh.m_FaceIdx == nullptr
|| mesh.m_Normals == nullptr
|| mesh.m_FaceIdxSize == 0
|| mesh.m_VertexSize == 0 )
{
continue;
}
|| mesh.m_Positions == nullptr
|| mesh.m_FaceIdx == nullptr
|| mesh.m_Normals == nullptr
|| mesh.m_FaceIdxSize == 0
|| mesh.m_VertexSize == 0 )
continue;
MESH_GROUP& mesh_group = mesh_groups[mesh.m_MaterialIdx];
MATERIAL& material = m_materials[mesh.m_MaterialIdx];
auto& mesh_group = mesh_groups[mesh.m_MaterialIdx];
auto& material = m_materials[mesh.m_MaterialIdx];
if( material.IsTransparent() && m_materialMode != MATERIAL_MODE::DIFFUSE_ONLY )
if( material.IsTransparent()
&& m_materialMode != MATERIAL_MODE::DIFFUSE_ONLY )
m_have_transparent_meshes = true;
else
else
m_have_opaque_meshes = true;
const unsigned int vtx_offset = mesh_group.m_vertices.size();
@@ -177,20 +176,19 @@ MODEL_3D::MODEL_3D( const S3DMODEL& a3DModel, MATERIAL_MODE aMaterialMode )
// use material color for mesh bounding box or some sort of average vertex color.
glm::vec3 avg_color = material.m_Diffuse;
BBOX_3D &mesh_bbox = m_meshes_bbox[mesh_i];
for( unsigned int vtx_i = 0; vtx_i < mesh.m_VertexSize; ++vtx_i )
{
mesh_bbox.Union( mesh.m_Positions[vtx_i] );
m_meshes_bbox[mesh_i].Union( mesh.m_Positions[vtx_i] );
VERTEX& vtx_out = mesh_group.m_vertices[vtx_offset + vtx_i];
auto& vtx_out = mesh_group.m_vertices[vtx_offset + vtx_i];
vtx_out.m_pos = mesh.m_Positions[vtx_i];
vtx_out.m_nrm = glm::clamp( glm::vec4( mesh.m_Normals[vtx_i], 1.0f ) * 127.0f,
-127.0f, 127.0f );
vtx_out.m_tex_uv = mesh.m_Texcoords != nullptr ? mesh.m_Texcoords[vtx_i]
: glm::vec2 (0);
vtx_out.m_tex_uv = mesh.m_Texcoords != nullptr
? mesh.m_Texcoords[vtx_i]
: glm::vec2 (0);
if( mesh.m_Color != nullptr )
{
@@ -224,19 +222,16 @@ MODEL_3D::MODEL_3D( const S3DMODEL& a3DModel, MATERIAL_MODE aMaterialMode )
}
}
if( mesh_bbox.IsInitialized() )
if( m_meshes_bbox[mesh_i].IsInitialized() )
{
// generate geometry for the bounding box
MakeBbox( mesh_bbox, ( mesh_i + 1 ) * bbox_vtx_count,
MakeBbox( m_meshes_bbox[mesh_i], ( mesh_i + 1 ) * bbox_vtx_count,
&bbox_tmp_vertices[( mesh_i + 1 ) * bbox_vtx_count],
&bbox_tmp_indices[( mesh_i + 1 ) * bbox_idx_count],
{ avg_color, 1.0f } );
// bump the outer bounding box
m_model_bbox.Union( mesh_bbox );
// add to the material group
material.m_bbox.Union( mesh_bbox );
m_model_bbox.Union( m_meshes_bbox[mesh_i] );
}
@@ -304,7 +299,7 @@ MODEL_3D::MODEL_3D( const S3DMODEL& a3DModel, MATERIAL_MODE aMaterialMode )
unsigned int total_vertex_count = 0;
unsigned int total_index_count = 0;
for( const MESH_GROUP& mg : mesh_groups )
for( auto& mg : mesh_groups )
{
total_vertex_count += mg.m_vertices.size();
total_index_count += mg.m_indices.size();
@@ -332,7 +327,8 @@ MODEL_3D::MODEL_3D( const S3DMODEL& a3DModel, MATERIAL_MODE aMaterialMode )
// temporary index buffer which will contain either GLushort or GLuint
// type indices. allocate with a bit of meadow at the end.
auto tmp_idx = std::make_unique<GLuint[]>( ( idx_size * total_index_count + 8 ) / sizeof( GLuint ) );
auto tmp_idx = std::make_unique<GLuint[]>(
( idx_size * total_index_count + 8 ) / sizeof( GLuint ) );
unsigned int prev_vtx_count = 0;
unsigned int idx_offset = 0;
@@ -340,22 +336,23 @@ MODEL_3D::MODEL_3D( const S3DMODEL& a3DModel, MATERIAL_MODE aMaterialMode )
for( unsigned int mg_i = 0; mg_i < mesh_groups.size (); ++mg_i )
{
MESH_GROUP& mg = mesh_groups[mg_i];
MATERIAL& mat = m_materials[mg_i];
uintptr_t tmp_idx_ptr = reinterpret_cast<uintptr_t>( tmp_idx.get() );
auto& mg = mesh_groups[mg_i];
auto& mat = m_materials[mg_i];
if( m_index_buffer_type == GL_UNSIGNED_SHORT )
{
GLushort* idx_out = reinterpret_cast<GLushort*>( tmp_idx_ptr + idx_offset );
auto idx_out = reinterpret_cast<GLushort*>(
reinterpret_cast<uintptr_t>( tmp_idx.get() ) + idx_offset );
for( GLuint idx : mg.m_indices )
for( auto idx : mg.m_indices )
*idx_out++ = static_cast<GLushort>( idx + prev_vtx_count );
}
else if( m_index_buffer_type == GL_UNSIGNED_INT )
{
GLuint* idx_out = reinterpret_cast<GLuint*>( tmp_idx_ptr + idx_offset );
auto idx_out = reinterpret_cast<GLuint*>(
reinterpret_cast<uintptr_t>( tmp_idx.get() ) + idx_offset );
for( GLuint idx : mg.m_indices )
for( auto idx : mg.m_indices )
*idx_out++ = static_cast<GLuint>( idx + prev_vtx_count );
}
@@ -415,9 +412,7 @@ void MODEL_3D::EndDrawMulti()
void MODEL_3D::Draw( bool aTransparent, float aOpacity, bool aUseSelectedMaterial,
const SFVEC3F& aSelectionColor,
const glm::mat4 *aModelWorldMatrix,
const SFVEC3F *aCameraWorldPos ) const
SFVEC3F& aSelectionColor ) const
{
if( aOpacity <= FLT_EPSILON )
return;
@@ -446,100 +441,28 @@ 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 )
// BeginDrawMulti();
for( const MODEL_3D::MATERIAL& mat : m_materials )
{
// Sort Material groups
std::vector<std::pair<const MODEL_3D::MATERIAL*, float>> materialsSorted;
// Calculate the distance to the camera for each material group
for( const MODEL_3D::MATERIAL& mat : m_materials )
{
if( mat.m_render_idx_count == 0 )
{
continue;
}
if( ( mat.IsTransparent() != aTransparent )
if( ( mat.IsTransparent() != aTransparent )
&& ( aOpacity >= 1.0f )
&& m_materialMode != MATERIAL_MODE::DIFFUSE_ONLY )
{
continue;
}
const BBOX_3D& bBox = mat.m_bbox;
const SFVEC3F& bBoxCenter = bBox.GetCenter();
const SFVEC3F bBoxWorld = *aModelWorldMatrix * glm::vec4( bBoxCenter, 1.0f );
const float distanceToCamera = glm::length( *aCameraWorldPos - bBoxWorld );
materialsSorted.emplace_back( &mat, distanceToCamera );
}
// 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 );
// If A is inside B, then A is rendered first
if( aInsideB != bInsideA )
return bInsideA;
if( a.second != b.second )
return a.second > b.second;
return a.first > b.first; // compare pointers as a last resort
} );
for( const std::pair<const MODEL_3D::MATERIAL*, float>& mat : materialsSorted )
{
materialsToRender.push_back( mat.first );
continue;
}
}
else
{
for( const MODEL_3D::MATERIAL& mat : m_materials )
{
// There is at least one default material created in case a mesh has no declared materials.
// Most meshes have a material, so usually the first material will have nothing to render and is skip.
// See S3D::GetModel for more details.
if( mat.m_render_idx_count == 0 )
{
continue;
}
if( ( mat.IsTransparent() != aTransparent )
&& ( aOpacity >= 1.0f )
&& m_materialMode != MATERIAL_MODE::DIFFUSE_ONLY )
{
continue;
}
materialsToRender.push_back( &mat );
}
}
for( const MODEL_3D::MATERIAL* mat : materialsToRender )
{
switch( m_materialMode )
{
case MATERIAL_MODE::NORMAL:
OglSetMaterial( *mat, aOpacity, aUseSelectedMaterial, aSelectionColor );
OglSetMaterial( mat, aOpacity, aUseSelectedMaterial, aSelectionColor );
break;
case MATERIAL_MODE::DIFFUSE_ONLY:
OglSetDiffuseMaterial( mat->m_Diffuse, aOpacity, aUseSelectedMaterial, aSelectionColor );
OglSetDiffuseMaterial( mat.m_Diffuse, aOpacity, aUseSelectedMaterial, aSelectionColor );
break;
case MATERIAL_MODE::CAD_MODE:
OglSetDiffuseMaterial( MaterialDiffuseToColorCAD( mat->m_Diffuse ), aOpacity,
OglSetDiffuseMaterial( MaterialDiffuseToColorCAD( mat.m_Diffuse ), aOpacity,
aUseSelectedMaterial, aSelectionColor );
break;
@@ -547,9 +470,9 @@ void MODEL_3D::Draw( bool aTransparent, float aOpacity, bool aUseSelectedMateria
break;
}
glDrawElements( GL_TRIANGLES, mat->m_render_idx_count, m_index_buffer_type,
glDrawElements( GL_TRIANGLES, mat.m_render_idx_count, m_index_buffer_type,
reinterpret_cast<const void*>(
static_cast<uintptr_t>( mat->m_render_idx_buffer_offset ) ) );
static_cast<uintptr_t>( mat.m_render_idx_buffer_offset ) ) );
}
}
@@ -603,7 +526,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 ) ) );
}
+5 -14
View File
@@ -54,7 +54,7 @@ public:
*/
void DrawOpaque( bool aUseSelectedMaterial, SFVEC3F aSelectionColor = SFVEC3F( 0.0f ) ) const
{
Draw( false, 1.0f, aUseSelectedMaterial, aSelectionColor, nullptr, nullptr );
Draw( false, 1.0f, aUseSelectedMaterial, aSelectionColor );
}
/**
@@ -63,19 +63,9 @@ public:
void DrawTransparent( float aOpacity, bool aUseSelectedMaterial,
SFVEC3F aSelectionColor = SFVEC3F( 0.0f ) ) const
{
Draw( true, aOpacity, aUseSelectedMaterial, aSelectionColor, nullptr, nullptr );
Draw( true, aOpacity, aUseSelectedMaterial, aSelectionColor );
}
/**
* Render the model into the current context.
* if aModelWorldMatrix and aCameraWorldPos is provided,
* it renders the material groups sorted.
*/
void Draw( bool aTransparent, float aOpacity, bool aUseSelectedMaterial,
const SFVEC3F& aSelectionColor,
const glm::mat4 *aModelWorldMatrix,
const SFVEC3F *aCameraWorldPos ) const;
/**
* Return true if have opaque meshes to render.
*/
@@ -146,8 +136,6 @@ private:
unsigned int m_render_idx_buffer_offset = 0;
unsigned int m_render_idx_count = 0;
BBOX_3D m_bbox; ///< bounding box for this material group, used for transparent material ordering
MATERIAL( const SMATERIAL& aOther ) : SMATERIAL( aOther ) { }
bool IsTransparent() const { return m_Transparency > FLT_EPSILON; }
};
@@ -171,6 +159,9 @@ private:
static void MakeBbox( const BBOX_3D& aBox, unsigned int aIdxOffset, VERTEX* aVtxOut,
GLuint* aIdxOut, const glm::vec4& aColor );
void Draw( bool aTransparent, float aOpacity, bool aUseSelectedMaterial,
SFVEC3F& aSelectionColor ) const;
};
#endif // _MODEL_3D_H_
+162 -216
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-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
@@ -24,24 +23,23 @@
*/
#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 <fp_lib_table.h>
#include <profile.h> // To use GetRunningMicroSecs or another profiling utility
#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 +301,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 +315,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,37 +374,23 @@ OPENGL_RENDER_LIST* RENDER_3D_OPENGL::generateLayerList( const BVH_CONTAINER_2D*
}
OPENGL_RENDER_LIST* RENDER_3D_OPENGL::generateEmptyLayerList( PCB_LAYER_ID aLayer )
{
float layer_z_bot = 0.0f;
float layer_z_top = 0.0f;
getLayerZPos( aLayer, layer_z_top, layer_z_bot );
TRIANGLE_DISPLAY_LIST* layerTriangles = new TRIANGLE_DISPLAY_LIST( 1 );
// store in a list so it will be latter deleted
m_triangles.push_back( layerTriangles );
return new OPENGL_RENDER_LIST( *layerTriangles, m_circleTexture, layer_z_bot, layer_z_top );
}
OPENGL_RENDER_LIST* RENDER_3D_OPENGL::createBoard( const SHAPE_POLY_SET& aBoardPoly,
const BVH_CONTAINER_2D* aThroughHoles )
{
OPENGL_RENDER_LIST* dispLists = nullptr;
CONTAINER_2D boardContainer;
SHAPE_POLY_SET brd_outlines = aBoardPoly;
ConvertPolygonToTriangles( aBoardPoly, boardContainer, m_boardAdapter.BiuTo3dUnits(),
ConvertPolygonToTriangles( brd_outlines, boardContainer, m_boardAdapter.BiuTo3dUnits(),
(const BOARD_ITEM &)*m_boardAdapter.GetBoard() );
const LIST_OBJECT2D& listBoardObject2d = boardContainer.GetList();
if( listBoardObject2d.size() > 0 )
{
// We will set a unitary Z so it will in future used with transformations since the
// board poly will be used not only to draw itself but also the solder mask layers.
// We will set a unitary Z so it will in future used with transformations
// since the board poly will be used not only to draw itself but also the
// solder mask layers.
const float layer_z_top = 1.0f;
const float layer_z_bot = 0.0f;
@@ -454,7 +438,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 +449,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.GetFlag( FL_USE_REALISTIC_MODE ) )
{
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 );
SHAPE_POLY_SET board_poly_with_holes = m_boardAdapter.GetBoardPoly();
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 +481,26 @@ 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();
outerPolyTHT.BooleanIntersection( m_boardAdapter.GetBoardPoly(),
SHAPE_POLY_SET::PM_STRICTLY_SIMPLE );
if( m_boardAdapter.GetFlag( FL_USE_REALISTIC_MODE ) )
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_outerThroughHoles = generateHoles( m_boardAdapter.GetThroughHoleOds().GetList(),
outerPolyTHT, 1.0f, 0.0f, false,
&m_boardAdapter.GetThroughHoleIds() );
m_outerViaThroughHoles = generateHoles( m_boardAdapter.GetViaTH_ODs().GetList(),
m_boardAdapter.GetViaTH_ODPolys(), 1.0f, 0.0f, false );
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_annuli )
if( m_boardAdapter.GetFlag( FL_CLIP_SILK_ON_VIA_ANNULUS ) &&
m_boardAdapter.GetFlag( FL_USE_REALISTIC_MODE ) )
{
m_outerThroughHoleRings = generateHoles( m_boardAdapter.GetViaAnnuli().GetList(),
m_boardAdapter.GetViaAnnuliPolys(),
1.0f, 0.0f, false );
m_outerThroughHoleRings = generateHoles(
m_boardAdapter.GetThroughHoleAnnularRings().GetList(),
m_boardAdapter.GetThroughHoleAnnularRingPolys(), 1.0f, 0.0f, false );
}
const MAP_POLY& innerMapHoles = m_boardAdapter.GetHoleIdPolysMap();
@@ -522,20 +515,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 auto 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 auto 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,114 +547,102 @@ 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 auto 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;
SHAPE_POLY_SET* aPolyList = 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.GetFlag( FL_USE_REALISTIC_MODE ) )
{
polyListSubtracted = *map_poly.at( layer );
polyListSubtracted.BooleanIntersection( m_boardAdapter.GetBoardPoly(),
SHAPE_POLY_SET::PM_FAST );
if( LSET::PhysicalLayersMask().test( layer ) )
if( ( layer_id != B_Mask ) && ( layer_id != F_Mask ) )
{
polyListSubtracted.BooleanIntersection( m_boardAdapter.GetBoardPoly(),
SHAPE_POLY_SET::PM_FAST );
polyListSubtracted.BooleanSubtract( m_boardAdapter.GetThroughHoleOdPolys(),
SHAPE_POLY_SET::PM_FAST );
polyListSubtracted.BooleanSubtract(
m_boardAdapter.GetOuterNonPlatedThroughHolePoly(),
SHAPE_POLY_SET::PM_FAST );
}
if( layer != B_Mask && layer != F_Mask )
if( m_boardAdapter.GetFlag( FL_SUBTRACT_MASK_FROM_SILK ) )
{
polyListSubtracted.BooleanSubtract( m_boardAdapter.GetTH_ODPolys(),
SHAPE_POLY_SET::PM_FAST );
polyListSubtracted.BooleanSubtract( m_boardAdapter.GetNPTH_ODPolys(),
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;
}
aPolyList = &polyListSubtracted;
}
OPENGL_RENDER_LIST* oglList = generateLayerList( container2d, polyList, layer,
&m_boardAdapter.GetTH_IDs() );
OPENGL_RENDER_LIST* oglList = generateLayerList( container2d, aPolyList, 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.GetFlag( FL_RENDER_PLATED_PADS_AS_PLATED ) &&
m_boardAdapter.GetFlag( FL_USE_REALISTIC_MODE ) )
{
const SHAPE_POLY_SET* frontPlatedPadAndGraphicPolys = m_boardAdapter.GetFrontPlatedPadAndGraphicPolys();
const SHAPE_POLY_SET* backPlatedPadAndGraphicPolys = m_boardAdapter.GetBackPlatedPadAndGraphicPolys();
if( frontPlatedPadAndGraphicPolys )
if( m_boardAdapter.GetFrontPlatedPadPolys() )
{
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 = *m_boardAdapter.GetFrontPlatedPadPolys();
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 );
// 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 );
m_platedPadsFront = generateLayerList( m_boardAdapter.GetPlatedPadsFront(),
&polySubtracted, F_Cu );
}
if( backPlatedPadAndGraphicPolys )
if( m_boardAdapter.GetBackPlatedPadPolys() )
{
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 = *m_boardAdapter.GetBackPlatedPadPolys();
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 );
// 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 )
m_layers[B_Cu] = generateEmptyLayerList( B_Cu );
m_platedPadsBack = generateLayerList( m_boardAdapter.GetPlatedPadsBack(),
&polySubtracted, B_Cu );
}
}
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..." ) );
@@ -663,7 +652,8 @@ void RENDER_3D_OPENGL::reload( REPORTER* aStatusReporter, REPORTER* aWarningRepo
if( aStatusReporter )
{
// Calculation time in seconds
double calculation_time = (double)( GetRunningMicroSecs() - stats_startReloadTime) / 1e6;
const double calculation_time = (double)( GetRunningMicroSecs() -
stats_startReloadTime) / 1e6;
aStatusReporter->Report( wxString::Format( _( "Reload time %.3f s" ), calculation_time ) );
}
@@ -684,10 +674,10 @@ void RENDER_3D_OPENGL::addTopAndBottomTriangles( TRIANGLE_DISPLAY_LIST* aDst, co
}
void RENDER_3D_OPENGL::getLayerZPos( PCB_LAYER_ID aLayer, float& aOutZtop, float& aOutZbot ) const
void RENDER_3D_OPENGL::getLayerZPos( PCB_LAYER_ID aLayerID, float& aOutZtop, float& aOutZbot ) const
{
aOutZbot = m_boardAdapter.GetLayerBottomZPos( aLayer );
aOutZtop = m_boardAdapter.GetLayerTopZPos( aLayer );
aOutZbot = m_boardAdapter.GetLayerBottomZPos( aLayerID );
aOutZtop = m_boardAdapter.GetLayerTopZPos( aLayerID );
if( aOutZtop < aOutZbot )
{
@@ -742,11 +732,13 @@ void RENDER_3D_OPENGL::generateViasAndPads()
if( m_boardAdapter.GetViaCount() > 0 )
{
float averageDiameter = m_boardAdapter.GetAverageViaHoleDiameter();
unsigned int averageSegCount = m_boardAdapter.GetCircleSegmentCount( averageDiameter );
unsigned int trianglesEstimate = averageSegCount * 8 * m_boardAdapter.GetViaCount();
const unsigned int reserve_nr_triangles_estimation =
m_boardAdapter.GetCircleSegmentCount(
m_boardAdapter.GetAverageViaHoleDiameter() ) * 8 *
m_boardAdapter.GetViaCount();
TRIANGLE_DISPLAY_LIST* layerTriangleVIA = new TRIANGLE_DISPLAY_LIST( trianglesEstimate );
TRIANGLE_DISPLAY_LIST* layerTriangleVIA =
new TRIANGLE_DISPLAY_LIST( reserve_nr_triangles_estimation );
// Insert plated vertical holes inside the board
@@ -757,9 +749,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 +778,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() )
{
@@ -823,16 +793,17 @@ void RENDER_3D_OPENGL::generateViasAndPads()
{
if( pad->GetAttribute() != PAD_ATTRIB::NPTH )
{
const VECTOR2I drillsize = pad->GetDrillSize();
const bool hasHole = drillsize.x && drillsize.y;
const wxSize drillsize = pad->GetDrillSize();
const bool hasHole = drillsize.x && drillsize.y;
if( !hasHole )
continue;
pad->TransformHoleToPolygon( tht_outer_holes_poly, platingThickness,
ARC_HIGH_DEF, ERROR_INSIDE );
pad->TransformHoleToPolygon( tht_inner_holes_poly, 0, ARC_HIGH_DEF,
ERROR_INSIDE );
pad->TransformHoleWithClearanceToPolygon( tht_outer_holes_poly,
platingThickness,
ARC_HIGH_DEF, ERROR_INSIDE );
pad->TransformHoleWithClearanceToPolygon( tht_inner_holes_poly, 0,
ARC_HIGH_DEF, ERROR_INSIDE );
}
}
}
@@ -840,26 +811,29 @@ 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.GetFlag( FL_USE_REALISTIC_MODE ) )
tht_outer_holes_poly.BooleanSubtract( m_antiBoardPolys, SHAPE_POLY_SET::PM_FAST );
CONTAINER_2D holesContainer;
ConvertPolygonToTriangles( tht_outer_holes_poly, holesContainer,
m_boardAdapter.BiuTo3dUnits(), *m_boardAdapter.GetBoard() );
m_boardAdapter.BiuTo3dUnits(),
(const BOARD_ITEM &)*m_boardAdapter.GetBoard() );
const LIST_OBJECT2D& holes2D = holesContainer.GetList();
const LIST_OBJECT2D& listHolesObject2d = holesContainer.GetList();
if( holes2D.size() > 0 )
if( listHolesObject2d.size() > 0 )
{
float layer_z_top, layer_z_bot, dummy;
getLayerZPos( F_Cu, layer_z_top, dummy );
getLayerZPos( B_Cu, dummy, layer_z_bot );
TRIANGLE_DISPLAY_LIST* layerTriangles = new TRIANGLE_DISPLAY_LIST( holes2D.size() );
TRIANGLE_DISPLAY_LIST* layerTriangles =
new TRIANGLE_DISPLAY_LIST( listHolesObject2d.size() );
// Convert the list of objects(triangles) to triangle layer structure
for( const OBJECT_2D* itemOnLayer : holes2D )
for( const OBJECT_2D* itemOnLayer : listHolesObject2d )
{
const OBJECT_2D* object2d_A = itemOnLayer;
@@ -906,9 +880,7 @@ void RENDER_3D_OPENGL::Load3dModelsIfNeeded()
load3dModels( &activityReporter );
}
else
{
load3dModels( nullptr );
}
}
@@ -917,71 +889,45 @@ 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
&& !m_boardAdapter.m_Cfg->m_Render.show_footprints_insert
&& !m_boardAdapter.m_Cfg->m_Render.show_footprints_virtual )
if( !m_boardAdapter.GetFlag( FL_FP_ATTRIBUTES_NORMAL )
&& !m_boardAdapter.GetFlag( FL_FP_ATTRIBUTES_NORMAL_INSERT )
&& !m_boardAdapter.GetFlag( FL_FP_ATTRIBUTES_VIRTUAL ) )
{
return;
}
#endif
// Go for all footprints
for( const FOOTPRINT* footprint : m_boardAdapter.GetBoard()->Footprints() )
{
wxString libraryName = footprint->GetFPID().GetLibNickname();
wxString footprintBasePath = wxEmptyString;
if( m_boardAdapter.GetBoard()->GetProject() )
for( const FP_3DMODEL& model : footprint->Models() )
{
try
{
// FindRow() can throw an exception
const FP_LIB_TABLE_ROW* fpRow =
PROJECT_PCB::PcbFootprintLibs( m_boardAdapter.GetBoard()->GetProject() )
->FindRow( libraryName, false );
if( fpRow )
footprintBasePath = fpRow->GetFullURI( true );
}
catch( ... )
{
// Do nothing if the libraryName is not found in lib table
}
}
for( const FP_3DMODEL& fp_model : footprint->Models() )
{
if( fp_model.m_Show && !fp_model.m_Filename.empty() )
if( model.m_Show && !model.m_Filename.empty() )
{
if( aStatusReporter )
{
// Display the short filename of the 3D fp_model loaded:
// Display the short filename of the 3D model loaded:
// (the full name is usually too long to be displayed)
wxFileName fn( fp_model.m_Filename );
wxFileName fn( model.m_Filename );
aStatusReporter->Report( wxString::Format( _( "Loading %s..." ),
fn.GetFullName() ) );
}
// Check if the fp_model is not present in our cache map
// Check if the model is not present in our cache map
// (Not already loaded in memory)
if( m_3dModelMap.find( fp_model.m_Filename ) == m_3dModelMap.end() )
if( m_3dModelMap.find( model.m_Filename ) == m_3dModelMap.end() )
{
// It is not present, try get it from cache
const S3DMODEL* modelPtr =
m_boardAdapter.Get3dCacheManager()->GetModel( fp_model.m_Filename, footprintBasePath );
m_boardAdapter.Get3dCacheManager()->GetModel( model.m_Filename );
// only add it if the return is not NULL
if( modelPtr )
{
MATERIAL_MODE materialMode = m_boardAdapter.m_Cfg->m_Render.material_mode;
MODEL_3D* model = new MODEL_3D( *modelPtr, materialMode );
MATERIAL_MODE materialMode = m_boardAdapter.GetMaterialMode();
MODEL_3D* ogl_model = new MODEL_3D( *modelPtr, materialMode );
m_3dModelMap[ fp_model.m_Filename ] = model;
if( ogl_model )
m_3dModelMap[ model.m_Filename ] = ogl_model;
}
}
}
@@ -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;
@@ -629,7 +650,6 @@ GLuint OPENGL_RENDER_LIST::generate_top_or_bot_seg_ends(
glDrawArrays( GL_TRIANGLES, 0, aTriangleContainer->GetVertexSize() );
glBindTexture( GL_TEXTURE_2D, 0 );
glDisable( GL_TEXTURE_2D );
glDisable( GL_ALPHA_TEST );
glDisable( GL_BLEND );
@@ -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; }
+11 -12
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-2022 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
@@ -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 )
{
@@ -144,18 +144,18 @@ void DrawHalfOpenCylinder( unsigned int aNrSidesPerCircle )
if( aNrSidesPerCircle > 1 )
{
const float radius = 0.5f;
const EDA_ANGLE delta = ANGLE_360 / aNrSidesPerCircle;
const int delta = 3600 / aNrSidesPerCircle;
// Generate bottom
glNormal3f( 0.0f, 0.0f,-1.0f );
glBegin( GL_TRIANGLE_FAN );
glVertex3f( 0.0, 0.0, 0.0 ); // This is the V0 of the FAN
for( EDA_ANGLE ii = ANGLE_0; ii < ANGLE_180; ii += delta )
for( int ii = 0; ii < 1800; ii += delta )
{
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 );
@@ -166,12 +166,12 @@ void DrawHalfOpenCylinder( unsigned int aNrSidesPerCircle )
glBegin( GL_TRIANGLE_FAN );
glVertex3f( 0.0, 0.0, 1.0 ); // This is the V0 of the FAN
for( EDA_ANGLE ii = ANGLE_180; ii > ANGLE_0; ii -= delta )
for( int ii = 1800; ii > 0; ii -= delta )
{
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 );
@@ -180,15 +180,14 @@ void DrawHalfOpenCylinder( unsigned int aNrSidesPerCircle )
// Generate contours
glBegin( GL_QUAD_STRIP );
for( EDA_ANGLE ii = ANGLE_180; ii > ANGLE_0; ii -= delta )
for( int ii = 1800; ii > 0; ii -= delta )
{
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
@@ -41,8 +41,10 @@
#include <map>
typedef std::map< PCB_LAYER_ID, OPENGL_RENDER_LIST* > MAP_OGL_DISP_LISTS;
typedef std::list<TRIANGLE_DISPLAY_LIST* > LIST_TRIANGLES;
typedef std::map< wxString, MODEL_3D* > MAP_3DMODEL;
#define SIZE_OF_CIRCLE_TEXTURE 1024
@@ -73,16 +75,15 @@ 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 );
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 );
@@ -128,41 +129,18 @@ private:
*/
void load3dModels( REPORTER* aStatusReporter );
struct MODELTORENDER
{
glm::mat4 m_modelWorldMat;
const MODEL_3D* m_model;
float m_opacity;
bool m_isTransparent;
bool m_isSelected;
/**
* @param aRenderTopOrBot true will render Top, false will render bottom
* @param aRenderTransparentOnly true will render only the transparent objects, false will
* render opaque
*/
void render3dModels( bool aRenderTopOrBot, bool aRenderTransparentOnly );
MODELTORENDER( glm::mat4 aModelWorldMat,
const MODEL_3D* aNodel,
float aOpacity,
bool aIsTransparent,
bool aIsSelected ) :
m_modelWorldMat( std::move( aModelWorldMat ) ),
m_model( aNodel ),
m_opacity( aOpacity ),
m_isTransparent( aIsTransparent ),
m_isSelected( aIsSelected )
{
}
};
void render3dModelsSelected( bool aRenderTopOrBot, bool aRenderTransparentOnly,
bool aRenderSelectedOnly );
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 get3dModelsSelected( std::list<MODELTORENDER> &aDstRenderList, bool aGetTop, bool aGetBot,
bool aRenderTransparentOnly, bool aRenderSelectedOnly );
void get3dModelsFromFootprint( std::list<MODELTORENDER> &aDstRenderList,
const FOOTPRINT* aFootprint, bool aRenderTransparentOnly,
bool aIsSelected );
void renderFootprint( const FOOTPRINT* aFootprint, bool aRenderTransparentOnly,
bool aIsSelected );
void setLightFront( bool enabled );
void setLightTop( bool enabled );
@@ -185,6 +163,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,
@@ -211,8 +190,6 @@ private:
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;
@@ -231,9 +208,7 @@ private:
OPENGL_RENDER_LIST* m_vias;
OPENGL_RENDER_LIST* m_padHoles;
// Caches
std::map<wxString, MODEL_3D*> m_3dModelMap;
std::map<std::vector<float>, glm::mat4> m_3dModelMatrixMap;
MAP_3DMODEL m_3dModelMap;
BOARD_ITEM* m_currentRollOverItem;
+1 -1
View File
@@ -30,7 +30,7 @@
#ifndef POST_SHADER_H
#define POST_SHADER_H
#include <gal/3d/camera.h>
#include "camera.h"
class POST_SHADER
{
@@ -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 );
+155 -184
View File
@@ -1,9 +1,8 @@
/*
* 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-2023 KiCad Developers, see AUTHORS.txt for contributors.
* Copyright (C) 2015-2016 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
@@ -40,12 +39,9 @@
#include <board.h>
#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
@@ -69,28 +65,35 @@ static float TransparencyControl( float aGrayColorValue, float aTransparency )
/**
* Scale conversion from 3d model units to pcb units
*/
#define UNITS3D_TO_UNITSPCB ( pcbIUScale.IU_PER_MM )
#define UNITS3D_TO_UNITSPCB ( IU_PER_MM )
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 );
MATERIAL::SetDefaultRefractionRayCount( m_boardAdapter.m_RtRefractionSampleCount );
MATERIAL::SetDefaultReflectionRayCount( m_boardAdapter.m_RtReflectionSampleCount );
MATERIAL::SetDefaultRefractionRecursionCount( m_boardAdapter.m_Cfg->m_Render.raytrace_recursivelevel_refractions );
MATERIAL::SetDefaultReflectionRecursionCount( m_boardAdapter.m_Cfg->m_Render.raytrace_recursivelevel_reflections );
MATERIAL::SetDefaultRefractionRecursionCount( m_boardAdapter.m_RtRecursiveRefractionCount );
MATERIAL::SetDefaultReflectionRecursionCount( m_boardAdapter.m_RtRecursiveReflectionCount );
double mmTo3Dunits = pcbIUScale.IU_PER_MM * m_boardAdapter.BiuTo3dUnits();
double mmTo3Dunits = IU_PER_MM * m_boardAdapter.BiuTo3dUnits();
if( m_boardAdapter.m_Cfg->m_Render.raytrace_procedural_textures )
if( m_boardAdapter.GetFlag( FL_RENDER_RAYTRACING_PROCEDURAL_TEXTURES ) )
{
m_boardMaterial = BOARD_NORMAL( 0.40f * mmTo3Dunits );
m_copperMaterial = COPPER_NORMAL( 4.0f * mmTo3Dunits, &m_boardMaterial );
m_platedCopperMaterial = PLATED_COPPER_NORMAL( 0.5f * mmTo3Dunits );
m_solderMaskMaterial = SOLDER_MASK_NORMAL( &m_boardMaterial );
m_plasticMaterial = PLASTIC_NORMAL( 0.05f * mmTo3Dunits );
m_shinyPlasticMaterial = PLASTIC_SHINE_NORMAL( 0.1f * mmTo3Dunits );
m_brushedMetalMaterial = BRUSHED_METAL_NORMAL( 0.05f * mmTo3Dunits );
m_silkScreenMaterial = SILK_SCREEN_NORMAL( 0.25f * mmTo3Dunits );
}
@@ -104,14 +107,14 @@ void RENDER_3D_RAYTRACE::setupMaterials()
ConvertSRGBToLinear( (SFVEC3F) m_boardAdapter.m_CopperColor * 0.3f ),
SFVEC3F( 0.0f ), copperSpecularLinear, 0.4f * 128.0f, 0.0f, 0.0f );
if( m_boardAdapter.m_Cfg->m_Render.raytrace_procedural_textures )
if( m_boardAdapter.GetFlag( FL_RENDER_RAYTRACING_PROCEDURAL_TEXTURES ) )
m_materials.m_Copper.SetGenerator( &m_platedCopperMaterial );
m_materials.m_NonPlatedCopper = BLINN_PHONG_MATERIAL(
ConvertSRGBToLinear( SFVEC3F( 0.191f, 0.073f, 0.022f ) ), SFVEC3F( 0.0f, 0.0f, 0.0f ),
SFVEC3F( 0.256f, 0.137f, 0.086f ), 0.15f * 128.0f, 0.0f, 0.0f );
if( m_boardAdapter.m_Cfg->m_Render.raytrace_procedural_textures )
if( m_boardAdapter.GetFlag( FL_RENDER_RAYTRACING_PROCEDURAL_TEXTURES ) )
m_materials.m_NonPlatedCopper.SetGenerator( &m_copperMaterial );
m_materials.m_Paste = BLINN_PHONG_MATERIAL(
@@ -129,7 +132,7 @@ void RENDER_3D_RAYTRACE::setupMaterials()
(SFVEC3F) m_boardAdapter.m_SilkScreenColorTop ) ),
SFVEC3F( 0.0f ), SFVEC3F( 0.10f ) ), 0.078125f * 128.0f, 0.0f, 0.0f );
if( m_boardAdapter.m_Cfg->m_Render.raytrace_procedural_textures )
if( m_boardAdapter.GetFlag( FL_RENDER_RAYTRACING_PROCEDURAL_TEXTURES ) )
m_materials.m_SilkS.SetGenerator( &m_silkScreenMaterial );
// Assume that SolderMaskTop == SolderMaskBot
@@ -150,7 +153,7 @@ void RENDER_3D_RAYTRACE::setupMaterials()
m_materials.m_SolderMask.SetCastShadows( true );
m_materials.m_SolderMask.SetRefractionRayCount( 1 );
if( m_boardAdapter.m_Cfg->m_Render.raytrace_procedural_textures )
if( m_boardAdapter.GetFlag( FL_RENDER_RAYTRACING_PROCEDURAL_TEXTURES ) )
m_materials.m_SolderMask.SetGenerator( &m_solderMaskMaterial );
m_materials.m_EpoxyBoard =
@@ -163,7 +166,7 @@ void RENDER_3D_RAYTRACE::setupMaterials()
m_materials.m_EpoxyBoard.SetAbsorvance( 10.0f );
if( m_boardAdapter.m_Cfg->m_Render.raytrace_procedural_textures )
if( m_boardAdapter.GetFlag( FL_RENDER_RAYTRACING_PROCEDURAL_TEXTURES ) )
m_materials.m_EpoxyBoard.SetGenerator( &m_boardMaterial );
SFVEC3F bgTop = ConvertSRGBToLinear( (SFVEC3F) m_boardAdapter.m_BgColorTop );
@@ -236,9 +239,7 @@ void RENDER_3D_RAYTRACE::createItemsFromContainer( const BVH_CONTAINER_2D* aCont
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 +278,11 @@ void RENDER_3D_RAYTRACE::createItemsFromContainer( const BVH_CONTAINER_2D* aCont
// 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.GetFlag( FL_CLIP_SILK_ON_VIA_ANNULUS )
&& m_boardAdapter.GetFlag( FL_USE_REALISTIC_MODE )
&& ( ( aLayer_id == B_SilkS ) || ( aLayer_id == F_SilkS ) ) ) ?
m_boardAdapter.GetThroughHoleAnnularRings() :
m_boardAdapter.GetThroughHoleOds();
if( !throughHoleOuter.GetList().empty() )
{
@@ -304,13 +308,14 @@ void RENDER_3D_RAYTRACE::createItemsFromContainer( const BVH_CONTAINER_2D* aCont
const MAP_CONTAINER_2D_BASE& mapLayers = m_boardAdapter.GetLayerMap();
if( cfg.subtract_mask_from_silk
if( m_boardAdapter.GetFlag( FL_SUBTRACT_MASK_FROM_SILK )
&& m_boardAdapter.GetFlag( FL_USE_REALISTIC_MODE )
&& ( ( 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 +335,8 @@ void RENDER_3D_RAYTRACE::createItemsFromContainer( const BVH_CONTAINER_2D* aCont
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 +348,8 @@ void RENDER_3D_RAYTRACE::createItemsFromContainer( const BVH_CONTAINER_2D* aCont
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 ) );
@@ -368,7 +373,7 @@ void RENDER_3D_RAYTRACE::Reload( REPORTER* aStatusReporter, REPORTER* aWarningRe
OBJECT_2D_STATS::Instance().ResetStats();
OBJECT_3D_STATS::Instance().ResetStats();
int64_t stats_startReloadTime = GetRunningMicroSecs();
unsigned stats_startReloadTime = GetRunningMicroSecs();
if( !aOnlyLoadCopperAndShapes )
{
@@ -393,8 +398,6 @@ void RENDER_3D_RAYTRACE::Reload( REPORTER* aStatusReporter, REPORTER* aWarningRe
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 +439,7 @@ void RENDER_3D_RAYTRACE::Reload( REPORTER* aStatusReporter, REPORTER* aWarningRe
*m_boardAdapter.GetBoard(), ii );
}
if( layerFlags.test( LAYER_3D_BOARD ) )
if( m_boardAdapter.GetFlag( FL_SHOW_BOARD_BODY ) )
{
const LIST_OBJECT2D& listObjects = m_outlineBoard2dObjects->GetList();
@@ -445,9 +448,9 @@ void RENDER_3D_RAYTRACE::Reload( REPORTER* aStatusReporter, REPORTER* aWarningRe
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 +514,9 @@ void RENDER_3D_RAYTRACE::Reload( REPORTER* aStatusReporter, REPORTER* aWarningRe
// 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 )
{
@@ -560,9 +563,9 @@ void RENDER_3D_RAYTRACE::Reload( REPORTER* aStatusReporter, REPORTER* aWarningRe
aStatusReporter->Report( _( "Load Raytracing: layers" ) );
// Add layers maps (except B_Mask and F_Mask)
for( const std::pair<const PCB_LAYER_ID, BVH_CONTAINER_2D*>& entry : m_boardAdapter.GetLayerMap() )
for( auto entry : m_boardAdapter.GetLayerMap() )
{
const PCB_LAYER_ID layer_id = entry.first;
PCB_LAYER_ID layer_id = entry.first;
const BVH_CONTAINER_2D* container2d = entry.second;
// Only process layers that exist
@@ -588,33 +591,40 @@ void RENDER_3D_RAYTRACE::Reload( REPORTER* aStatusReporter, REPORTER* aWarningRe
case B_Paste:
case F_Paste:
materialLayer = &m_materials.m_Paste;
layerColor = m_boardAdapter.m_SolderPasteColor;
if( m_boardAdapter.GetFlag( FL_USE_REALISTIC_MODE ) )
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.GetFlag( FL_USE_REALISTIC_MODE ) )
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.GetFlag( FL_USE_REALISTIC_MODE ) )
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,17 +636,19 @@ void RENDER_3D_RAYTRACE::Reload( REPORTER* aStatusReporter, REPORTER* aWarningRe
break;
default:
if( m_boardAdapter.m_Cfg->m_Render.differentiate_plated_copper )
if( m_boardAdapter.GetFlag( FL_USE_REALISTIC_MODE ) )
{
layerColor = SFVEC3F( 184.0f / 255.0f, 115.0f / 255.0f, 50.0f / 255.0f );
materialLayer = &m_materials.m_NonPlatedCopper;
if( m_boardAdapter.GetFlag( FL_RENDER_PLATED_PADS_AS_PLATED ) )
layerColor = SFVEC3F( 184.0f / 255.0f, 115.0f / 255.0f, 50.0f / 255.0f );
else
layerColor = m_boardAdapter.m_CopperColor;
}
else
{
layerColor = m_boardAdapter.m_CopperColor;
materialLayer = &m_materials.m_Copper;
layerColor = m_boardAdapter.GetLayerColor( layer_id );
}
materialLayer = &m_materials.m_NonPlatedCopper;
break;
}
@@ -644,15 +656,16 @@ void RENDER_3D_RAYTRACE::Reload( REPORTER* aStatusReporter, REPORTER* aWarningRe
} // for each layer on map
// Create plated copper
if( m_boardAdapter.m_Cfg->m_Render.differentiate_plated_copper )
if( m_boardAdapter.GetFlag( FL_RENDER_PLATED_PADS_AS_PLATED )
&& m_boardAdapter.GetFlag( FL_USE_REALISTIC_MODE ) )
{
createItemsFromContainer( m_boardAdapter.GetPlatedPadsFront(), F_Cu, &m_materials.m_Copper,
m_boardAdapter.m_CopperColor,
m_boardAdapter.GetFrontCopperThickness() * 0.1f );
m_boardAdapter.GetCopperThickness() * 0.1f );
createItemsFromContainer( m_boardAdapter.GetPlatedPadsBack(), B_Cu, &m_materials.m_Copper,
m_boardAdapter.m_CopperColor,
-m_boardAdapter.GetBackCopperThickness() * 0.1f );
-m_boardAdapter.GetCopperThickness() * 0.1f );
}
if( !aOnlyLoadCopperAndShapes )
@@ -661,15 +674,13 @@ void RENDER_3D_RAYTRACE::Reload( REPORTER* aStatusReporter, REPORTER* aWarningRe
// 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.GetFlag( FL_SOLDERMASK ) && !m_outlineBoard2dObjects->GetList().empty() )
{
const MATERIAL* materialLayer = &m_materials.m_SolderMask;
for( const std::pair<const PCB_LAYER_ID, BVH_CONTAINER_2D*>& entry : m_boardAdapter.GetLayerMap() )
for( auto entry : m_boardAdapter.GetLayerMap() )
{
const PCB_LAYER_ID layer_id = entry.first;
PCB_LAYER_ID layer_id = entry.first;
const BVH_CONTAINER_2D* container2d = entry.second;
// Only process layers that exist
@@ -677,22 +688,22 @@ void RENDER_3D_RAYTRACE::Reload( REPORTER* aStatusReporter, REPORTER* aWarningRe
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.GetFlag( FL_USE_REALISTIC_MODE ) )
{
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 +714,9 @@ void RENDER_3D_RAYTRACE::Reload( REPORTER* aStatusReporter, REPORTER* aWarningRe
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 +782,8 @@ void RENDER_3D_RAYTRACE::Reload( REPORTER* aStatusReporter, REPORTER* aWarningRe
}
#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,13 +792,13 @@ void RENDER_3D_RAYTRACE::Reload( REPORTER* aStatusReporter, REPORTER* aWarningRe
load3DModels( m_objectContainer, aOnlyLoadCopperAndShapes );
#ifdef PRINT_STATISTICS_3D_VIEWER
int64_t stats_endLoad3DmodelsTime = GetRunningMicroSecs();
unsigned stats_endLoad3DmodelsTime = GetRunningMicroSecs();
#endif
if( !aOnlyLoadCopperAndShapes )
{
// Add floor
if( m_boardAdapter.m_Cfg->m_Render.raytrace_backfloor )
if( m_boardAdapter.GetFlag( FL_RENDER_RAYTRACING_BACKFLOOR ) )
{
BBOX_3D boardBBox = m_boardAdapter.GetBBox();
@@ -867,47 +878,41 @@ void RENDER_3D_RAYTRACE::Reload( REPORTER* aStatusReporter, REPORTER* aWarningRe
&& ( aSource.b < ( 1.0f / 255.0f ) ) );
};
SFVEC3F cameraLightColor =
m_boardAdapter.GetColor( m_boardAdapter.m_Cfg->m_Render.raytrace_lightColorCamera );
SFVEC3F topLightColor =
m_boardAdapter.GetColor( m_boardAdapter.m_Cfg->m_Render.raytrace_lightColorTop );
SFVEC3F bottomLightColor =
m_boardAdapter.GetColor( m_boardAdapter.m_Cfg->m_Render.raytrace_lightColorBottom );
m_cameraLight = new DIRECTIONAL_LIGHT( SFVEC3F( 0.0f, 0.0f, 0.0f ), cameraLightColor );
m_cameraLight = new DIRECTIONAL_LIGHT( SFVEC3F( 0.0f, 0.0f, 0.0f ),
m_boardAdapter.m_RtCameraLightColor );
m_cameraLight->SetCastShadows( false );
if( !IsColorZero( cameraLightColor ) )
if( !IsColorZero( m_boardAdapter.m_RtCameraLightColor ) )
m_lights.push_back( m_cameraLight );
const SFVEC3F& boardCenter = m_boardAdapter.GetBBox().GetCenter();
if( !IsColorZero( topLightColor ) )
if( !IsColorZero( m_boardAdapter.m_RtLightColorTop ) )
{
m_lights.push_back( new POINT_LIGHT( SFVEC3F( boardCenter.x, boardCenter.y,
+RANGE_SCALE_3D * 2.0f ),
topLightColor ) );
m_boardAdapter.m_RtLightColorTop ) );
}
if( !IsColorZero( bottomLightColor ) )
if( !IsColorZero( m_boardAdapter.m_RtLightColorBottom ) )
{
m_lights.push_back( new POINT_LIGHT( SFVEC3F( boardCenter.x, boardCenter.y,
-RANGE_SCALE_3D * 2.0f ),
bottomLightColor ) );
m_boardAdapter.m_RtLightColorBottom ) );
}
for( size_t i = 0; i < m_boardAdapter.m_Cfg->m_Render.raytrace_lightColor.size(); ++i )
{
SFVEC3F lightColor =
m_boardAdapter.GetColor( m_boardAdapter.m_Cfg->m_Render.raytrace_lightColor[i] );
wxASSERT( m_boardAdapter.m_RtLightColor.size()
== m_boardAdapter.m_RtLightSphericalCoords.size() );
if( !IsColorZero( lightColor ) )
for( size_t i = 0; i < m_boardAdapter.m_RtLightColor.size(); ++i )
{
if( !IsColorZero( m_boardAdapter.m_RtLightColor[i] ) )
{
const SFVEC2F sc = m_boardAdapter.GetSphericalCoord( i );
const SFVEC2F sc = m_boardAdapter.m_RtLightSphericalCoords[i];
m_lights.push_back( new DIRECTIONAL_LIGHT(
SphericalToCartesian( glm::pi<float>() * sc.x, glm::pi<float>() * sc.y ),
lightColor ) );
m_boardAdapter.m_RtLightColor[i] ) );
}
}
}
@@ -919,33 +924,10 @@ void RENDER_3D_RAYTRACE::Reload( REPORTER* aStatusReporter, REPORTER* aWarningRe
{
float ratio =
std::max( 1.0f, m_objectContainer.GetBBox().GetMaxDimension() / RANGE_SCALE_3D );
m_camera.SetMaxZoom( m_camera.GetMaxZoom() * 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,7 +937,7 @@ void RENDER_3D_RAYTRACE::Reload( REPORTER* aStatusReporter, REPORTER* aWarningRe
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 ) );
}
@@ -970,10 +952,10 @@ void RENDER_3D_RAYTRACE::insertHole( const PCB_VIA* aVia )
aVia->LayerPair( &top_layer, &bottom_layer );
float topZ = m_boardAdapter.GetLayerBottomZPos( top_layer )
+ m_boardAdapter.GetFrontCopperThickness();
+ m_boardAdapter.GetCopperThickness();
float botZ = m_boardAdapter.GetLayerBottomZPos( bottom_layer )
- m_boardAdapter.GetBackCopperThickness();
- m_boardAdapter.GetCopperThickness();
const SFVEC2F center = SFVEC2F( aVia->GetStart().x * m_boardAdapter.BiuTo3dUnits(),
-aVia->GetStart().y * m_boardAdapter.BiuTo3dUnits() );
@@ -987,7 +969,15 @@ void RENDER_3D_RAYTRACE::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.GetFlag( FL_USE_REALISTIC_MODE ) )
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 );
}
@@ -997,9 +987,15 @@ void RENDER_3D_RAYTRACE::insertHole( const PAD* aPad )
{
const OBJECT_2D* object2d_A = nullptr;
SFVEC3F objColor = m_boardAdapter.m_CopperColor;
const VECTOR2I drillsize = aPad->GetDrillSize();
const bool hasHole = drillsize.x && drillsize.y;
SFVEC3F objColor;
if( m_boardAdapter.GetFlag( FL_USE_REALISTIC_MODE ) )
objColor = m_boardAdapter.m_CopperColor;
else
objColor = m_boardAdapter.GetItemColor( LAYER_PADS_TH );
const wxSize drillsize = aPad->GetDrillSize();
const bool hasHole = drillsize.x && drillsize.y;
if( !hasHole )
return;
@@ -1007,10 +1003,10 @@ void RENDER_3D_RAYTRACE::insertHole( const PAD* aPad )
CONST_LIST_OBJECT2D antiOutlineIntersectionList;
const float topZ = m_boardAdapter.GetLayerBottomZPos( F_Cu )
+ m_boardAdapter.GetFrontCopperThickness() * 0.99f;
+ m_boardAdapter.GetCopperThickness() * 0.99f;
const float botZ = m_boardAdapter.GetLayerBottomZPos( B_Cu )
- m_boardAdapter.GetBackCopperThickness() * 0.99f;
- m_boardAdapter.GetCopperThickness() * 0.99f;
if( drillsize.x == drillsize.y ) // usual round hole
{
@@ -1057,7 +1053,7 @@ void RENDER_3D_RAYTRACE::insertHole( const PAD* aPad )
}
else // Oblong hole
{
VECTOR2I ends_offset;
wxPoint ends_offset;
int width;
if( drillsize.x > drillsize.y ) // Horizontal oval
@@ -1071,10 +1067,10 @@ void RENDER_3D_RAYTRACE::insertHole( const PAD* aPad )
width = drillsize.x;
}
RotatePoint( ends_offset, aPad->GetOrientation() );
RotatePoint( &ends_offset, aPad->GetOrientation() );
VECTOR2I start = VECTOR2I( aPad->GetPosition() ) + ends_offset;
VECTOR2I end = VECTOR2I( aPad->GetPosition() ) - ends_offset;
wxPoint start = aPad->GetPosition() + ends_offset;
wxPoint end = aPad->GetPosition() - ends_offset;
ROUND_SEGMENT_2D* innerSeg =
new ROUND_SEGMENT_2D( SFVEC2F( start.x * m_boardAdapter.BiuTo3dUnits(),
@@ -1116,11 +1112,12 @@ void RENDER_3D_RAYTRACE::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 )
{
@@ -1198,10 +1195,9 @@ void RENDER_3D_RAYTRACE::load3DModels( CONTAINER_3D& aDstContainer, bool aSkipMa
if( !m_boardAdapter.GetBoard() )
return;
if( !m_boardAdapter.m_IsPreviewer
&& !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 )
if( !m_boardAdapter.GetFlag( FL_FP_ATTRIBUTES_NORMAL )
&& !m_boardAdapter.GetFlag( FL_FP_ATTRIBUTES_NORMAL_INSERT )
&& !m_boardAdapter.GetFlag( FL_FP_ATTRIBUTES_VIRTUAL ) )
{
return;
}
@@ -1214,7 +1210,7 @@ void RENDER_3D_RAYTRACE::load3DModels( CONTAINER_3D& aDstContainer, bool aSkipMa
{
double zpos = m_boardAdapter.GetFootprintZPos( fp->IsFlipped() );
VECTOR2I pos = fp->GetPosition();
wxPoint pos = fp->GetPosition();
glm::mat4 fpMatrix = glm::mat4( 1.0f );
@@ -1223,10 +1219,11 @@ void RENDER_3D_RAYTRACE::load3DModels( CONTAINER_3D& aDstContainer, bool aSkipMa
-pos.y * m_boardAdapter.BiuTo3dUnits(),
zpos ) );
if( !fp->GetOrientation().IsZero() )
if( fp->GetOrientation() )
{
fpMatrix = glm::rotate( fpMatrix, (float) fp->GetOrientation().AsRadians(),
SFVEC3F( 0.0f, 0.0f, 1.0f ) );
fpMatrix = glm::rotate( fpMatrix,
( (float) ( fp->GetOrientation() / 10.0f ) / 180.0f ) * glm::pi<float>(),
SFVEC3F( 0.0f, 0.0f, 1.0f ) );
}
if( fp->IsFlipped() )
@@ -1250,35 +1247,13 @@ void RENDER_3D_RAYTRACE::load3DModels( CONTAINER_3D& aDstContainer, bool aSkipMa
auto sM = fp->Models().begin();
auto eM = fp->Models().end();
wxString libraryName = fp->GetFPID().GetLibNickname();
wxString footprintBasePath = wxEmptyString;
if( m_boardAdapter.GetBoard()->GetProject() )
{
try
{
// FindRow() can throw an exception
const FP_LIB_TABLE_ROW* fpRow =
PROJECT_PCB::PcbFootprintLibs( m_boardAdapter.GetBoard()->GetProject() )
->FindRow( libraryName, false );
if( fpRow )
footprintBasePath = fpRow->GetFullURI( true );
}
catch( ... )
{
// Do nothing if the libraryName is not found in lib table
}
}
while( sM != eM )
{
if( ( static_cast<float>( sM->m_Opacity ) > FLT_EPSILON )
&& ( sM->m_Show && !sM->m_Filename.empty() ) )
{
// get it from cache
const S3DMODEL* modelPtr =
cacheMgr->GetModel( sM->m_Filename, footprintBasePath );
const S3DMODEL* modelPtr = cacheMgr->GetModel( sM->m_Filename );
// only add it if the return is not NULL.
if( modelPtr )
@@ -1337,7 +1312,7 @@ MODEL_MATERIALS* RENDER_3D_RAYTRACE::getModelMaterial( const S3DMODEL* a3DModel
for( unsigned int imat = 0; imat < a3DModel->m_MaterialsSize; ++imat )
{
if( m_boardAdapter.m_Cfg->m_Render.material_mode == MATERIAL_MODE::NORMAL )
if( m_boardAdapter.GetMaterialMode() == MATERIAL_MODE::NORMAL )
{
const SMATERIAL& material = a3DModel->m_Materials[imat];
@@ -1359,7 +1334,7 @@ MODEL_MATERIALS* RENDER_3D_RAYTRACE::getModelMaterial( const S3DMODEL* a3DModel
ConvertSRGBToLinear( material.m_Specular ), material.m_Shininess * 180.0f,
material.m_Transparency, reflectionFactor );
if( m_boardAdapter.m_Cfg->m_Render.raytrace_procedural_textures )
if( m_boardAdapter.GetFlag( FL_RENDER_RAYTRACING_PROCEDURAL_TEXTURES ) )
{
// Guess material type and apply a normal perturbator
if( ( RGBtoGray( material.m_Diffuse ) < 0.3f )
@@ -1527,7 +1502,7 @@ void RENDER_3D_RAYTRACE::addModels( CONTAINER_3D& aDstContainer, const S3DMODEL*
const SFVEC3F diffuseColor =
a3DModel->m_Materials[mesh.m_MaterialIdx].m_Diffuse;
if( m_boardAdapter.m_Cfg->m_Render.material_mode == MATERIAL_MODE::CAD_MODE )
if( m_boardAdapter.GetMaterialMode() == MATERIAL_MODE::CAD_MODE )
newTriangle->SetColor( ConvertSRGBToLinear(
MaterialDiffuseToColorCAD( diffuseColor ) ) );
else
@@ -1535,8 +1510,7 @@ void RENDER_3D_RAYTRACE::addModels( CONTAINER_3D& aDstContainer, const S3DMODEL*
}
else
{
if( m_boardAdapter.m_Cfg->m_Render.material_mode == MATERIAL_MODE::CAD_MODE )
{
if( m_boardAdapter.GetMaterialMode() == MATERIAL_MODE::CAD_MODE )
newTriangle->SetColor(
ConvertSRGBToLinear( MaterialDiffuseToColorCAD(
mesh.m_Color[idx0] ) ),
@@ -1544,14 +1518,11 @@ void RENDER_3D_RAYTRACE::addModels( CONTAINER_3D& aDstContainer, const S3DMODEL*
mesh.m_Color[idx1] ) ),
ConvertSRGBToLinear( MaterialDiffuseToColorCAD(
mesh.m_Color[idx2] ) ) );
}
else
{
newTriangle->SetColor(
ConvertSRGBToLinear( mesh.m_Color[idx0] ),
ConvertSRGBToLinear( mesh.m_Color[idx1] ),
ConvertSRGBToLinear( mesh.m_Color[idx2] ) );
}
}
}
}
@@ -1,8 +1,8 @@
/*
* 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) 2015-2022 KiCad Developers, see AUTHORS.txt for contributors.
* 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
@@ -223,7 +223,7 @@ SFVEC3F PLATED_COPPER_NORMAL::Generate( const RAY& aRay, const HITINFO& aHitInfo
const float noise1 = ( s_perlinNoise.noise( hitPos.x, hitPos.y ) - 0.5f );
const float noise2 = ( s_perlinNoise.noise( hitPos.y, hitPos.x ) - 0.5f );
return SFVEC3F( noise1, noise2, 0.0f ) * 0.1f;
return SFVEC3F( noise1, noise2, -( noise1 + noise2 ) ) * 0.02f;
}
+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 ) )
@@ -2,7 +2,7 @@
* 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-2023 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
@@ -27,6 +27,7 @@
#include <algorithm>
#include <atomic>
#include <chrono>
#include <climits>
#include <thread>
#include "render_3d_raytrace.h"
@@ -35,7 +36,7 @@
#include "3d_fastmath.h"
#include "3d_math.h"
#include "../common_ogl/ogl_utils.h"
#include <core/profile.h> // To use GetRunningMicroSecs or another profiling utility
#include <profile.h> // To use GetRunningMicroSecs or another profiling utility
#include <wx/log.h>
@@ -91,7 +92,7 @@ RENDER_3D_RAYTRACE::~RENDER_3D_RAYTRACE()
int RENDER_3D_RAYTRACE::GetWaitForEditingTimeOut()
{
return 200; // ms
return 1000; // ms
}
@@ -292,7 +293,7 @@ void RENDER_3D_RAYTRACE::render( GLubyte* ptrPBO, REPORTER* aStatusReporter )
if( m_cameraLight )
m_cameraLight->SetDirection( -m_camera.GetDir() );
if( m_boardAdapter.m_Cfg->m_Render.engine == RENDER_ENGINE::OPENGL )
if( m_boardAdapter.GetRenderEngine() == RENDER_ENGINE::OPENGL )
{
// Set all pixels of PBO transparent (Alpha to 0)
// This way it will draw the full buffer but only shows the updated (
@@ -398,7 +399,7 @@ void RENDER_3D_RAYTRACE::renderTracing( GLubyte* ptrPBO, REPORTER* aStatusReport
// or mark it as finished
if( m_blockRenderProgressCount >= m_blockPositions.size() )
{
if( m_boardAdapter.m_Cfg->m_Render.raytrace_post_processing )
if( m_boardAdapter.GetFlag( FL_RENDER_RAYTRACING_POST_PROCESSING ) )
m_renderState = RT_RENDER_STATE_POST_PROCESS_SHADE;
else
m_renderState = RT_RENDER_STATE_FINISH;
@@ -503,7 +504,7 @@ void RENDER_3D_RAYTRACE::renderAntiAliasPackets( const SFVEC3F* aBgColorY,
const HITINFO_PACKET* aHitPck_AA_X1Y1,
const RAY* aRayPck, SFVEC3F* aOutHitColor )
{
const bool is_testShadow = m_boardAdapter.m_Cfg->m_Render.raytrace_shadows;
const bool is_testShadow = m_boardAdapter.GetFlag( FL_RENDER_RAYTRACING_SHADOWS );
for( unsigned int y = 0, i = 0; y < RAYPACKET_DIM; ++y )
{
@@ -651,7 +652,7 @@ void RENDER_3D_RAYTRACE::renderBlockTracing( GLubyte* ptrPBO, signed int iBlock
if( !m_accelerator->Intersect( blockPacket, hitPacket_X0Y0 ) )
{
// If block is empty then set shades and continue
if( m_boardAdapter.m_Cfg->m_Render.raytrace_post_processing )
if( m_boardAdapter.GetFlag( FL_RENDER_RAYTRACING_POST_PROCESSING ) )
{
for( unsigned int y = 0; y < RAYPACKET_DIM; ++y )
{
@@ -669,9 +670,10 @@ void RENDER_3D_RAYTRACE::renderBlockTracing( GLubyte* ptrPBO, signed int iBlock
}
// This will set the output color to be displayed
// If post processing is enabled, it will not reflect the final result (as the final
// color will be computed on post processing) but it is used for report progress
const bool isFinalColor = !m_boardAdapter.m_Cfg->m_Render.raytrace_post_processing;
// If post processing is enabled, it will not reflect the final result
// (as the final color will be computed on post processing)
// but it is used for report progress
const bool isFinalColor = !m_boardAdapter.GetFlag( FL_RENDER_RAYTRACING_POST_PROCESSING );
for( unsigned int y = 0; y < RAYPACKET_DIM; ++y )
{
@@ -696,9 +698,9 @@ void RENDER_3D_RAYTRACE::renderBlockTracing( GLubyte* ptrPBO, signed int iBlock
// Shade original (0, 0) hits ("paint" the intersected objects)
renderRayPackets( bgColor, blockPacket.m_ray, hitPacket_X0Y0,
m_boardAdapter.m_Cfg->m_Render.raytrace_shadows, hitColor_X0Y0 );
m_boardAdapter.GetFlag( FL_RENDER_RAYTRACING_SHADOWS ), hitColor_X0Y0 );
if( m_boardAdapter.m_Cfg->m_Render.raytrace_anti_aliasing )
if( m_boardAdapter.GetFlag( FL_RENDER_RAYTRACING_ANTI_ALIASING ) )
{
SFVEC3F hitColor_AA_X1Y1[RAYPACKET_RAYS_PER_PACKET];
@@ -717,13 +719,16 @@ void RENDER_3D_RAYTRACE::renderBlockTracing( GLubyte* ptrPBO, signed int iBlock
const SFVEC3F& outColor = bgColor[y];
for( unsigned int x = 0; x < RAYPACKET_DIM; ++x, ++i )
{
hitColor_AA_X1Y1[i] = outColor;
}
}
}
else
{
renderRayPackets( bgColor, blockPacket_AA_X1Y1.m_ray, hitPacket_AA_X1Y1,
m_boardAdapter.m_Cfg->m_Render.raytrace_shadows, hitColor_AA_X1Y1 );
m_boardAdapter.GetFlag( FL_RENDER_RAYTRACING_SHADOWS ),
hitColor_AA_X1Y1 );
}
SFVEC3F hitColor_AA_X1Y0[RAYPACKET_RAYS_PER_PACKET];
@@ -732,7 +737,8 @@ void RENDER_3D_RAYTRACE::renderBlockTracing( GLubyte* ptrPBO, signed int iBlock
for( unsigned int i = 0; i < RAYPACKET_RAYS_PER_PACKET; ++i )
{
SFVEC3F color_average = ( hitColor_X0Y0[i] + hitColor_AA_X1Y1[i] ) * SFVEC3F( 0.5f );
const SFVEC3F color_average = ( hitColor_X0Y0[i] +
hitColor_AA_X1Y1[i] ) * SFVEC3F( 0.5f );
hitColor_AA_X1Y0[i] = color_average;
hitColor_AA_X0Y1[i] = color_average;
@@ -778,7 +784,7 @@ void RENDER_3D_RAYTRACE::renderBlockTracing( GLubyte* ptrPBO, signed int iBlock
const uint32_t ptrInc = ( m_realBufferSize.x - RAYPACKET_DIM ) * 4;
if( m_boardAdapter.m_Cfg->m_Render.raytrace_post_processing )
if( m_boardAdapter.GetFlag( FL_RENDER_RAYTRACING_POST_PROCESSING ) )
{
SFVEC2I bPos;
bPos.y = blockPos.y;
@@ -792,7 +798,6 @@ void RENDER_3D_RAYTRACE::renderBlockTracing( GLubyte* ptrPBO, signed int iBlock
const SFVEC3F& hColor = hitColor_X0Y0[i];
if( hitPacket_X0Y0[i].m_hitresult == true )
{
m_postShaderSsao.SetPixelData( bPos.x, bPos.y,
hitPacket_X0Y0[i].m_HitInfo.m_HitNormal,
hColor,
@@ -800,12 +805,9 @@ void RENDER_3D_RAYTRACE::renderBlockTracing( GLubyte* ptrPBO, signed int iBlock
hitPacket_X0Y0[i].m_HitInfo.m_tHit ),
hitPacket_X0Y0[i].m_HitInfo.m_tHit,
hitPacket_X0Y0[i].m_HitInfo.m_ShadowFactor );
}
else
{
m_postShaderSsao.SetPixelData( bPos.x, bPos.y, SFVEC3F( 0.0f ), hColor,
SFVEC3F( 0.0f ), 0, 1.0f );
}
renderFinalColor( ptr, hColor, false );
@@ -835,12 +837,13 @@ void RENDER_3D_RAYTRACE::renderBlockTracing( GLubyte* ptrPBO, signed int iBlock
void RENDER_3D_RAYTRACE::postProcessShading( GLubyte* /* ptrPBO */, REPORTER* aStatusReporter )
{
if( m_boardAdapter.m_Cfg->m_Render.raytrace_post_processing )
if( m_boardAdapter.GetFlag( FL_RENDER_RAYTRACING_POST_PROCESSING ) )
{
if( aStatusReporter )
aStatusReporter->Report( _( "Rendering: Post processing shader" ) );
m_postShaderSsao.SetShadowsEnabled( m_boardAdapter.m_Cfg->m_Render.raytrace_shadows );
m_postShaderSsao.SetShadowsEnabled(
m_boardAdapter.GetFlag( FL_RENDER_RAYTRACING_SHADOWS ) );
std::atomic<size_t> nextBlock( 0 );
std::atomic<size_t> threadsFinished( 0 );
@@ -887,7 +890,7 @@ void RENDER_3D_RAYTRACE::postProcessShading( GLubyte* /* ptrPBO */, REPORTER* aS
void RENDER_3D_RAYTRACE::postProcessBlurFinish( GLubyte* ptrPBO, REPORTER* /* aStatusReporter */ )
{
if( m_boardAdapter.m_Cfg->m_Render.raytrace_post_processing )
if( m_boardAdapter.GetFlag( FL_RENDER_RAYTRACING_POST_PROCESSING ) )
{
// Now blurs the shader result and compute the final color
std::atomic<size_t> nextBlock( 0 );
@@ -1557,7 +1560,8 @@ SFVEC3F RENDER_3D_RAYTRACE::shadeHit( const SFVEC3F& aBgColor, const RAY& aRay,
const SFVEC3F diffuseColorObj = aHitInfo.pHitObject->GetDiffuseColor( aHitInfo );
#if USE_EXPERIMENTAL_SOFT_SHADOWS
bool is_aa_enabled = m_boardAdapter.m_Cfg->m_Render.raytrace_anti_aliasing && !m_isPreview;
const bool is_aa_enabled = m_boardAdapter.GetFlag( FL_RENDER_RAYTRACING_ANTI_ALIASING ) &&
(!m_isPreview);
#endif
float shadow_att_factor_sum = 0.0f;
@@ -1603,8 +1607,9 @@ SFVEC3F RENDER_3D_RAYTRACE::shadeHit( const SFVEC3F& aBgColor, const RAY& aRay,
}
else // Experimental softshadow calculation
{
const unsigned int shadow_number_of_samples =
m_boardAdapter.m_Cfg->m_Render.raytrace_nrsamples_shadows;
m_boardAdapter.m_RtShadowSampleCount;
const float shadow_inc_factor = 1.0f / (float) ( shadow_number_of_samples );
for( unsigned int i = 0; i < shadow_number_of_samples; ++i )
@@ -1620,7 +1625,7 @@ SFVEC3F RENDER_3D_RAYTRACE::shadeHit( const SFVEC3F& aBgColor, const RAY& aRay,
const SFVEC3F unifVector = UniformRandomHemisphereDirection();
const SFVEC3F disturbed_vector_to_light =
glm::normalize( vectorToLight + unifVector *
m_boardAdapter.m_Cfg->m_Render.raytrace_spread_shadows );
m_boardAdapter.m_RtSpreadShadows );
rayToLight.Init( hitPoint, disturbed_vector_to_light );
}
@@ -1665,7 +1670,7 @@ SFVEC3F RENDER_3D_RAYTRACE::shadeHit( const SFVEC3F& aBgColor, const RAY& aRay,
{
// Reflections
if( ( objMaterial->GetReflection() > 0.0f )
&& m_boardAdapter.m_Cfg->m_Render.raytrace_reflections
&& m_boardAdapter.GetFlag( FL_RENDER_RAYTRACING_REFLECTIONS )
&& ( aRecursiveLevel < objMaterial->GetReflectionRecursionCount() ) )
{
const unsigned int reflection_number_of_samples =
@@ -1690,7 +1695,7 @@ SFVEC3F RENDER_3D_RAYTRACE::shadeHit( const SFVEC3F& aBgColor, const RAY& aRay,
const SFVEC3F random_reflectVector =
glm::normalize( reflectVector +
UniformRandomHemisphereDirection() *
m_boardAdapter.m_Cfg->m_Render.raytrace_spread_reflections );
m_boardAdapter.m_RtSpreadReflections );
reflectedRay.Init( hitPoint, random_reflectVector );
}
@@ -1716,7 +1721,7 @@ SFVEC3F RENDER_3D_RAYTRACE::shadeHit( const SFVEC3F& aBgColor, const RAY& aRay,
// Refraction
const float objTransparency = aHitInfo.pHitObject->GetModelTransparency();
if( ( objTransparency > 0.0f ) && m_boardAdapter.m_Cfg->m_Render.raytrace_refractions
if( ( objTransparency > 0.0f ) && m_boardAdapter.GetFlag( FL_RENDER_RAYTRACING_REFRACTIONS )
&& ( aRecursiveLevel < objMaterial->GetRefractionRecursionCount() ) )
{
const float airIndex = 1.000293f;
@@ -1755,7 +1760,7 @@ SFVEC3F RENDER_3D_RAYTRACE::shadeHit( const SFVEC3F& aBgColor, const RAY& aRay,
const SFVEC3F randomizeRefractedVector =
glm::normalize( refractedVector +
UniformRandomHemisphereDirection() *
m_boardAdapter.m_Cfg->m_Render.raytrace_spread_refractions );
m_boardAdapter.m_RtSpreadRefractions );
refractedRay.Init( startPoint, randomizeRefractedVector );
}
@@ -1910,19 +1915,9 @@ void RENDER_3D_RAYTRACE::initializeBlockPositions()
const SFVEC2UI center( m_realBufferSize.x / 2, m_realBufferSize.y / 2 );
std::sort( m_blockPositions.begin(), m_blockPositions.end(),
[&]( const SFVEC2UI& a, const SFVEC2UI& b )
{
[&]( const SFVEC2UI& a, const SFVEC2UI& b ) {
// Sort order: inside out.
float distanceA = distance( a, center );
float distanceB = distance( b, center );
if( distanceA != distanceB )
return distanceA < distanceB;
if( a[0] != b[0] )
return a[0] < b[0];
return a[1] < b[1];
return distance( a, center ) < distance( b, center );
} );
// Create m_shader buffer
@@ -154,7 +154,7 @@ private:
RT_RENDER_STATE m_renderState;
/// Time that the render starts
int64_t m_renderStartTime;
unsigned long int m_renderStartTime;
/// Save the number of blocks progress of the render
size_t m_blockRenderProgressCount;
@@ -229,16 +229,6 @@ bool BBOX_2D::Inside( const SFVEC2F& aPoint ) const
}
bool BBOX_2D::Inside( const BBOX_2D& aBBox ) const
{
wxASSERT( IsInitialized() );
wxASSERT( aBBox.IsInitialized() );
return Inside( aBBox.Min() ) &&
Inside( aBBox.Max() );
}
float BBOX_2D::Area() const
{
SFVEC2F extent = GetExtent();
@@ -132,14 +132,6 @@ public:
*/
bool Inside( const SFVEC2F& aPoint ) const;
/**
* Check if a bounding box is inside this bounding box.
*
* @param aBBox the bounding box to test if it is inside
* @return true if aBBox is smaller and all points are inside
*/
bool Inside( const BBOX_2D& aBBox ) const;
/**
* Calculate the area of a bounding box.
*
@@ -2,7 +2,7 @@
* 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) 1992-2022 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
@@ -22,14 +22,19 @@
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
*/
/**
* @file object_2d.cpp
*/
#include "object_2d.h"
#include <wx/log.h>
#include <map>
OBJECT_2D_STATS *OBJECT_2D_STATS::s_instance = nullptr;
OBJECT_2D::OBJECT_2D( OBJECT_2D_TYPE aObjType, const BOARD_ITEM& aBoardItem ) :
m_boardItem( aBoardItem )
OBJECT_2D::OBJECT_2D( OBJECT_2D_TYPE aObjType, const BOARD_ITEM& aBoardItem )
: m_boardItem(aBoardItem)
{
m_obj_type = aObjType;
OBJECT_2D_STATS::Instance().AddOne( aObjType );
@@ -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;
@@ -118,19 +118,19 @@ bool TRIANGLE_2D::IsPointInside( const SFVEC2F& aPoint ) const
}
void ConvertPolygonToTriangles( const SHAPE_POLY_SET& aPolyList, CONTAINER_2D_BASE& aDstContainer,
void ConvertPolygonToTriangles( SHAPE_POLY_SET& aPolyList, CONTAINER_2D_BASE& aDstContainer,
float aBiuTo3dUnitsScale, const BOARD_ITEM& aBoardItem )
{
VECTOR2I a;
VECTOR2I b;
VECTOR2I c;
const_cast<SHAPE_POLY_SET&>( aPolyList ).CacheTriangulation( false );
aPolyList.CacheTriangulation( false );
const double conver_d = (double)aBiuTo3dUnitsScale;
for( unsigned int j = 0; j < aPolyList.TriangulatedPolyCount(); j++ )
{
const SHAPE_POLY_SET::TRIANGULATED_POLYGON* triPoly = aPolyList.TriangulatedPolygon( j );
auto triPoly = aPolyList.TriangulatedPolygon( j );
for( size_t i = 0; i < triPoly->GetTriangleCount(); i++ )
{
@@ -64,6 +64,6 @@ private:
};
void ConvertPolygonToTriangles( const SHAPE_POLY_SET& aPolyList, CONTAINER_2D_BASE& aDstContainer,
void ConvertPolygonToTriangles( SHAPE_POLY_SET& aPolyList, CONTAINER_2D_BASE& aDstContainer,
float aBiuTo3dUnitsScale, const BOARD_ITEM& aBoardItem );
#endif // _TRIANGLE_2D_H_
@@ -238,16 +238,6 @@ bool BBOX_3D::Inside( const SFVEC3F& aPoint ) const
}
bool BBOX_3D::Inside( const BBOX_3D& aBBox ) const
{
wxASSERT( IsInitialized() );
wxASSERT( aBBox.IsInitialized() );
return Inside( aBBox.Min() ) &&
Inside( aBBox.Max() );
}
float BBOX_3D::Volume() const
{
wxASSERT( IsInitialized() );
@@ -264,6 +254,47 @@ SFVEC3F BBOX_3D::Offset( const SFVEC3F& p ) const
}
/// @todo Why are we keeping both implementations of Intersect()?
// Intersection code based on the book:
// "Physical Based Ray Tracing" (by Matt Pharr and Greg Humphrey)
// https://github.com/mmp/pbrt-v2/blob/master/src/core/geometry.cpp#L68
#if 0
bool BBOX_3D::Intersect( const RAY& aRay, float* aOutHitt0, float* aOutHitt1 ) const
{
float t0 = 0.0f;
float t1 = FLT_MAX;
for( unsigned int i = 0; i < 3; ++i )
{
// Update interval for _i_th bounding box slab
float tNear = ( m_min[i] - aRay.m_Origin[i] ) * aRay.m_InvDir[i];
float tFar = ( m_max[i] - aRay.m_Origin[i] ) * aRay.m_InvDir[i];
// Update parametric interval from slab intersection
if( tNear > tFar )
{
// Swap
float ftemp = tNear;
tNear = tFar;
tFar = ftemp;
}
t0 = tNear > t0 ? tNear : t0;
t1 = tFar < t1 ? tFar : t1;
if( t0 > t1 )
return false;
}
if( aOutHitt0 )
*aOutHitt0 = t0;
if( aOutHitt1 )
*aOutHitt1 = t1;
return true;
}
#else
// https://github.com/mmp/pbrt-v2/blob/master/src/accelerators/bvh.cpp#L126
bool BBOX_3D::Intersect( const RAY& aRay, float* aOutHitt0, float* aOutHitt1 ) const
{
@@ -301,6 +332,7 @@ bool BBOX_3D::Intersect( const RAY& aRay, float* aOutHitt0, float* aOutHitt1 ) c
return true;
}
#endif
void BBOX_3D::ApplyTransformation( glm::mat4 aTransformMatrix )
@@ -317,3 +349,22 @@ void BBOX_3D::ApplyTransformation( glm::mat4 aTransformMatrix )
}
void BBOX_3D::ApplyTransformationAA( glm::mat4 aTransformMatrix )
{
wxASSERT( IsInitialized() );
// apply the transformation matrix for each of vertices of the bounding box
// and make a union with all vertices
BBOX_3D tmpBBox = BBOX_3D(
SFVEC3F( aTransformMatrix * glm::vec4( m_min.x, m_min.y, m_min.z, 1.0f ) ) );
tmpBBox.Union( SFVEC3F( aTransformMatrix * glm::vec4( m_max.x, m_min.y, m_min.z, 1.0f ) ) );
tmpBBox.Union( SFVEC3F( aTransformMatrix * glm::vec4( m_min.x, m_max.y, m_min.z, 1.0f ) ) );
tmpBBox.Union( SFVEC3F( aTransformMatrix * glm::vec4( m_min.x, m_min.y, m_max.z, 1.0f ) ) );
tmpBBox.Union( SFVEC3F( aTransformMatrix * glm::vec4( m_min.x, m_max.y, m_max.z, 1.0f ) ) );
tmpBBox.Union( SFVEC3F( aTransformMatrix * glm::vec4( m_max.x, m_max.y, m_min.z, 1.0f ) ) );
tmpBBox.Union( SFVEC3F( aTransformMatrix * glm::vec4( m_max.x, m_min.y, m_max.z, 1.0f ) ) );
tmpBBox.Union( SFVEC3F( aTransformMatrix * glm::vec4( m_max.x, m_max.y, m_max.z, 1.0f ) ) );
m_min = tmpBBox.m_min;
m_max = tmpBBox.m_max;
}
@@ -125,14 +125,6 @@ public:
*/
bool Inside( const SFVEC3F& aPoint ) const;
/**
* Check if a bounding box is inside this bounding box.
*
* @param aBBox the bounding box to test if it is inside
* @return true if aBBox is smaller and all points are inside
*/
bool Inside( const BBOX_3D& aBBox ) const;
/**
* Apply a transformation matrix to the box points.
*
@@ -140,6 +132,14 @@ public:
*/
void ApplyTransformation( glm::mat4 aTransformMatrix );
/**
* Apply a transformation matrix to the box points and recalculate it
* to fit an axis aligned bounding box.
*
* @param aTransformMatrix matrix to apply to the points of the bounding box.
*/
void ApplyTransformationAA( glm::mat4 aTransformMatrix );
/**
* Calculate the volume of a bounding box.
*
@@ -23,7 +23,8 @@
*/
/**
* @file cylinder_3d.cpp
* @file ccylinder.cpp
* @brief
*/
#include "3d_fastmath.h"
@@ -1,8 +1,8 @@
/*
* 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) 1992-2022 KiCad Developers, see AUTHORS.txt for contributors.
* Copyright (C) 2015-2016 Mario Luzeiro <mrluzeiro@ua.pt>
* 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
@@ -25,10 +25,6 @@
#include "layer_item_3d.h"
#include "3d_fastmath.h"
#include <wx/debug.h>
#include <advanced_config.h>
extern float g_BevelThickness3DU;
LAYER_ITEM::LAYER_ITEM( const OBJECT_2D* aObject2D, float aZMin, float aZMax ) :
@@ -227,53 +223,18 @@ bool LAYER_ITEM::Intersect( const RAY& aRay, HITINFO& aHitInfo ) const
{
aHitInfo.m_tHit = t;
aHitInfo.m_HitPoint = hitPoint;
aHitInfo.pHitObject = this;
const float zNormalDir = hit_top?1.0f:hit_bot?-1.0f:0.0f;
if( ( outNormal.x == 0.0f ) && ( outNormal.y == 0.0f ) )
{
aHitInfo.m_HitNormal = SFVEC3F( 0.0f, 0.0f, zNormalDir );
aHitInfo.m_HitNormal = SFVEC3F( 0.0f, 0.0f, 1.0f );
}
else
{
// Calculate smooth bevel normal
float zBend = 0.0f;
if( hit_top || hit_bot )
{
float zDistanceToTopOrBot;
// Calculate the distance from hitpoint z to the Max/Min z of the layer
if( hit_top )
{
zDistanceToTopOrBot = ( m_bbox.Max().z - hitPoint.z );
}
else
{
zDistanceToTopOrBot = ( hitPoint.z - m_bbox.Min().z );
}
// For items that are > than g_BevelThickness3DU
// (eg on board vias / plated holeS) use a factor based on m_bbox.GetExtent().z
const float bevelThickness = glm::max( g_BevelThickness3DU,
m_bbox.GetExtent().z *
(float)ADVANCED_CFG::GetCfg().m_3DRT_BevelExtentFactor );
if( ( zDistanceToTopOrBot > 0.0f ) && ( zDistanceToTopOrBot < bevelThickness ) )
{
// Invert and Normalize the distance 0..1
zBend = ( bevelThickness - zDistanceToTopOrBot ) / bevelThickness;
}
}
const SFVEC3F normalLateral = SFVEC3F( outNormal.x, outNormal.y, 0.0f );
const SFVEC3F normalTopBot = SFVEC3F( 0.0f, 0.0f, zNormalDir );
// Interpolate between the regular lateral normal and the top/bot normal
aHitInfo.m_HitNormal = glm::mix( normalLateral, normalTopBot, zBend );
aHitInfo.m_HitNormal = SFVEC3F( outNormal.x, outNormal.y, 0.0f );
}
aHitInfo.pHitObject = this;
m_material->Generate( aHitInfo.m_HitNormal, aRay, aHitInfo );
return true;
@@ -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 )
+1 -1
View File
@@ -98,7 +98,7 @@ protected:
*/
std::unique_ptr<BUSY_INDICATOR> CreateBusyIndicator() const;
///< the canvas to display the scene
///< the canvas to disply the scene
EDA_3D_CANVAS* m_canvas;
///< Settings reference in use for this render.
+49 -23
View File
@@ -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.
*/
@@ -33,23 +33,22 @@
#include "../3d_math.h"
#include <wx/log.h>
#include <glm/gtc/quaternion.hpp>
// stdlib
#include <algorithm>
TRACK_BALL::TRACK_BALL( float aInitialDistance ) :
CAMERA( aInitialDistance )
{
wxLogTrace( m_logTrace, wxT( "TRACK_BALL::TRACK_BALL" ) );
memset( m_quat, 0, sizeof( m_quat ) );
memset( m_quat_t0, 0, sizeof( m_quat_t0 ) );
memset( m_quat_t1, 0, sizeof( m_quat_t1 ) );
trackball( m_quat, 0.0, 0.0, 0.0, 0.0 );
trackball( m_quat_t0, 0.0, 0.0, 0.0, 0.0 );
trackball( m_quat_t1, 0.0, 0.0, 0.0, 0.0 );
}
void TRACK_BALL::Drag( const wxPoint& aNewMousePosition )
{
m_parametersChanged = true;
@@ -65,15 +64,34 @@ void TRACK_BALL::Drag( const wxPoint& aNewMousePosition )
zoom * ( 2.0 * aNewMousePosition.x - m_windowSize.x ) / m_windowSize.x,
zoom * ( m_windowSize.y - 2.0 * aNewMousePosition.y ) / m_windowSize.y );
float spin_matrix[4][4];
build_rotmatrix( spin_matrix, spin_quat );
m_rotationMatrix = glm::make_mat4( &spin_matrix[0][0] ) * m_rotationMatrix;
add_quats( spin_quat, m_quat, m_quat );
float rotationMatrix[4][4];
build_rotmatrix( rotationMatrix, m_quat );
m_rotationMatrix = glm::make_mat4( &rotationMatrix[0][0] );
updateViewMatrix();
updateFrustum();
}
void TRACK_BALL::SetLookAtPos( const SFVEC3F& aLookAtPos )
{
if( m_lookat_pos != aLookAtPos )
{
m_lookat_pos = aLookAtPos;
updateViewMatrix();
updateFrustum();
m_parametersChanged = true;
}
}
void TRACK_BALL::Pan( const wxPoint& aNewMousePosition )
{
m_parametersChanged = true;
@@ -88,7 +106,7 @@ void TRACK_BALL::Pan( const wxPoint& aNewMousePosition )
else // PROJECTION_TYPE::PERSPECTIVE
{
// Unproject the coordinates using the precomputed frustum tangent (zoom level dependent)
const float panFactor = -m_camera_pos.z * m_frustum.tang * 2;
const float panFactor = -m_camera_pos.z * m_frustum.tang * 2;
m_camera_pos.x -= panFactor * m_frustum.ratio *
( m_lastPosition.x - aNewMousePosition.x ) / m_windowSize.x;
m_camera_pos.y -= panFactor * ( aNewMousePosition.y - m_lastPosition.y ) / m_windowSize.y;
@@ -98,6 +116,7 @@ void TRACK_BALL::Pan( const wxPoint& aNewMousePosition )
updateFrustum();
}
void TRACK_BALL::Pan( const SFVEC3F& aDeltaOffsetInc )
{
m_parametersChanged = true;
@@ -108,11 +127,22 @@ void TRACK_BALL::Pan( const SFVEC3F& aDeltaOffsetInc )
updateFrustum();
}
void TRACK_BALL::Pan_T1( const SFVEC3F& aDeltaOffsetInc )
{
m_camera_pos_t1 = m_camera_pos + aDeltaOffsetInc;
}
void TRACK_BALL::Reset()
{
CAMERA::Reset();
memset( m_quat, 0, sizeof( m_quat ) );
trackball( m_quat, 0.0, 0.0, 0.0, 0.0 );
}
void TRACK_BALL::Reset_T1()
{
CAMERA::Reset_T1();
@@ -121,20 +151,16 @@ void TRACK_BALL::Reset_T1()
trackball( m_quat_t1, 0.0, 0.0, 0.0, 0.0 );
}
void TRACK_BALL::SetT0_and_T1_current_T()
{
CAMERA::SetT0_and_T1_current_T();
double quat[4];
// Charge the quaternions with the current rotation matrix to allow dual input.
std::copy_n( glm::value_ptr( glm::conjugate( glm::quat_cast( m_rotationMatrix ) ) ),
sizeof( quat ) / sizeof( quat[0] ), quat );
memcpy( m_quat_t0, quat, sizeof( quat ) );
memcpy( m_quat_t1, quat, sizeof( quat ) );
memcpy( m_quat_t0, m_quat, sizeof( m_quat ) );
memcpy( m_quat_t1, m_quat, sizeof( m_quat ) );
}
void TRACK_BALL::Interpolate( float t )
{
wxASSERT( t >= 0.0f );
@@ -158,15 +184,15 @@ void TRACK_BALL::Interpolate( float t )
}
const float t0 = 1.0f - t;
double quat[4];
quat[0] = m_quat_t0[0] * t0 + m_quat_t1[0] * t;
quat[1] = m_quat_t0[1] * t0 + m_quat_t1[1] * t;
quat[2] = m_quat_t0[2] * t0 + m_quat_t1[2] * t;
quat[3] = m_quat_t0[3] * t0 + m_quat_t1[3] * t;
m_quat[0] = m_quat_t0[0] * t0 + m_quat_t1[0] * t;
m_quat[1] = m_quat_t0[1] * t0 + m_quat_t1[1] * t;
m_quat[2] = m_quat_t0[2] * t0 + m_quat_t1[2] * t;
m_quat[3] = m_quat_t0[3] * t0 + m_quat_t1[3] * t;
float rotationMatrix[4][4];
build_rotmatrix( rotationMatrix, quat );
build_rotmatrix( rotationMatrix, m_quat );
m_rotationMatrix = glm::make_mat4( &rotationMatrix[0][0] );
+7 -2
View File
@@ -30,7 +30,7 @@
#ifndef TRACK_BALL_H
#define TRACK_BALL_H
#include <gal/3d/camera.h>
#include "camera.h"
class TRACK_BALL : public CAMERA
@@ -50,6 +50,10 @@ public:
void Pan_T1( const SFVEC3F& aDeltaOffsetInc ) override;
void SetLookAtPos( const SFVEC3F& aLookAtPos ) override;
void Reset() override;
void Reset_T1() override;
void SetT0_and_T1_current_T() override;
@@ -58,8 +62,9 @@ public:
private:
/**
* interpolate quaternions of the trackball
* quarternion of the trackball
*/
double m_quat[4];
double m_quat_t0[4];
double m_quat_t1[4];
};
+29 -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,36 @@ 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->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 +149,4 @@ void EDA_3D_VIEWER_FRAME::doReCreateMenuBar()
AddStandardHelpMenu( menuBar );
SetMenuBar( menuBar );
delete oldMenuBar;
}
+5 -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-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
@@ -26,11 +25,10 @@
*/
#include <wx/wupdlock.h>
#include <wx/choice.h>
#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>
@@ -97,9 +95,9 @@ 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->KiRealize();
}
+267 -344
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-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,23 +28,19 @@
#include <wx/wupdlock.h>
#include <wx/clipbrd.h>
#include <wx/filedlg.h>
#include <wx/dialog.h>
#include <wx/treebook.h>
#include "eda_3d_viewer_frame.h"
#include "dialogs/appearance_controls_3D.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 <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>
#include <settings/common_settings.h>
#include <settings/settings_manager.h>
#include <tool/action_manager.h>
@@ -53,12 +48,14 @@
#include <tool/tool_manager.h>
#include <tool/tool_dispatcher.h>
#include <tool/action_toolbar.h>
#include <widgets/wx_infobar.h>
#include <widgets/wx_aui_utils.h>
#include <widgets/infobar.h>
#include <widgets/paged_dialog.h>
#include <dialogs/panel_3D_display_options.h>
#include <dialogs/panel_3D_opengl_options.h>
#include <dialogs/panel_3D_raytracing_options.h>
#include <dialogs/panel_3D_colors.h>
#include <panel_hotkeys_editor.h>
#include <wildcards_and_files_ext.h>
#include <project_pcb.h>
#include <3d_navlib/nl_3d_viewer_plugin.h>
/**
* Flag to enable 3D viewer main frame window debug tracing.
@@ -70,7 +67,7 @@
const wxChar* EDA_3D_VIEWER_FRAME::m_logTrace = wxT( "KI_TRACE_EDA_3D_VIEWER" );
BEGIN_EVENT_TABLE( EDA_3D_VIEWER_FRAME, KIWAY_PLAYER )
BEGIN_EVENT_TABLE( EDA_3D_VIEWER_FRAME, EDA_BASE_FRAME )
EVT_ACTIVATE( EDA_3D_VIEWER_FRAME::OnActivate )
EVT_SET_FOCUS( EDA_3D_VIEWER_FRAME::OnSetFocus )
@@ -79,27 +76,26 @@ BEGIN_EVENT_TABLE( EDA_3D_VIEWER_FRAME, KIWAY_PLAYER )
EDA_3D_VIEWER_FRAME::Process_Special_Functions )
EVT_MENU( wxID_CLOSE, EDA_3D_VIEWER_FRAME::Exit3DFrame )
EVT_MENU( ID_RENDER_CURRENT_VIEW, EDA_3D_VIEWER_FRAME::onRenderEngineSelection )
EVT_MENU( ID_DISABLE_RAY_TRACING, EDA_3D_VIEWER_FRAME::onDisableRayTracing )
EVT_MENU( ID_RENDER_CURRENT_VIEW, EDA_3D_VIEWER_FRAME::OnRenderEngineSelection )
EVT_MENU( ID_DISABLE_RAY_TRACING, EDA_3D_VIEWER_FRAME::OnDisableRayTracing )
EVT_CLOSE( EDA_3D_VIEWER_FRAME::OnCloseWindow )
END_EVENT_TABLE()
EDA_3D_VIEWER_FRAME::EDA_3D_VIEWER_FRAME( KIWAY* aKiway, PCB_BASE_FRAME* aParent,
const wxString& aTitle, long style ) :
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 ),
wxDefaultSize, style, QUALIFIED_VIEWER3D_FRAMENAME( aParent ) ),
m_mainToolBar( nullptr ),
m_canvas( nullptr ),
m_currentCamera( m_trackBallCamera ),
m_trackBallCamera( 2 * RANGE_SCALE_3D ),
m_spaceMouse( nullptr )
m_trackBallCamera( 2 * RANGE_SCALE_3D )
{
wxLogTrace( m_logTrace, wxT( "EDA_3D_VIEWER_FRAME::EDA_3D_VIEWER_FRAME %s" ), aTitle );
m_disable_ray_tracing = false;
m_aboutTitle = _HKI( "KiCad 3D Viewer" );
m_aboutTitle = _( "KiCad 3D Viewer" );
// Give it an icon
wxIcon icon;
@@ -107,29 +103,25 @@ 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 );
SETTINGS_MANAGER& mgr = Pgm().GetSettingsManager();
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( m_boardAdapter.GetAntiAliasingMode() ),
m_boardAdapter, m_currentCamera,
Prj().Get3DCacheManager() );
m_canvas = new EDA_3D_CANVAS( this, OGL_ATT_LIST::GetAttributesList( aaMode ), m_boardAdapter,
m_currentCamera,
PROJECT_PCB::Get3DCacheManager( &Prj() ) );
auto config = Pgm().GetSettingsManager().GetAppSettings<EDA_3D_VIEWER_SETTINGS>();
LoadSettings( config );
m_appearancePanel = new APPEARANCE_CONTROLS_3D( this, GetCanvas() );
LoadSettings( cfg );
// Some settings need the canvas
loadCommonSettings();
m_appearancePanel->SetUserViewports( Prj().GetProjectFile().m_Viewports3D );
// Create the manager
m_toolManager = new TOOL_MANAGER;
m_toolManager->SetEnvironment( GetBoard(), nullptr, nullptr, cfg, this );
m_toolManager->SetEnvironment( GetBoard(), nullptr, nullptr, config, this );
m_actions = new EDA_3D_ACTIONS();
m_toolDispatcher = new TOOL_DISPATCHER( m_toolManager );
@@ -143,56 +135,33 @@ EDA_3D_VIEWER_FRAME::EDA_3D_VIEWER_FRAME( KIWAY* aKiway, PCB_BASE_FRAME* aParent
setupUIConditions();
if( EDA_3D_CONTROLLER* ctrlTool = GetToolManager()->GetTool<EDA_3D_CONTROLLER>() )
ctrlTool->SetRotationIncrement( cfg->m_Camera.rotation_increment );
ctrlTool->SetRotationIncrement( config->m_Camera.rotation_increment );
// 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( "MainToolbar" ).Top().Layer( 6 ) );
m_auimgr.AddPane( m_infoBar, EDA_PANE().InfoBar().Name( "InfoBar" ).Top().Layer(1) );
m_auimgr.AddPane( m_canvas, EDA_PANE().Canvas().Name( "DrawFrame" ).Center() );
// Call Update() to fix all pane default sizes, especially the "InfoBar" pane before
// hiding it.
m_auimgr.Update();
// We don't want the infobar displayed right away
m_auimgr.GetPane( wxS( "InfoBar" ) ).Hide();
m_auimgr.GetPane( "InfoBar" ).Hide();
m_auimgr.Update();
m_canvas->SetInfoBar( m_infoBar );
m_canvas->SetStatusBar( status_bar );
try
{
m_spaceMouse = new NL_3D_VIEWER_PLUGIN( m_canvas );
}
catch( const std::system_error& e )
{
wxLogTrace( wxT( "KI_TRACE_NAVLIB" ), e.what() );
}
// 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.
@@ -202,13 +171,13 @@ EDA_3D_VIEWER_FRAME::EDA_3D_VIEWER_FRAME( KIWAY* aKiway, PCB_BASE_FRAME* aParent
EDA_3D_VIEWER_FRAME::~EDA_3D_VIEWER_FRAME()
{
delete m_spaceMouse;
Prj().GetProjectFile().m_Viewports3D = m_appearancePanel->GetUserViewports();
m_canvas->SetEventDispatcher( nullptr );
m_auimgr.UnInit();
// m_canvas delete will be called by wxWidget manager
//delete m_canvas;
//m_canvas = nullptr;
}
@@ -220,192 +189,75 @@ void EDA_3D_VIEWER_FRAME::setupUIConditions()
EDA_3D_CONDITIONS cond( &m_boardAdapter );
// Helper to define check conditions
#define FlagCheck( x ) ACTION_CONDITIONS().Check( cond.Flag( x ) )
#define GridSizeCheck( x ) ACTION_CONDITIONS().Check( cond.GridSize( x ) )
auto raytracing =
auto raytracingCondition =
[this]( const SELECTION& aSel )
{
return m_boardAdapter.m_Cfg->m_Render.engine != RENDER_ENGINE::OPENGL;
return m_boardAdapter.GetRenderEngine() != RENDER_ENGINE::OPENGL;
};
auto showTH =
[this]( const SELECTION& aSel )
{
return m_boardAdapter.m_Cfg->m_Render.show_footprints_normal;
};
auto showSMD =
[this]( const SELECTION& aSel )
{
return m_boardAdapter.m_Cfg->m_Render.show_footprints_insert;
};
auto showVirtual =
[this]( const SELECTION& aSel )
{
return m_boardAdapter.m_Cfg->m_Render.show_footprints_virtual;
};
auto show_NotInPosfile =
[this]( const SELECTION& aSel )
{
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;
};
auto showAxes =
[this]( const SELECTION& aSel )
{
return m_boardAdapter.m_Cfg->m_Render.show_axis;
};
auto ortho =
RegisterUIUpdateHandler( ID_RENDER_CURRENT_VIEW,
ACTION_CONDITIONS().Check( raytracingCondition ) );
mgr->SetConditions( EDA_3D_ACTIONS::showTHT, FlagCheck( FL_FP_ATTRIBUTES_NORMAL ) );
mgr->SetConditions( EDA_3D_ACTIONS::showSMD, FlagCheck( FL_FP_ATTRIBUTES_NORMAL_INSERT ) );
mgr->SetConditions( EDA_3D_ACTIONS::showVirtual, FlagCheck( FL_FP_ATTRIBUTES_VIRTUAL ) );
mgr->SetConditions( EDA_3D_ACTIONS::showBBoxes, FlagCheck( FL_RENDER_OPENGL_SHOW_MODEL_BBOX ) );
mgr->SetConditions( EDA_3D_ACTIONS::showAxis, FlagCheck( FL_AXIS ) );
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 ) );
auto orthoCondition =
[this]( const SELECTION& )
{
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 ) );
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::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::toggleOrtho, ACTION_CONDITIONS().Check( orthoCondition ) );
#undef FlagCheck
#undef GridSizeCheck
}
bool EDA_3D_VIEWER_FRAME::TryBefore( wxEvent& aEvent )
void EDA_3D_VIEWER_FRAME::InstallPreferences( PAGED_DIALOG* aParent,
PANEL_HOTKEYS_EDITOR* aHotkeysPanel )
{
static bool s_presetSwitcherShown = false;
static bool s_viewportSwitcherShown = false;
wxTreebook* book = aParent->GetTreebook();
// wxWidgets generates no key events for the tab key when the ctrl key is held down. One
// way around this is to look at all events and inspect the keyboard state of the tab key.
// However, this runs into issues on some linux VMs where querying the keyboard state is
// very slow. Fortunately we only use ctrl-tab on Mac, so we implement this lovely hack:
#ifdef __WXMAC__
if( wxGetKeyState( WXK_TAB ) )
#else
if( ( aEvent.GetEventType() == wxEVT_CHAR || aEvent.GetEventType() == wxEVT_CHAR_HOOK )
&& 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();
book->AddPage( new wxPanel( book ), _( "3D Viewer" ) );
book->AddSubPage( new PANEL_3D_DISPLAY_OPTIONS( this, book ), _( "General" ) );
book->AddSubPage( new PANEL_3D_OPENGL_OPTIONS( this, book ), _( "Realtime Renderer" ) );
book->AddSubPage( new PANEL_3D_RAYTRACING_OPTIONS( this, book ), _( "Raytracing Renderer" ) );
book->AddSubPage( new PANEL_3D_COLORS( this, book ), _( "Colors" ) );
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( this->IsActive() )
{
const wxArrayString& viewportMRU = m_appearancePanel->GetViewportsMRU();
if( viewportMRU.size() > 0 )
{
EDA_VIEW_SWITCHER switcher( this, viewportMRU, VIEWPORT_SWITCH_KEY );
s_viewportSwitcherShown = true;
switcher.ShowModal();
s_viewportSwitcherShown = false;
int idx = switcher.GetSelection();
if( idx >= 0 && idx < (int) viewportMRU.size() )
m_appearancePanel->ApplyViewport( viewportMRU[idx] );
return true;
}
}
}
}
return wxFrame::TryBefore( aEvent );
}
void EDA_3D_VIEWER_FRAME::handleIconizeEvent( wxIconizeEvent& aEvent )
{
KIWAY_PLAYER::handleIconizeEvent( aEvent );
if( m_spaceMouse && aEvent.IsIconized() )
m_spaceMouse->SetFocus( false );
aHotkeysPanel->AddHotKeys( GetToolManager() );
}
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();
}
@@ -413,14 +265,14 @@ void EDA_3D_VIEWER_FRAME::NewDisplay( bool aForceImmediateRedraw )
void EDA_3D_VIEWER_FRAME::Redraw()
{
// Only update in OpenGL for an interactive interaction
if( m_boardAdapter.m_Cfg->m_Render.engine == RENDER_ENGINE::OPENGL )
if( m_boardAdapter.GetRenderEngine() == RENDER_ENGINE::OPENGL )
m_canvas->Request_refresh( true );
}
void EDA_3D_VIEWER_FRAME::refreshRender()
{
if( m_boardAdapter.m_Cfg->m_Render.engine == RENDER_ENGINE::OPENGL )
if( m_boardAdapter.GetRenderEngine() == RENDER_ENGINE::OPENGL )
m_canvas->Request_refresh();
else
NewDisplay( true );
@@ -439,14 +291,13 @@ 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();
// m_canvas delete will be called by wxWidget manager
//delete m_canvas;
//m_canvas = nullptr;
Destroy();
event.Skip( true );
}
@@ -497,31 +348,31 @@ void EDA_3D_VIEWER_FRAME::Process_Special_Functions( wxCommandEvent &event )
}
void EDA_3D_VIEWER_FRAME::onRenderEngineSelection( wxCommandEvent &event )
void EDA_3D_VIEWER_FRAME::OnRenderEngineSelection( wxCommandEvent &event )
{
RENDER_ENGINE& engine = m_boardAdapter.m_Cfg->m_Render.engine;
RENDER_ENGINE old_engine = engine;
const RENDER_ENGINE old_engine = m_boardAdapter.GetRenderEngine();
if( old_engine == RENDER_ENGINE::OPENGL )
engine = RENDER_ENGINE::RAYTRACING;
m_boardAdapter.SetRenderEngine( RENDER_ENGINE::RAYTRACING );
else
engine = RENDER_ENGINE::OPENGL;
m_boardAdapter.SetRenderEngine( RENDER_ENGINE::OPENGL );
wxLogTrace( m_logTrace, wxT( "EDA_3D_VIEWER_FRAME::OnRenderEngineSelection type %s " ),
engine == RENDER_ENGINE::RAYTRACING ? wxT( "raytracing" ) : wxT( "realtime" ) );
m_boardAdapter.GetRenderEngine() == RENDER_ENGINE::RAYTRACING ? wxT( "raytracing" )
: wxT( "realtime" ) );
if( old_engine != engine )
if( old_engine != m_boardAdapter.GetRenderEngine() )
RenderEngineChanged();
}
void EDA_3D_VIEWER_FRAME::onDisableRayTracing( wxCommandEvent& aEvent )
void EDA_3D_VIEWER_FRAME::OnDisableRayTracing( wxCommandEvent& aEvent )
{
wxLogTrace( m_logTrace, wxT( "EDA_3D_VIEWER_FRAME::%s disabling ray tracing." ),
__WXFUNCTION__ );
m_disable_ray_tracing = true;
m_boardAdapter.m_Cfg->m_Render.engine = RENDER_ENGINE::OPENGL;
m_boardAdapter.SetRenderEngine( RENDER_ENGINE::OPENGL );
}
@@ -540,9 +391,6 @@ void EDA_3D_VIEWER_FRAME::OnActivate( wxActivateEvent &aEvent )
m_canvas->SetFocus();
}
if( m_spaceMouse )
m_spaceMouse->SetFocus( aEvent.GetActive() );
aEvent.Skip(); // required under wxMAC
}
@@ -568,35 +416,109 @@ void EDA_3D_VIEWER_FRAME::LoadSettings( APP_SETTINGS_BASE *aCfg )
if( cfg )
{
applySettings( cfg );
m_boardAdapter.m_RtCameraLightColor =
m_boardAdapter.GetColor( cfg->m_Render.raytrace_lightColorCamera );
m_boardAdapter.m_RtLightColorTop =
m_boardAdapter.GetColor( cfg->m_Render.raytrace_lightColorTop );
m_boardAdapter.m_RtLightColorBottom =
m_boardAdapter.GetColor( cfg->m_Render.raytrace_lightColorBottom );
m_boardAdapter.SetBoard( GetBoard() );
m_boardAdapter.m_RtLightColor.resize( cfg->m_Render.raytrace_lightColor.size() );
m_boardAdapter.m_RtLightSphericalCoords.resize( cfg->m_Render.raytrace_lightColor.size() );
// 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 )
for( size_t i = 0; i < cfg->m_Render.raytrace_lightColor.size(); ++i )
{
wxString legacyColorsPresetName = _( "legacy colors" );
m_boardAdapter.m_RtLightColor[i] =
m_boardAdapter.GetColor( cfg->m_Render.raytrace_lightColor[i] );
cfg->m_UseStackupColors = false;
SFVEC2F sphericalCoord =
SFVEC2F( ( cfg->m_Render.raytrace_lightElevation[i] + 90.0f ) / 180.0f,
cfg->m_Render.raytrace_lightAzimuth[i] / 180.0f );
if( !cfg->FindPreset( legacyColorsPresetName ) )
{
cfg->m_LayerPresets.emplace_back( legacyColorsPresetName,
GetAdapter().GetDefaultVisibleLayers(),
GetAdapter().GetDefaultColors() );
}
sphericalCoord.x = glm::clamp( sphericalCoord.x, 0.0f, 1.0f );
sphericalCoord.y = glm::clamp( sphericalCoord.y, 0.0f, 2.0f );
cfg->m_CurrentPreset = wxEmptyString;
m_boardAdapter.m_RtLightSphericalCoords[i] = sphericalCoord;
}
m_boardAdapter.InitSettings( nullptr, nullptr );
#define TRANSFER_SETTING( flag, field ) m_boardAdapter.SetFlag( flag, cfg->m_Render.field )
if( m_appearancePanel )
m_appearancePanel->CommonSettingsChanged();
TRANSFER_SETTING( FL_USE_REALISTIC_MODE, realistic );
TRANSFER_SETTING( FL_SUBTRACT_MASK_FROM_SILK, subtract_mask_from_silk );
// OpenGL options
TRANSFER_SETTING( FL_RENDER_OPENGL_COPPER_THICKNESS, opengl_copper_thickness );
TRANSFER_SETTING( FL_RENDER_OPENGL_SHOW_MODEL_BBOX, opengl_show_model_bbox );
TRANSFER_SETTING( FL_HIGHLIGHT_ROLLOVER_ITEM, opengl_highlight_on_rollover );
TRANSFER_SETTING( FL_RENDER_OPENGL_AA_DISABLE_ON_MOVE, opengl_AA_disableOnMove );
TRANSFER_SETTING( FL_RENDER_OPENGL_THICKNESS_DISABLE_ON_MOVE, opengl_thickness_disableOnMove );
TRANSFER_SETTING( FL_RENDER_OPENGL_VIAS_DISABLE_ON_MOVE, opengl_vias_disableOnMove );
TRANSFER_SETTING( FL_RENDER_OPENGL_HOLES_DISABLE_ON_MOVE, opengl_holes_disableOnMove );
// Raytracing options
TRANSFER_SETTING( FL_RENDER_RAYTRACING_SHADOWS, raytrace_shadows );
TRANSFER_SETTING( FL_RENDER_RAYTRACING_BACKFLOOR, raytrace_backfloor );
TRANSFER_SETTING( FL_RENDER_RAYTRACING_REFRACTIONS, raytrace_refractions );
TRANSFER_SETTING( FL_RENDER_RAYTRACING_REFLECTIONS, raytrace_reflections );
TRANSFER_SETTING( FL_RENDER_RAYTRACING_POST_PROCESSING, raytrace_post_processing );
TRANSFER_SETTING( FL_RENDER_RAYTRACING_ANTI_ALIASING, raytrace_anti_aliasing );
TRANSFER_SETTING( FL_RENDER_RAYTRACING_PROCEDURAL_TEXTURES, raytrace_procedural_textures );
TRANSFER_SETTING( FL_AXIS, show_axis );
TRANSFER_SETTING( FL_FP_ATTRIBUTES_NORMAL, show_footprints_normal );
TRANSFER_SETTING( FL_FP_ATTRIBUTES_NORMAL_INSERT, show_footprints_insert );
TRANSFER_SETTING( FL_FP_ATTRIBUTES_VIRTUAL, show_footprints_virtual );
TRANSFER_SETTING( FL_ZONE, show_zones );
TRANSFER_SETTING( FL_ADHESIVE, show_adhesive );
TRANSFER_SETTING( FL_SILKSCREEN, show_silkscreen );
TRANSFER_SETTING( FL_SOLDERMASK, show_soldermask );
TRANSFER_SETTING( FL_SOLDERPASTE, show_solderpaste );
TRANSFER_SETTING( FL_COMMENTS, show_comments );
TRANSFER_SETTING( FL_ECO, show_eco );
TRANSFER_SETTING( FL_SHOW_BOARD_BODY, show_board_body );
TRANSFER_SETTING( FL_CLIP_SILK_ON_VIA_ANNULUS, clip_silk_on_via_annulus );
TRANSFER_SETTING( FL_RENDER_PLATED_PADS_AS_PLATED, renderPlatedPadsAsPlated );
m_boardAdapter.SetGridType( static_cast<GRID3D_TYPE>( cfg->m_Render.grid_type ) );
m_boardAdapter.SetAntiAliasingMode(
static_cast<ANTIALIASING_MODE>( cfg->m_Render.opengl_AA_mode ) );
m_boardAdapter.m_OpenGlSelectionColor =
m_boardAdapter.GetColor( cfg->m_Render.opengl_selection_color );
m_boardAdapter.m_RtShadowSampleCount = cfg->m_Render.raytrace_nrsamples_shadows;
m_boardAdapter.m_RtReflectionSampleCount = cfg->m_Render.raytrace_nrsamples_reflections;
m_boardAdapter.m_RtRefractionSampleCount = cfg->m_Render.raytrace_nrsamples_refractions;
m_boardAdapter.m_RtSpreadShadows = cfg->m_Render.raytrace_spread_shadows;
m_boardAdapter.m_RtSpreadReflections = cfg->m_Render.raytrace_spread_reflections;
m_boardAdapter.m_RtSpreadRefractions = cfg->m_Render.raytrace_spread_refractions;
m_boardAdapter.m_RtRecursiveRefractionCount =
cfg->m_Render.raytrace_recursivelevel_refractions;
m_boardAdapter.m_RtRecursiveReflectionCount =
cfg->m_Render.raytrace_recursivelevel_reflections;
// When opening the 3D viewer, we use the opengl mode, not the ray tracing engine
// because the ray tracing is very time consumming, and can be seen as not working
// (freeze window) with large boards.
#if 0
RENDER_ENGINE engine = static_cast<RENDER_ENGINE>( cfg->m_Render.engine );
wxLogTrace( m_logTrace, engine == RENDER_ENGINE::RAYTRACING ?
wxT( "EDA_3D_VIEWER_FRAME::LoadSettings render setting Ray Trace" )
:
wxT( "EDA_3D_VIEWER_FRAME::LoadSettings render setting OpenGL" ) );
#else
m_boardAdapter.SetRenderEngine( RENDER_ENGINE::OPENGL );
#endif
m_boardAdapter.SetMaterialMode( static_cast<MATERIAL_MODE>( cfg->m_Render.material_mode ) );
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 );
#undef TRANSFER_SETTING
}
}
@@ -609,14 +531,53 @@ void EDA_3D_VIEWER_FRAME::SaveSettings( APP_SETTINGS_BASE *aCfg )
wxLogTrace( m_logTrace, wxT( "EDA_3D_VIEWER_FRAME::SaveSettings" ) );
wxLogTrace( m_logTrace, m_boardAdapter.m_Cfg->m_Render.engine == RENDER_ENGINE::RAYTRACING ?
wxT( "EDA_3D_VIEWER_FRAME::SaveSettings render setting Ray Trace" )
:
wxT( "EDA_3D_VIEWER_FRAME::SaveSettings render setting OpenGL" ) );
wxLogTrace( m_logTrace, m_boardAdapter.GetRenderEngine() == RENDER_ENGINE::RAYTRACING ?
wxT( "EDA_3D_VIEWER_FRAME::SaveSettings render setting Ray Trace" ) :
wxT( "EDA_3D_VIEWER_FRAME::SaveSettings render setting OpenGL" ) );
if( cfg )
{
cfg->m_AuiPanels.right_panel_width = m_appearancePanel->GetSize().x;
auto save_color =
[] ( const SFVEC3F& aSource, COLOR4D& aTarget )
{
aTarget = COLOR4D( aSource.r, aSource.g, aSource.b, 1.0 );
};
save_color( m_boardAdapter.m_RtCameraLightColor, cfg->m_Render.raytrace_lightColorCamera );
save_color( m_boardAdapter.m_RtLightColorTop, cfg->m_Render.raytrace_lightColorTop );
save_color( m_boardAdapter.m_RtLightColorBottom, cfg->m_Render.raytrace_lightColorBottom );
for( size_t i = 0; i < cfg->m_Render.raytrace_lightColor.size(); ++i )
{
save_color( m_boardAdapter.m_RtLightColor[i], cfg->m_Render.raytrace_lightColor[i] );
cfg->m_Render.raytrace_lightElevation[i] =
(int)( m_boardAdapter.m_RtLightSphericalCoords[i].x * 180.0f - 90.0f );
cfg->m_Render.raytrace_lightAzimuth[i] =
(int)( m_boardAdapter.m_RtLightSphericalCoords[i].y * 180.0f );
}
cfg->m_Render.raytrace_nrsamples_shadows = m_boardAdapter.m_RtShadowSampleCount;
cfg->m_Render.raytrace_nrsamples_reflections = m_boardAdapter.m_RtReflectionSampleCount;
cfg->m_Render.raytrace_nrsamples_refractions = m_boardAdapter.m_RtRefractionSampleCount;
cfg->m_Render.raytrace_spread_shadows = m_boardAdapter.m_RtSpreadShadows;
cfg->m_Render.raytrace_spread_reflections = m_boardAdapter.m_RtSpreadReflections;
cfg->m_Render.raytrace_spread_refractions = m_boardAdapter.m_RtSpreadRefractions;
cfg->m_Render.raytrace_recursivelevel_refractions =
m_boardAdapter.m_RtRecursiveRefractionCount;
cfg->m_Render.raytrace_recursivelevel_reflections =
m_boardAdapter.m_RtRecursiveReflectionCount;
#define TRANSFER_SETTING( field, flag ) cfg->m_Render.field = m_boardAdapter.GetFlag( flag )
cfg->m_Render.engine = static_cast<int>( m_boardAdapter.GetRenderEngine() );
cfg->m_Render.grid_type = static_cast<int>( m_boardAdapter.GetGridType() );
cfg->m_Render.material_mode = static_cast<int>( m_boardAdapter.GetMaterialMode() );
cfg->m_Render.opengl_AA_mode = static_cast<int>( m_boardAdapter.GetAntiAliasingMode() );
save_color( m_boardAdapter.m_OpenGlSelectionColor, cfg->m_Render.opengl_selection_color );
cfg->m_Camera.animation_enabled = m_canvas->GetAnimationEnabled();
cfg->m_Camera.moving_speed_multiplier = m_canvas->GetMovingSpeedMultiplier();
@@ -624,6 +585,41 @@ void EDA_3D_VIEWER_FRAME::SaveSettings( APP_SETTINGS_BASE *aCfg )
if( EDA_3D_CONTROLLER* ctrlTool = GetToolManager()->GetTool<EDA_3D_CONTROLLER>() )
cfg->m_Camera.rotation_increment = ctrlTool->GetRotationIncrement();
TRANSFER_SETTING( opengl_AA_disableOnMove, FL_RENDER_OPENGL_AA_DISABLE_ON_MOVE );
TRANSFER_SETTING( opengl_copper_thickness, FL_RENDER_OPENGL_COPPER_THICKNESS );
TRANSFER_SETTING( opengl_show_model_bbox, FL_RENDER_OPENGL_SHOW_MODEL_BBOX );
TRANSFER_SETTING( opengl_highlight_on_rollover, FL_HIGHLIGHT_ROLLOVER_ITEM );
TRANSFER_SETTING( opengl_thickness_disableOnMove, FL_RENDER_OPENGL_THICKNESS_DISABLE_ON_MOVE );
TRANSFER_SETTING( opengl_vias_disableOnMove, FL_RENDER_OPENGL_VIAS_DISABLE_ON_MOVE );
TRANSFER_SETTING( opengl_holes_disableOnMove, FL_RENDER_OPENGL_HOLES_DISABLE_ON_MOVE );
TRANSFER_SETTING( raytrace_anti_aliasing, FL_RENDER_RAYTRACING_ANTI_ALIASING );
TRANSFER_SETTING( raytrace_backfloor, FL_RENDER_RAYTRACING_BACKFLOOR );
TRANSFER_SETTING( raytrace_post_processing, FL_RENDER_RAYTRACING_POST_PROCESSING );
TRANSFER_SETTING( raytrace_procedural_textures, FL_RENDER_RAYTRACING_PROCEDURAL_TEXTURES );
TRANSFER_SETTING( raytrace_reflections, FL_RENDER_RAYTRACING_REFLECTIONS );
TRANSFER_SETTING( raytrace_refractions, FL_RENDER_RAYTRACING_REFRACTIONS );
TRANSFER_SETTING( raytrace_shadows, FL_RENDER_RAYTRACING_SHADOWS );
TRANSFER_SETTING( realistic, FL_USE_REALISTIC_MODE );
TRANSFER_SETTING( show_adhesive, FL_ADHESIVE );
TRANSFER_SETTING( show_axis, FL_AXIS );
TRANSFER_SETTING( show_board_body, FL_SHOW_BOARD_BODY );
TRANSFER_SETTING( clip_silk_on_via_annulus, FL_CLIP_SILK_ON_VIA_ANNULUS );
TRANSFER_SETTING( renderPlatedPadsAsPlated, FL_RENDER_PLATED_PADS_AS_PLATED );
TRANSFER_SETTING( show_comments, FL_COMMENTS );
TRANSFER_SETTING( show_eco, FL_ECO );
TRANSFER_SETTING( show_footprints_insert, FL_FP_ATTRIBUTES_NORMAL_INSERT );
TRANSFER_SETTING( show_footprints_normal, FL_FP_ATTRIBUTES_NORMAL );
TRANSFER_SETTING( show_footprints_virtual, FL_FP_ATTRIBUTES_VIRTUAL );
TRANSFER_SETTING( show_silkscreen, FL_SILKSCREEN );
TRANSFER_SETTING( show_soldermask, FL_SOLDERMASK );
TRANSFER_SETTING( show_solderpaste, FL_SOLDERPASTE );
TRANSFER_SETTING( show_zones, FL_ZONE );
TRANSFER_SETTING( subtract_mask_from_silk, FL_SUBTRACT_MASK_FROM_SILK );
#undef TRANSFER_SETTING
}
}
@@ -639,64 +635,11 @@ void EDA_3D_VIEWER_FRAME::CommonSettingsChanged( bool aEnvVarsChanged, bool aTex
ReCreateMainToolbar();
loadCommonSettings();
applySettings( Pgm().GetSettingsManager().GetAppSettings<EDA_3D_VIEWER_SETTINGS>() );
m_appearancePanel->CommonSettingsChanged();
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" ) );
m_appearancePanel->OnLanguageChanged();
}
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;
@@ -708,8 +651,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() )
@@ -750,13 +693,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 );
@@ -766,8 +704,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 );
@@ -812,21 +748,8 @@ void EDA_3D_VIEWER_FRAME::loadCommonSettings()
COMMON_SETTINGS* settings = Pgm().GetCommonSettings();
const DPI_SCALING_COMMON dpi{ settings, this };
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() );
m_boardAdapter.SetFlag( FL_MOUSEWHEEL_PANNING, settings->m_Input.scroll_modifier_zoom != 0 );
}
+22 -34
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-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,7 +25,7 @@
*/
/**
* @file eda_3d_viewer_frame.h
* @file eda_3d_viewer.h
* @brief Declaration of the eda_3d_viewer class
*/
@@ -41,11 +40,12 @@
#include <dialogs/dialog_color_picker.h> // for CUSTOM_COLORS_LIST definition
#define KICAD_DEFAULT_3D_DRAWFRAME_STYLE (wxDEFAULT_FRAME_STYLE | wxWANTS_CHARS)
/// A variable name whose value holds the path of 3D shape files.
/// Currently an environment variable, eventually a project variable.
#define KICAD6_3DMODEL_DIR wxT( "KICAD6_3DMODEL_DIR" )
// Forward declarations
class NL_3D_VIEWER_PLUGIN;
class APPEARANCE_CONTROLS_3D;
#define KICAD_DEFAULT_3D_DRAWFRAME_STYLE (wxDEFAULT_FRAME_STYLE | wxWANTS_CHARS)
enum EDA_3D_VIEWER_STATUSBAR
@@ -54,7 +54,6 @@ enum EDA_3D_VIEWER_STATUSBAR
HOVERED_ITEM,
X_POS,
Y_POS,
ZOOM_LEVEL,
};
/**
@@ -74,6 +73,8 @@ public:
wxWindow* GetToolCanvas() const override { return m_canvas; }
void InstallPreferences( PAGED_DIALOG* aParent, PANEL_HOTKEYS_EDITOR* aHotkeysPanel ) override;
/**
* Request reloading the 3D view.
*
@@ -115,36 +116,28 @@ 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;
private:
/// Called when user press the File->Exit
void Exit3DFrame( wxCommandEvent& event );
void OnCloseWindow( wxCloseEvent& event );
bool TryBefore( wxEvent& aEvent ) override;
void Process_Special_Functions( wxCommandEvent& event );
void onRenderEngineSelection( wxCommandEvent& event );
void onDisableRayTracing( wxCommandEvent& aEvent );
void OnRenderEngineSelection( wxCommandEvent& event );
void OnDisableRayTracing( wxCommandEvent& aEvent );
void OnActivate( wxActivateEvent& event );
void OnSetFocus( wxFocusEvent& event );
void doReCreateMenuBar() override;
void Install3DViewOptionDialog( wxCommandEvent& event );
void CreateMenuBar();
void ReCreateMainToolbar();
/**
@@ -167,20 +160,15 @@ private:
*/
void loadCommonSettings();
void applySettings( EDA_3D_VIEWER_SETTINGS* aSettings );
wxFileName m_defaultSaveScreenshotFileName;
private:
wxFileName m_defaultSaveScreenshotFileName;
ACTION_TOOLBAR* m_mainToolBar;
EDA_3D_CANVAS* m_canvas;
BOARD_ADAPTER m_boardAdapter;
CAMERA& m_currentCamera;
TRACK_BALL m_trackBallCamera;
ACTION_TOOLBAR* m_mainToolBar;
EDA_3D_CANVAS* m_canvas;
BOARD_ADAPTER m_boardAdapter;
CAMERA& m_currentCamera;
TRACK_BALL m_trackBallCamera;
bool m_disable_ray_tracing;
NL_3D_VIEWER_PLUGIN* m_spaceMouse;
bool m_disable_ray_tracing;
/**
* Trace mask used to enable or disable the trace output of this class.
+39 -268
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 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,193 +22,40 @@
#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>( "render.engine", &m_Render.engine,
static_cast<int>( RENDER_ENGINE::OPENGL ),
static_cast<int>( RENDER_ENGINE::OPENGL ),
static_cast<int>( RENDER_ENGINE::RAYTRACING ) ) );
m_params.emplace_back( new PARAM<int>( "aui.right_panel_width",
&m_AuiPanels.right_panel_width, -1 ) );
m_params.emplace_back( new PARAM<int>( "render.grid_type", &m_Render.grid_type,
static_cast<int>( GRID3D_TYPE::NONE ),
static_cast<int>( GRID3D_TYPE::NONE ),
static_cast<int>( GRID3D_TYPE::GRID_10MM ) ) );
m_params.emplace_back( new PARAM_ENUM<RENDER_ENGINE>( "render.engine", &m_Render.engine,
RENDER_ENGINE::OPENGL,
RENDER_ENGINE::OPENGL,
RENDER_ENGINE::RAYTRACING ) );
m_params.emplace_back( new PARAM<int>( "render.material_mode", &m_Render.material_mode,
static_cast<int>( MATERIAL_MODE::NORMAL ),
static_cast<int>( MATERIAL_MODE::NORMAL ),
static_cast<int>( MATERIAL_MODE::CAD_MODE ) ) );
m_params.emplace_back( new PARAM_ENUM<GRID3D_TYPE>( "render.grid_type", &m_Render.grid_type,
GRID3D_TYPE::NONE,
GRID3D_TYPE::NONE,
GRID3D_TYPE::GRID_10MM ) );
m_params.emplace_back( new PARAM_ENUM<MATERIAL_MODE>( "render.material_mode",
&m_Render.material_mode,
MATERIAL_MODE::NORMAL,
MATERIAL_MODE::NORMAL,
MATERIAL_MODE::CAD_MODE ) );
m_params.emplace_back( new PARAM_ENUM<ANTIALIASING_MODE>( "render.opengl_AA_mode",
&m_Render.opengl_AA_mode,
ANTIALIASING_MODE::AA_8X,
ANTIALIASING_MODE::AA_NONE,
ANTIALIASING_MODE::AA_8X ) );
m_params.emplace_back( new PARAM<int>( "render.opengl_AA_mode", &m_Render.opengl_AA_mode,
static_cast<int>( ANTIALIASING_MODE::AA_8X ),
static_cast<int>( ANTIALIASING_MODE::AA_NONE ),
static_cast<int>( ANTIALIASING_MODE::AA_8X ) ) );
m_params.emplace_back( new PARAM<COLOR4D>( "render.opengl_selection_color",
&m_Render.opengl_selection_color,
@@ -219,11 +65,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",
@@ -242,7 +86,7 @@ EDA_3D_VIEWER_SETTINGS::EDA_3D_VIEWER_SETTINGS() :
&m_Render.raytrace_backfloor, false ) );
m_params.emplace_back( new PARAM<bool>( "render.raytrace_post_processing",
&m_Render.raytrace_post_processing, true ) );
m_params.emplace_back( new PARAM<bool>( "render.raytrace_procedural_textures",
m_params.emplace_back( new PARAM<bool>( "render.raytrace_procedural_textures",
&m_Render.raytrace_procedural_textures, true ) );
m_params.emplace_back( new PARAM<bool>( "render.raytrace_reflections",
&m_Render.raytrace_reflections, true ) );
@@ -316,6 +160,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,50 +170,28 @@ 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",
&m_Render.show_footprints_normal, true ) );
m_params.emplace_back( new PARAM<bool>( "render.show_footprints_virtual",
&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,66 +201,13 @@ 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, LEGACY_PRESET_FLAG ) );
registerMigration( 0, 1, std::bind( &EDA_3D_VIEWER_SETTINGS::migrateSchema0to1, this ) );
registerMigration( 1, 2,
[&]() -> bool
{
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 )
registerMigration( 1, 2, [&]() -> bool
{
if( preset.name == aName )
return &preset;
}
return nullptr;
Set( "render.opengl_copper_thickness", false );
return true;
} );
}
+14 -82
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 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
@@ -22,76 +21,27 @@
#ifndef EDA_3D_VIEWER_SETTINGS_H_
#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" )
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;
};
#include <plugins/3dapi/xv3d_types.h>
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;
GRID3D_TYPE grid_type;
ANTIALIASING_MODE opengl_AA_mode;
MATERIAL_MODE material_mode;
int engine;
int grid_type;
int opengl_AA_mode;
int material_mode;
bool opengl_AA_disableOnMove;
bool opengl_thickness_disableOnMove;
bool opengl_vias_disableOnMove;
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;
@@ -120,32 +70,22 @@ 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
@@ -160,19 +100,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"; }
+209 -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,248 @@
#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,
0, "",
_( "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, (void*) FL_FP_ATTRIBUTES_NORMAL );
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, (void*) FL_FP_ATTRIBUTES_NORMAL_INSERT );
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 Other 3D models" ), _( "Toggle 3D models for 'Other' type components" ),
BITMAPS::show_other, AF_NONE, (void*) FL_FP_ATTRIBUTES_VIRTUAL );
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::showBBoxes( "3DViewer.Control.showBoundingBoxes",
AS_GLOBAL, 0, "",
_( "Show Model Bounding Boxes" ), _( "Show Model Bounding Boxes" ),
BITMAPS::ortho, AF_NONE, (void*) FL_RENDER_OPENGL_SHOW_MODEL_BBOX );
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::toggleRealisticMode( "3DViewer.Control.toggleRealisticMode",
AS_GLOBAL, 0, "",
_( "Toggle realistic mode" ), _( "Toggle realistic mode" ),
BITMAPS::INVALID_BITMAP, AF_NONE, (void*) FL_USE_REALISTIC_MODE );
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::toggleBoardBody( "3DViewer.Control.toggleBoardBody",
AS_GLOBAL, 0, "",
_( "Toggle board body display" ), _( "Toggle board body display" ),
BITMAPS::INVALID_BITMAP, AF_NONE, (void*) FL_SHOW_BOARD_BODY );
TOOL_ACTION EDA_3D_ACTIONS::showAxis( "3DViewer.Control.showAxis",
AS_GLOBAL, 0, "",
_( "Show 3D Axis" ), _( "Show 3D Axis" ),
BITMAPS::axis3d_front, AF_NONE, (void*) FL_AXIS );
TOOL_ACTION EDA_3D_ACTIONS::toggleZones( "3DViewer.Control.toggleZones",
AS_GLOBAL, 0, "",
_( "Toggle zone display" ), _( "Toggle zone display" ),
BITMAPS::INVALID_BITMAP, AF_NONE, (void*) FL_ZONE );
TOOL_ACTION EDA_3D_ACTIONS::toggleAdhesive( "3DViewer.Control.toggleAdhesive",
AS_GLOBAL, 0, "",
_( "Toggle adhesive display" ), _( "Toggle display of adhesive layers" ),
BITMAPS::INVALID_BITMAP, AF_NONE, (void*) FL_ADHESIVE );
TOOL_ACTION EDA_3D_ACTIONS::toggleSilk( "3DViewer.Control.toggleSilk",
AS_GLOBAL, 0, "",
_( "Toggle silkscreen display" ), _( "Toggle display of silkscreen layers" ),
BITMAPS::INVALID_BITMAP, AF_NONE, (void*) FL_SILKSCREEN );
TOOL_ACTION EDA_3D_ACTIONS::toggleSolderMask( "3DViewer.Control.toggleSolderMask",
AS_GLOBAL, 0, "",
_( "Toggle solder mask display" ), _( "Toggle display of solder mask layers" ),
BITMAPS::INVALID_BITMAP, AF_NONE, (void*) FL_SOLDERMASK );
TOOL_ACTION EDA_3D_ACTIONS::toggleSolderPaste( "3DViewer.Control.toggleSolderPaste",
AS_GLOBAL, 0, "",
_( "Toggle solder paste display" ), _( "Toggle display of solder paste layers" ),
BITMAPS::INVALID_BITMAP, AF_NONE, (void*) FL_SOLDERPASTE );
TOOL_ACTION EDA_3D_ACTIONS::toggleComments( "3DViewer.Control.toggleComments",
AS_GLOBAL, 0, "",
_( "Toggle comments display" ), _( "Toggle display of comments and drawings layers" ),
BITMAPS::INVALID_BITMAP, AF_NONE, (void*) FL_COMMENTS );
TOOL_ACTION EDA_3D_ACTIONS::toggleECO( "3DViewer.Control.toggleECO",
AS_GLOBAL, 0, "",
_( "Toggle ECO display" ), _( "Toggle display of ECO layers" ),
BITMAPS::INVALID_BITMAP, AF_NONE, (void*) FL_ECO );
+12 -5
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;
@@ -77,11 +78,17 @@ public:
static TOOL_ACTION showTHT;
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
@@ -30,15 +30,43 @@
using namespace std::placeholders;
SELECTION_CONDITION EDA_3D_CONDITIONS::MaterialMode( MATERIAL_MODE aMaterial )
{
return std::bind( &EDA_3D_CONDITIONS::materialModeFunction, _1, m_adapter, aMaterial );
}
SELECTION_CONDITION EDA_3D_CONDITIONS::Flag( DISPLAY3D_FLG aFlag )
{
return std::bind( &EDA_3D_CONDITIONS::flagFunction, _1, m_adapter, aFlag );
}
SELECTION_CONDITION EDA_3D_CONDITIONS::GridSize( GRID3D_TYPE aGridSize )
{
return std::bind( &EDA_3D_CONDITIONS::gridSizeFunction, _1, m_adapter, aGridSize );
}
bool EDA_3D_CONDITIONS::materialModeFunction( const SELECTION& aSelection,
BOARD_ADAPTER* aAdapter,
MATERIAL_MODE aMaterial )
{
return aAdapter->GetMaterialMode() == aMaterial;
}
bool EDA_3D_CONDITIONS::flagFunction( const SELECTION& aSelection,
BOARD_ADAPTER* aAdapter,
DISPLAY3D_FLG aFlag )
{
return aAdapter->GetFlag( aFlag );
}
bool EDA_3D_CONDITIONS::gridSizeFunction( const SELECTION& aSelection,
BOARD_ADAPTER* aAdapter,
GRID3D_TYPE aGridSize )
{
return aAdapter->m_Cfg->m_Render.grid_type == aGridSize;
return aAdapter->GetGridType() == aGridSize;
}
@@ -44,6 +44,24 @@ public:
m_adapter( aAdapter )
{}
/**
* Creates a functor that tests if a specific material mode is active.
*
* @param aAdapter is the board adapter the setting is in
* @param aMaterial is the material mode to test for.
* @return Functor testing if a material mode is active.
*/
SELECTION_CONDITION MaterialMode( MATERIAL_MODE aMaterial );
/**
* Creates a functor that tests if the board adapter has a flag set currently.
*
* @param aAdapter is the board adapter the setting is in
* @param aFlag is the flag to test for.
* @return Functor testing if the flag is set.
*/
SELECTION_CONDITION Flag( DISPLAY3D_FLG aFlag );
/**
* Creates a functor that tests the current grid size.
*
@@ -54,6 +72,14 @@ public:
SELECTION_CONDITION GridSize( GRID3D_TYPE aGridSize );
private:
///< Helper function used by MaterialMode()
static bool materialModeFunction( const SELECTION& aSelection, BOARD_ADAPTER* aAdapter,
MATERIAL_MODE aMaterial );
///< Helper function used by Flag()
static bool flagFunction( const SELECTION& aSelection, BOARD_ADAPTER* aAdapter,
DISPLAY3D_FLG aFlag );
///< Helper function used by GridDize()
static bool gridSizeFunction( const SELECTION& aSelection, BOARD_ADAPTER* aAdapter,
GRID3D_TYPE aGridSize );
+83 -85
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 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,7 @@
#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 <3d_rendering/opengl/render_3d_opengl.h>
@@ -81,7 +78,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 );
@@ -115,33 +113,10 @@ int EDA_3D_CONTROLLER::Main( const TOOL_EVENT& aEvent )
// Main loop: keep receiving events
while( TOOL_EVENT* evt = Wait() )
{
if( evt->IsCancelInteractive() )
{
wxWindow* canvas = m_toolMgr->GetToolHolder()->GetToolCanvas();
wxWindow* topLevelParent = wxGetTopLevelParent( canvas->GetParent() );
if( topLevelParent && dynamic_cast<DIALOG_SHIM*>( topLevelParent ) )
{
DIALOG_SHIM* dialog = static_cast<DIALOG_SHIM*>( topLevelParent );
if( dialog->IsQuasiModal() )
dialog->EndQuasiModal( wxID_CANCEL );
else
dialog->EndModal( wxID_CANCEL );
}
else
{
evt->SetPassEvent();
}
}
else if( evt->IsClick( BUT_RIGHT ) )
{
if( evt->IsClick( BUT_RIGHT ) )
m_menu.ShowContextMenu();
}
else
{
evt->SetPassEvent();
}
}
return 0;
@@ -150,7 +125,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 +133,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;
@@ -177,17 +152,17 @@ int EDA_3D_CONTROLLER::RotateView( const TOOL_EVENT& aEvent )
switch( aEvent.Parameter<ROTATION_DIR>() )
{
case ROTATION_DIR::X_CW: m_camera->RotateX( -rotIncrement ); break;
case ROTATION_DIR::X_CW: m_camera->RotateX( -rotIncrement ); break;
case ROTATION_DIR::X_CCW: m_camera->RotateX( rotIncrement ); break;
/// Y rotations are backward b/c the RHR has Y pointing into the screen
case ROTATION_DIR::Y_CW: m_camera->RotateY( rotIncrement ); break;
case ROTATION_DIR::Y_CCW: m_camera->RotateY( -rotIncrement ); break;
case ROTATION_DIR::Z_CW: m_camera->RotateZ( -rotIncrement ); break;
case ROTATION_DIR::Y_CW: m_camera->RotateY( rotIncrement ); break;
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 )
if( m_boardAdapter->GetRenderEngine() == RENDER_ENGINE::OPENGL )
m_canvas->Request_refresh();
else
m_canvas->RenderRaytracingRequest();
@@ -198,7 +173,9 @@ int EDA_3D_CONTROLLER::RotateView( const TOOL_EVENT& aEvent )
int EDA_3D_CONTROLLER::SetMaterial( const TOOL_EVENT& aEvent )
{
m_boardAdapter->m_Cfg->m_Render.material_mode = aEvent.Parameter<MATERIAL_MODE>();
MATERIAL_MODE mode = aEvent.Parameter<MATERIAL_MODE>();
m_boardAdapter->SetMaterialMode( mode );
if( auto* viewer = dynamic_cast<EDA_3D_VIEWER_FRAME*>( m_toolMgr->GetToolHolder() ) )
viewer->NewDisplay( true );
@@ -213,7 +190,7 @@ int EDA_3D_CONTROLLER::ToggleOrtho( const TOOL_EVENT& aEvent )
{
m_camera->ToggleProjection();
if( m_boardAdapter->m_Cfg->m_Render.engine == RENDER_ENGINE::OPENGL )
if( m_boardAdapter->GetRenderEngine() == RENDER_ENGINE::OPENGL )
m_canvas->Request_refresh();
else
m_canvas->RenderRaytracingRequest();
@@ -221,46 +198,57 @@ int EDA_3D_CONTROLLER::ToggleOrtho( const TOOL_EVENT& aEvent )
return 0;
}
int EDA_3D_CONTROLLER::ToggleVisibility( const TOOL_EVENT& aEvent )
{
std::bitset<LAYER_3D_END> visibilityFlags = m_boardAdapter->GetVisibleLayers();
APPEARANCE_CONTROLS_3D* appearanceManager = nullptr;
DISPLAY3D_FLG flag = aEvent.Parameter<DISPLAY3D_FLG>();
auto flipLayer =
[&]( int layer )
{
appearanceManager->OnLayerVisibilityChanged( layer, !visibilityFlags.test( layer ) );
};
m_boardAdapter->SetFlag( flag, !m_boardAdapter->GetFlag( flag ) );
if( auto viewer = dynamic_cast<EDA_3D_VIEWER_FRAME*>( m_toolMgr->GetToolHolder() ) )
appearanceManager = viewer->GetAppearanceManager();
if( appearanceManager )
switch( flag )
{
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 );
// These commands do not request a 3D scene rebuild (and do not exist in raytracing):
case FL_RENDER_OPENGL_SHOW_MODEL_BBOX:
case FL_AXIS:
m_canvas->Request_refresh();
break;
// These commands do not request a 3D scene rebuild and exist in raytracing:
case FL_RENDER_RAYTRACING_SHADOWS:
case FL_RENDER_RAYTRACING_REFRACTIONS:
case FL_RENDER_RAYTRACING_REFLECTIONS:
case FL_RENDER_RAYTRACING_ANTI_ALIASING:
if( m_boardAdapter->GetRenderEngine() == RENDER_ENGINE::OPENGL )
m_canvas->Request_refresh();
else
m_canvas->RenderRaytracingRequest();
break;
case FL_FP_ATTRIBUTES_NORMAL:
case FL_FP_ATTRIBUTES_NORMAL_INSERT:
case FL_FP_ATTRIBUTES_VIRTUAL:
// Loading 3D shapes can be needed if not yet loaded
if( m_boardAdapter->GetRenderEngine() == RENDER_ENGINE::OPENGL )
{
RENDER_3D_OPENGL* render = static_cast<RENDER_3D_OPENGL*>( m_canvas->GetCurrentRender() );
render->Load3dModelsIfNeeded();
m_canvas->Request_refresh();
}
else
m_canvas->RenderRaytracingRequest();
break;
default:
{
if( auto viewer = dynamic_cast<EDA_3D_VIEWER_FRAME*>( m_toolMgr->GetToolHolder() ) )
viewer->NewDisplay( true );
else
m_canvas->Request_refresh();
break;
}
}
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();
return 0;
}
@@ -268,7 +256,8 @@ int EDA_3D_CONTROLLER::ToggleLayersManager( const TOOL_EVENT& aEvent )
int EDA_3D_CONTROLLER::On3DGridSelection( const TOOL_EVENT& aEvent )
{
m_boardAdapter->m_Cfg->m_Render.grid_type = aEvent.Parameter<GRID3D_TYPE>();
GRID3D_TYPE grid = aEvent.Parameter<GRID3D_TYPE>();
m_boardAdapter->SetGridType( grid );
if( m_canvas )
m_canvas->Request_refresh();
@@ -302,7 +291,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 +303,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 +335,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() );
@@ -382,9 +372,17 @@ void EDA_3D_CONTROLLER::setTransitions()
Go( &EDA_3D_CONTROLLER::ToggleVisibility, EDA_3D_ACTIONS::showTHT.MakeEvent() );
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::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,
+27 -29
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(
@@ -11,11 +11,11 @@ include_directories(
3d_viewer
${CMAKE_SOURCE_DIR}
${CMAKE_SOURCE_DIR}/include/gal/opengl
${CMAKE_SOURCE_DIR}/common/dialogs
${INC_AFTER}
)
# 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 +27,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
@@ -71,6 +77,7 @@ set(3D-VIEWER_SRCS
${DIR_RAY_3D}/triangle_3d.cpp
3d_rendering/buffers_debug.cpp
3d_rendering/render_3d_base.cpp
3d_rendering/camera.cpp
3d_rendering/color_rgb.cpp
3d_rendering/image.cpp
3d_rendering/post_shader.cpp
@@ -80,6 +87,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
@@ -89,38 +104,21 @@ 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})
add_dependencies( 3d-viewer pcbcommon )
target_link_libraries( 3d-viewer
PRIVATE
gal
kimath
core
common
nlohmann_json
Boost::headers
${wxWidgets_LIBRARIES}
${OPENGL_LIBRARIES}
kicad_3dsg )
gal
kimath
${Boost_LIBRARIES}
${wxWidgets_LIBRARIES}
${OPENGL_LIBRARIES}
kicad_3dsg )
target_include_directories( 3d-viewer PRIVATE
$<TARGET_PROPERTY:nlohmann_json,INTERFACE_INCLUDE_DIRECTORIES>
)
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)
+4 -5
View File
@@ -33,11 +33,10 @@
/// Anti-aliasing options
enum class ANTIALIASING_MODE
{
// Do not change these numbers, they are stored in the config file
AA_NONE = 0,
AA_2X = 1,
AA_4X = 2,
AA_8X = 3
AA_NONE,
AA_2X,
AA_4X,
AA_8X
};
/**
-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 -2
View File
@@ -1,8 +1,7 @@
Credits
=======
The 3D-viewer contains parts, source code or adaptations or implementations that should give the following
aknowledgments:
The 3D-viewer contains parts, source code or adaptations or implementations that should give the following aknowledge:
cbvh_packet_traversal.cpp
+1 -1
View File
@@ -45,7 +45,7 @@ bool S3D::Select3DModel( wxWindow* aParent, S3D_CACHE* aCache, wxString& prevMod
bool S3D::Configure3DPaths( wxWindow* aParent, FILENAME_RESOLVER* aResolver )
{
DIALOG_CONFIGURE_PATHS dlg( aParent );
DIALOG_CONFIGURE_PATHS dlg( aParent, aResolver );
// Use QuasiModal so that HTML help window will work
return( dlg.ShowQuasiModal() == wxID_OK );
@@ -1,978 +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 indicatorSize = ConvertDialogToPixels( wxSize( 6, 6 ) ).x / dpi.GetContentScaleFactor();
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 >= indicatorSize )
m_pointSize = m_pointSize * 8 / 10;
m_cbLayerPresets->Bind( wxEVT_CHOICE, &APPEARANCE_CONTROLS_3D::onLayerPresetChanged, this );
m_toggleGridRenderer = new GRID_BITMAP_TOGGLE_RENDERER( KiBitmap( BITMAPS::visibility ),
KiBitmap( BITMAPS::visibility_off ) );
}
APPEARANCE_CONTROLS_3D::~APPEARANCE_CONTROLS_3D()
{
}
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::OnLanguageChanged()
{
Freeze();
rebuildLayers();
m_cbUseBoardStackupColors->SetLabel( _( "Use board stackup colors" ) );
rebuildLayerPresetsWidget();
rebuildViewportsWidget();
Thaw();
Refresh();
}
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()
{
OnLanguageChanged();
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,
KiBitmap( BITMAPS::visibility ),
KiBitmap( 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();
}
-191
View File
@@ -1,191 +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 OnLanguageChanged();
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;
private:
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();
};
+2 -3
View File
@@ -3,7 +3,7 @@
*
* Copyright (C) 2016 Mario Luzeiro <mrluzeiro@ua.pt>
* Copyright (C) 2016 Cirilo Bernardo <cirilo.bernardo@gmail.com>
* Copyright (C) 2017-2022 KiCad Developers, see AUTHORS.txt for contributors.
* Copyright (C) 2017-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
@@ -34,7 +34,6 @@
#include <common_ogl/ogl_attr_list.h>
#include <filename_resolver.h>
#include <pcbnew/footprint.h>
#include <wx_filename.h>
#include <wx/filedlg.h>
@@ -165,7 +164,7 @@ bool DIALOG_SELECT_3DMODEL::TransferDataFromWindow()
// file selection mode: retrieve the filename and specify a
// path relative to one of the config paths
wxFileName fname = m_FileTree->GetFilePath();
fname.Normalize( FN_NORMALIZE_FLAGS | wxPATH_NORM_ENV_VARS );
fname.Normalize();
m_model->m_Filename = m_resolver->ShortenPath( fname.GetFullPath() );
return true;
@@ -1,5 +1,5 @@
///////////////////////////////////////////////////////////////////////////
// C++ code generated with wxFormBuilder (version 3.10.1-0-g8feb16b)
// C++ code generated with wxFormBuilder (version Oct 26 2018)
// http://www.wxformbuilder.org/
//
// PLEASE DO *NOT* EDIT THIS FILE!
@@ -57,7 +57,7 @@ DIALOG_SELECT_3D_MODEL_BASE::DIALOG_SELECT_3D_MODEL_BASE( wxWindow* parent, wxWi
m_stDirChoice = new wxStaticText( this, wxID_ANY, _("Available paths:"), wxDefaultPosition, wxDefaultSize, 0 );
m_stDirChoice->Wrap( -1 );
bSizerLower->Add( m_stDirChoice, 0, wxALIGN_CENTER_VERTICAL|wxBOTTOM|wxLEFT|wxRIGHT|wxTOP, 5 );
bSizerLower->Add( m_stDirChoice, 0, wxALIGN_CENTER_VERTICAL|wxTOP|wxBOTTOM|wxLEFT, 5 );
wxArrayString m_dirChoicesChoices;
m_dirChoices = new wxChoice( this, wxID_ANY, wxDefaultPosition, wxDefaultSize, m_dirChoicesChoices, 0 );
@@ -1,6 +1,6 @@
<?xml version="1.0" encoding="UTF-8" standalone="yes" ?>
<wxFormBuilder_Project>
<FileVersion major="1" minor="16" />
<FileVersion major="1" minor="15" />
<object class="Project" expanded="1">
<property name="class_decoration">; </property>
<property name="code_generation">C++</property>
@@ -14,7 +14,6 @@
<property name="file">dialog_select_3d_model_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">dialog_select_3d_model_base</property>
@@ -26,7 +25,6 @@
<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="Dialog" expanded="1">
@@ -52,7 +50,6 @@
<property name="subclass">DIALOG_SHIM; dialog_shim.h; forward_declare</property>
<property name="title">Select 3D Model</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"></property>
@@ -330,7 +327,7 @@
<property name="permission">none</property>
<object class="sizeritem" expanded="1">
<property name="border">5</property>
<property name="flag">wxALIGN_CENTER_VERTICAL|wxBOTTOM|wxLEFT|wxRIGHT|wxTOP</property>
<property name="flag">wxALIGN_CENTER_VERTICAL|wxTOP|wxBOTTOM|wxLEFT</property>
<property name="proportion">0</property>
<object class="wxStaticText" expanded="1">
<property name="BottomDockable">1</property>
@@ -467,7 +464,6 @@
<property name="aui_name"></property>
<property name="aui_position"></property>
<property name="aui_row"></property>
<property name="auth_needed">0</property>
<property name="best_size"></property>
<property name="bg"></property>
<property name="bitmap"></property>
@@ -1,5 +1,5 @@
///////////////////////////////////////////////////////////////////////////
// C++ code generated with wxFormBuilder (version 3.10.1-0-g8feb16b)
// C++ code generated with wxFormBuilder (version Oct 26 2018)
// http://www.wxformbuilder.org/
//
// PLEASE DO *NOT* EDIT THIS FILE!
@@ -22,10 +22,10 @@
#include <wx/splitter.h>
#include <wx/stattext.h>
#include <wx/choice.h>
#include <wx/button.h>
#include <wx/bitmap.h>
#include <wx/image.h>
#include <wx/icon.h>
#include <wx/button.h>
#include <wx/dialog.h>
///////////////////////////////////////////////////////////////////////////
@@ -51,7 +51,7 @@ class DIALOG_SELECT_3D_MODEL_BASE : public DIALOG_SHIM
wxButton* m_sdbSizerOK;
wxButton* m_sdbSizerCancel;
// Virtual event handlers, override them in your derived class
// Virtual event handlers, overide them in your derived class
virtual void OnFileActivated( wxCommandEvent& event ) { event.Skip(); }
virtual void OnSelectionChanged( wxCommandEvent& event ) { event.Skip(); }
virtual void SetRootDir( wxCommandEvent& event ) { event.Skip(); }
@@ -61,7 +61,6 @@ class DIALOG_SELECT_3D_MODEL_BASE : public DIALOG_SHIM
public:
DIALOG_SELECT_3D_MODEL_BASE( wxWindow* parent, wxWindowID id = wxID_ANY, const wxString& title = _("Select 3D Model"), const wxPoint& pos = wxDefaultPosition, const wxSize& size = wxSize( -1,-1 ), long style = wxDEFAULT_DIALOG_STYLE|wxRESIZE_BORDER );
~DIALOG_SELECT_3D_MODEL_BASE();
void m_splitterWinOnIdle( wxIdleEvent& )
+110
View File
@@ -0,0 +1,110 @@
/*
* 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( EDA_3D_VIEWER_FRAME* aFrame, wxWindow* aParent ) :
PANEL_3D_COLORS_BASE( aParent ),
m_boardAdapter( aFrame->GetAdapter() )
{
m_backgroundTop->SetDefaultColor( m_boardAdapter.g_DefaultBackgroundTop );
m_backgroundBottom->SetDefaultColor( m_boardAdapter.g_DefaultBackgroundBot );
m_silkscreenTop->SetUserColors( &m_boardAdapter.g_SilkscreenColors );
m_silkscreenTop->SetDefaultColor( m_boardAdapter.g_DefaultSilkscreen );
m_silkscreenBottom->SetUserColors( &m_boardAdapter.g_SilkscreenColors );
m_silkscreenBottom->SetDefaultColor( m_boardAdapter.g_DefaultSilkscreen );
m_solderMaskTop->SetUserColors( &m_boardAdapter.g_MaskColors );
m_solderMaskTop->SetDefaultColor( m_boardAdapter.g_DefaultSolderMask );
m_solderMaskBottom->SetUserColors( &m_boardAdapter.g_MaskColors );
m_solderMaskBottom->SetDefaultColor( m_boardAdapter.g_DefaultSolderMask );
m_solderPaste->SetUserColors( &m_boardAdapter.g_PasteColors );
m_solderPaste->SetDefaultColor( m_boardAdapter.g_DefaultSolderPaste );
m_surfaceFinish->SetUserColors( &m_boardAdapter.g_FinishColors );
m_surfaceFinish->SetDefaultColor( m_boardAdapter.g_DefaultSurfaceFinish );
m_boardBody->SetUserColors( &m_boardAdapter.g_BoardColors );
m_boardBody->SetDefaultColor( m_boardAdapter.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;
}
+46
View File
@@ -0,0 +1,46 @@
/*
* 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( EDA_3D_VIEWER_FRAME* aFrame, wxWindow* aParent );
/// Automatically called when clicking on the OK button
bool TransferDataFromWindow() override;
/// Automatically called after creating the dialog
bool TransferDataToWindow() override;
private:
BOARD_ADAPTER& m_boardAdapter;
};
#endif // PANEL_3D_COLORS_H

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