Compare commits

..

392 Commits

Author SHA1 Message Date
Wayne Stambaugh 582732918d Tag release version 7.0.2. 2023-04-13 16:27:39 -04:00
Lucas Dumont f1f69c607e Check KiFACE return value
Avoid segfault when cancelling initial global library setup

(Cherry-picked from 3c24017aa4)
2023-04-13 14:39:49 +01:00
Jeff Young 8e82fee494 Attempt to fix gcc compile error. 2023-04-13 13:57:14 +01:00
Jeff Young a51475a094 Performance improvement for GetShownColumns.
(This needs to be fast as it's called from OnUpdateUI events.)

(cherry picked from commit 8e29a054f3)
2023-04-13 13:47:21 +01:00
Jeff Young f25e2d48bd Search in label fields.
Fixes https://gitlab.com/kicad/code/kicad/issues/14075

(cherry picked from commit a24a63e416)
2023-04-13 10:59:39 +01:00
jean-pierre charras 2bbff64a12 Fix compatibility of QA golden files with 7.0x version 2023-04-13 08:01:32 +02:00
Seth Hillbrand 70b4503187 Fix cherry-pick errors 2023-04-13 02:11:39 +02:00
Jeff Young 912bd4458f Don't trip over a uniquified-name in the schematic library-symbol cache.
Fixes https://gitlab.com/kicad/code/kicad/issues/14160
2023-04-12 18:35:27 +01:00
Ian McInerney d3f4494925 Make version info work without lsb-release installed
(Cherry-picked from 8351c8923a)
2023-04-12 16:13:51 +01:00
Ian McInerney 464467ae8b Fix nanodbc build with clang and gcc stdlib
This should really be fixed upstream somehow, but the upstream build
with clang is broken on Fedora 38 right now anyway due to header issues.

(Cherry-picked from 45b8dced92)
2023-04-12 16:10:20 +01:00
Ian McInerney 8e579ec8e0 Remove python-based board_item duplicate method
This method shadows the C++ method, and doesn't properly handle updating
the duplicated object's KIID to be unique.

Also add tests to ensure the KIIDs are unique after duplication.

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

(Cherry-picked from 5d0b5e16ff)
2023-04-12 16:07:00 +01:00
Ian McInerney 4ef6cbf4fb Add hack to speed up font choice box widget creation
There are problems internal to GTK that mean creating choice boxes with
a lot of items is a very slow process. This hack works around one of
those issues to make it faster to create and display the menu in the
choice box.

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

(Cherry-picked from a77e94d16f)
2023-04-12 15:24:25 +01:00
Seth Hillbrand 68dfcddbe9 Allow bus elements to connect
Previously, bus elements that were not instantiated as individual nets
could not connect to each other.  This caused issues for complex
schematics where busses needed to connect to other busses with elements
that resolved to the same net names.  Functionally, this means mixing
bus elements, which we will replace with first-class elements in version
8 but currently can only be accomplished either by using bus aliases and
  this patch or by individually instantiating each bus element as a
local label

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

(cherry picked from commit 16b4ec3c7e)
2023-04-12 16:10:50 +02:00
jean-pierre charras 907761f14e SCH_LABEL_BASE::SetPosition(): ensure field positions are also handled.
Fixes #14520
https://gitlab.com/kicad/code/kicad/issues/14520
2023-04-12 11:20:41 +02:00
jean-pierre charras be7917c8d8 LIB_TABLE_GRID_TRICKS, popup context menu: fix minor issues:
- add separator only if needed
- ensure selection parameters are up to date.
From master branch
2023-04-12 11:20:11 +02:00
jean-pierre charras 2e25f09ae4 French translation update 2023-04-12 09:47:43 +02:00
jean-pierre charras ea95d8604a Ensure we do not use a non existing pin in SIM_MODEL::MigrateSimModel()
From master branch
Fixes #14522
https://gitlab.com/kicad/code/kicad/issues/14522
2023-04-12 09:41:07 +02:00
Marek Roszko 35def3ab2e Prevent VIEW::UpdateItems and onShowTimer from firing repaints if GAL did not complete init
This appears to be a possible event race on startup

Fixes sentry KICAD-10A


(cherry picked from commit bfad8bb0d5)
2023-04-12 02:10:34 +00:00
Marek Roszko 5527c12a8d Fix crash due to extra right parens in pcad files
Fixes sentry KICAD-TA


(cherry picked from commit 37eaa29679)
2023-04-12 01:53:29 +00:00
Mark Roszko fb1cc72013 Don't crash on empty pcad polygons
Fixes sentry KICAD-103
2023-04-12 01:41:06 +00:00
Jeff Young 1f34883a27 Make symbol/footprint trees sensitive to language change.
(cherry picked from commit eef3492fc0)
2023-04-12 00:01:58 +01:00
jean-pierre charras 724262651f manage libraries dialog: show new state of widgets as soon as the context-menu
activate/deactivate changes their state
From master branch
Fixes #14517
https://gitlab.com/kicad/code/kicad/issues/14517
2023-04-11 18:55:51 +02:00
Alex d7b2247878 opengl_gal: Remove extra padding of bitmap textures.
Since the format has been changed to RGBA8, default (UN)PACK_ALIGNMENT = 4
works correctly, so the texture width padding to 4 is not needed anymore.

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


(cherry picked from commit e91b53fc39)
2023-04-11 04:32:42 +00:00
jean-pierre charras 372e7b6312 fix 2 issues related to SCH_GLOBALLABEL items:
- Ensure the first field in m_fields has id = 0 to be seen has hypertext
(it was not the case after reading a .kicad_sch file)
- when converting this item to another label/text, remove this special Field
from the copied field list to the converted label.
From master branch.
2023-04-10 10:02:50 +02:00
Jeff Young 323a2d83fa Ease acquisition of a target item.
pickSingleItem() had a two-attempt algorithm, but the second attempt
was never made because we'd check for no hits before throwing out the
aAvoidItems.

The second attempt would fail anyway because QueryHoverItems() ignored
the aUseClearance flag when not idle, and didn't factor in the actual
clearance.

(cherry picked from commit d040690f60)
2023-04-09 23:13:44 +01:00
Jeff Young 03c3393616 Handle more pad shapes when building diffpair gateways.
Fixes https://gitlab.com/kicad/code/kicad/issues/1883

(cherry picked from commit 1d19672054)
2023-04-09 23:07:38 +01:00
Jeff Young cbff011e3c Don't delete default intersheetrefs field from global labels.
Fixes https://gitlab.com/kicad/code/kicad/issues/14493

(cherry picked from commit a226f7fc14)
2023-04-09 19:04:33 +01:00
Jeff Young 2ba6fad633 Centralize NPTH has-annulus processing.
Fixes https://gitlab.com/kicad/code/kicad/issues/13437

(cherry picked from commit 3b63d70d01)
2023-04-09 19:04:33 +01:00
Mark Roszko bc4878d71e Update ngspice to 40 in vcpkg 2023-04-09 02:16:09 +00:00
jean-pierre charras e991ae504b DIALOG_IMAGE_PROPERTIES: fix some issues:
- add missing panel_image_properties_base.fpb file
- fix not displayed image.
From master branch
2023-04-08 17:04:02 +02:00
Seth Hillbrand c18181042f Simplify test for substantial nubs
Substantial elements following a divot should be at least as far in each
cardinal direction from the origin point in order to be considered
substantial.  This catches cases where the "substantial" element is
actually a straight segment away from the divot

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

(cherry picked from commit 914b5a4d21)
2023-04-07 16:41:11 -07:00
jean-pierre charras 3de80d3b20 Plot gerber: fix a too zealous plot of negative objects on the silkscreen layers,
when merging layers to silkscreen layers.
From master branch
2023-04-07 11:34:42 +02:00
Seth Hillbrand 39dcd0a352 Handle nested netclass assignments
Netclass directives should not be overriden, instead hold our error
checking for actually missing nets

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

(cherry picked from commit 012737593b)
2023-04-06 17:38:42 -07:00
Jeff Young 199e31ea3f Eagle template footprints don't actually belong to board.
Set their parent to nullptr before deleting (as the board may have
already been deleted).

Likely fix for Sentry KICAD-79.

(cherry picked from commit 13e79af8a0)
2023-04-04 14:21:19 +01:00
Jeff Young dce2247925 Improve scoping control of connetion members.
(The real bug here is that CONNECTION_GRAPH::assignNetCodesToBus() was
growing the bus aliases members list because it used a non-const
reference to it as a local storage list.  The const scoping of it will
prevent this type of error in future.)

Fixes https://gitlab.com/kicad/code/kicad/issues/14269
2023-04-04 11:35:06 +01:00
Jeff Young 89e78c0276 Fix Mac crash-on-quit when timed infobar is up.
(cherry picked from commit b3e2cf218f)
2023-04-03 23:47:14 +01:00
Jeff Young 9a57c11348 Possible protection from acessing deleted window data.
(Long shot for Sentry KICAD-MM.)

(cherry picked from commit bd60f38569)
2023-04-03 23:47:09 +01:00
Jeff Young 1dbe8b2a79 Nullptr safety.
(This is a long shot for Sentry KICAD-MV, but you never know....)

(cherry picked from commit a4e8fa96d4)
2023-04-03 23:47:00 +01:00
Seth Hillbrand 29fd0caf58 Update translator contributions
Adds a number of missing contributors to our translations

(cherry picked from commit d135295ac8)
2023-04-03 13:07:33 -07:00
jean-pierre charras d30701ed59 Fix compil warnings.
(cherry picked from commit ac71227e75)
2023-04-03 10:14:14 -07:00
Seth Hillbrand e39550e77f Update to Clipper 1.2+
Updates to Clipper2 742614f, which includes bug fixes for specific KiCad
boards beyond Clipper2 itself

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

(cherry picked from commit 97558b62ec)

Fixes https://gitlab.com/kicad/code/kicad/issues/14475
2023-04-03 10:06:34 -07:00
Jeff Young a21e7a5eee Don't pass a FRAME-based UNITS_PROVIDER to a modeless dialog.
(The dialog may outlive said frame.)
Should fix Sentry KICAD-3A.

(cherry picked from commit 9b4627e782)
2023-04-03 17:20:06 +01:00
Jeff Young 927b5ae707 Use enums for column ids.
(The nickname, in particular, is no longer column 1.)

Fixes https://gitlab.com/kicad/code/kicad/issues/14291
2023-04-02 15:28:11 +01:00
jean-pierre charras f59626004c PCB_TEXT::TransformTextToPolySet(): fix missing code for knockout texts.
From master branch
Fixes #14473
https://gitlab.com/kicad/code/kicad/issues/14473
2023-04-02 10:29:18 +02:00
Jeff Young 2ece2719d0 Naming conventions and nullptr usage. No functional changes. 2023-04-01 15:14:35 +01:00
Jeff Young 78ee542d8d Naming conventions. 2023-04-01 14:11:56 +01:00
Jeff Young cea9b38815 Update local coords after changing footprint item properties.
Fixes https://gitlab.com/kicad/code/kicad/issues/14348

(cherry picked from commit 0f9a4ef7b7)
2023-04-01 13:57:47 +01:00
Jeff Young cb8f6db68d Add hole clearance to moutning hole keepouts for SPECCTRA.
Fixes https://gitlab.com/kicad/code/kicad/issues/14439
2023-04-01 13:57:47 +01:00
Seth Hillbrand 85038c2b46 Prevent PCB Editor from opening multiple board_setup
ShowBoardSetup can be called multiple times from multiple locations,
resulting in duplicate board setup dialog boxes.  This is confusing and
should be prevented.  We use the established patter from the symbol
picker to ensure that only one copy of the dialog is ever opened at a
time

(cherry picked from commit 7695d510d6)
2023-03-30 15:34:42 -07:00
Roberto Fernandez Bautista 1e8055f504 CADSTAR PCB Importer: Ignore construction layers on outer surfaces
Fixes https://gitlab.com/kicad/code/kicad/-/issues/14443

7.0 version of d5bc223ff2 (no strings)
2023-03-31 00:17:06 +02:00
jean-pierre charras a7a5f20d1c Pcbnew: fix incorrect position of cached text shapes when moving a footprint.
when moving a footprint, the position of texts living in FP_TEXT_BOX was
not updated when the text shape was cached (non Kicad fonts).
From master branch.
Fixes #14452
https://gitlab.com/kicad/code/kicad/issues/14452
2023-03-30 17:33:44 +02:00
jean-pierre charras 0d744a4e74 kicad-cli, layer names: allows using both names used in GUI and in board files
From master branch
Fixes #14455
https://gitlab.com/kicad/code/kicad/issues/14455
2023-03-30 13:50:09 +02:00
jean-pierre charras 216ec60dc1 kicad-cli, export drill files: fix duplicate options and fix some others:
- remove --separate-files duplicate option
- change --units to --excellon-units (valid only for Excellon) and default to mm
- Gerber resolution: 5 -> 6 (default must be always the higher resolution)
From Master
Fixes #14454
https://gitlab.com/kicad/code/kicad/issues/14454
2023-03-30 10:35:46 +02:00
Roberto Fernandez Bautista 3d9047bec4 Revert "CADSTAR PCB importer: Fix incorrect position of overridden pads"
This reverts commit 5cab66fb18
2023-03-29 21:53:14 +00:00
Roberto Fernandez Bautista 08d65beb26 CADSTAR PCB importer: Fix loading of rounded rectangle pads
Fixes https://gitlab.com/kicad/code/kicad/-/issues/14445


(cherry picked from commit aaeb8ca739)
2023-03-29 20:56:14 +00:00
Roberto Fernandez Bautista 5cab66fb18 CADSTAR PCB importer: Fix incorrect position of overridden pads
(cherry picked from commit 89441d807d)
2023-03-29 20:55:50 +00:00
jean-pierre charras 9466624f9d Footprint editor: always export the currently loaded footprint.
Previously, it was not always the edited footprint, but a footprint
selected from the library tree.
It was especially annoying when the footprint was loaded from the board editor:
The footprint was not the loaded footprint, but its copy from library.
From master branch
2023-03-29 20:30:25 +02:00
jean-pierre charras 80b842a704 Footprint viewer: ensure the footprint is updated after new library selection
Previously, if the first fp of the new lib has the same name as the old
displayed fp, the old fp was not replace by the new fp.
From master branch
2023-03-29 16:59:12 +02:00
Seth Hillbrand d513a9fe5c Locked shadow needs to be in shadow color
Otherwise, text shadow is stroked by text color

(cherry picked from commit f93fde15b7)
2023-03-28 13:02:18 -07:00
jean-pierre charras c98081cb04 QA test: disable Silk clearance test in solder mask bridge QA test.
the Silk clearance test has nothing to do with a solder mask bridge QA test
From master branch
2023-03-27 12:50:14 +02:00
Jon Evans 17a1dc18be Properties: Hide Net Class from GUI
It is confusing users who want to change the netclass of a net.

(cherry picked from commit 3f42e6b702)
2023-03-26 19:50:10 -04:00
Jon Evans b22ff229db DbLib: Get rid of some GCC warnings
(cherry picked from commit c35cefe1d5)
2023-03-26 19:48:58 -04:00
Jon Evans 23b03fd6ab Properties: Rename methods to better reflect their purposes
(cherry picked from commit 65193487a6)
2023-03-26 19:48:46 -04:00
Jeff Young 97b273905a Manual cherry-pick of a214ac0310. 2023-03-26 21:06:24 +01:00
Jeff Young e759c4d27a Only report on clearances where there was one defined.
If it's 0, it's just a straight-up collision.

(cherry picked from commit 9976b9ce8c)
2023-03-26 20:59:41 +01:00
Jeff Young 76685ae2d9 Run SILK_CLEARANCE rules on mask layer when testing silk-to-mask clearance.
This allows custom rules to be authored without firing the auto-generated
rule from Board Setup > Silk Item Clearance (which should be only for silk-
to-silk clearances).

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

(cherry picked from commit 0266d03f79)
2023-03-26 20:59:36 +01:00
Jeff Young 3fad3ceb35 Update allow-solder-mask-bridges when updating footprint from library.
Fixes https://gitlab.com/kicad/code/kicad/issues/14422
2023-03-26 16:25:54 +01:00
Jeff Young dede9e8549 Test silk/mask collisions on the correct layer.
Fixes https://gitlab.com/kicad/code/kicad/issues/14417
2023-03-26 16:25:54 +01:00
Roberto Fernandez Bautista 97c018118d CADSTAR Sch: TERMATTR may have more than one attribute subnode
Fixes https://gitlab.com/kicad/code/kicad/-/issues/13526


(cherry picked from commit fc04f5135f)
2023-03-26 14:55:06 +00:00
jean-pierre charras 8b1ce36402 QA pcbnew: Add missing golden files and disable issue14294 that always fails.
It needs a Clipper2 update, not yet made in stable branch (made only in testing).
2023-03-26 15:09:35 +02:00
Jeff Young 7931f315b1 Manually cherry-pick some fixes back from master.
Fixes https://gitlab.com/kicad/code/kicad/issues/14424
2023-03-26 11:00:23 +01:00
Marek Roszko abb6404ab2 Move up a layer validity check to prevent crash
Fixes sentry crash KICAD-RF


(cherry picked from commit 604a7d69db)
2023-03-25 21:13:38 +00:00
Wayne Stambaugh c434542c65 Fix GCC compile error.
(cherry picked from commit a79108f102)
2023-03-25 17:35:39 +00:00
Marek Roszko 42b7aa6450 Use read/write locks in the settings_manager to avoid thread issues in some scenarios
Fixes sentry issue KICAD-90


(cherry picked from commit ab28650d57)
2023-03-25 17:35:31 +00:00
jean-pierre charras f2ce9cf857 Plot symbol graphic texts: fix incorrect position of texts in some rotations.
The plot code is now similar to the one for symbol fields
From master branch.
Fixes #14327
https://gitlab.com/kicad/code/kicad/issues/14327
2023-03-25 18:27:35 +01:00
jean-pierre charras 56134d0202 KICAD_CURL_EASY: fix compil warnings (avoid using deprecated functions) 2023-03-25 18:27:35 +01:00
Jeff Young f33bbe2d5d Add regression test for 14412.
(cherry picked from commit 30b3645e60)
2023-03-25 16:16:10 +00:00
Jeff Young 59a478bdc5 Allow solder mask bridges between net-tie-group pads.
Fixes https://gitlab.com/kicad/code/kicad/issues/14412

(cherry picked from commit c5e66361db)
2023-03-25 16:15:46 +00:00
Jeff Young 141b332d4f Add regression test for 13988.
(cherry picked from commit 35ca3e7264)
2023-03-25 15:37:57 +00:00
Jeff Young d4a312d6cb Move separation of model name from params earlier in the process.
We need just the model name when we look for a match in the library file.

(cherry picked from commit 60aadfee40)
2023-03-25 15:37:57 +00:00
Jeff Young 31d688b34c Add regression test for 14334.
(cherry picked from commit e65a58b823)
2023-03-25 15:37:57 +00:00
Jeff Young fbef9ea600 Keep track of single-pad-islands so we can discount spokes to them.
(cherry picked from commit d6dd58fff9)
2023-03-25 15:37:57 +00:00
Marek Roszko 0688491e1b Fix typo
(cherry picked from commit eb90448247)
2023-03-24 23:55:24 +00:00
Marek Roszko 434161687e Fix cli crash due to dialogs buried in the pcb parser...
Fixes sentry KICAD-Q2


(cherry picked from commit 8a8589b9db)
2023-03-24 23:53:15 +00:00
Seth Hillbrand 4b3709b96b Revert "Update to Clipper2 1.2+"
This reverts commit 560717de76.
2023-03-24 12:30:11 -07:00
Seth Hillbrand 1fa993303d Revert "Undefine None for X11 after Clipper2 update"
This reverts commit 4f265a52a2.
2023-03-24 12:30:11 -07:00
Seth Hillbrand 01897e7755 Revert "Fix GCC 13 build error."
This reverts commit 00d1e01e12.
2023-03-24 12:30:10 -07:00
Seth Hillbrand 7040b2178d Revert "Update for Clipper 1.2"
This reverts commit e758391a23.
2023-03-24 12:30:09 -07:00
Seth Hillbrand edf23c4c18 Revert "Clean up various simplify steps"
This reverts commit 798e13f70d.
2023-03-24 12:30:06 -07:00
Jon Evans b0b9e66fad Move to requiring explicit action to save project settings
(cherry picked from commit 610e787ada)

Fixes https://gitlab.com/kicad/code/kicad/issues/14414
2023-03-24 11:49:50 -07:00
Seth Hillbrand 89488a43b9 Pins are case-sensitive
Cleanup should remove mis-matched cases

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

(cherry picked from commit 0984599624)
2023-03-24 11:35:20 -07:00
Seth Hillbrand 798e13f70d Clean up various simplify steps
Adds the option to simplify the output of Clipper ops that remove minor
detours from the output lines.  These detours are not substantive, so
removing them speeds up the rest of the system by removing unimportant
vertices.  This also prevents the introduction of inadvertant concave
points when unioning two, closely-sized rounded shapes
2023-03-24 09:42:01 -07:00
Seth Hillbrand e758391a23 Update for Clipper 1.2 2023-03-24 09:42:01 -07:00
Steven A. Falco 00d1e01e12 Fix GCC 13 build error.
See https://kicad.zulipchat.com/#narrow/stream/258851-Developer-Chat/topic/GCC.20Breakage
for more info.
2023-03-24 09:42:01 -07:00
Seth Hillbrand 4f265a52a2 Undefine None for X11 after Clipper2 update 2023-03-24 09:42:01 -07:00
Seth Hillbrand 560717de76 Update to Clipper2 1.2+
Updates to 303232e, which includes bug fixes for specific KiCad boards
beyond Clipper2 1.2 itself

Fixes https://gitlab.com/kicad/code/kicad/issues/14294
2023-03-24 09:42:01 -07:00
jean-pierre charras 0f40894317 Pcbnew, APPEARANCE_CONTROLS: do not change objects visibility, when changing
layers visibility using Preset layers widget.
Fixes #14381
https://gitlab.com/kicad/code/kicad/issues/14381
2023-03-24 15:06:06 +01:00
jean-pierre charras 3915e882a8 Gerbview: Aperture Macro: handle overwriting of variables
Gerbview did not handle redefinition of variable like $3 = $3 / 2
This redefinition is sometimes found in Gerber files.
This is a long standing issue now fixed.
From master branch
2023-03-24 12:02:49 +01:00
jean-pierre charras c5caa23a63 Manager teardrops on arcs. From master branch. 2023-03-24 11:46:11 +01:00
jean-pierre charras 36978d2ddc Gerber plotter: fix incorrect arcs in regions when using a plot offset.
The arc center in Gerber units was incorrectly calculated.
From master
Fixes #14402
https://gitlab.com/kicad/code/kicad/issues/14402
2023-03-24 11:37:26 +01:00
Marek Roszko 3f90c895b9 Prevent crash in color settings due to dropdown weirdness
Fixes sentry reported crash KICAD-R6


(cherry picked from commit c65e33ac13)
2023-03-23 23:47:13 +00:00
Jon Evans 2ada171806 Be more flexible about extracting booleans from database
Fixes https://gitlab.com/kicad/code/kicad/-/issues/14376


(cherry picked from commit dd8b52af93)
2023-03-23 01:25:09 +00:00
Marek Roszko 5dc683c968 Fix crash editing footprint editor defaults
Missing one level of GetParent()....use a dynamic_cast to sanity check it in debug

Fixes sentry crash KICAD-R4


(cherry picked from commit d49562a7aa)
2023-03-22 22:41:57 +00:00
Jeff Young 7026cfe140 Split name from additional params only when model is a library reference.
(cherry picked from commit b8cf7cc080)
2023-03-22 14:12:42 +00:00
Jeff Young b7cd1dd764 Handle single-token flag parameters.
Also fixes a bug where all VDMOS instance parameters weren't marked as
instance parameters.

Also fixes a bug where VDMOS thermal models weren't supported (they
have two extra pins: Tj and Tcase).

(cherry picked from commit 5bda3b99f9)
2023-03-22 14:12:42 +00:00
Jeff Young 09bb8fc4f4 Don't include non-overridden parameters in Sim.Params.
Fixes https://gitlab.com/kicad/code/kicad/issues/14369

(cherry picked from commit 9dc16eb014)
2023-03-22 14:12:42 +00:00
jean-pierre charras 746ab49d36 Ensure 3D shapes are always shown in footprint settings dialog.
From master branch
Fixes #14371
https://gitlab.com/kicad/code/kicad/issues/14371
2023-03-22 08:53:42 +01:00
Jeff Young 1614dc975a Separate legacy model name from parameters.
Fixes https://gitlab.com/kicad/code/kicad/issues/13988

(cherry picked from commit 39a801423e)
2023-03-21 13:31:20 +00:00
Alex ba7598d90d Fix clashing error dialogs when can't load dynamic library.
(cherry picked from commit 672c468342)
2023-03-21 09:57:46 +00:00
Alex 92fc4872e8 GTK: Fix settings import paths showing up twice.
(cherry picked from commit b89545e484)
2023-03-21 09:57:28 +00:00
jean-pierre charras 30dbfc33a4 step exporter: fix missing initialization of a member (m_pcbBaseName)
EXPORTER_STEP: rename m_pcbName to m_pcbBaseName.
From master.
2023-03-21 09:52:41 +01:00
Mark Roszko b3de5aa08e Put the project name back into the step pcb label.
Software like Solidworks and other CAD treat STEP labels as unique entries.
When you import multi STEP files into the same project, it'll start deduplicating your design by those name.
So two completely unrelated PCBs with the same "PCB" name will result in one being replaced by another.
2023-03-21 01:18:33 +00:00
Jeff Young ba4773e448 Orthogonal dimension are always cardinal, even when their start points are not.
Fixes https://gitlab.com/kicad/code/kicad/issues/13728

(cherry picked from commit bb2a0f825a)
2023-03-20 21:32:06 +00:00
Jeff Young a713ee852c Ignore extraneous LTSpice parameters for VDMOS models.
Also adds special case handling of VDMOS syntax to allow parens (or extra
spaces, linebreaks, etc.) between "VDMOS" and "NCHAN"/"PCHAN".

Fixes https://gitlab.com/kicad/code/kicad/issues/14299
2023-03-20 16:16:13 +00:00
jean-pierre charras a65accd412 EDA_SHAPE_DESC(): catch a std::runtime_error when emitted by
template<typename T> T Get( PROPERTY_BASE* aProperty ) to avoid a crash,
and displays in Debug mode the runtime error message.
From master branch.
Fixes #14347
https://gitlab.com/kicad/code/kicad/issues/14347
2023-03-20 16:21:54 +01:00
Jeff Young 1dc9583e06 Don't attempt to load unknown plot types. 2023-03-20 10:24:22 +00:00
Jeff Young 3afe02ac1f Make sure legend reflects gain/phase for AC small signal analyses.
Fixes https://gitlab.com/kicad/code/kicad/issues/14301

(cherry picked from commit ec6d709929)
2023-03-20 10:24:22 +00:00
Jeff Young 57aa61f1ba Formatting. (No functional changes.)
(cherry picked from commit 6f44b85c13)
2023-03-20 09:59:30 +00:00
Jeff Young 121ea14fe4 Filter Selected Items... is inclusive, not exclusive.
Fixes https://gitlab.com/kicad/code/kicad/issues/14273

(cherry picked from commit 897984aa22)
2023-03-19 21:31:08 +00:00
Jeff Young 9d457dc0ab Less nagging. (If we need a field name, then create one.)
Also cleans up empty fields when exiting the dialog.
2023-03-19 19:15:28 +00:00
Jeff Young befd836ab4 Clean up items which weren't pasted from clipboard.
Fixes https://gitlab.com/kicad/code/kicad/issues/14335

(cherry picked from commit ad5d3d4eba)
2023-03-18 23:38:09 +00:00
Jeff Young 044c301d64 Remove accelerator keys from schematic find/replace dialog.
Fixes https://gitlab.com/kicad/code/kicad/issues/14304

(cherry picked from commit afe813cae5)
2023-03-18 23:38:09 +00:00
jean-pierre charras 94fd0df2e2 BOARD_NETLIST_UPDATER: add missing count of warnings
From master branch
Fixes #14290
https://gitlab.com/kicad/code/kicad/issues/14290
2023-03-18 17:57:07 +01:00
Salvador E. Tropea e5087ca3db Load the global fp-lib-table before running the Python DRC
Without this we get parity errors for all the KiCad footprints
2023-03-17 21:00:41 +00:00
jean-pierre charras 819a9da599 Pcbnew: fix crash when loading a library with a ft containing a dimension.
(crash due to the use of a null pointer during loading)

(cherry picked from commit 5735a57504)
2023-03-17 16:00:34 +00:00
Jeff Young fb02e55424 Don't pass a REPORTER when checking for overrides.
It fails the unit tests (as it generates a message whenever no override
is found).
2023-03-17 15:30:24 +00:00
Jeff Young 70e86434ef Manual cherry-pick of much of 6d296038f3 2023-03-17 14:12:58 +00:00
Jeff Young c41b1e2f06 Manual cherry-pick of bug fix part of ee1d9c561c. 2023-03-17 13:35:23 +00:00
Jeff Young 64641c28ef Handle underscore in parameter names.
Fixes https://gitlab.com/kicad/code/kicad/issues/14308

(cherry picked from commit 222cd4d009)
2023-03-16 23:51:56 +00:00
jean-pierre charras 69e9f4ada2 DIALOG_LABEL_PROPERTIES, add global label: better filtering of candidates.
The list of candidates (names) must be restricted to existing global labels
and symbols creating a global net name: power symbols having only one power
input pin (a power output does not create net name).
Fixes #14319
https://gitlab.com/kicad/code/kicad/issues/14319
2023-03-16 16:01:18 +01:00
Wayne Stambaugh d28cf632e4 Coverity fixes and code cleaning.
(cherry picked from commit a1fb8e1b1d)
2023-03-16 10:59:05 -04:00
Alex b466bfa6c8 Improve anti-overflow in SEG::intersects.
Caused issues when testing against
A=( -INT_MAX, ... ), B=( INT_MAX, ... ) segments.

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


(cherry picked from commit 98e635869f)
2023-03-16 02:50:22 +00:00
Alex 1c06f4cf06 Don't create 0-length tracks when placing via in the middle of a track.
(cherry picked from commit 8fe78101db)
2023-03-16 02:49:54 +00:00
jean-pierre charras 25f40566ed Symbol editor: fix incorrect position of fields when loading a symbol from schematic.
In symbol editor, symbols are always shown not mirrored, not rotated.
So if the loaded symbol from schematic was rotated/mirrored, the position
of fields must be recalculated for the rotation 0, no mirror.
From master branch
2023-03-15 18:03:11 +01:00
Marco Ciampa e8fa2cbc4d Small fix in Italian translation 2023-03-15 13:35:38 +01:00
Marco Ciampa 779c441e0a Small fix in Italian translation 2023-03-15 13:31:29 +01:00
Marco Ciampa e33031ee7d Updated Italian translation 2023-03-15 10:18:07 +01:00
jean-pierre charras ae63313b55 PDF plotter: encode the letters ( and ) in strings with context CTX_JS_STR
They are separators and cannot be used in user strings.
Fixes #14302
https://gitlab.com/kicad/code/kicad/issues/14302
2023-03-15 09:36:01 +01:00
jean-pierre charras ae50b8d839 make QA link-able on msys2 (from master branch). 2023-03-14 18:05:18 +01:00
Jeff Young 10a27156c2 Defenses in depth for ratsnest drawing.
(cherry picked from commit e60837ec95)
2023-03-14 12:00:03 +00:00
Jeff Young 94057886a3 Support SHEET_PATH when printing.
Fixes https://gitlab.com/kicad/code/kicad/issues/14233

(cherry picked from commit dc78797274)
2023-03-14 11:56:33 +00:00
Jeff Young 2d9bcb6e4f Select correct face from a .ttc file.
Fixes https://gitlab.com/kicad/code/kicad/issues/13314

(cherry picked from commit 7b3e01ce52)
2023-03-14 11:56:33 +00:00
Jeff Young 249bcd9e1a Update dimension units when opening PCBs in CLI.
Fixes https://gitlab.com/kicad/code/kicad/issues/14170

(cherry picked from commit a0adb59437)
2023-03-14 11:56:33 +00:00
Jeff Young b2679b7648 Swap pins for undo.
Fixes https://gitlab.com/kicad/code/kicad/issues/14100

(cherry picked from commit c266913ec7)
2023-03-14 11:56:33 +00:00
Seth Hillbrand 9995b8714b Check for dirtied items in the cluster
When drawing the ratsnest, we need to be careful to avoid accessing
CONN_ITEMs that have been changed by the underlying model.  Checking for
dirty items instead of valid items will prevent us looking at data that
are out of date

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

(cherry picked from commit 283770fc45)
2023-03-13 16:11:27 -07:00
jean-pierre charras 7b4dd2f7f5 DIALOG_BOARD_REANNOTATE: ensure indexes are not out of bound. 2023-03-13 20:25:54 +01:00
Seth Hillbrand cc6b01cf88 Force initialization of board units
Unitialized variables are the devil's playground

(cherry picked from commit f0892598a4)
2023-03-13 12:15:51 -07:00
Seth Hillbrand 3568ff72bf Avoid drawing null-arcs in 3d viewer
An arc with no radius or no angle is not visible and should be avoided

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

(cherry picked from commit 72ebe5a429)
2023-03-13 11:48:24 -07:00
Jeff Young e20614660b Fix qa gold value.
(cherry picked from commit 6eb73133f0)
2023-03-12 21:06:28 +00:00
Jeff Young c5a69f073c Added PSPICE/LTSPICE JFET model parameters.
Fixes https://gitlab.com/kicad/code/kicad/issues/12425

(cherry picked from commit 3bc5e3dd8a)
2023-03-12 21:05:06 +00:00
Jeff Young 3025671b1a Add missing command to SPICE directives list.
Fixes https://gitlab.com/kicad/code/kicad/issues/14215

(cherry picked from commit 6d29088668)
2023-03-12 21:04:50 +00:00
Jeff Young 74da0043b4 Move automatic dimension processing inside PCB_DIMENSION_BASE.
Also move dimension precision to an enum so it can get a proper dropdown
in the properties inspector.

(cherry picked from commit 461def2719)
2023-03-12 21:04:09 +00:00
Jeff Young c0ddca12df Add Property Inspector support for dimension objects.
Includes changing the class hierarchy so that dimension objects inherit
from PCB_TEXT rather than containing a PCB_TEXT member variable.

(cherry picked from commit 23accffc6d)
2023-03-12 21:03:58 +00:00
Jeff Young bf55e610b9 Handle plotting of text on solder mask layer.
Admittedly this is an odd thing to do, but we should still be internally
consistent, and it has come up in customers' files.

Fixes https://gitlab.com/kicad/code/kicad/issues/14226
2023-03-12 21:00:19 +00:00
Mark Roszko 4e775a4090 Move vcpkg forwards for newer curl and python 3.9.16 2023-03-12 02:18:35 +00:00
Jon Evans 9f7b31b5c5 Do not try to process invalid ratsnest nodes
Fixes https://gitlab.com/kicad/code/kicad/-/issues/14254


(cherry picked from commit 8eaa3cfac9)
2023-03-11 21:12:33 +00:00
Simon Richter 279641df73 Avoid "suggest parentheses around assignment used as truth value" 2023-03-10 23:09:41 +01:00
Wayne Stambaugh 9e1fd16329 Coverity fixes and code cleaning.
(cherry picked from commit 4e99812145)
2023-03-10 11:21:19 -05:00
Wayne Stambaugh d6ff5f0239 Begin 7.0.2 development. 2023-03-09 17:03:32 -05:00
Wayne Stambaugh 3f5d3fa0c6 Tag release version 7.0.1. 2023-03-09 16:59:45 -05:00
Seth Hillbrand 51dc2b109e Handle fully-nested zones
The logic to handle divots needs to account for fully nested, same net
zones.  The process of subtracting led to us considering the inner zone
to be a zone knock-out (negative polygon).  To avoid this, we need to
check if the inner, higher priority zone has any connection to the outer
zone.  If it does not, then we can treat it as an isolated zone without
worrying about divots to the outer zone.

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


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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

Adds testing of pin types to netlist QA unit tests.

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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


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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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


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

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

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

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

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

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

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

Also fix calculation of arc geometry for ccw arcs.

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


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


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


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

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


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

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


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

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


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

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

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

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

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

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

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

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

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


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


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


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


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

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

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

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

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

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

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

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

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

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


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


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


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

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

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


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


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

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


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


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

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

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

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


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


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

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


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


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

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

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

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

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


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

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

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


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


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

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

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

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

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

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

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

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

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

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


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

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


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


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

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

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

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

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

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

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

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


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

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

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

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

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


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

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