Compare commits
291 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 702e8b8915 | |||
| 9226144312 | |||
| d937abb5b8 | |||
| bfd5afd6c8 | |||
| ab878cc257 | |||
| a8c275ae5d | |||
| d75329b6f1 | |||
| 861589d837 | |||
| 54f91a0221 | |||
| 8e1e8e1492 | |||
| 20ef0e54fe | |||
| aa126a12f2 | |||
| eecb54bff2 | |||
| b554c4cb66 | |||
| b447d55900 | |||
| a444addd89 | |||
| 209d593ca0 | |||
| 4fbb957fa3 | |||
| 8100a8940f | |||
| 485e4ddf05 | |||
| 4ab750e926 | |||
| a10d9628c9 | |||
| 5b175d6d53 | |||
| 10217f5507 | |||
| f185511698 | |||
| db972a708a | |||
| efaabfa852 | |||
| 932cb82c82 | |||
| f0d52ff2de | |||
| fc737ffffd | |||
| 4df36a3438 | |||
| e72bd34383 | |||
| 8fc831cbc2 | |||
| aa5b6c70a7 | |||
| 7d5c1d7b5c | |||
| f5a56c1ebc | |||
| 3af606a020 | |||
| 132358211e | |||
| f412d8d461 | |||
| 71bcc9883a | |||
| be958e3fdb | |||
| b2c99dd953 | |||
| c875af48e7 | |||
| 471c0c4c1d | |||
| 9e5e46514d | |||
| ba70f202ce | |||
| e18fc36646 | |||
| 4657614e4f | |||
| d295025964 | |||
| 2365c1e96f | |||
| 430c4862b6 | |||
| 4c81307391 | |||
| 57cbe261f2 | |||
| 50d3a507d0 | |||
| 7642a9db79 | |||
| 527e06d989 | |||
| 69b69aa431 | |||
| d6a86fa9e0 | |||
| 0a13f15a9d | |||
| ef94f31204 | |||
| 7601a3385f | |||
| ccf2a63f45 | |||
| 901685f01b | |||
| bdf235c25f | |||
| 0ffa266315 | |||
| 5c94d59e75 | |||
| 02f93805d0 | |||
| 2e324aa845 | |||
| fecb625459 | |||
| b883eee911 | |||
| 01f3a14dc3 | |||
| 2425444947 | |||
| 66e12af548 | |||
| ea38056e33 | |||
| c805144c08 | |||
| 927afe313d | |||
| 03f643ca42 | |||
| 945b841e1b | |||
| 6771ceb050 | |||
| 61853a2d7c | |||
| 92773335f7 | |||
| ef58267013 | |||
| 35e9c57555 | |||
| 1e3b3df808 | |||
| c062ba3044 | |||
| 44b4e6753c | |||
| 9c22a8000e | |||
| 83729adca4 | |||
| 2585f7e7a4 | |||
| a7d586818c | |||
| 0030ddee26 | |||
| 1853900389 | |||
| f1a04828f7 | |||
| c8b0a3697f | |||
| e8774181f8 | |||
| b253d9085d | |||
| 6d1351fa98 | |||
| d7eef72c29 | |||
| 84bae1f3df | |||
| b5bc942758 | |||
| 86f485619a | |||
| a9f832556c | |||
| 01aff3bf80 | |||
| 5ba8dcdcf1 | |||
| c2edf23118 | |||
| 00dd29ae8b | |||
| 5c4389a3c4 | |||
| c81a71627f | |||
| 6d84acfacd | |||
| 788c607d47 | |||
| 169881dcf1 | |||
| a7fbdfe918 | |||
| 3d11ce5139 | |||
| 833ce19221 | |||
| 73d0d7796c | |||
| 42dfdf8c38 | |||
| 70d00689ca | |||
| 26dfc4477f | |||
| 38a4894d92 | |||
| c2707f3cc0 | |||
| 8753051db6 | |||
| 8ae304dcca | |||
| 796893de56 | |||
| ea52101c1b | |||
| ca27b38182 | |||
| 3f6a4296d9 | |||
| 2a27899b9b | |||
| 1a534ade89 | |||
| fddfce4fb1 | |||
| ab184ba9f3 | |||
| a1615cce7e | |||
| 871556ebda | |||
| 7152c4ebb8 | |||
| 34dafdd2c1 | |||
| f12d0cb0e2 | |||
| 029e42f8d1 | |||
| 60ae18893e | |||
| e0b835fe20 | |||
| d6c4215a1f | |||
| 8b6a166698 | |||
| e9a5e5466c | |||
| 0317185860 | |||
| c02cadec2a | |||
| b608ebd058 | |||
| 6d7659fb20 | |||
| dd7029ea07 | |||
| 323a069738 | |||
| 615eda816e | |||
| 6810479a19 | |||
| d9c6765be7 | |||
| 857683d372 | |||
| 24865971af | |||
| 10ce515aca | |||
| da28ade004 | |||
| f97a0fb3e9 | |||
| cccdac136f | |||
| 2306d00c89 | |||
| 20bbf9b179 | |||
| cf4d46b24d | |||
| 739c14eaa2 | |||
| adfbfc27af | |||
| 26047615bd | |||
| dcb8f29317 | |||
| 57d58fe335 | |||
| 56d87a8613 | |||
| 9a0323fe17 | |||
| 0a9271f98e | |||
| 3c91b0c693 | |||
| 562bd7d564 | |||
| ad726dc6e4 | |||
| b2ecf097ed | |||
| 8dca61ce9c | |||
| e8e25fd732 | |||
| bd7841bf96 | |||
| 55020c2b89 | |||
| a74d1d9962 | |||
| 4d899d7820 | |||
| 4907b90215 | |||
| a399f799ad | |||
| 55cd2da432 | |||
| 096600ffc4 | |||
| b4bae29c02 | |||
| e4a5ce78aa | |||
| 522738284d | |||
| cc0d5ec46a | |||
| f2018a09d8 | |||
| 54952ca97e | |||
| a8543b1122 | |||
| 790ca19445 | |||
| f56b3bdd07 | |||
| 7d635d3d43 | |||
| 37f62e539b | |||
| 3196f4adb6 | |||
| b4d67b6b29 | |||
| f7d790598b | |||
| bbf00e0461 | |||
| a91f807e13 | |||
| 100cf757fe | |||
| 76f21d950d | |||
| 69469b254a | |||
| bfca928900 | |||
| 62f8603353 | |||
| 9a2332dfcf | |||
| 4bcfa8df1f | |||
| a0e424c2ac | |||
| f4b9a92b94 | |||
| 184a592f82 | |||
| 3e6bf7814b | |||
| 9864337914 | |||
| 78e737b9d8 | |||
| d014f0307b | |||
| 7c9340f855 | |||
| 3069b198b1 | |||
| 05d3dc533b | |||
| 1e05732f55 | |||
| 71e7b4b77b | |||
| b8a7a66a0a | |||
| 55087a9e82 | |||
| 444801ada6 | |||
| 7afe188a29 | |||
| 1ad1cf8374 | |||
| abaee94109 | |||
| d60e77176f | |||
| 7f1648934f | |||
| bef762e652 | |||
| a05ec04ee8 | |||
| 362eedc510 | |||
| 11402e2db1 | |||
| b1658fdf9a | |||
| f9d8ec6137 | |||
| e9b91b6fab | |||
| 873353d8d7 | |||
| a326d777f0 | |||
| dec310f7f8 | |||
| ca8cf14dff | |||
| ed9a3deb57 | |||
| 58b07efd99 | |||
| 1874ad2f7e | |||
| b115aec42b | |||
| 5e884d14c7 | |||
| e36381bdd2 | |||
| 45182febaf | |||
| ea99c42df6 | |||
| 0065036899 | |||
| bb388d47fc | |||
| 134b09004b | |||
| c52421869a | |||
| addc5574b4 | |||
| bd75cffff3 | |||
| 3453bf3f88 | |||
| f139cc2d9f | |||
| 6fd93eaa1e | |||
| cf8c614a02 | |||
| 9fd1ad9b7b | |||
| d45472adcd | |||
| f67c0ea8c7 | |||
| 3c2bb97eae | |||
| cbdfb5d396 | |||
| e19acb4632 | |||
| 11c967b259 | |||
| 517e44e917 | |||
| 0ec440805d | |||
| 67fe8904c0 | |||
| da850036e3 | |||
| b80595903c | |||
| c83880428c | |||
| cc84344499 | |||
| 32be48222a | |||
| b7ec594c0a | |||
| 2481b21d80 | |||
| ceb4d08ce9 | |||
| 6edc605cab | |||
| d913e6a8f7 | |||
| bde0c3e879 | |||
| b95032901e | |||
| 753e08a944 | |||
| ee1b327162 | |||
| da5f2366f9 | |||
| e7cc177d94 | |||
| 93c48b9d46 | |||
| 1b033d56a7 | |||
| ad583eab13 | |||
| 0d3246e3ab | |||
| 76fd029cd6 | |||
| 2efa878287 | |||
| 1dc78c4adc | |||
| 34d855cd53 | |||
| 9cb36e5bc5 | |||
| b6ff44cccf | |||
| e9e742816d | |||
| b403930601 |
@@ -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
@@ -1,2 +1,2 @@
|
||||
custom: "https://donate.kicad.org"
|
||||
community_bridge: kicad
|
||||
community_bridge: kicad
|
||||
custom: "https://donate.cernandsocietyfoundation.cern/b/my-donation?cid=4&_cv=1"
|
||||
+10
-15
@@ -1,9 +1,8 @@
|
||||
.downloads-by-cmake
|
||||
.gdb_history
|
||||
boost_root
|
||||
/Build*
|
||||
/build*
|
||||
/cmake-build-*
|
||||
Build*
|
||||
build*
|
||||
common/fp_lib_table_keywords.cpp
|
||||
common/drc_rules_keywords.cpp
|
||||
common/drc_rules_lexer.h
|
||||
@@ -24,17 +23,19 @@ eeschema/dialogs/dialog_bom_cfg_lexer.h
|
||||
common/template_fieldnames_keywords.cpp
|
||||
common/template_fieldnames_lexer.h
|
||||
eeschema/schematic_keywords.*
|
||||
eeschema/sch_text_help_md.h
|
||||
pcbnew/pcb_plot_params_keywords.cpp
|
||||
pcbnew/pcb_plot_params_lexer.h
|
||||
pcbnew/dialogs/panel_setup_rules_help_md.h
|
||||
Makefile
|
||||
CMakeUserPresets.json
|
||||
CMakeCache.txt
|
||||
.cache/
|
||||
auto_renamed_to_cpp
|
||||
Testing
|
||||
version.h
|
||||
config.h
|
||||
install_manifest.txt
|
||||
doxygen/out
|
||||
Documentation/doxygen
|
||||
Documentation/development/doxygen
|
||||
*.bak
|
||||
*.pyc
|
||||
common/pcb_plot_params_keywords.cpp
|
||||
@@ -52,7 +53,6 @@ bitmaps_png/tmp
|
||||
common/pcb_keywords.cpp
|
||||
include/pcb_lexer.h
|
||||
fp-info-cache
|
||||
qa/tests/output/**
|
||||
|
||||
# demo project auxiliary files
|
||||
demos/**/*-bak
|
||||
@@ -80,6 +80,7 @@ pcbnew/Info.plist
|
||||
*.o.*
|
||||
*.a
|
||||
*.a.*
|
||||
*.cmake
|
||||
*.orig
|
||||
*.rej
|
||||
*.so
|
||||
@@ -89,7 +90,7 @@ pcbnew/Info.plist
|
||||
*.patch
|
||||
|
||||
# These CMake files are wanted
|
||||
!cmake/**/*.cmake
|
||||
!CMakeModules/*.cmake
|
||||
|
||||
# Eclipse IDE
|
||||
.settings/
|
||||
@@ -102,8 +103,6 @@ __pycache__
|
||||
.vs/
|
||||
.editorconfig
|
||||
CMakeSettings.json
|
||||
.vscode/
|
||||
/vcpkg_installed
|
||||
|
||||
# Sublime Text
|
||||
*.sublime-*
|
||||
@@ -121,14 +120,10 @@ i18n_status.csv
|
||||
*.kicad_prl
|
||||
*-backups
|
||||
|
||||
# QA dataoutput
|
||||
qa/data/**/*.csv
|
||||
|
||||
# Don't actually ignore any of these files, since we need them in the tree
|
||||
!resources/linux/icons/hicolor/**/**/*
|
||||
!resources/linux/icons-nightly/hicolor/**/**/*
|
||||
!CMakeModules/**/*
|
||||
!resources/bitmaps_png/png/**/*
|
||||
!bitmaps_png/png/**/*
|
||||
|
||||
# Junk temp files generated by MSVC for resource files
|
||||
/resources/msw/RC*
|
||||
|
||||
+29
-4
@@ -5,16 +5,41 @@ stages:
|
||||
|
||||
default:
|
||||
image:
|
||||
name: registry.gitlab.com/kicad/kicad-ci/source_containers/master/fedora:36
|
||||
name: registry.gitlab.com/kicad/kicad-ci/source_containers/master/fedora:34
|
||||
entrypoint: ["/bin/sh", "-c"]
|
||||
|
||||
|
||||
##########################################################################
|
||||
# Test the formatting in a merge request using clang-format
|
||||
##########################################################################
|
||||
# The variable CI_COMMIT_BEFORE_SHA is not available in normal merge requests
|
||||
# so we must build the commit hash ourselves, see:
|
||||
# https://gitlab.com/gitlab-org/gitlab/issues/12850
|
||||
test_formatting:
|
||||
stage: test
|
||||
needs: []
|
||||
only:
|
||||
- merge_requests
|
||||
allow_failure: true
|
||||
before_script:
|
||||
# We must manually add the KiCad remote to ensure it is named sensibly
|
||||
- git remote add product https://gitlab.com/kicad/code/kicad.git
|
||||
- git remote add source ${CI_MERGE_REQUEST_SOURCE_PROJECT_URL}.git
|
||||
- git fetch -n product
|
||||
- git fetch -n source
|
||||
# Get the SHAs of the commits
|
||||
- "TARGET_HEAD_SHA=$(git rev-parse product/${CI_MERGE_REQUEST_TARGET_BRANCH_NAME})"
|
||||
- "SOURCE_HEAD_SHA=$(git rev-parse source/${CI_MERGE_REQUEST_SOURCE_BRANCH_NAME})"
|
||||
- "MERGE_BASE_SHA=$(git merge-base ${TARGET_HEAD_SHA} ${SOURCE_HEAD_SHA})"
|
||||
script:
|
||||
- echo "Testing formatting from commit ${MERGE_BASE_SHA}"
|
||||
- ./tools/check_coding.sh --diff --ci --commit ${MERGE_BASE_SHA}
|
||||
|
||||
|
||||
include:
|
||||
- local: '/.gitlab/templates.yml'
|
||||
- local: '/.gitlab/Fedora-Linux-CI.yml'
|
||||
- local: '/.gitlab/Ubuntu-20.04-CI.yml'
|
||||
- local: '/.gitlab/Windows-CI.yml'
|
||||
- local: '/.gitlab/macOS-CI.yml'
|
||||
- local: '/.gitlab/coverity.yml'
|
||||
- local: '/.gitlab/linux-metadata-validate.yml'
|
||||
- local: '/.gitlab/doxygen.yml'
|
||||
- local: '/.gitlab/mr_formatting.yml'
|
||||
|
||||
+18
-98
@@ -1,12 +1,11 @@
|
||||
##########################################################################
|
||||
# Build KiCad on Fedora and save the results
|
||||
##########################################################################
|
||||
.fedora_build_linux_base:
|
||||
fedora_build_linux:
|
||||
stage: build
|
||||
# Don't tag until we have separate CI for MRs
|
||||
# tags:
|
||||
# - kicad-fedora
|
||||
image: registry.gitlab.com/kicad/kicad-ci/source_containers/master/fedora:38
|
||||
tags:
|
||||
- kicad-fedora
|
||||
image: registry.gitlab.com/kicad/kicad-ci/source_containers/master/fedora:34
|
||||
extends: .only_code
|
||||
interruptible: false
|
||||
cache:
|
||||
@@ -23,11 +22,11 @@
|
||||
- cd build/linux
|
||||
- cmake
|
||||
-G Ninja
|
||||
-DCMAKE_BUILD_TYPE=QABUILD
|
||||
-DCMAKE_BUILD_TYPE=Debug
|
||||
-DKICAD_STDLIB_LIGHT_DEBUG=ON
|
||||
-DKICAD_USE_OCC=ON
|
||||
-DKICAD_SPICE=ON
|
||||
-DKICAD_BUILD_I18N=ON
|
||||
-DKICAD_TEST_XML_OUTPUT=ON
|
||||
-DKICAD_BUILD_PNS_DEBUG_TOOL=ON
|
||||
../../
|
||||
- ninja 2>&1 | tee compilation_log.txt
|
||||
- cd ../../
|
||||
@@ -39,40 +38,19 @@
|
||||
when: always
|
||||
paths:
|
||||
- build/linux/3d-viewer/
|
||||
- build/linux/common/libkicommon.so*
|
||||
- build/linux/common/gal/libkigal.so*
|
||||
- build/linux/eeschema/_eeschema.kiface
|
||||
- build/linux/kicad/kicad-cli
|
||||
- build/linux/pcbnew/pcbnew.py
|
||||
- build/linux/pcbnew/_pcbnew.kiface
|
||||
- build/linux/pcbnew/_pcbnew.so
|
||||
- build/linux/qa/
|
||||
- build/linux/compilation_log.txt
|
||||
exclude:
|
||||
- build/linux/**/*.o
|
||||
- build/linux/**/*.a
|
||||
|
||||
# This split is to ensure we can always use our runner for our jobs
|
||||
fedora_build_linux_kicad:
|
||||
extends: .fedora_build_linux_base
|
||||
tags:
|
||||
- kicad-fedora
|
||||
only:
|
||||
variables:
|
||||
- $CI_PROJECT_ROOT_NAMESPACE == "kicad"
|
||||
|
||||
fedora_build_linux_public:
|
||||
extends: .fedora_build_linux_base
|
||||
except:
|
||||
variables:
|
||||
- $CI_PROJECT_ROOT_NAMESPACE == "kicad"
|
||||
|
||||
|
||||
# Upload the compilation log in an easily downloadable form
|
||||
.fedora_report_build_warn:
|
||||
fedora_report_build_warn:
|
||||
stage: report
|
||||
extends: .only_code
|
||||
when: always
|
||||
needs:
|
||||
- job: fedora_build_linux
|
||||
artifacts: true
|
||||
script:
|
||||
- echo "Uploading compilation log"
|
||||
- cp build/linux/compilation_log.txt compilation_log.txt
|
||||
@@ -83,32 +61,14 @@ fedora_build_linux_public:
|
||||
paths:
|
||||
- compilation_log.txt
|
||||
|
||||
fedora_report_build_warn_kicad:
|
||||
extends: .fedora_report_build_warn
|
||||
tags:
|
||||
- kicad-fedora
|
||||
needs:
|
||||
- job: fedora_build_linux_kicad
|
||||
artifacts: true
|
||||
only:
|
||||
variables:
|
||||
- $CI_PROJECT_ROOT_NAMESPACE == "kicad"
|
||||
|
||||
fedora_report_build_warn_public:
|
||||
extends: .fedora_report_build_warn
|
||||
needs:
|
||||
- job: fedora_build_linux_public
|
||||
artifacts: true
|
||||
except:
|
||||
variables:
|
||||
- $CI_PROJECT_ROOT_NAMESPACE == "kicad"
|
||||
|
||||
|
||||
# Report on the metrics of the code
|
||||
.fedora_report_metrics:
|
||||
fedora_report_metrics:
|
||||
stage: report
|
||||
extends: .only_code
|
||||
when: always
|
||||
needs:
|
||||
- job: fedora_build_linux
|
||||
artifacts: true
|
||||
script:
|
||||
- cat build/linux/compilation_log.txt | { grep "warning:" || test $? = 1; } | awk 'END{print "number_of_fedora_warnings "NR}' > metrics.txt
|
||||
- cat metrics.txt
|
||||
@@ -116,58 +76,18 @@ fedora_report_build_warn_public:
|
||||
reports:
|
||||
metrics: metrics.txt
|
||||
|
||||
fedora_report_metrics_kicad:
|
||||
extends: .fedora_report_metrics
|
||||
tags:
|
||||
- kicad-fedora
|
||||
needs:
|
||||
- job: fedora_build_linux_kicad
|
||||
artifacts: true
|
||||
only:
|
||||
variables:
|
||||
- $CI_PROJECT_ROOT_NAMESPACE == "kicad"
|
||||
|
||||
fedora_report_metrics_public:
|
||||
extends: .fedora_report_metrics
|
||||
needs:
|
||||
- job: fedora_build_linux_public
|
||||
artifacts: true
|
||||
except:
|
||||
variables:
|
||||
- $CI_PROJECT_ROOT_NAMESPACE == "kicad"
|
||||
|
||||
##########################################################################
|
||||
# Run the code unit tests.
|
||||
##########################################################################
|
||||
.fedora_qa:
|
||||
image: registry.gitlab.com/kicad/kicad-ci/source_containers/master/fedora:38
|
||||
fedora_qa:
|
||||
extends:
|
||||
- .unit_test
|
||||
- .only_code
|
||||
before_script:
|
||||
- if [ "$TEST" == "cli" ] || [ "$TEST" == "python" ]; then python3 -m pip install -r qa/tests/requirements.txt; fi
|
||||
- if [ "$TEST" == "cli" ]; then sudo dnf -y install gerbv; fi
|
||||
parallel:
|
||||
matrix:
|
||||
# The name of the test without the qa_ prefix
|
||||
- TEST: [python, cli, common, gerbview, pcbnew, pns_regressions, eeschema, kimath, sexpr, kicad2step, spice]
|
||||
|
||||
fedora_qa_kicad:
|
||||
extends: .fedora_qa
|
||||
tags:
|
||||
- kicad-fedora
|
||||
- TEST: [python, common, gerbview, pcbnew, eeschema, kimath, sexpr, kicad2step]
|
||||
needs:
|
||||
- job: fedora_build_linux_kicad
|
||||
- job: fedora_build_linux
|
||||
artifacts: true
|
||||
only:
|
||||
variables:
|
||||
- $CI_PROJECT_ROOT_NAMESPACE == "kicad"
|
||||
|
||||
fedora_qa_public:
|
||||
extends: .fedora_qa
|
||||
needs:
|
||||
- job: fedora_build_linux_public
|
||||
artifacts: true
|
||||
except:
|
||||
variables:
|
||||
- $CI_PROJECT_ROOT_NAMESPACE == "kicad"
|
||||
|
||||
@@ -28,10 +28,11 @@
|
||||
-G Ninja
|
||||
-DCMAKE_C_COMPILER_LAUNCHER=ccache
|
||||
-DCMAKE_CXX_COMPILER_LAUNCHER=ccache
|
||||
-DCMAKE_BUILD_TYPE=Release
|
||||
-DCMAKE_BUILD_TYPE=Debug
|
||||
-DKICAD_STDLIB_LIGHT_DEBUG=ON
|
||||
-DKICAD_SCRIPTING_WXPYTHON=ON
|
||||
-DKICAD_USE_OCC=ON
|
||||
-DKICAD_SPICE=ON
|
||||
-DKICAD_BUILD_I18N=ON
|
||||
-DKICAD_BUILD_PNS_DEBUG_TOOL=ON
|
||||
../../
|
||||
@@ -46,13 +47,9 @@
|
||||
paths:
|
||||
- build/linux/3d-viewer/
|
||||
- build/linux/pcbnew/pcbnew.py
|
||||
- build/linux/pcbnew/_pcbnew.kiface
|
||||
- build/linux/pcbnew/_pcbnew.so
|
||||
- build/linux/qa/
|
||||
- build/linux/compilation_log.txt
|
||||
exclude:
|
||||
- build/linux/**/*.o
|
||||
- build/linux/**/*.a
|
||||
|
||||
# Upload the compilation log in an easily downloadable form
|
||||
.ubuntu20.04_report_build_warn:
|
||||
@@ -115,4 +112,4 @@
|
||||
parallel:
|
||||
matrix:
|
||||
# The name of the test without the qa_ prefix
|
||||
- TEST: [python, common, gerbview, pcbnew, eeschema, kimath, sexpr, kicad2step, spice]
|
||||
- TEST: [python, common, gerbview, pcbnew, eeschema, kimath, sexpr, kicad2step]
|
||||
|
||||
+7
-21
@@ -5,37 +5,23 @@ win64_build:
|
||||
stage: build
|
||||
tags:
|
||||
- kicad-windows-1809
|
||||
extends: .only_code
|
||||
interruptible: false
|
||||
image: registry.gitlab.com/kicad/kicad-ci/windows-build-image/win1809-msvc:latest
|
||||
variables:
|
||||
VCPKG_BINARY_SOURCES: 'nuget,kicad,readwrite'
|
||||
# Switch the compressor to fastzip and reduce the compression level
|
||||
FF_USE_FASTZIP: "true"
|
||||
CACHE_COMPRESSION_LEVEL: "fast"
|
||||
cache:
|
||||
key: win64-vcpkg-"$CI_COMMIT_REF_SLUG"
|
||||
paths:
|
||||
- build\windows\vcpkg_installed
|
||||
- .vcpkgCache
|
||||
rules:
|
||||
- if: $CI_PIPELINE_SOURCE == "schedule"
|
||||
when: never
|
||||
- if: $CI_PROJECT_ROOT_NAMESPACE == "kicad" && $CI_COMMIT_REF_PROTECTED == "true"
|
||||
image: registry.gitlab.com/kicad/kicad-ci/source_containers/win64:msvc1809
|
||||
only:
|
||||
- branches@kicad/code/kicad
|
||||
- tags@kicad/code/kicad
|
||||
script:
|
||||
- C:\builder\build.ps1 -Env -Arch x64
|
||||
- $vcpkgCache=Join-Path -Path (Get-Location) -ChildPath ".vcpkgCache";$env:VCPKG_DEFAULT_BINARY_CACHE=$vcpkgCache;New-Item -ItemType Directory -Force -Path $vcpkgCache
|
||||
- nuget.exe sources add -Name kicad -Source "https://nuget.kicad.org:443/v3/index.json"
|
||||
- nuget.exe setapikey $env:KICAD_NUGET_KEY -Source "https://nuget.kicad.org:443/v3/index.json"
|
||||
- mkdir -p build/windows -Force
|
||||
- cd build/windows
|
||||
- cmake `
|
||||
-G "Ninja" `
|
||||
-DCMAKE_TOOLCHAIN_FILE=C:\builder\vcpkg\scripts\buildsystems\vcpkg.cmake `
|
||||
-DCMAKE_TOOLCHAIN_FILE=C:\build\vcpkg\scripts\buildsystems\vcpkg.cmake `
|
||||
-DCMAKE_BUILD_TYPE=Debug `
|
||||
-DKICAD_SCRIPTING_WXPYTHON=OFF `
|
||||
-DKICAD_USE_OCC=ON `
|
||||
-DKICAD_SPICE=ON `
|
||||
-DKICAD_BUILD_PNS_DEBUG_TOOL=ON `
|
||||
-DKICAD_USE_3DCONNEXION=ON `
|
||||
../../
|
||||
- cmake --build . 2>&1 | tee compilation_log.txt
|
||||
- cd ../../
|
||||
|
||||
+15
-18
@@ -22,16 +22,13 @@
|
||||
# These results will be saved for 1 day if the build fails.
|
||||
.coverity_submit: &coverity_submit |
|
||||
echo "Creating tar file of scan results"
|
||||
export COV_INT_FILENAME=cov-int-$(date +"%Y%m%d%H%M").tar.gz
|
||||
tar cfz $COV_INT_FILENAME cov-int
|
||||
tar cfz cov-int.tar.gz cov-int
|
||||
echo "Submitting scan results"
|
||||
s5cmd/s5cmd cp $COV_INT_FILENAME s3://$KICAD_CI_R2_BUCKET/coverity/
|
||||
export FILE_URL="$KICAD_CI_R2_PUBLIC_BASE/coverity/$COV_INT_FILENAME"
|
||||
export KICAD_VERSION=$(sed 's/[()]//g' kicad_build_version.txt)
|
||||
curl https://scan.coverity.com/builds?project=$COVERITY_SCAN_PROJECT_NAME \
|
||||
curl -v https://scan.coverity.com/builds?project=$COVERITY_SCAN_PROJECT_NAME \
|
||||
--form token=$COVERITY_SCAN_TOKEN \
|
||||
--form email=$GITLAB_USER_EMAIL \
|
||||
--form url="$FILE_URL" \
|
||||
--form file=@cov-int.tar.gz \
|
||||
--form version="$KICAD_VERSION" \
|
||||
--form description="$KICAD_VERSION / $CI_COMMIT_TITLE" 2>&1 \
|
||||
| tee curl-response.txt
|
||||
@@ -42,9 +39,13 @@ Coverity:
|
||||
tags:
|
||||
- coverity
|
||||
stage: build
|
||||
image: registry.gitlab.com/kicad/kicad-ci/source_containers/master/fedora:38
|
||||
rules:
|
||||
- if: $CI_PIPELINE_SOURCE == "schedule" && $SCHEDULED_JOB_NAME == "coverity"
|
||||
# Use Fedora 33 because Coverity needs GCC 10 still (as of 06/16/2021)
|
||||
image: registry.gitlab.com/kicad/kicad-ci/source_containers/master/fedora:33
|
||||
only:
|
||||
refs:
|
||||
- schedules
|
||||
variables:
|
||||
- $SCHEDULED_JOB_NAME == "coverity"
|
||||
cache:
|
||||
key: coverity
|
||||
paths:
|
||||
@@ -53,23 +54,19 @@ Coverity:
|
||||
- export COVERITY_SCAN_PROJECT_NAME="kicad"
|
||||
- test "$(git rev-parse --is-shallow-repository)" = "false" || (git fetch --unshallow)
|
||||
- git fetch origin
|
||||
- curl -LO https://github.com/peak/s5cmd/releases/download/v2.0.0/s5cmd_2.0.0_Linux-64bit.tar.gz
|
||||
- mkdir s5cmd
|
||||
- tar -xvf ./s5cmd_2.0.0_Linux-64bit.tar.gz -C s5cmd
|
||||
- export AWS_ACCESS_KEY_ID=$KICAD_CI_R2_KEY_ID
|
||||
- export AWS_SECRET_ACCESS_KEY=$KICAD_CI_R2_ACCESS_KEY
|
||||
- export S3_ENDPOINT_URL=$KICAD_CI_R2_ENDPOINT
|
||||
script:
|
||||
- *coverity_cache_prep
|
||||
- cmake
|
||||
-DCMAKE_BUILD_TYPE=RelWithDebInfo
|
||||
-DCMAKE_BUILD_TYPE=Debug
|
||||
-DKICAD_STDLIB_LIGHT_DEBUG=ON
|
||||
-DKICAD_SCRIPTING_WXPYTHON=ON
|
||||
- coverity/bin/cov-build --dir cov-int make -j10
|
||||
-DKICAD_USE_OCC=ON
|
||||
-DKICAD_SPICE=ON
|
||||
- coverity/bin/cov-build --dir cov-int make -j8
|
||||
- *coverity_submit
|
||||
artifacts:
|
||||
expire_in: 1 year
|
||||
expose_as: 'Coverity log'
|
||||
name: "coverity_log.txt"
|
||||
paths:
|
||||
- cov-int/build-log.txt
|
||||
- cov-int/build-log.txt
|
||||
|
||||
@@ -1,15 +0,0 @@
|
||||
build_doxygen_docker:
|
||||
image: docker:stable
|
||||
services:
|
||||
- docker:dind
|
||||
stage: build
|
||||
rules:
|
||||
- if: $CI_PIPELINE_SOURCE == "schedule" && $SCHEDULED_JOB_NAME == "doxygen"
|
||||
tags:
|
||||
- docker
|
||||
before_script:
|
||||
- docker info
|
||||
- docker login -u gitlab-ci-token -p "$CI_JOB_TOKEN" "$CI_REGISTRY"
|
||||
script:
|
||||
- docker build -t "${CI_REGISTRY_IMAGE}/doxygen:$CI_COMMIT_BRANCH" -f ./doxygen/doxygen.Dockerfile .
|
||||
- docker push "${CI_REGISTRY_IMAGE}/doxygen:$CI_COMMIT_BRANCH"
|
||||
@@ -1,20 +0,0 @@
|
||||
<!-- --------Before Creating a New Issue-----------
|
||||
* Limit report to a single issue.
|
||||
* Search the issue tracker to verify the issue has not already been reported.
|
||||
* Complete all instructions between `template comment markers <>.
|
||||
* Keep report contents limited to the necessary information required to fix the issue.
|
||||
* When creating an issue against the stable version of KiCad, make sure the latest available stable version is installed as issues may have already been resolved in later stable versions. -->
|
||||
# Description
|
||||
<!-- What is the current behavior and what is the expected behavior? -->
|
||||
<!-- If the issue is visual/graphical, please attach screenshots of the problem. -->
|
||||
<!-- Add the issue details below this line and before the "Steps to reproduce" heading. -->
|
||||
|
||||
# Steps to reproduce
|
||||
<!-- If there are multiple steps to reproduce it or it is a visual issue, then providing a screen recording as an attachment to this report is recommended. -->
|
||||
<!-- If this issue is specific to a project, please attach the necessary files to this issue. -->
|
||||
<!-- Add the steps to reproduce using the numbers below -->
|
||||
<!-- Add new step numbers before the "KiCad Version" heading. -->
|
||||
1.
|
||||
|
||||
# KiCad Version
|
||||
|
||||
@@ -6,18 +6,23 @@ validate_linux_metadata:
|
||||
needs: []
|
||||
interruptible: false
|
||||
# This is the only CI image with the utilities needed for this test
|
||||
image: registry.gitlab.com/kicad/kicad-ci/source_containers/master/fedora:38
|
||||
image: registry.gitlab.com/kicad/kicad-ci/source_containers/master/fedora:34
|
||||
# Due to bug https://github.com/hughsie/appstream-glib/issues/381, this doesn't think our description tag
|
||||
# is localized even though it actually is.
|
||||
allow_failure: true
|
||||
rules:
|
||||
- if: $CI_PIPELINE_SOURCE == "schedule"
|
||||
when: never
|
||||
- if: $CI_PIPELINE_SOURCE == "push" || $CI_PIPELINE_SOURCE == "merge_request_event"
|
||||
changes:
|
||||
- resources/linux/**/*
|
||||
- qa/resources/linux/**/*
|
||||
- translation/**/*
|
||||
only:
|
||||
refs:
|
||||
- master
|
||||
- branches
|
||||
- merge_requests
|
||||
- pushes
|
||||
changes:
|
||||
# Only run if the resources, its tests, or the translations are updated
|
||||
- resources/linux/**/*
|
||||
- qa/resources/linux/**/*
|
||||
- translation/**/*
|
||||
except:
|
||||
- schedules
|
||||
# Only build the metadata files in this CI job
|
||||
script:
|
||||
- mkdir -p build/linux
|
||||
@@ -26,6 +31,8 @@ validate_linux_metadata:
|
||||
-DCMAKE_BUILD_TYPE=Debug
|
||||
-DKICAD_STDLIB_LIGHT_DEBUG=ON
|
||||
-DKICAD_SCRIPTING_WXPYTHON=ON
|
||||
-DKICAD_USE_OCC=ON
|
||||
-DKICAD_SPICE=ON
|
||||
-DKICAD_BUILD_I18N=ON
|
||||
../../
|
||||
- make metadata
|
||||
|
||||
@@ -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
|
||||
@@ -1,27 +0,0 @@
|
||||
##########################################################################
|
||||
# Test the formatting in a merge request using clang-format
|
||||
##########################################################################
|
||||
# The variable CI_COMMIT_BEFORE_SHA is not available in normal merge requests
|
||||
# so we must build the commit hash ourselves, see:
|
||||
# https://gitlab.com/gitlab-org/gitlab/-/issues/12850
|
||||
test_formatting:
|
||||
stage: test
|
||||
needs: []
|
||||
rules:
|
||||
- if: $CI_PIPELINE_SOURCE == "merge_request_event"
|
||||
allow_failure: true
|
||||
before_script:
|
||||
# We must manually add the KiCad remote to ensure it is named sensibly
|
||||
- git remote add product https://gitlab.com/kicad/code/kicad.git ||
|
||||
git remote set-url product https://gitlab.com/kicad/code/kicad.git
|
||||
- git remote add source ${CI_MERGE_REQUEST_SOURCE_PROJECT_URL}.git ||
|
||||
git remote set-url source ${CI_MERGE_REQUEST_SOURCE_PROJECT_URL}.git
|
||||
- git fetch -n product
|
||||
- git fetch -n source
|
||||
# Get the SHAs of the commits
|
||||
- "TARGET_HEAD_SHA=$(git rev-parse product/${CI_MERGE_REQUEST_TARGET_BRANCH_NAME})"
|
||||
- "SOURCE_HEAD_SHA=$(git rev-parse source/${CI_MERGE_REQUEST_SOURCE_BRANCH_NAME})"
|
||||
- "MERGE_BASE_SHA=$(git merge-base ${TARGET_HEAD_SHA} ${SOURCE_HEAD_SHA})"
|
||||
script:
|
||||
- echo "Testing formatting from commit ${MERGE_BASE_SHA}"
|
||||
- ./tools/check_coding.sh --diff --ci --commit ${MERGE_BASE_SHA}
|
||||
+11
-11
@@ -11,27 +11,27 @@
|
||||
- schedules
|
||||
|
||||
##########################################################################
|
||||
# Define a template for all the unit tests, since each one is run in a separate
|
||||
# Define a template for all the unit tests, since each one is run in a separate
|
||||
# job to make the display nicer.
|
||||
##########################################################################
|
||||
.unit_test:
|
||||
stage: test
|
||||
when: on_success
|
||||
variables:
|
||||
BOOST_TEST_LOGGER: 'JUNIT,warning,test_results.${TEST}.xml:HRF,warning'
|
||||
CTEST_OUTPUT_ON_FAILURE: 1
|
||||
# We define this using a before script because GitLab cannot merge variable
|
||||
# definitions across inheritance (so the variables block from this would disappear)
|
||||
before_script:
|
||||
- export BOOST_TEST_LOGGER='JUNIT,all,test_results.${TEST}.xml:HRF,warning'
|
||||
- export CTEST_OUTPUT_ON_FAILURE=1
|
||||
script:
|
||||
- cd build/linux/qa
|
||||
- ctest -R qa_${TEST}
|
||||
# GitLab supports displaying the results in the GUI through JUNIT artifacts
|
||||
# (https://docs.gitlab.com/ee/ci/junit_test_reports.html)
|
||||
# so we upload the JUNIT results.
|
||||
# so we upload the JUNIT results. Note that there is a bug with how paths
|
||||
# are processed in the junit report (https://gitlab.com/gitlab-org/gitlab/issues/23835)
|
||||
# so we can't use a glob and have to list out each hierarchy separately.
|
||||
artifacts:
|
||||
when: always
|
||||
paths:
|
||||
- build/linux/qa/**/*.log
|
||||
- build/linux/qa/**/output/*
|
||||
- build/linux/qa/**/*.xml
|
||||
reports:
|
||||
junit:
|
||||
- build/linux/qa/**/*.xml
|
||||
- build/linux/qa/*/*.xml
|
||||
- build/linux/qa/*/*/*.xml
|
||||
|
||||
@@ -2,8 +2,7 @@
|
||||
* This program source code file is part of KiCad, a free EDA CAD application.
|
||||
*
|
||||
* Copyright (C) 2015-2016 Cirilo Bernardo <cirilo.bernardo@gmail.com>
|
||||
* Copyright (C) 2018-2022 KiCad Developers, see AUTHORS.txt for contributors.
|
||||
* Copyright (C) 2022 CERN
|
||||
* Copyright (C) 2018-2020 KiCad Developers, see AUTHORS.txt for contributors.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
@@ -30,6 +29,7 @@
|
||||
|
||||
#include <wx/datetime.h>
|
||||
#include <wx/dir.h>
|
||||
#include <wx/filename.h>
|
||||
#include <wx/log.h>
|
||||
#include <wx/stdpaths.h>
|
||||
|
||||
@@ -55,12 +55,12 @@
|
||||
#include <project.h>
|
||||
#include <settings/common_settings.h>
|
||||
#include <settings/settings_manager.h>
|
||||
#include <wx_filename.h>
|
||||
|
||||
|
||||
#define MASK_3D_CACHE "3D_CACHE"
|
||||
|
||||
static std::mutex mutex3D_cache;
|
||||
static std::mutex mutex3D_cacheManager;
|
||||
|
||||
|
||||
static bool isSHA1Same( const unsigned char* shaA, const unsigned char* shaB ) noexcept
|
||||
@@ -194,20 +194,29 @@ S3D_CACHE::S3D_CACHE()
|
||||
|
||||
S3D_CACHE::~S3D_CACHE()
|
||||
{
|
||||
COMMON_SETTINGS* commonSettings = Pgm().GetCommonSettings();
|
||||
|
||||
FlushCache();
|
||||
|
||||
// We'll delete ".3dc" cache files older than this many days
|
||||
int clearCacheInterval = commonSettings->m_System.clear_3d_cache_interval;
|
||||
|
||||
// An interval of zero means the user doesn't want to ever clear the cache
|
||||
|
||||
if( clearCacheInterval > 0 )
|
||||
CleanCacheDir( clearCacheInterval );
|
||||
|
||||
delete m_FNResolver;
|
||||
delete m_Plugins;
|
||||
}
|
||||
|
||||
|
||||
SCENEGRAPH* S3D_CACHE::load( const wxString& aModelFile, const wxString& aBasePath,
|
||||
S3D_CACHE_ENTRY** aCachePtr )
|
||||
SCENEGRAPH* S3D_CACHE::load( const wxString& aModelFile, S3D_CACHE_ENTRY** aCachePtr )
|
||||
{
|
||||
if( aCachePtr )
|
||||
*aCachePtr = nullptr;
|
||||
|
||||
wxString full3Dpath = m_FNResolver->ResolvePath( aModelFile, aBasePath );
|
||||
wxString full3Dpath = m_FNResolver->ResolvePath( aModelFile );
|
||||
|
||||
if( full3Dpath.empty() )
|
||||
{
|
||||
@@ -272,9 +281,9 @@ SCENEGRAPH* S3D_CACHE::load( const wxString& aModelFile, const wxString& aBasePa
|
||||
}
|
||||
|
||||
|
||||
SCENEGRAPH* S3D_CACHE::Load( const wxString& aModelFile, const wxString& aBasePath )
|
||||
SCENEGRAPH* S3D_CACHE::Load( const wxString& aModelFile )
|
||||
{
|
||||
return load( aModelFile, aBasePath );
|
||||
return load( aModelFile );
|
||||
}
|
||||
|
||||
|
||||
@@ -295,7 +304,8 @@ SCENEGRAPH* S3D_CACHE::checkCache( const wxString& aFileName, S3D_CACHE_ENTRY**
|
||||
// or we do not have a configured cache file directory, we create an
|
||||
// entry to prevent further attempts at loading the file
|
||||
|
||||
if( m_CacheMap.emplace( aFileName, ep ).second == false )
|
||||
if( m_CacheMap.insert( std::pair< wxString, S3D_CACHE_ENTRY* >
|
||||
( aFileName, ep ) ).second == false )
|
||||
{
|
||||
wxLogTrace( MASK_3D_CACHE,
|
||||
wxT( "%s:%s:%d\n * [BUG] duplicate entry in map file; key = '%s'" ),
|
||||
@@ -313,7 +323,8 @@ SCENEGRAPH* S3D_CACHE::checkCache( const wxString& aFileName, S3D_CACHE_ENTRY**
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
if( m_CacheMap.emplace( aFileName, ep ).second == false )
|
||||
if( m_CacheMap.insert( std::pair< wxString, S3D_CACHE_ENTRY* >
|
||||
( aFileName, ep ) ).second == false )
|
||||
{
|
||||
wxLogTrace( MASK_3D_CACHE,
|
||||
wxT( "%s:%s:%d\n * [BUG] duplicate entry in map file; key = '%s'" ),
|
||||
@@ -502,7 +513,7 @@ bool S3D_CACHE::Set3DConfigDir( const wxString& aConfigDir )
|
||||
|
||||
wxFileName cfgdir( ExpandEnvVarSubstitutions( aConfigDir, m_project ), wxEmptyString );
|
||||
|
||||
cfgdir.Normalize( FN_NORMALIZE_FLAGS );
|
||||
cfgdir.Normalize();
|
||||
|
||||
if( !cfgdir.DirExists() )
|
||||
{
|
||||
@@ -631,10 +642,10 @@ void S3D_CACHE::ClosePlugins()
|
||||
}
|
||||
|
||||
|
||||
S3DMODEL* S3D_CACHE::GetModel( const wxString& aModelFileName, const wxString& aBasePath )
|
||||
S3DMODEL* S3D_CACHE::GetModel( const wxString& aModelFileName )
|
||||
{
|
||||
S3D_CACHE_ENTRY* cp = nullptr;
|
||||
SCENEGRAPH* sp = load( aModelFileName, aBasePath,&cp );
|
||||
SCENEGRAPH* sp = load( aModelFileName, &cp );
|
||||
|
||||
if( !sp )
|
||||
return nullptr;
|
||||
@@ -696,4 +707,40 @@ void S3D_CACHE::CleanCacheDir( int aNumDaysOld )
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
S3D_CACHE* PROJECT::Get3DCacheManager( bool aUpdateProjDir )
|
||||
{
|
||||
std::lock_guard<std::mutex> lock( mutex3D_cacheManager );
|
||||
|
||||
// Get the existing cache from the project
|
||||
S3D_CACHE* cache = dynamic_cast<S3D_CACHE*>( GetElem( ELEM_3DCACHE ) );
|
||||
|
||||
if( !cache )
|
||||
{
|
||||
// Create a cache if there is not one already
|
||||
cache = new S3D_CACHE();
|
||||
|
||||
wxFileName cfgpath;
|
||||
cfgpath.AssignDir( SETTINGS_MANAGER::GetUserSettingsPath() );
|
||||
cfgpath.AppendDir( wxT( "3d" ) );
|
||||
|
||||
cache->SetProgramBase( &Pgm() );
|
||||
cache->Set3DConfigDir( cfgpath.GetFullPath() );
|
||||
|
||||
SetElem( ELEM_3DCACHE, cache );
|
||||
aUpdateProjDir = true;
|
||||
}
|
||||
|
||||
if( aUpdateProjDir )
|
||||
cache->SetProject( this );
|
||||
|
||||
return cache;
|
||||
}
|
||||
|
||||
|
||||
FILENAME_RESOLVER* PROJECT::Get3DFilenameResolver()
|
||||
{
|
||||
return Get3DCacheManager()->GetResolver();
|
||||
}
|
||||
|
||||
@@ -92,10 +92,9 @@ public:
|
||||
|
||||
*
|
||||
* @param aModelFile is the partial or full path to the model to be loaded.
|
||||
* @param aBasePath is the path to search for any relative files
|
||||
* @return true if the model was successfully loaded, otherwise false.
|
||||
*/
|
||||
SCENEGRAPH* Load( const wxString& aModelFile, const wxString& aBasePath );
|
||||
SCENEGRAPH* Load( const wxString& aModelFile );
|
||||
|
||||
FILENAME_RESOLVER* GetResolver() noexcept;
|
||||
|
||||
@@ -125,7 +124,7 @@ public:
|
||||
* @param aModelFileName is the full path to the model to be loaded.
|
||||
* @return is a pointer to the render data or NULL if not available.
|
||||
*/
|
||||
S3DMODEL* GetModel( const wxString& aModelFileName, const wxString& aBasePath );
|
||||
S3DMODEL* GetModel( const wxString& aModelFileName );
|
||||
|
||||
/**
|
||||
* Delete up old cache files in cache directory.
|
||||
@@ -165,7 +164,7 @@ private:
|
||||
bool saveCacheData( S3D_CACHE_ENTRY* aCacheItem );
|
||||
|
||||
// the real load function (can supply a cache entry pointer to member functions)
|
||||
SCENEGRAPH* load( const wxString& aModelFile, const wxString& aBasePath, S3D_CACHE_ENTRY** aCachePtr = nullptr );
|
||||
SCENEGRAPH* load( const wxString& aModelFile, S3D_CACHE_ENTRY** aCachePtr = nullptr );
|
||||
|
||||
/// cache entries
|
||||
std::list< S3D_CACHE_ENTRY* > m_CacheList;
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
* This program source code file is part of KiCad, a free EDA CAD application.
|
||||
*
|
||||
* Copyright (C) 2015-2016 Cirilo Bernardo <cirilo.bernardo@gmail.com>
|
||||
* Copyright (C) 2020-2023 KiCad Developers, see AUTHORS.txt for contributors.
|
||||
* Copyright (C) 2020 KiCad Developers, see AUTHORS.txt for contributors.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
@@ -29,13 +29,13 @@
|
||||
|
||||
#include <wx/dir.h>
|
||||
#include <wx/dynlib.h>
|
||||
#include <wx/filename.h>
|
||||
#include <wx/log.h>
|
||||
#include <wx/stdpaths.h>
|
||||
#include <wx/string.h>
|
||||
|
||||
#include <common.h>
|
||||
#include <paths.h>
|
||||
#include <wx_filename.h>
|
||||
#include "3d_plugin_manager.h"
|
||||
#include "plugins/3d/3d_plugin.h"
|
||||
#include "3d_cache/sg/scenegraph.h"
|
||||
@@ -55,7 +55,7 @@
|
||||
S3D_PLUGIN_MANAGER::S3D_PLUGIN_MANAGER()
|
||||
{
|
||||
// create the initial file filter list entry
|
||||
m_FileFilters.emplace_back( _( "All Files" ) + wxT( " (*.*)|*.*" ) );
|
||||
m_FileFilters.push_back( _( "All Files" ) + wxT( " (*.*)|*.*" ) );
|
||||
|
||||
// discover and load plugins
|
||||
loadPlugins();
|
||||
@@ -120,48 +120,57 @@ S3D_PLUGIN_MANAGER::~S3D_PLUGIN_MANAGER()
|
||||
|
||||
void S3D_PLUGIN_MANAGER::loadPlugins( void )
|
||||
{
|
||||
std::list<wxString> searchpaths;
|
||||
std::list<wxString> pluginlist;
|
||||
wxFileName fn;
|
||||
std::list< wxString > searchpaths;
|
||||
std::list< wxString > pluginlist;
|
||||
wxFileName fn;
|
||||
|
||||
#ifndef __WXMAC__
|
||||
if( wxGetEnv( wxT( "KICAD_RUN_FROM_BUILD_DIR" ), nullptr ) )
|
||||
|
||||
#ifdef DEBUG
|
||||
// set up to work from the build directory
|
||||
fn.Assign( wxStandardPaths::Get().GetExecutablePath() );
|
||||
fn.AppendDir( wxT( ".." ) );
|
||||
fn.AppendDir( wxT( "plugins" ) );
|
||||
fn.AppendDir( wxT( "3d" ) );
|
||||
|
||||
std::string testpath = std::string( fn.GetPathWithSep().ToUTF8() );
|
||||
checkPluginPath( testpath, searchpaths );
|
||||
|
||||
// add subdirectories too
|
||||
wxDir debugPluginDir;
|
||||
wxString subdir;
|
||||
|
||||
debugPluginDir.Open( testpath );
|
||||
|
||||
if( debugPluginDir.IsOpened() && debugPluginDir.GetFirst( &subdir, wxEmptyString, wxDIR_DIRS ) )
|
||||
{
|
||||
// set up to work from the build directory
|
||||
fn.Assign( wxStandardPaths::Get().GetExecutablePath() );
|
||||
fn.AppendDir( wxT( ".." ) );
|
||||
fn.AppendDir( wxT( "plugins" ) );
|
||||
fn.AppendDir( wxT( "3d" ) );
|
||||
checkPluginPath( testpath + subdir, searchpaths );
|
||||
|
||||
std::string testpath = std::string( fn.GetPathWithSep().ToUTF8() );
|
||||
checkPluginPath( testpath, searchpaths );
|
||||
|
||||
// add subdirectories too
|
||||
wxDir debugPluginDir;
|
||||
wxString subdir;
|
||||
|
||||
debugPluginDir.Open( testpath );
|
||||
|
||||
if( debugPluginDir.IsOpened()
|
||||
&& debugPluginDir.GetFirst( &subdir, wxEmptyString, wxDIR_DIRS ) )
|
||||
{
|
||||
while( debugPluginDir.GetNext( &subdir ) )
|
||||
checkPluginPath( testpath + subdir, searchpaths );
|
||||
|
||||
while( debugPluginDir.GetNext( &subdir ) )
|
||||
checkPluginPath( testpath + subdir, searchpaths );
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
fn.AssignDir( PATHS::GetStockPlugins3DPath() );
|
||||
checkPluginPath( std::string( fn.GetPathWithSep().ToUTF8() ), searchpaths );
|
||||
|
||||
// check for per-user third party plugins
|
||||
// note: GetUserDataDir() gives '.pcbnew' rather than '.kicad' since it uses the exe name;
|
||||
fn.AssignDir( PATHS::GetUserPlugins3DPath() );
|
||||
checkPluginPath( fn.GetPathWithSep(), searchpaths );
|
||||
#else
|
||||
|
||||
// Search path on OS X is
|
||||
// (1) Machine /Library/Application Support/kicad/PlugIns/3d
|
||||
// (1) User ~/Library/Application Support/kicad/PlugIns/3d
|
||||
checkPluginPath( PATHS::GetOSXKicadUserDataDir() + wxT( "/PlugIns/3d" ), searchpaths );
|
||||
|
||||
// (2) Machine /Library/Application Support/kicad/PlugIns/3d
|
||||
checkPluginPath( PATHS::GetOSXKicadMachineDataDir() + wxT( "/PlugIns/3d" ), searchpaths );
|
||||
|
||||
// (2) Bundle kicad.app/Contents/PlugIns/3d
|
||||
// (3) Bundle kicad.app/Contents/PlugIns/3d
|
||||
fn.AssignDir( PATHS::GetStockPlugins3DPath() );
|
||||
checkPluginPath( fn.GetPathWithSep(), searchpaths );
|
||||
|
||||
#endif
|
||||
|
||||
std::list< wxString >::iterator sPL = searchpaths.begin();
|
||||
@@ -248,7 +257,7 @@ void S3D_PLUGIN_MANAGER::listPlugins( const wxString& aPath, std::list< wxString
|
||||
// Per definition a loadable "xxx.bundle" is similar to an "xxx.app" app
|
||||
// bundle being a folder with some special content in it. We obviously don't
|
||||
// want to have that here for our loadable module, so just use ".so".
|
||||
nameFilter.Append( wxS( ".so" ) );
|
||||
nameFilter.Append( ".so" );
|
||||
#endif
|
||||
|
||||
wxString lp = wd.GetNameWithSep();
|
||||
@@ -279,7 +288,7 @@ void S3D_PLUGIN_MANAGER::checkPluginName( const wxString& aPath,
|
||||
|
||||
wxFileName path( ExpandEnvVarSubstitutions( aPath, nullptr ) );
|
||||
|
||||
path.Normalize( FN_NORMALIZE_FLAGS );
|
||||
path.Normalize();
|
||||
|
||||
// determine if the path is already in the list
|
||||
wxString wxpath = path.GetFullPath();
|
||||
@@ -294,16 +303,6 @@ void S3D_PLUGIN_MANAGER::checkPluginName( const wxString& aPath,
|
||||
++bl;
|
||||
}
|
||||
|
||||
// prevent loading non-plugin dlls
|
||||
if( wxGetEnv( wxT( "KICAD_RUN_FROM_BUILD_DIR" ), nullptr ) )
|
||||
{
|
||||
if( !path.GetName().StartsWith( "s3d_plugin" )
|
||||
&& !path.GetName().StartsWith( "libs3d_plugin" ) )
|
||||
{
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
aPluginList.push_back( wxpath );
|
||||
|
||||
wxLogTrace( MASK_3D_PLUGINMGR, wxT( " * [INFO] found 3D plugin '%s'\n" ), wxpath.GetData() );
|
||||
@@ -313,15 +312,21 @@ void S3D_PLUGIN_MANAGER::checkPluginName( const wxString& aPath,
|
||||
void S3D_PLUGIN_MANAGER::checkPluginPath( const wxString& aPath,
|
||||
std::list< wxString >& aSearchList )
|
||||
{
|
||||
// check the existence of a path and add it to the path search list
|
||||
if( aPath.empty() )
|
||||
return;
|
||||
|
||||
wxLogTrace( MASK_3D_PLUGINMGR, wxT( " * [INFO] checking if valid plugin directory '%s'\n" ),
|
||||
wxLogTrace( MASK_3D_PLUGINMGR, wxT( " * [INFO] checking for 3D plugins in '%s'\n" ),
|
||||
aPath.GetData() );
|
||||
|
||||
wxFileName path;
|
||||
path.AssignDir( aPath );
|
||||
path.Normalize( FN_NORMALIZE_FLAGS );
|
||||
|
||||
if( aPath.StartsWith( wxT( "${" ) ) || aPath.StartsWith( wxT( "$(" ) ) )
|
||||
path.Assign( ExpandEnvVarSubstitutions( aPath, nullptr ), wxEmptyString );
|
||||
else
|
||||
path.Assign( aPath, wxEmptyString );
|
||||
|
||||
path.Normalize();
|
||||
|
||||
if( !wxFileName::DirExists( path.GetFullPath() ) )
|
||||
return;
|
||||
@@ -386,7 +391,7 @@ void S3D_PLUGIN_MANAGER::addExtensionMap( KICAD_PLUGIN_LDR_3D* aPlugin )
|
||||
|
||||
if( !ws.empty() )
|
||||
{
|
||||
m_ExtMap.emplace( ws, aPlugin );
|
||||
m_ExtMap.insert( std::pair< const wxString, KICAD_PLUGIN_LDR_3D* >( ws, aPlugin ) );
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -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()
|
||||
@@ -359,7 +359,7 @@ S3DMODEL* S3D::GetModel( SCENEGRAPH* aNode )
|
||||
app.transparency = 0.0f;
|
||||
|
||||
materials.matorder.push_back( &app );
|
||||
materials.matmap.emplace( &app, 0 );
|
||||
materials.matmap.insert( std::pair< SGAPPEARANCE const*, int >( &app, 0 ) );
|
||||
|
||||
if( aNode->Prepare( nullptr, materials, meshes ) )
|
||||
{
|
||||
|
||||
@@ -420,7 +420,8 @@ bool S3D::CalcTriangleNormals( std::vector< SGPOINT > coords, std::vector< int >
|
||||
}
|
||||
else
|
||||
{
|
||||
vmap.emplace( p1, std::list < glm::dvec3 >( 1, tri ) );
|
||||
vmap.insert( std::pair < int, std::list < glm::dvec3 > >
|
||||
( p1, std::list < glm::dvec3 >( 1, tri ) ) );
|
||||
}
|
||||
|
||||
ip = vmap.find( p2 );
|
||||
@@ -431,7 +432,8 @@ bool S3D::CalcTriangleNormals( std::vector< SGPOINT > coords, std::vector< int >
|
||||
}
|
||||
else
|
||||
{
|
||||
vmap.emplace( p2, std::list < glm::dvec3 >( 1, tri ) );
|
||||
vmap.insert( std::pair < int, std::list < glm::dvec3 > >
|
||||
( p2, std::list < glm::dvec3 >( 1, tri ) ) );
|
||||
}
|
||||
|
||||
ip = vmap.find( p3 );
|
||||
@@ -442,7 +444,8 @@ bool S3D::CalcTriangleNormals( std::vector< SGPOINT > coords, std::vector< int >
|
||||
}
|
||||
else
|
||||
{
|
||||
vmap.emplace( p3, std::list < glm::dvec3 >( 1, tri ) );
|
||||
vmap.insert( std::pair < int, std::list < glm::dvec3 > >
|
||||
( p3, std::list < glm::dvec3 >( 1, tri ) ) );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -260,7 +260,7 @@ bool S3D::GetMatIndex( MATLIST& aList, SGNODE* aNode, int& aIndex )
|
||||
|
||||
int idx = (int)aList.matorder.size();
|
||||
aList.matorder.push_back( node );
|
||||
aList.matmap.emplace( node, idx );
|
||||
aList.matmap.insert( std::pair< SGAPPEARANCE const*, int >( node, idx ) );
|
||||
aIndex = idx;
|
||||
|
||||
return true;
|
||||
|
||||
@@ -699,7 +699,7 @@ bool SGSHAPE::Prepare( const glm::dmat4* aTransform, S3D::MATLIST& materials,
|
||||
|
||||
if( mit == indexmap.end() )
|
||||
{
|
||||
indexmap.emplace( lv[i], vertices.size() );
|
||||
indexmap.insert( std::pair< int, unsigned int >( lv[i], vertices.size() ) );
|
||||
vertices.push_back( lv[i] );
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,9 +1,8 @@
|
||||
/*
|
||||
* This program source code file is part of KiCad, a free EDA CAD application.
|
||||
*
|
||||
* Copyright (C) 2015-2023 Mario Luzeiro <mrluzeiro@ua.pt>
|
||||
* Copyright (C) 2023 CERN
|
||||
* Copyright (C) 1992-2024 KiCad Developers, see AUTHORS.txt for contributors.
|
||||
* Copyright (C) 2015-2016 Mario Luzeiro <mrluzeiro@ua.pt>
|
||||
* Copyright (C) 1992-2021 KiCad Developers, see AUTHORS.txt for contributors.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
@@ -23,7 +22,7 @@
|
||||
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
|
||||
*/
|
||||
|
||||
#include <gal/3d/camera.h>
|
||||
#include "../3d_rendering/camera.h"
|
||||
#include "board_adapter.h"
|
||||
#include <board_design_settings.h>
|
||||
#include <board_stackup_manager/board_stackup.h>
|
||||
@@ -34,23 +33,13 @@
|
||||
#include <3d_math.h>
|
||||
#include "3d_fastmath.h"
|
||||
#include <geometry/geometry_utils.h>
|
||||
#include <convert_to_biu.h>
|
||||
#include <pgm_base.h>
|
||||
#include <settings/settings_manager.h>
|
||||
#include <wx/log.h>
|
||||
#include <pcbnew_settings.h>
|
||||
#include <advanced_config.h>
|
||||
|
||||
|
||||
#define DEFAULT_BOARD_THICKNESS pcbIUScale.mmToIU( 1.6 )
|
||||
#define DEFAULT_COPPER_THICKNESS pcbIUScale.mmToIU( 0.035 ) // for 35 um
|
||||
// The solder mask layer (and silkscreen) thickness
|
||||
#define DEFAULT_TECH_LAYER_THICKNESS pcbIUScale.mmToIU( 0.025 )
|
||||
// The solder paste thickness is chosen bigger than the solder mask layer
|
||||
// to be sure is covers the mask when overlapping.
|
||||
#define SOLDERPASTE_LAYER_THICKNESS pcbIUScale.mmToIU( 0.04 )
|
||||
|
||||
|
||||
CUSTOM_COLORS_LIST BOARD_ADAPTER::g_SilkColors;
|
||||
CUSTOM_COLORS_LIST BOARD_ADAPTER::g_SilkscreenColors;
|
||||
CUSTOM_COLORS_LIST BOARD_ADAPTER::g_MaskColors;
|
||||
CUSTOM_COLORS_LIST BOARD_ADAPTER::g_PasteColors;
|
||||
CUSTOM_COLORS_LIST BOARD_ADAPTER::g_FinishColors;
|
||||
@@ -63,11 +52,6 @@ KIGFX::COLOR4D BOARD_ADAPTER::g_DefaultSolderMask;
|
||||
KIGFX::COLOR4D BOARD_ADAPTER::g_DefaultSolderPaste;
|
||||
KIGFX::COLOR4D BOARD_ADAPTER::g_DefaultSurfaceFinish;
|
||||
KIGFX::COLOR4D BOARD_ADAPTER::g_DefaultBoardBody;
|
||||
KIGFX::COLOR4D BOARD_ADAPTER::g_DefaultComments;
|
||||
KIGFX::COLOR4D BOARD_ADAPTER::g_DefaultECOs;
|
||||
|
||||
// To be used in Raytracing render to create bevels on layer items
|
||||
float g_BevelThickness3DU = 0.0f;
|
||||
|
||||
static bool g_ColorsLoaded = false;
|
||||
|
||||
@@ -83,10 +67,6 @@ const wxChar *BOARD_ADAPTER::m_logTrace = wxT( "KI_TRACE_EDA_CINFO3D_VISU" );
|
||||
|
||||
|
||||
BOARD_ADAPTER::BOARD_ADAPTER() :
|
||||
m_Cfg( nullptr ),
|
||||
m_IsBoardView( true ),
|
||||
m_MousewheelPanning( true ),
|
||||
m_IsPreviewer( false ),
|
||||
m_board( nullptr ),
|
||||
m_3dModelManager( nullptr ),
|
||||
m_colors( nullptr ),
|
||||
@@ -95,26 +75,32 @@ BOARD_ADAPTER::BOARD_ADAPTER() :
|
||||
{
|
||||
wxLogTrace( m_logTrace, wxT( "BOARD_ADAPTER::BOARD_ADAPTER" ) );
|
||||
|
||||
ReloadColorSettings();
|
||||
m_gridType = GRID3D_TYPE::NONE;
|
||||
m_antiAliasingMode = ANTIALIASING_MODE::AA_8X;
|
||||
m_drawFlags.resize( FL_LAST, false );
|
||||
|
||||
m_boardPos = VECTOR2I();
|
||||
m_boardSize = VECTOR2I();
|
||||
if( PgmOrNull() )
|
||||
m_colors = Pgm().GetSettingsManager().GetColorSettings();
|
||||
|
||||
m_renderEngine = RENDER_ENGINE::OPENGL;
|
||||
m_materialMode = MATERIAL_MODE::NORMAL;
|
||||
|
||||
m_boardPos = wxPoint();
|
||||
m_boardSize = wxSize();
|
||||
m_boardCenter = SFVEC3F( 0.0f );
|
||||
|
||||
m_boardBoundingBox.Reset();
|
||||
|
||||
m_TH_IDs.Clear();
|
||||
m_TH_ODs.Clear();
|
||||
m_viaAnnuli.Clear();
|
||||
|
||||
m_copperLayersCount = 2;
|
||||
m_throughHoleIds.Clear();
|
||||
m_throughHoleOds.Clear();
|
||||
m_throughHoleAnnularRings.Clear();
|
||||
|
||||
m_copperLayersCount = -1;
|
||||
m_epoxyThickness3DU = 0.0f;
|
||||
m_copperThickness3DU = 0.0f;
|
||||
m_nonCopperLayerThickness3DU = 0.0f;
|
||||
m_solderPasteLayerThickness3DU = 0.0f;
|
||||
m_biuTo3Dunits = 1.0;
|
||||
m_boardBodyThickness3DU = DEFAULT_BOARD_THICKNESS * m_biuTo3Dunits;
|
||||
m_frontCopperThickness3DU = DEFAULT_COPPER_THICKNESS * m_biuTo3Dunits;
|
||||
m_backCopperThickness3DU = DEFAULT_COPPER_THICKNESS * m_biuTo3Dunits;
|
||||
m_nonCopperLayerThickness3DU = DEFAULT_TECH_LAYER_THICKNESS * m_biuTo3Dunits;
|
||||
m_solderPasteLayerThickness3DU = SOLDERPASTE_LAYER_THICKNESS * m_biuTo3Dunits;
|
||||
|
||||
m_trackCount = 0;
|
||||
m_viaCount = 0;
|
||||
@@ -123,6 +109,27 @@ BOARD_ADAPTER::BOARD_ADAPTER() :
|
||||
m_averageHoleDiameter = 0.0f;
|
||||
m_averageTrackWidth = 0.0f;
|
||||
|
||||
SetFlag( FL_USE_REALISTIC_MODE, true );
|
||||
SetFlag( FL_FP_ATTRIBUTES_NORMAL, true );
|
||||
SetFlag( FL_SHOW_BOARD_BODY, true );
|
||||
SetFlag( FL_CLIP_SILK_ON_VIA_ANNULUS, false );
|
||||
SetFlag( FL_FP_ATTRIBUTES_NORMAL, true );
|
||||
SetFlag( FL_FP_ATTRIBUTES_NORMAL_INSERT, true );
|
||||
SetFlag( FL_FP_ATTRIBUTES_VIRTUAL, true );
|
||||
SetFlag( FL_ZONE, true );
|
||||
SetFlag( FL_SILKSCREEN, true );
|
||||
SetFlag( FL_SOLDERMASK, true );
|
||||
SetFlag( FL_SUBTRACT_MASK_FROM_SILK, false );
|
||||
|
||||
SetFlag( FL_RENDER_OPENGL_COPPER_THICKNESS, true );
|
||||
SetFlag( FL_RENDER_OPENGL_AA_DISABLE_ON_MOVE, false );
|
||||
SetFlag( FL_RENDER_OPENGL_THICKNESS_DISABLE_ON_MOVE, false );
|
||||
SetFlag( FL_RENDER_OPENGL_VIAS_DISABLE_ON_MOVE, false );
|
||||
SetFlag( FL_RENDER_OPENGL_HOLES_DISABLE_ON_MOVE, false );
|
||||
|
||||
SetFlag( FL_USE_SELECTION, true );
|
||||
SetFlag( FL_HIGHLIGHT_ROLLOVER_ITEM, true );
|
||||
|
||||
m_BgColorBot = SFVEC4F( 0.4, 0.4, 0.5, 1.0 );
|
||||
m_BgColorTop = SFVEC4F( 0.8, 0.8, 0.9, 1.0 );
|
||||
m_BoardBodyColor = SFVEC4F( 0.4, 0.4, 0.5, 0.9 );
|
||||
@@ -132,34 +139,38 @@ BOARD_ADAPTER::BOARD_ADAPTER() :
|
||||
m_SilkScreenColorTop = SFVEC4F( 0.9, 0.9, 0.9, 1.0 );
|
||||
m_SilkScreenColorBot = SFVEC4F( 0.9, 0.9, 0.9, 1.0 );
|
||||
m_CopperColor = SFVEC4F( 0.75, 0.61, 0.23, 1.0 );
|
||||
m_UserDrawingsColor = SFVEC4F( 0.85, 0.85, 0.85, 1.0 );
|
||||
m_UserCommentsColor = SFVEC4F( 0.85, 0.85, 0.85, 1.0 );
|
||||
m_ECO1Color = SFVEC4F( 0.70, 0.10, 0.10, 1.0 );
|
||||
m_ECO2Color = SFVEC4F( 0.70, 0.10, 0.10, 1.0 );
|
||||
|
||||
m_platedPadsFront = nullptr;
|
||||
m_platedPadsBack = nullptr;
|
||||
m_offboardPadsFront = nullptr;
|
||||
m_offboardPadsBack = nullptr;
|
||||
|
||||
m_frontPlatedPadAndGraphicPolys = nullptr;
|
||||
m_backPlatedPadAndGraphicPolys = nullptr;
|
||||
m_frontPlatedCopperPolys = nullptr;
|
||||
m_backPlatedCopperPolys = nullptr;
|
||||
m_frontPlatedPadPolys = nullptr;
|
||||
m_backPlatedPadPolys = nullptr;
|
||||
|
||||
// Avoid raytracing options not initialized:
|
||||
m_RtShadowSampleCount = 0;
|
||||
m_RtReflectionSampleCount = 0;
|
||||
m_RtRefractionSampleCount = 0;
|
||||
|
||||
m_RtSpreadShadows = 0.0;
|
||||
m_RtSpreadReflections = 0.0;
|
||||
m_RtSpreadRefractions = 0.0;
|
||||
|
||||
m_RtRecursiveReflectionCount = 0;
|
||||
m_RtRecursiveRefractionCount = 0;
|
||||
|
||||
if( !g_ColorsLoaded )
|
||||
{
|
||||
#define ADD_COLOR( list, r, g, b, a, name ) \
|
||||
list.emplace_back( r/255.0, g/255.0, b/255.0, a, name )
|
||||
list.push_back( CUSTOM_COLOR_ITEM( r/255.0, g/255.0, b/255.0, a, name ) )
|
||||
|
||||
ADD_COLOR( g_SilkColors, 245, 245, 245, 1.0, NotSpecifiedPrm() ); // White
|
||||
ADD_COLOR( g_SilkColors, 20, 51, 36, 1.0, wxT( "Green" ) );
|
||||
ADD_COLOR( g_SilkColors, 181, 19, 21, 1.0, wxT( "Red" ) );
|
||||
ADD_COLOR( g_SilkColors, 2, 59, 162, 1.0, wxT( "Blue" ) );
|
||||
ADD_COLOR( g_SilkColors, 11, 11, 11, 1.0, wxT( "Black" ) );
|
||||
ADD_COLOR( g_SilkColors, 245, 245, 245, 1.0, wxT( "White" ) );
|
||||
ADD_COLOR( g_SilkColors, 32, 2, 53, 1.0, wxT( "Purple" ) );
|
||||
ADD_COLOR( g_SilkColors, 194, 195, 0, 1.0, wxT( "Yellow" ) );
|
||||
ADD_COLOR( g_SilkscreenColors, 245, 245, 245, 1.0, NotSpecifiedPrm() ); // White
|
||||
ADD_COLOR( g_SilkscreenColors, 20, 51, 36, 1.0, wxT( "Green" ) );
|
||||
ADD_COLOR( g_SilkscreenColors, 181, 19, 21, 1.0, wxT( "Red" ) );
|
||||
ADD_COLOR( g_SilkscreenColors, 2, 59, 162, 1.0, wxT( "Blue" ) );
|
||||
ADD_COLOR( g_SilkscreenColors, 11, 11, 11, 1.0, wxT( "Black" ) );
|
||||
ADD_COLOR( g_SilkscreenColors, 245, 245, 245, 1.0, wxT( "White" ) );
|
||||
ADD_COLOR( g_SilkscreenColors, 32, 2, 53, 1.0, wxT( "Purple" ) );
|
||||
ADD_COLOR( g_SilkscreenColors, 194, 195, 0, 1.0, wxT( "Yellow" ) );
|
||||
|
||||
ADD_COLOR( g_MaskColors, 20, 51, 36, 0.83, NotSpecifiedPrm() ); // Green
|
||||
ADD_COLOR( g_MaskColors, 20, 51, 36, 0.83, wxT( "Green" ) );
|
||||
@@ -206,9 +217,6 @@ BOARD_ADAPTER::BOARD_ADAPTER() :
|
||||
g_DefaultSurfaceFinish = COLOR4D( 0.75, 0.61, 0.23, 1.0 );
|
||||
g_DefaultBoardBody = COLOR4D( 0.43, 0.45, 0.30, 0.90 );
|
||||
|
||||
g_DefaultComments = COLOR4D( 0.85, 0.85, 0.85, 1.0 );
|
||||
g_DefaultECOs = COLOR4D( 0.70, 0.10, 0.10, 1.0 );
|
||||
|
||||
g_ColorsLoaded = true;
|
||||
}
|
||||
#undef ADD_COLOR
|
||||
@@ -221,88 +229,110 @@ BOARD_ADAPTER::~BOARD_ADAPTER()
|
||||
}
|
||||
|
||||
|
||||
void BOARD_ADAPTER::ReloadColorSettings() noexcept
|
||||
{
|
||||
wxCHECK( PgmOrNull(), /* void */ );
|
||||
|
||||
PCBNEW_SETTINGS* cfg = nullptr;
|
||||
|
||||
try
|
||||
{
|
||||
cfg = Pgm().GetSettingsManager().GetAppSettings<PCBNEW_SETTINGS>();
|
||||
}
|
||||
catch( const std::runtime_error& e )
|
||||
{
|
||||
wxFAIL_MSG( e.what() );
|
||||
}
|
||||
|
||||
if( cfg )
|
||||
{
|
||||
m_colors = Pgm().GetSettingsManager().GetColorSettings( cfg->m_ColorTheme );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
bool BOARD_ADAPTER::Is3dLayerEnabled( PCB_LAYER_ID aLayer,
|
||||
const std::bitset<LAYER_3D_END>& aVisibilityFlags ) const
|
||||
bool BOARD_ADAPTER::Is3dLayerEnabled( PCB_LAYER_ID aLayer ) const
|
||||
{
|
||||
wxASSERT( aLayer < PCB_LAYER_ID_COUNT );
|
||||
|
||||
if( m_board && !m_board->IsLayerEnabled( aLayer ) )
|
||||
return false;
|
||||
|
||||
// see if layer needs to be shown
|
||||
// check the flags
|
||||
switch( aLayer )
|
||||
{
|
||||
case B_Cu: return aVisibilityFlags.test( LAYER_3D_COPPER_BOTTOM );
|
||||
case F_Cu: return aVisibilityFlags.test( LAYER_3D_COPPER_TOP );
|
||||
case B_Adhes: return aVisibilityFlags.test( LAYER_3D_ADHESIVE );
|
||||
case F_Adhes: return aVisibilityFlags.test( LAYER_3D_ADHESIVE );
|
||||
case B_Paste: return aVisibilityFlags.test( LAYER_3D_SOLDERPASTE );
|
||||
case F_Paste: return aVisibilityFlags.test( LAYER_3D_SOLDERPASTE );
|
||||
case B_SilkS: return aVisibilityFlags.test( LAYER_3D_SILKSCREEN_BOTTOM );
|
||||
case F_SilkS: return aVisibilityFlags.test( LAYER_3D_SILKSCREEN_TOP );
|
||||
case B_Mask: return aVisibilityFlags.test( LAYER_3D_SOLDERMASK_BOTTOM );
|
||||
case F_Mask: return aVisibilityFlags.test( LAYER_3D_SOLDERMASK_TOP );
|
||||
case Dwgs_User: return aVisibilityFlags.test( LAYER_3D_USER_DRAWINGS );
|
||||
case Cmts_User: return aVisibilityFlags.test( LAYER_3D_USER_COMMENTS );
|
||||
case Eco1_User: return aVisibilityFlags.test( LAYER_3D_USER_ECO1 );
|
||||
case Eco2_User: return aVisibilityFlags.test( LAYER_3D_USER_ECO2 );
|
||||
default: return m_board && m_board->IsLayerVisible( aLayer );
|
||||
case B_Adhes:
|
||||
case F_Adhes:
|
||||
return GetFlag( FL_ADHESIVE );
|
||||
|
||||
case B_Paste:
|
||||
case F_Paste:
|
||||
return GetFlag( FL_SOLDERPASTE );
|
||||
|
||||
case B_SilkS:
|
||||
case F_SilkS:
|
||||
return GetFlag( FL_SILKSCREEN );
|
||||
|
||||
case B_Mask:
|
||||
case F_Mask:
|
||||
return GetFlag( FL_SOLDERMASK );
|
||||
|
||||
case Dwgs_User:
|
||||
case Cmts_User:
|
||||
if( GetFlag( FL_USE_REALISTIC_MODE ) )
|
||||
return false;
|
||||
|
||||
return GetFlag( FL_COMMENTS );
|
||||
|
||||
case Eco1_User:
|
||||
case Eco2_User:
|
||||
if( GetFlag( FL_USE_REALISTIC_MODE ) )
|
||||
return false;
|
||||
|
||||
return GetFlag( FL_ECO );
|
||||
|
||||
case Edge_Cuts:
|
||||
if( GetFlag( FL_SHOW_BOARD_BODY ) || GetFlag( FL_USE_REALISTIC_MODE ) )
|
||||
return false;
|
||||
|
||||
return true;
|
||||
|
||||
case Margin:
|
||||
if( GetFlag( FL_USE_REALISTIC_MODE ) )
|
||||
return false;
|
||||
|
||||
return true;
|
||||
|
||||
case B_Cu:
|
||||
case F_Cu:
|
||||
return m_board ? m_board->IsLayerVisible( aLayer ) || GetFlag( FL_USE_REALISTIC_MODE )
|
||||
: true;
|
||||
|
||||
default:
|
||||
// the layer is an internal copper layer, used the visibility
|
||||
return m_board && m_board->IsLayerVisible( aLayer );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
bool BOARD_ADAPTER::GetFlag( DISPLAY3D_FLG aFlag ) const
|
||||
{
|
||||
wxASSERT( aFlag < FL_LAST );
|
||||
|
||||
return m_drawFlags[aFlag];
|
||||
}
|
||||
|
||||
|
||||
void BOARD_ADAPTER::SetFlag( DISPLAY3D_FLG aFlag, bool aState )
|
||||
{
|
||||
wxASSERT( aFlag < FL_LAST );
|
||||
|
||||
m_drawFlags[aFlag] = aState;
|
||||
}
|
||||
|
||||
|
||||
bool BOARD_ADAPTER::IsFootprintShown( FOOTPRINT_ATTR_T aFPAttributes ) const
|
||||
{
|
||||
if( m_IsPreviewer ) // In panel Preview, footprints are always shown, of course
|
||||
return true;
|
||||
|
||||
if( aFPAttributes & FP_EXCLUDE_FROM_POS_FILES )
|
||||
{
|
||||
if( !m_Cfg->m_Render.show_footprints_not_in_posfile )
|
||||
return false;
|
||||
}
|
||||
|
||||
if( aFPAttributes & FP_DNP )
|
||||
{
|
||||
if( !m_Cfg->m_Render.show_footprints_dnp )
|
||||
return false;
|
||||
}
|
||||
|
||||
if( aFPAttributes & FP_SMD )
|
||||
return m_Cfg->m_Render.show_footprints_insert;
|
||||
|
||||
if( aFPAttributes & FP_THROUGH_HOLE )
|
||||
return m_Cfg->m_Render.show_footprints_normal;
|
||||
|
||||
return m_Cfg->m_Render.show_footprints_virtual;
|
||||
return GetFlag( FL_FP_ATTRIBUTES_NORMAL_INSERT );
|
||||
else if( aFPAttributes & FP_THROUGH_HOLE )
|
||||
return GetFlag( FL_FP_ATTRIBUTES_NORMAL );
|
||||
else
|
||||
return GetFlag( FL_FP_ATTRIBUTES_VIRTUAL );
|
||||
}
|
||||
|
||||
|
||||
// !TODO: define the actual copper thickness by user from board stackup
|
||||
#define COPPER_THICKNESS Millimeter2iu( 0.035 ) // for 35 um
|
||||
// The solder mask layer (and silkscreen) thickness
|
||||
#define TECH_LAYER_THICKNESS Millimeter2iu( 0.025 )
|
||||
// The solder paste thickness is chosen bigger than the solder mask layer
|
||||
// to be sure is covers the mask when overlapping.
|
||||
#define SOLDERPASTE_LAYER_THICKNESS Millimeter2iu( 0.04 )
|
||||
|
||||
int BOARD_ADAPTER::GetHolePlatingThickness() const noexcept
|
||||
{
|
||||
return m_board ? m_board->GetDesignSettings().GetHolePlatingThickness()
|
||||
: DEFAULT_COPPER_THICKNESS;
|
||||
: 0.035 * PCB_IU_PER_MM;
|
||||
}
|
||||
|
||||
|
||||
@@ -318,7 +348,7 @@ unsigned int BOARD_ADAPTER::GetCircleSegmentCount( int aDiameterBIU ) const
|
||||
{
|
||||
wxASSERT( aDiameterBIU > 0 );
|
||||
|
||||
return GetArcToSegmentCount( aDiameterBIU / 2, ARC_HIGH_DEF, FULL_CIRCLE );
|
||||
return GetArcToSegmentCount( aDiameterBIU / 2, ARC_HIGH_DEF, 360.0 );
|
||||
}
|
||||
|
||||
|
||||
@@ -331,24 +361,34 @@ void BOARD_ADAPTER::InitSettings( REPORTER* aStatusReporter, REPORTER* aWarningR
|
||||
|
||||
wxString msg;
|
||||
|
||||
const bool haveOutline = createBoardPolygon( &msg );
|
||||
const bool succeedToGetBoardPolygon = createBoardPolygon( &msg );
|
||||
|
||||
if( aWarningReporter )
|
||||
{
|
||||
if( !haveOutline )
|
||||
if( !succeedToGetBoardPolygon )
|
||||
aWarningReporter->Report( msg, RPT_SEVERITY_WARNING );
|
||||
else
|
||||
aWarningReporter->Report( wxEmptyString );
|
||||
}
|
||||
|
||||
BOX2I bbbox;
|
||||
// Calculates the board bounding box (board outlines + items)
|
||||
// to ensure any item, even outside the board outlines can be seen
|
||||
bool boardEdgesOnly = true;
|
||||
|
||||
if( ( m_board && m_board->IsFootprintHolder() ) || !GetFlag( FL_USE_REALISTIC_MODE )
|
||||
|| !succeedToGetBoardPolygon )
|
||||
{
|
||||
boardEdgesOnly = false;
|
||||
}
|
||||
|
||||
EDA_RECT bbbox;
|
||||
|
||||
if( m_board )
|
||||
bbbox = m_board->ComputeBoundingBox( !m_board->IsFootprintHolder() && haveOutline );
|
||||
bbbox = m_board->ComputeBoundingBox( boardEdgesOnly );
|
||||
|
||||
// Gives a non null size to avoid issues in zoom / scale calculations
|
||||
if( ( bbbox.GetWidth() == 0 ) && ( bbbox.GetHeight() == 0 ) )
|
||||
bbbox.Inflate( pcbIUScale.mmToIU( 10 ) );
|
||||
bbbox.Inflate( Millimeter2iu( 10 ) );
|
||||
|
||||
m_boardSize = bbbox.GetSize();
|
||||
m_boardPos = bbbox.Centre();
|
||||
@@ -367,63 +407,20 @@ void BOARD_ADAPTER::InitSettings( REPORTER* aStatusReporter, REPORTER* aWarningR
|
||||
// Calculate the conversion to apply to all positions.
|
||||
m_biuTo3Dunits = RANGE_SCALE_3D / std::max( m_boardSize.x, m_boardSize.y );
|
||||
|
||||
// Hack to keep "home" zoom from being too small.
|
||||
if( !m_board || !m_board->IsFootprintHolder() )
|
||||
m_biuTo3Dunits *= 1.6f;
|
||||
m_epoxyThickness3DU = m_board
|
||||
? m_board->GetDesignSettings().GetBoardThickness() * m_biuTo3Dunits
|
||||
: 1.6 * PCB_IU_PER_MM * m_biuTo3Dunits;
|
||||
|
||||
m_boardBodyThickness3DU = DEFAULT_BOARD_THICKNESS * m_biuTo3Dunits;
|
||||
m_frontCopperThickness3DU = DEFAULT_COPPER_THICKNESS * m_biuTo3Dunits;
|
||||
m_backCopperThickness3DU = DEFAULT_COPPER_THICKNESS * m_biuTo3Dunits;
|
||||
m_nonCopperLayerThickness3DU = DEFAULT_TECH_LAYER_THICKNESS * m_biuTo3Dunits;
|
||||
m_solderPasteLayerThickness3DU = SOLDERPASTE_LAYER_THICKNESS * m_biuTo3Dunits;
|
||||
|
||||
g_BevelThickness3DU = pcbIUScale.mmToIU( ADVANCED_CFG::GetCfg().m_3DRT_BevelHeight_um / 1000.0 ) * m_biuTo3Dunits;
|
||||
|
||||
if( m_board )
|
||||
{
|
||||
const BOARD_DESIGN_SETTINGS& bds = m_board->GetDesignSettings();
|
||||
|
||||
if( bds.GetStackupDescriptor().GetCount() )
|
||||
{
|
||||
int thickness = 0;
|
||||
|
||||
for( BOARD_STACKUP_ITEM* item : bds.GetStackupDescriptor().GetList() )
|
||||
{
|
||||
switch( item->GetType() )
|
||||
{
|
||||
case BS_ITEM_TYPE_DIELECTRIC:
|
||||
for( int sublayer = 0; sublayer < item->GetSublayersCount(); sublayer++ )
|
||||
thickness += item->GetThickness( sublayer );
|
||||
break;
|
||||
|
||||
case BS_ITEM_TYPE_COPPER:
|
||||
{
|
||||
// The copper thickness must be > 0 to avoid draw issues (divide by 0 for instance)
|
||||
// We use a minimal arbitrary value = 1 micrometer here:
|
||||
int copper_thickness = std::max( item->GetThickness(), pcbIUScale.mmToIU( 0.001 ) );
|
||||
|
||||
if( item->GetBrdLayerId() == F_Cu )
|
||||
m_frontCopperThickness3DU = copper_thickness * m_biuTo3Dunits;
|
||||
else if( item->GetBrdLayerId() == B_Cu )
|
||||
m_backCopperThickness3DU = copper_thickness * m_biuTo3Dunits;
|
||||
else if( item->IsEnabled() )
|
||||
thickness += copper_thickness;
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
m_boardBodyThickness3DU = thickness * m_biuTo3Dunits;
|
||||
}
|
||||
}
|
||||
// !TODO: use value defined by user (currently use default values by ctor
|
||||
m_copperThickness3DU = COPPER_THICKNESS * m_biuTo3Dunits;
|
||||
m_nonCopperLayerThickness3DU = TECH_LAYER_THICKNESS * m_biuTo3Dunits;
|
||||
m_solderPasteLayerThickness3DU = SOLDERPASTE_LAYER_THICKNESS * m_biuTo3Dunits;
|
||||
|
||||
// Init Z position of each layer
|
||||
// calculate z position for each copper layer
|
||||
// Zstart = -m_epoxyThickness / 2.0 is the z position of the back (bottom layer) (layer id = 31)
|
||||
// Zstart = +m_epoxyThickness / 2.0 is the z position of the front (top layer) (layer id = 0)
|
||||
// all unused copper layer z position are set to 0
|
||||
|
||||
// ____==__________==________==______ <- Bottom = +m_epoxyThickness / 2.0,
|
||||
// | | Top = Bottom + m_copperThickness
|
||||
@@ -435,26 +432,24 @@ void BOARD_ADAPTER::InitSettings( REPORTER* aStatusReporter, REPORTER* aWarningR
|
||||
|
||||
for( layer = 0; layer < m_copperLayersCount; ++layer )
|
||||
{
|
||||
// This approximates internal layer positions (because we're treating all the dielectric
|
||||
// layers as having the same thickness). But we don't render them anyway so it doesn't
|
||||
// really matter.
|
||||
m_layerZcoordBottom[layer] = m_boardBodyThickness3DU / 2.0f -
|
||||
(m_boardBodyThickness3DU * layer / (m_copperLayersCount - 1) );
|
||||
m_layerZcoordBottom[layer] = m_epoxyThickness3DU / 2.0f -
|
||||
(m_epoxyThickness3DU * layer / (m_copperLayersCount - 1) );
|
||||
|
||||
if( layer < (m_copperLayersCount / 2) )
|
||||
m_layerZcoordTop[layer] = m_layerZcoordBottom[layer] + m_frontCopperThickness3DU;
|
||||
m_layerZcoordTop[layer] = m_layerZcoordBottom[layer] + m_copperThickness3DU;
|
||||
else
|
||||
m_layerZcoordTop[layer] = m_layerZcoordBottom[layer] - m_backCopperThickness3DU;
|
||||
m_layerZcoordTop[layer] = m_layerZcoordBottom[layer] - m_copperThickness3DU;
|
||||
}
|
||||
|
||||
#define layerThicknessMargin 1.1
|
||||
const float zpos_offset = m_nonCopperLayerThickness3DU * layerThicknessMargin;
|
||||
|
||||
// Fill remaining unused copper layers and back layer zpos with -m_boardBodyThickness / 2.0
|
||||
// Fill remaining unused copper layers and back layer zpos
|
||||
// with -m_epoxyThickness / 2.0
|
||||
for( ; layer < MAX_CU_LAYERS; layer++ )
|
||||
{
|
||||
m_layerZcoordBottom[layer] = -( m_boardBodyThickness3DU / 2.0f );
|
||||
m_layerZcoordTop[layer] = m_layerZcoordBottom[layer] - m_backCopperThickness3DU;
|
||||
m_layerZcoordBottom[layer] = -(m_epoxyThickness3DU / 2.0f);
|
||||
m_layerZcoordTop[layer] = -(m_epoxyThickness3DU / 2.0f) - m_copperThickness3DU;
|
||||
}
|
||||
|
||||
// This is the top of the copper layer thickness.
|
||||
@@ -510,6 +505,7 @@ void BOARD_ADAPTER::InitSettings( REPORTER* aStatusReporter, REPORTER* aWarningR
|
||||
zposTop = zposBottom + m_nonCopperLayerThickness3DU;
|
||||
break;
|
||||
|
||||
// !TODO: review
|
||||
default:
|
||||
zposTop = zpos_copperTop_front + (layer_id - MAX_CU_LAYERS + 3.0f) * zpos_offset;
|
||||
zposBottom = zposTop - m_nonCopperLayerThickness3DU;
|
||||
@@ -535,7 +531,7 @@ void BOARD_ADAPTER::InitSettings( REPORTER* aStatusReporter, REPORTER* aWarningR
|
||||
m_boardBoundingBox = BBOX_3D( boardMin, boardMax );
|
||||
|
||||
#ifdef PRINT_STATISTICS_3D_VIEWER
|
||||
int64_t stats_startCreateBoardPolyTime = GetRunningMicroSecs();
|
||||
unsigned stats_startCreateBoardPolyTime = GetRunningMicroSecs();
|
||||
#endif
|
||||
|
||||
if( aStatusReporter )
|
||||
@@ -543,73 +539,22 @@ void BOARD_ADAPTER::InitSettings( REPORTER* aStatusReporter, REPORTER* aWarningR
|
||||
|
||||
createLayers( aStatusReporter );
|
||||
|
||||
COLOR_SETTINGS* colors = Pgm().GetSettingsManager().GetColorSettings();
|
||||
|
||||
auto to_SFVEC4F =
|
||||
[]( const COLOR4D& src )
|
||||
{
|
||||
return SFVEC4F( src.r, src.g, src.b, src.a );
|
||||
};
|
||||
|
||||
std::map<int, COLOR4D> colors = GetLayerColors();
|
||||
m_BgColorTop = to_SFVEC4F( colors->GetColor( LAYER_3D_BACKGROUND_TOP ) );
|
||||
m_BgColorBot = to_SFVEC4F( colors->GetColor( LAYER_3D_BACKGROUND_BOTTOM ) );
|
||||
|
||||
m_BgColorTop = to_SFVEC4F( colors[ LAYER_3D_BACKGROUND_TOP ] );
|
||||
m_BgColorBot = to_SFVEC4F( colors[ LAYER_3D_BACKGROUND_BOTTOM ] );
|
||||
m_SolderPasteColor = to_SFVEC4F( colors[ LAYER_3D_SOLDERPASTE ] );
|
||||
m_SilkScreenColorBot = to_SFVEC4F( colors[ LAYER_3D_SILKSCREEN_BOTTOM ] );
|
||||
m_SilkScreenColorTop = to_SFVEC4F( colors[ LAYER_3D_SILKSCREEN_TOP ] );
|
||||
m_SolderMaskColorBot = to_SFVEC4F( colors[ LAYER_3D_SOLDERMASK_BOTTOM ] );
|
||||
m_SolderMaskColorTop = to_SFVEC4F( colors[ LAYER_3D_SOLDERMASK_TOP ] );
|
||||
m_CopperColor = to_SFVEC4F( colors[ LAYER_3D_COPPER_TOP ] );
|
||||
m_BoardBodyColor = to_SFVEC4F( colors[ LAYER_3D_BOARD ] );
|
||||
m_UserDrawingsColor = to_SFVEC4F( colors[ LAYER_3D_USER_DRAWINGS ] );
|
||||
m_UserCommentsColor = to_SFVEC4F( colors[ LAYER_3D_USER_COMMENTS ] );
|
||||
m_ECO1Color = to_SFVEC4F( colors[ LAYER_3D_USER_ECO1 ] );
|
||||
m_ECO2Color = to_SFVEC4F( colors[ LAYER_3D_USER_ECO2 ] );
|
||||
}
|
||||
m_SolderPasteColor = to_SFVEC4F( colors->GetColor( LAYER_3D_SOLDERPASTE ) );
|
||||
|
||||
|
||||
std::map<int, COLOR4D> BOARD_ADAPTER::GetDefaultColors() const
|
||||
{
|
||||
std::map<int, COLOR4D> colors;
|
||||
|
||||
colors[ LAYER_3D_BACKGROUND_TOP ] = BOARD_ADAPTER::g_DefaultBackgroundTop;
|
||||
colors[ LAYER_3D_BACKGROUND_BOTTOM ] = BOARD_ADAPTER::g_DefaultBackgroundBot;
|
||||
colors[ LAYER_3D_BOARD ] = BOARD_ADAPTER::g_DefaultBoardBody;
|
||||
colors[ LAYER_3D_COPPER_TOP ] = BOARD_ADAPTER::g_DefaultSurfaceFinish;
|
||||
colors[ LAYER_3D_COPPER_BOTTOM ] = BOARD_ADAPTER::g_DefaultSurfaceFinish;
|
||||
colors[ LAYER_3D_SILKSCREEN_TOP ] = BOARD_ADAPTER::g_DefaultSilkscreen;
|
||||
colors[ LAYER_3D_SILKSCREEN_BOTTOM ] = BOARD_ADAPTER::g_DefaultSilkscreen;
|
||||
colors[ LAYER_3D_SOLDERMASK_TOP ] = BOARD_ADAPTER::g_DefaultSolderMask;
|
||||
colors[ LAYER_3D_SOLDERMASK_BOTTOM ] = BOARD_ADAPTER::g_DefaultSolderMask;
|
||||
colors[ LAYER_3D_SOLDERPASTE ] = BOARD_ADAPTER::g_DefaultSolderPaste;
|
||||
colors[ LAYER_3D_USER_DRAWINGS ] = BOARD_ADAPTER::g_DefaultComments;
|
||||
colors[ LAYER_3D_USER_COMMENTS ] = BOARD_ADAPTER::g_DefaultComments;
|
||||
colors[ LAYER_3D_USER_ECO1 ] = BOARD_ADAPTER::g_DefaultECOs;
|
||||
colors[ LAYER_3D_USER_ECO2 ] = BOARD_ADAPTER::g_DefaultECOs;
|
||||
|
||||
return colors;
|
||||
}
|
||||
|
||||
|
||||
std::map<int, COLOR4D> BOARD_ADAPTER::GetLayerColors() const
|
||||
{
|
||||
std::map<int, COLOR4D> colors;
|
||||
|
||||
if( LAYER_PRESET_3D* preset = m_Cfg->FindPreset( m_Cfg->m_CurrentPreset ) )
|
||||
{
|
||||
colors = preset->colors;
|
||||
}
|
||||
else
|
||||
{
|
||||
COLOR_SETTINGS* settings = Pgm().GetSettingsManager().GetColorSettings();
|
||||
|
||||
for( const auto& [ layer, defaultColor /* unused */ ] : GetDefaultColors() )
|
||||
colors[ layer ] = settings->GetColor( layer );
|
||||
}
|
||||
|
||||
if( m_Cfg->m_UseStackupColors && m_board )
|
||||
if( m_board && colors->GetUseBoardStackupColors() )
|
||||
{
|
||||
const BOARD_STACKUP& stackup = m_board->GetDesignSettings().GetStackupDescriptor();
|
||||
KIGFX::COLOR4D bodyColor( 0, 0, 0, 0 );
|
||||
|
||||
auto findColor =
|
||||
[]( const wxString& aColorName, const CUSTOM_COLORS_LIST& aColorSet )
|
||||
@@ -630,6 +575,13 @@ std::map<int, COLOR4D> BOARD_ADAPTER::GetLayerColors() const
|
||||
return KIGFX::COLOR4D();
|
||||
};
|
||||
|
||||
m_SilkScreenColorTop = to_SFVEC4F( g_DefaultSilkscreen );
|
||||
m_SilkScreenColorBot = to_SFVEC4F( g_DefaultSilkscreen );
|
||||
m_SolderMaskColorTop = to_SFVEC4F( g_DefaultSolderMask );
|
||||
m_SolderMaskColorBot = to_SFVEC4F( g_DefaultSolderMask );
|
||||
|
||||
KIGFX::COLOR4D bodyColor( 0, 0, 0, 0 );
|
||||
|
||||
for( const BOARD_STACKUP_ITEM* stackupItem : stackup.GetList() )
|
||||
{
|
||||
wxString colorName = stackupItem->GetColor();
|
||||
@@ -638,23 +590,47 @@ std::map<int, COLOR4D> BOARD_ADAPTER::GetLayerColors() const
|
||||
{
|
||||
case BS_ITEM_TYPE_SILKSCREEN:
|
||||
if( stackupItem->GetBrdLayerId() == F_SilkS )
|
||||
colors[ LAYER_3D_SILKSCREEN_TOP ] = findColor( colorName, g_SilkColors );
|
||||
m_SilkScreenColorTop = to_SFVEC4F( findColor( colorName, g_SilkscreenColors ) );
|
||||
else
|
||||
colors[ LAYER_3D_SILKSCREEN_BOTTOM ] = findColor( colorName, g_SilkColors );
|
||||
|
||||
m_SilkScreenColorBot = to_SFVEC4F( findColor( colorName, g_SilkscreenColors ) );
|
||||
break;
|
||||
|
||||
case BS_ITEM_TYPE_SOLDERMASK:
|
||||
if( stackupItem->GetBrdLayerId() == F_Mask )
|
||||
colors[ LAYER_3D_SOLDERMASK_TOP ] = findColor( colorName, g_MaskColors );
|
||||
m_SolderMaskColorTop = to_SFVEC4F( findColor( colorName, g_MaskColors ) );
|
||||
else
|
||||
colors[ LAYER_3D_SOLDERMASK_BOTTOM ] = findColor( colorName, g_MaskColors );
|
||||
m_SolderMaskColorBot = to_SFVEC4F( findColor( colorName, g_MaskColors ) );
|
||||
|
||||
break;
|
||||
|
||||
case BS_ITEM_TYPE_DIELECTRIC:
|
||||
{
|
||||
KIGFX::COLOR4D layerColor = findColor( colorName, g_BoardColors );
|
||||
KIGFX::COLOR4D layerColor = COLOR4D::UNSPECIFIED;
|
||||
const wxString& materialName = stackupItem->GetMaterial();
|
||||
|
||||
if( materialName.StartsWith( wxT( "FR4" ) ) )
|
||||
{
|
||||
layerColor = findColor( wxT( "FR4 natural" ), g_BoardColors );
|
||||
}
|
||||
else if( materialName.IsSameAs( wxT( "PTFE" ) )
|
||||
|| materialName.IsSameAs( wxT( "Teflon" ) ) )
|
||||
{
|
||||
layerColor = findColor( wxT( "PTFE natural" ), g_BoardColors );
|
||||
}
|
||||
else if( materialName.IsSameAs( wxT( "Polyimide" ) )
|
||||
|| materialName.IsSameAs( wxT( "Kapton" ) ) )
|
||||
{
|
||||
layerColor = findColor( wxT( "Polyimide" ), g_BoardColors );
|
||||
}
|
||||
else if( materialName.IsSameAs( wxT( "Al" ) ) )
|
||||
{
|
||||
layerColor = findColor( wxT( "Aluminum" ), g_BoardColors );
|
||||
}
|
||||
else // A default color value for unknown dielectric material
|
||||
// (i.e. an exotic name entered by hand)
|
||||
{
|
||||
layerColor = findColor( wxT( "FR4 natural" ), g_BoardColors );
|
||||
}
|
||||
|
||||
if( bodyColor == COLOR4D( 0, 0, 0, 0 ) )
|
||||
bodyColor = layerColor;
|
||||
@@ -671,221 +647,52 @@ std::map<int, COLOR4D> BOARD_ADAPTER::GetLayerColors() const
|
||||
}
|
||||
|
||||
if( bodyColor != COLOR4D( 0, 0, 0, 0 ) )
|
||||
colors[ LAYER_3D_BOARD ] = bodyColor;
|
||||
m_BoardBodyColor = to_SFVEC4F( bodyColor );
|
||||
else
|
||||
m_BoardBodyColor = to_SFVEC4F( g_DefaultBoardBody );
|
||||
|
||||
const wxString& finishName = stackup.m_FinishType;
|
||||
|
||||
if( finishName.EndsWith( wxT( "OSP" ) ) )
|
||||
{
|
||||
colors[ LAYER_3D_COPPER_TOP ] = findColor( wxT( "Copper" ), g_FinishColors );
|
||||
m_CopperColor = to_SFVEC4F( findColor( wxT( "Copper" ), g_FinishColors ) );
|
||||
}
|
||||
else if( finishName.EndsWith( wxT( "IG" ) )
|
||||
|| finishName.EndsWith( wxT( "gold" ) ) )
|
||||
{
|
||||
colors[ LAYER_3D_COPPER_TOP ] = findColor( wxT( "Gold" ), g_FinishColors );
|
||||
m_CopperColor = to_SFVEC4F( findColor( wxT( "Gold" ), g_FinishColors ) );
|
||||
}
|
||||
else if( finishName.StartsWith( wxT( "HAL" ) )
|
||||
|| finishName.StartsWith( wxT( "HASL" ) )
|
||||
|| finishName.EndsWith( wxT( "tin" ) )
|
||||
|| finishName.EndsWith( wxT( "nickel" ) ) )
|
||||
{
|
||||
colors[ LAYER_3D_COPPER_TOP ] = findColor( wxT( "Tin" ), g_FinishColors );
|
||||
m_CopperColor = to_SFVEC4F( findColor( wxT( "Tin" ), g_FinishColors ) );
|
||||
}
|
||||
else if( finishName.EndsWith( wxT( "silver" ) ) )
|
||||
{
|
||||
colors[ LAYER_3D_COPPER_TOP ] = findColor( wxT( "Silver" ), g_FinishColors );
|
||||
m_CopperColor = to_SFVEC4F( findColor( wxT( "Silver" ), g_FinishColors ) );
|
||||
}
|
||||
else
|
||||
{
|
||||
m_CopperColor = to_SFVEC4F( g_DefaultSurfaceFinish );
|
||||
}
|
||||
}
|
||||
|
||||
colors[ LAYER_3D_COPPER_BOTTOM ] = colors[ LAYER_3D_COPPER_TOP ];
|
||||
return colors;
|
||||
}
|
||||
|
||||
|
||||
void BOARD_ADAPTER::SetLayerColors( const std::map<int, COLOR4D>& aColors )
|
||||
{
|
||||
COLOR_SETTINGS* settings = Pgm().GetSettingsManager().GetColorSettings();
|
||||
|
||||
for( const auto& [ layer, color ] : aColors )
|
||||
settings->SetColor( layer, color );
|
||||
}
|
||||
|
||||
|
||||
void BOARD_ADAPTER::SetVisibleLayers( const std::bitset<LAYER_3D_END>& aLayers )
|
||||
{
|
||||
m_Cfg->m_Render.show_board_body = aLayers.test( LAYER_3D_BOARD );
|
||||
m_Cfg->m_Render.show_copper_top = aLayers.test( LAYER_3D_COPPER_TOP );
|
||||
m_Cfg->m_Render.show_copper_bottom = aLayers.test( LAYER_3D_COPPER_BOTTOM );
|
||||
m_Cfg->m_Render.show_silkscreen_top = aLayers.test( LAYER_3D_SILKSCREEN_TOP );
|
||||
m_Cfg->m_Render.show_silkscreen_bottom = aLayers.test( LAYER_3D_SILKSCREEN_BOTTOM );
|
||||
m_Cfg->m_Render.show_soldermask_top = aLayers.test( LAYER_3D_SOLDERMASK_TOP );
|
||||
m_Cfg->m_Render.show_soldermask_bottom = aLayers.test( LAYER_3D_SOLDERMASK_BOTTOM );
|
||||
m_Cfg->m_Render.show_solderpaste = aLayers.test( LAYER_3D_SOLDERPASTE );
|
||||
m_Cfg->m_Render.show_adhesive = aLayers.test( LAYER_3D_ADHESIVE );
|
||||
m_Cfg->m_Render.show_comments = aLayers.test( LAYER_3D_USER_COMMENTS );
|
||||
m_Cfg->m_Render.show_drawings = aLayers.test( LAYER_3D_USER_DRAWINGS );
|
||||
m_Cfg->m_Render.show_eco1 = aLayers.test( LAYER_3D_USER_ECO1 );
|
||||
m_Cfg->m_Render.show_eco2 = aLayers.test( LAYER_3D_USER_ECO2 );
|
||||
|
||||
m_Cfg->m_Render.show_footprints_normal = aLayers.test( LAYER_3D_TH_MODELS );
|
||||
m_Cfg->m_Render.show_footprints_insert = aLayers.test( LAYER_3D_SMD_MODELS );
|
||||
m_Cfg->m_Render.show_footprints_virtual = aLayers.test( LAYER_3D_VIRTUAL_MODELS );
|
||||
m_Cfg->m_Render.show_footprints_not_in_posfile = aLayers.test( LAYER_3D_MODELS_NOT_IN_POS );
|
||||
m_Cfg->m_Render.show_footprints_dnp = aLayers.test( LAYER_3D_MODELS_MARKED_DNP );
|
||||
|
||||
m_Cfg->m_Render.show_fp_references = aLayers.test( LAYER_FP_REFERENCES );
|
||||
m_Cfg->m_Render.show_fp_values = aLayers.test( LAYER_FP_VALUES );
|
||||
m_Cfg->m_Render.show_fp_text = aLayers.test( LAYER_FP_TEXT );
|
||||
|
||||
m_Cfg->m_Render.show_model_bbox = aLayers.test( LAYER_3D_BOUNDING_BOXES );
|
||||
m_Cfg->m_Render.show_off_board_silk = aLayers.test( LAYER_3D_OFF_BOARD_SILK );
|
||||
m_Cfg->m_Render.show_axis = aLayers.test( LAYER_3D_AXES );
|
||||
}
|
||||
|
||||
|
||||
std::bitset<LAYER_3D_END> BOARD_ADAPTER::GetVisibleLayers() const
|
||||
{
|
||||
std::bitset<LAYER_3D_END> ret;
|
||||
|
||||
ret.set( LAYER_3D_BOARD, m_Cfg->m_Render.show_board_body );
|
||||
ret.set( LAYER_3D_COPPER_TOP, m_Cfg->m_Render.show_copper_top );
|
||||
ret.set( LAYER_3D_COPPER_BOTTOM, m_Cfg->m_Render.show_copper_bottom );
|
||||
ret.set( LAYER_3D_SILKSCREEN_TOP, m_Cfg->m_Render.show_silkscreen_top );
|
||||
ret.set( LAYER_3D_SILKSCREEN_BOTTOM, m_Cfg->m_Render.show_silkscreen_bottom );
|
||||
ret.set( LAYER_3D_SOLDERMASK_TOP, m_Cfg->m_Render.show_soldermask_top );
|
||||
ret.set( LAYER_3D_SOLDERMASK_BOTTOM, m_Cfg->m_Render.show_soldermask_bottom );
|
||||
ret.set( LAYER_3D_SOLDERPASTE, m_Cfg->m_Render.show_solderpaste );
|
||||
ret.set( LAYER_3D_ADHESIVE, m_Cfg->m_Render.show_adhesive );
|
||||
ret.set( LAYER_3D_USER_COMMENTS, m_Cfg->m_Render.show_comments );
|
||||
ret.set( LAYER_3D_USER_DRAWINGS, m_Cfg->m_Render.show_drawings );
|
||||
ret.set( LAYER_3D_USER_ECO1, m_Cfg->m_Render.show_eco1 );
|
||||
ret.set( LAYER_3D_USER_ECO2, m_Cfg->m_Render.show_eco2 );
|
||||
|
||||
ret.set( LAYER_FP_REFERENCES, m_Cfg->m_Render.show_fp_references );
|
||||
ret.set( LAYER_FP_VALUES, m_Cfg->m_Render.show_fp_values );
|
||||
ret.set( LAYER_FP_TEXT, m_Cfg->m_Render.show_fp_text );
|
||||
|
||||
ret.set( LAYER_3D_TH_MODELS, m_Cfg->m_Render.show_footprints_normal );
|
||||
ret.set( LAYER_3D_SMD_MODELS, m_Cfg->m_Render.show_footprints_insert );
|
||||
ret.set( LAYER_3D_VIRTUAL_MODELS, m_Cfg->m_Render.show_footprints_virtual );
|
||||
ret.set( LAYER_3D_MODELS_NOT_IN_POS, m_Cfg->m_Render.show_footprints_not_in_posfile );
|
||||
ret.set( LAYER_3D_MODELS_MARKED_DNP, m_Cfg->m_Render.show_footprints_dnp );
|
||||
|
||||
ret.set( LAYER_3D_BOUNDING_BOXES, m_Cfg->m_Render.show_model_bbox );
|
||||
ret.set( LAYER_3D_OFF_BOARD_SILK, m_Cfg->m_Render.show_off_board_silk );
|
||||
ret.set( LAYER_3D_AXES, m_Cfg->m_Render.show_axis );
|
||||
|
||||
if( m_Cfg->m_CurrentPreset == FOLLOW_PCB )
|
||||
{
|
||||
if( !m_board )
|
||||
return ret;
|
||||
|
||||
ret.set( LAYER_3D_BOARD, true );
|
||||
ret.set( LAYER_3D_COPPER_TOP, m_board->IsLayerVisible( F_Cu ) );
|
||||
ret.set( LAYER_3D_COPPER_BOTTOM, m_board->IsLayerVisible( B_Cu ) );
|
||||
ret.set( LAYER_3D_SILKSCREEN_TOP, m_board->IsLayerVisible( F_SilkS ) );
|
||||
ret.set( LAYER_3D_SILKSCREEN_BOTTOM, m_board->IsLayerVisible( B_SilkS ) );
|
||||
ret.set( LAYER_3D_SOLDERMASK_TOP, m_board->IsLayerVisible( F_Mask ) );
|
||||
ret.set( LAYER_3D_SOLDERMASK_BOTTOM, m_board->IsLayerVisible( B_Mask ) );
|
||||
ret.set( LAYER_3D_SOLDERPASTE, m_board->IsLayerVisible( F_Paste ) );
|
||||
ret.set( LAYER_3D_ADHESIVE, m_board->IsLayerVisible( F_Adhes ) );
|
||||
ret.set( LAYER_3D_USER_COMMENTS, m_board->IsLayerVisible( Cmts_User ) );
|
||||
ret.set( LAYER_3D_USER_DRAWINGS, m_board->IsLayerVisible( Dwgs_User ) );
|
||||
ret.set( LAYER_3D_USER_ECO1, m_board->IsLayerVisible( Eco1_User ) );
|
||||
ret.set( LAYER_3D_USER_ECO2, m_board->IsLayerVisible( Eco2_User ) );
|
||||
|
||||
for( GAL_LAYER_ID layer : { LAYER_FP_REFERENCES, LAYER_FP_VALUES, LAYER_FP_TEXT } )
|
||||
ret.set( layer, m_board->IsElementVisible( layer ) );
|
||||
}
|
||||
else if( m_Cfg->m_CurrentPreset == FOLLOW_PLOT_SETTINGS )
|
||||
{
|
||||
if( !m_board )
|
||||
return ret;
|
||||
|
||||
const PCB_PLOT_PARAMS& plotParams = m_board->GetPlotOptions();
|
||||
LSET layers = plotParams.GetLayerSelection() | plotParams.GetPlotOnAllLayersSelection();
|
||||
|
||||
ret.set( LAYER_3D_BOARD, true );
|
||||
ret.set( LAYER_3D_COPPER_TOP, layers.test( F_Cu ) );
|
||||
ret.set( LAYER_3D_COPPER_BOTTOM, layers.test( B_Cu ) );
|
||||
ret.set( LAYER_3D_SILKSCREEN_TOP, layers.test( F_SilkS ) );
|
||||
ret.set( LAYER_3D_SILKSCREEN_BOTTOM, layers.test( B_SilkS ) );
|
||||
ret.set( LAYER_3D_SOLDERMASK_TOP, layers.test( F_Mask ) );
|
||||
ret.set( LAYER_3D_SOLDERMASK_BOTTOM, layers.test( B_Mask ) );
|
||||
ret.set( LAYER_3D_SOLDERPASTE, layers.test( F_Paste ) );
|
||||
ret.set( LAYER_3D_ADHESIVE, layers.test( F_Adhes ) );
|
||||
ret.set( LAYER_3D_USER_COMMENTS, layers.test( Cmts_User ) );
|
||||
ret.set( LAYER_3D_USER_DRAWINGS, layers.test( Dwgs_User ) );
|
||||
ret.set( LAYER_3D_USER_ECO1, layers.test( Eco1_User ) );
|
||||
ret.set( LAYER_3D_USER_ECO2, layers.test( Eco2_User ) );
|
||||
|
||||
ret.set( LAYER_FP_REFERENCES, plotParams.GetPlotReference() );
|
||||
ret.set( LAYER_FP_VALUES, plotParams.GetPlotValue() );
|
||||
ret.set( LAYER_FP_TEXT, plotParams.GetPlotFPText() );
|
||||
}
|
||||
else if( LAYER_PRESET_3D* preset = m_Cfg->FindPreset( m_Cfg->m_CurrentPreset ) )
|
||||
{
|
||||
ret = preset->layers;
|
||||
}
|
||||
else
|
||||
{
|
||||
ret.set( LAYER_3D_BOARD, m_Cfg->m_Render.show_board_body );
|
||||
ret.set( LAYER_3D_COPPER_TOP, m_Cfg->m_Render.show_copper_top );
|
||||
ret.set( LAYER_3D_COPPER_BOTTOM, m_Cfg->m_Render.show_copper_bottom );
|
||||
ret.set( LAYER_3D_SILKSCREEN_TOP, m_Cfg->m_Render.show_silkscreen_top );
|
||||
ret.set( LAYER_3D_SILKSCREEN_BOTTOM, m_Cfg->m_Render.show_silkscreen_bottom );
|
||||
ret.set( LAYER_3D_SOLDERMASK_TOP, m_Cfg->m_Render.show_soldermask_top );
|
||||
ret.set( LAYER_3D_SOLDERMASK_BOTTOM, m_Cfg->m_Render.show_soldermask_bottom );
|
||||
ret.set( LAYER_3D_SOLDERPASTE, m_Cfg->m_Render.show_solderpaste );
|
||||
ret.set( LAYER_3D_ADHESIVE, m_Cfg->m_Render.show_adhesive );
|
||||
ret.set( LAYER_3D_USER_COMMENTS, m_Cfg->m_Render.show_comments );
|
||||
ret.set( LAYER_3D_USER_DRAWINGS, m_Cfg->m_Render.show_drawings );
|
||||
ret.set( LAYER_3D_USER_ECO1, m_Cfg->m_Render.show_eco1 );
|
||||
ret.set( LAYER_3D_USER_ECO2, m_Cfg->m_Render.show_eco2 );
|
||||
|
||||
ret.set( LAYER_FP_REFERENCES, m_Cfg->m_Render.show_fp_references );
|
||||
ret.set( LAYER_FP_VALUES, m_Cfg->m_Render.show_fp_values );
|
||||
ret.set( LAYER_FP_TEXT, m_Cfg->m_Render.show_fp_text );
|
||||
m_SilkScreenColorBot = to_SFVEC4F( colors->GetColor( LAYER_3D_SILKSCREEN_BOTTOM ) );
|
||||
m_SilkScreenColorTop = to_SFVEC4F( colors->GetColor( LAYER_3D_SILKSCREEN_TOP ) );
|
||||
m_SolderMaskColorBot = to_SFVEC4F( colors->GetColor( LAYER_3D_SOLDERMASK_BOTTOM ) );
|
||||
m_SolderMaskColorTop = to_SFVEC4F( colors->GetColor( LAYER_3D_SOLDERMASK_TOP ) );
|
||||
m_CopperColor = to_SFVEC4F( colors->GetColor( LAYER_3D_COPPER ) );
|
||||
m_BoardBodyColor = to_SFVEC4F( colors->GetColor( LAYER_3D_BOARD ) );
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
std::bitset<LAYER_3D_END> BOARD_ADAPTER::GetDefaultVisibleLayers() const
|
||||
{
|
||||
std::bitset<LAYER_3D_END> ret;
|
||||
|
||||
ret.set( LAYER_3D_BOARD, true );
|
||||
ret.set( LAYER_3D_COPPER_TOP, true );
|
||||
ret.set( LAYER_3D_COPPER_BOTTOM, true );
|
||||
ret.set( LAYER_3D_SILKSCREEN_TOP, true );
|
||||
ret.set( LAYER_3D_SILKSCREEN_BOTTOM, true );
|
||||
ret.set( LAYER_3D_SOLDERMASK_TOP, true );
|
||||
ret.set( LAYER_3D_SOLDERMASK_BOTTOM, true );
|
||||
ret.set( LAYER_3D_SOLDERPASTE, true );
|
||||
ret.set( LAYER_3D_ADHESIVE, true );
|
||||
ret.set( LAYER_3D_USER_COMMENTS, false );
|
||||
ret.set( LAYER_3D_USER_DRAWINGS, false );
|
||||
ret.set( LAYER_3D_USER_ECO1, false );
|
||||
ret.set( LAYER_3D_USER_ECO2, false );
|
||||
|
||||
ret.set( LAYER_FP_REFERENCES, true );
|
||||
ret.set( LAYER_FP_VALUES, true );
|
||||
ret.set( LAYER_FP_TEXT, true );
|
||||
|
||||
ret.set( LAYER_3D_TH_MODELS, true );
|
||||
ret.set( LAYER_3D_SMD_MODELS, true );
|
||||
ret.set( LAYER_3D_VIRTUAL_MODELS, true );
|
||||
ret.set( LAYER_3D_MODELS_NOT_IN_POS, false );
|
||||
ret.set( LAYER_3D_MODELS_MARKED_DNP, false );
|
||||
|
||||
ret.set( LAYER_3D_BOUNDING_BOXES, false );
|
||||
ret.set( LAYER_3D_OFF_BOARD_SILK, false );
|
||||
ret.set( LAYER_3D_AXES, true );
|
||||
|
||||
return ret;
|
||||
}
|
||||
extern bool BuildFootprintPolygonOutlines( BOARD* aBoard, SHAPE_POLY_SET& aOutlines,
|
||||
int aErrorMax, int aChainingEpsilon,
|
||||
OUTLINE_ERROR_HANDLER* aErrorHandler = nullptr );
|
||||
|
||||
|
||||
bool BOARD_ADAPTER::createBoardPolygon( wxString* aErrorMsg )
|
||||
@@ -907,8 +714,7 @@ bool BOARD_ADAPTER::createBoardPolygon( wxString* aErrorMsg )
|
||||
return false;
|
||||
}
|
||||
|
||||
// max dist from one endPt to next startPt
|
||||
int chainingEpsilon = m_board->GetOutlinesChainingEpsilon();
|
||||
int chainingEpsilon = Millimeter2iu( 0.02 ); // max dist from one endPt to next startPt
|
||||
|
||||
success = BuildFootprintPolygonOutlines( m_board, m_board_poly,
|
||||
m_board->GetDesignSettings().m_MaxError,
|
||||
@@ -925,7 +731,7 @@ bool BOARD_ADAPTER::createBoardPolygon( wxString* aErrorMsg )
|
||||
}
|
||||
else
|
||||
{
|
||||
success = m_board->GetBoardPolygonOutlines( m_board_poly, nullptr, false, true );
|
||||
success = m_board->GetBoardPolygonOutlines( m_board_poly );
|
||||
|
||||
if( !success && aErrorMsg )
|
||||
*aErrorMsg = _( "Board outline is missing or malformed. Run DRC for a full analysis." );
|
||||
@@ -938,9 +744,19 @@ bool BOARD_ADAPTER::createBoardPolygon( wxString* aErrorMsg )
|
||||
float BOARD_ADAPTER::GetFootprintZPos( bool aIsFlipped ) const
|
||||
{
|
||||
if( aIsFlipped )
|
||||
return m_layerZcoordBottom[B_Paste];
|
||||
{
|
||||
if( GetFlag( FL_SOLDERPASTE ) )
|
||||
return m_layerZcoordBottom[B_SilkS];
|
||||
else
|
||||
return m_layerZcoordBottom[B_Paste];
|
||||
}
|
||||
else
|
||||
return m_layerZcoordTop[F_Paste];
|
||||
{
|
||||
if( GetFlag( FL_SOLDERPASTE ) )
|
||||
return m_layerZcoordTop[F_SilkS];
|
||||
else
|
||||
return m_layerZcoordTop[F_Paste];
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -964,16 +780,3 @@ SFVEC4F BOARD_ADAPTER::GetColor( const COLOR4D& aColor ) const
|
||||
{
|
||||
return SFVEC4F( aColor.r, aColor.g, aColor.b, aColor.a );
|
||||
}
|
||||
|
||||
|
||||
SFVEC2F BOARD_ADAPTER::GetSphericalCoord( int i ) const
|
||||
{
|
||||
SFVEC2F sphericalCoord =
|
||||
SFVEC2F( ( m_Cfg->m_Render.raytrace_lightElevation[i] + 90.0f ) / 180.0f,
|
||||
m_Cfg->m_Render.raytrace_lightAzimuth[i] / 180.0f );
|
||||
|
||||
sphericalCoord.x = glm::clamp( sphericalCoord.x, 0.0f, 1.0f );
|
||||
sphericalCoord.y = glm::clamp( sphericalCoord.y, 0.0f, 2.0f );
|
||||
|
||||
return sphericalCoord;
|
||||
}
|
||||
|
||||
+443
-167
@@ -2,8 +2,7 @@
|
||||
* This program source code file is part of KiCad, a free EDA CAD application.
|
||||
*
|
||||
* Copyright (C) 2015-2016 Mario Luzeiro <mrluzeiro@ua.pt>
|
||||
* Copyright (C) 2023 CERN
|
||||
* Copyright (C) 1992-2023 KiCad Developers, see AUTHORS.txt for contributors.
|
||||
* Copyright (C) 1992-2021 KiCad Developers, see AUTHORS.txt for contributors.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
@@ -31,15 +30,15 @@
|
||||
#include "../3d_rendering/raytracing/accelerators/container_2d.h"
|
||||
#include "../3d_rendering/raytracing/accelerators/container_3d.h"
|
||||
#include "../3d_rendering/raytracing/shapes3D/bbox_3d.h"
|
||||
#include <gal/3d/camera.h>
|
||||
#include "../3d_rendering/camera.h"
|
||||
#include "../3d_enums.h"
|
||||
#include "../3d_cache/3d_cache.h"
|
||||
#include "../common_ogl/ogl_attr_list.h"
|
||||
#include "../3d_viewer/eda_3d_viewer_settings.h"
|
||||
|
||||
#include <layer_ids.h>
|
||||
#include <pad.h>
|
||||
#include <pcb_track.h>
|
||||
#include <wx/gdicmn.h>
|
||||
#include <pcb_base_frame.h>
|
||||
#include <pcb_text.h>
|
||||
#include <pcb_shape.h>
|
||||
@@ -50,13 +49,12 @@
|
||||
#include <dialogs/dialog_color_picker.h>
|
||||
|
||||
class COLOR_SETTINGS;
|
||||
class PCB_TEXTBOX;
|
||||
|
||||
/// A type that stores a container of 2d objects for each layer id
|
||||
typedef std::map<PCB_LAYER_ID, BVH_CONTAINER_2D*> MAP_CONTAINER_2D_BASE;
|
||||
typedef std::map< PCB_LAYER_ID, BVH_CONTAINER_2D *> MAP_CONTAINER_2D_BASE;
|
||||
|
||||
/// A type that stores polysets for each layer id
|
||||
typedef std::map<PCB_LAYER_ID, SHAPE_POLY_SET*> MAP_POLY;
|
||||
typedef std::map< PCB_LAYER_ID, SHAPE_POLY_SET *> MAP_POLY;
|
||||
|
||||
/// This defines the range that all coord will have to be rendered.
|
||||
/// It will use this value to convert to a normalized value between
|
||||
@@ -79,16 +77,41 @@ public:
|
||||
*
|
||||
* @param aCachePointer: the pointer to the 3D cache manager.
|
||||
*/
|
||||
void Set3dCacheManager( S3D_CACHE* aCacheMgr ) noexcept { m_3dModelManager = aCacheMgr; }
|
||||
S3D_CACHE* Get3dCacheManager() const noexcept { return m_3dModelManager; }
|
||||
void Set3dCacheManager( S3D_CACHE* aCachePointer ) noexcept
|
||||
{
|
||||
m_3dModelManager = aCachePointer;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the 3D cache manager pointer.
|
||||
*/
|
||||
S3D_CACHE* Get3dCacheManager() const noexcept
|
||||
{
|
||||
return m_3dModelManager;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a configuration status of a flag.
|
||||
*
|
||||
* @param aFlag the flag to get the status.
|
||||
* @return true if flag is set, false if not.
|
||||
*/
|
||||
bool GetFlag( DISPLAY3D_FLG aFlag ) const ;
|
||||
|
||||
/**
|
||||
* Set the status of a flag.
|
||||
*
|
||||
* @param aFlag the flag to set the status
|
||||
* @param aState status to set.
|
||||
*/
|
||||
void SetFlag( DISPLAY3D_FLG aFlag, bool aState );
|
||||
|
||||
/**
|
||||
* Check if a layer is enabled.
|
||||
*
|
||||
* @param aLayer layer ID to get status.
|
||||
*/
|
||||
bool Is3dLayerEnabled( PCB_LAYER_ID aLayer,
|
||||
const std::bitset<LAYER_3D_END>& aVisibilityFlags ) const;
|
||||
bool Is3dLayerEnabled( PCB_LAYER_ID aLayer ) const;
|
||||
|
||||
/**
|
||||
* Test if footprint should be displayed in relation to attributes and the flags.
|
||||
@@ -100,18 +123,25 @@ public:
|
||||
*
|
||||
* @param aBoard board to process.
|
||||
*/
|
||||
void SetBoard( BOARD* aBoard ) noexcept { m_board = aBoard; }
|
||||
const BOARD* GetBoard() const noexcept { return m_board; }
|
||||
void SetBoard( BOARD* aBoard ) noexcept
|
||||
{
|
||||
m_board = aBoard;
|
||||
}
|
||||
|
||||
void ReloadColorSettings() noexcept;
|
||||
/**
|
||||
* Get current board to be rendered.
|
||||
*
|
||||
* @return BOARD pointer
|
||||
*/
|
||||
const BOARD* GetBoard() const noexcept
|
||||
{
|
||||
return m_board;
|
||||
}
|
||||
|
||||
std::map<int, COLOR4D> GetLayerColors() const;
|
||||
std::map<int, COLOR4D> GetDefaultColors() const;
|
||||
void SetLayerColors( const std::map<int, COLOR4D>& aColors );
|
||||
|
||||
std::bitset<LAYER_3D_END> GetVisibleLayers() const;
|
||||
std::bitset<LAYER_3D_END> GetDefaultVisibleLayers() const;
|
||||
void SetVisibleLayers( const std::bitset<LAYER_3D_END>& aLayers );
|
||||
void SetColorSettings( COLOR_SETTINGS* aSettings ) noexcept
|
||||
{
|
||||
m_colors = aSettings;
|
||||
}
|
||||
|
||||
/**
|
||||
* Function to be called by the render when it need to reload the settings for the board.
|
||||
@@ -126,33 +156,55 @@ public:
|
||||
*
|
||||
* @return the conversion factor to transform a position from the board to 3D units.
|
||||
*/
|
||||
double BiuTo3dUnits() const noexcept { return m_biuTo3Dunits; }
|
||||
double BiuTo3dUnits() const noexcept
|
||||
{
|
||||
return m_biuTo3Dunits;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the board outling bounding box.
|
||||
*
|
||||
* @return the board bounding box in 3D units.
|
||||
*/
|
||||
const BBOX_3D& GetBBox() const noexcept { return m_boardBoundingBox; }
|
||||
const BBOX_3D& GetBBox() const noexcept
|
||||
{
|
||||
return m_boardBoundingBox;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the board body thickness, including internal copper layers (in 3D units).
|
||||
* Get the current epoxy thickness.
|
||||
*
|
||||
* @return epoxy thickness in 3D units.
|
||||
*/
|
||||
float GetBoardBodyThickness() const noexcept { return m_boardBodyThickness3DU; }
|
||||
float GetEpoxyThickness() const noexcept
|
||||
{
|
||||
return m_epoxyThickness3DU;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the non copper layers thickness (in 3D units).
|
||||
* Get the current non copper layers thickness.
|
||||
*
|
||||
* @return thickness in 3D units of non copper layers.
|
||||
*/
|
||||
float GetNonCopperLayerThickness() const noexcept { return m_nonCopperLayerThickness3DU; }
|
||||
float GetNonCopperLayerThickness() const noexcept
|
||||
{
|
||||
return m_nonCopperLayerThickness3DU;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the copper layer thicknesses (in 3D units).
|
||||
* Get the current copper layer thickness.
|
||||
*
|
||||
* @return thickness in 3D units of copper layers.
|
||||
*/
|
||||
float GetFrontCopperThickness() const noexcept { return m_frontCopperThickness3DU; }
|
||||
float GetBackCopperThickness() const noexcept { return m_backCopperThickness3DU; }
|
||||
float GetCopperThickness() const noexcept
|
||||
{
|
||||
return m_copperThickness3DU;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the hole plating thickness (NB: in BOARD UNITS!).
|
||||
* Get the current copper layer thickness.
|
||||
*
|
||||
* @return thickness in board units.
|
||||
*/
|
||||
int GetHolePlatingThickness() const noexcept;
|
||||
|
||||
@@ -161,21 +213,30 @@ public:
|
||||
*
|
||||
* @return size in BIU units.
|
||||
*/
|
||||
VECTOR2I GetBoardSize() const noexcept { return m_boardSize; }
|
||||
wxSize GetBoardSize() const noexcept
|
||||
{
|
||||
return m_boardSize;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the board center.
|
||||
*
|
||||
* @return position in BIU units.
|
||||
*/
|
||||
VECTOR2I GetBoardPos() const noexcept { return m_boardPos; }
|
||||
wxPoint GetBoardPos() const noexcept
|
||||
{
|
||||
return m_boardPos;
|
||||
}
|
||||
|
||||
/**
|
||||
* The board center position in 3D units.
|
||||
*
|
||||
* @return board center vector position in 3D units.
|
||||
*/
|
||||
const SFVEC3F& GetBoardCenter() const noexcept { return m_boardCenter; }
|
||||
const SFVEC3F& GetBoardCenter() const noexcept
|
||||
{
|
||||
return m_boardCenter;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the position of the footprint in 3d integer units considering if it is flipped or not.
|
||||
@@ -186,12 +247,81 @@ public:
|
||||
*/
|
||||
float GetFootprintZPos( bool aIsFlipped ) const ;
|
||||
|
||||
/**
|
||||
* Get the current grid.
|
||||
*
|
||||
* @return space type of the grid.
|
||||
*/
|
||||
GRID3D_TYPE GetGridType() const noexcept
|
||||
{
|
||||
return m_gridType;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the current grid.
|
||||
*
|
||||
* @param aGridType the type space of the grid.
|
||||
*/
|
||||
void SetGridType( GRID3D_TYPE aGridType ) noexcept
|
||||
{
|
||||
m_gridType = aGridType;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the current antialiasing mode value.
|
||||
*
|
||||
* @return antialiasing mode value
|
||||
*/
|
||||
ANTIALIASING_MODE GetAntiAliasingMode() const { return m_antiAliasingMode; }
|
||||
|
||||
/**
|
||||
* Set the current antialiasing mode value.
|
||||
*
|
||||
* @param aAAmode antialiasing mode value.
|
||||
*/
|
||||
void SetAntiAliasingMode( ANTIALIASING_MODE aAAmode ) { m_antiAliasingMode = aAAmode; }
|
||||
|
||||
/**
|
||||
* @param aRenderEngine the render engine mode selected.
|
||||
*/
|
||||
void SetRenderEngine( RENDER_ENGINE aRenderEngine ) noexcept
|
||||
{
|
||||
m_renderEngine = aRenderEngine;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return render engine on use.
|
||||
*/
|
||||
RENDER_ENGINE GetRenderEngine() const noexcept
|
||||
{
|
||||
return m_renderEngine;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param aMaterialMode the render material mode.
|
||||
*/
|
||||
void SetMaterialMode( MATERIAL_MODE aMaterialMode ) noexcept
|
||||
{
|
||||
m_materialMode = aMaterialMode;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return material rendering mode.
|
||||
*/
|
||||
MATERIAL_MODE GetMaterialMode() const noexcept
|
||||
{
|
||||
return m_materialMode;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the current polygon of the epoxy board.
|
||||
*
|
||||
* @return the shape polygon
|
||||
*/
|
||||
const SHAPE_POLY_SET& GetBoardPoly() const noexcept { return m_board_poly; }
|
||||
const SHAPE_POLY_SET& GetBoardPoly() const noexcept
|
||||
{
|
||||
return m_board_poly;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the technical color of a layer.
|
||||
@@ -215,8 +345,6 @@ public:
|
||||
*/
|
||||
SFVEC4F GetColor( const COLOR4D& aColor ) const;
|
||||
|
||||
SFVEC2F GetSphericalCoord( int i ) const;
|
||||
|
||||
/**
|
||||
* Get the top z position.
|
||||
*
|
||||
@@ -244,15 +372,50 @@ public:
|
||||
*
|
||||
* @return the map containers of this board.
|
||||
*/
|
||||
const MAP_CONTAINER_2D_BASE& GetLayerMap() const noexcept { return m_layerMap; }
|
||||
const BVH_CONTAINER_2D* GetPlatedPadsFront() const noexcept { return m_platedPadsFront; }
|
||||
const BVH_CONTAINER_2D* GetPlatedPadsBack() const noexcept { return m_platedPadsBack; }
|
||||
const BVH_CONTAINER_2D* GetOffboardPadsFront() const noexcept { return m_offboardPadsFront; }
|
||||
const BVH_CONTAINER_2D* GetOffboardPadsBack() const noexcept { return m_offboardPadsBack; }
|
||||
const MAP_CONTAINER_2D_BASE& GetLayerMap() const noexcept
|
||||
{
|
||||
return m_layerMap;
|
||||
}
|
||||
|
||||
const MAP_CONTAINER_2D_BASE& GetLayerHoleMap() const noexcept { return m_layerHoleMap; }
|
||||
const BVH_CONTAINER_2D& GetTH_IDs() const noexcept { return m_TH_IDs; }
|
||||
const BVH_CONTAINER_2D& GetTH_ODs() const noexcept { return m_TH_ODs; }
|
||||
const BVH_CONTAINER_2D* GetPlatedPadsFront() const noexcept
|
||||
{
|
||||
return m_platedPadsFront;
|
||||
}
|
||||
|
||||
const BVH_CONTAINER_2D* GetPlatedPadsBack() const noexcept
|
||||
{
|
||||
return m_platedPadsBack;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the map of container that have the holes per layer.
|
||||
*
|
||||
* @return the map containers of holes from this board.
|
||||
*/
|
||||
const MAP_CONTAINER_2D_BASE& GetLayerHoleMap() const noexcept
|
||||
{
|
||||
return m_layerHoleMap;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the inflated through hole outside diameters container.
|
||||
*
|
||||
* @return a container with holes.
|
||||
*/
|
||||
const BVH_CONTAINER_2D& GetThroughHoleOds() const noexcept
|
||||
{
|
||||
return m_throughHoleOds;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the through hole annular rings container.
|
||||
*
|
||||
* @return a container with through hole annular rings.
|
||||
*/
|
||||
const BVH_CONTAINER_2D& GetThroughHoleAnnularRings() const noexcept
|
||||
{
|
||||
return m_throughHoleAnnularRings;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get through hole outside diameter 2D polygons.
|
||||
@@ -261,56 +424,93 @@ public:
|
||||
*
|
||||
* @return a container with through hold outside diameter 2D polygons.
|
||||
*/
|
||||
const SHAPE_POLY_SET& GetTH_ODPolys() const noexcept
|
||||
const SHAPE_POLY_SET& GetThroughHoleOdPolys() const noexcept
|
||||
{
|
||||
return m_TH_ODPolys;
|
||||
return m_throughHoleOdPolys;
|
||||
}
|
||||
|
||||
const BVH_CONTAINER_2D& GetViaAnnuli() const noexcept
|
||||
const SHAPE_POLY_SET& GetThroughHoleAnnularRingPolys() const noexcept
|
||||
{
|
||||
return m_viaAnnuli;
|
||||
return m_throughHoleAnnularRingPolys;
|
||||
}
|
||||
|
||||
const SHAPE_POLY_SET& GetViaAnnuliPolys() const noexcept
|
||||
const SHAPE_POLY_SET& GetOuterNonPlatedThroughHolePoly() const noexcept
|
||||
{
|
||||
return m_viaAnnuliPolys;
|
||||
}
|
||||
|
||||
const SHAPE_POLY_SET& GetNPTH_ODPolys() const noexcept
|
||||
{
|
||||
return m_NPTH_ODPolys;
|
||||
return m_nonPlatedThroughHoleOdPolys;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return a container with through hole via hole outside diameters.
|
||||
*/
|
||||
const BVH_CONTAINER_2D& GetViaTH_ODs() const noexcept
|
||||
const BVH_CONTAINER_2D& GetThroughHoleViaOds() const noexcept
|
||||
{
|
||||
return m_viaTH_ODs;
|
||||
return m_throughHoleViaOds;
|
||||
}
|
||||
|
||||
const SHAPE_POLY_SET& GetViaTH_ODPolys() const noexcept
|
||||
const SHAPE_POLY_SET& GetThroughHoleViaOdPolys() const noexcept
|
||||
{
|
||||
return m_viaTH_ODPolys;
|
||||
return m_throughHoleViaOdPolys;
|
||||
}
|
||||
|
||||
unsigned int GetViaCount() const noexcept { return m_viaCount; }
|
||||
unsigned int GetHoleCount() const noexcept { return m_holeCount; }
|
||||
|
||||
/**
|
||||
* Get the through hole inner diameter container.
|
||||
*
|
||||
* @return a container with holes inner diameters.
|
||||
*/
|
||||
const BVH_CONTAINER_2D& GetThroughHoleIds() const noexcept
|
||||
{
|
||||
return m_throughHoleIds;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get number of vias in this board.
|
||||
*
|
||||
* @return number of vias.
|
||||
*/
|
||||
unsigned int GetViaCount() const noexcept
|
||||
{
|
||||
return m_viaCount;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get number of holes in this board.
|
||||
*
|
||||
* @return number of holes.
|
||||
*/
|
||||
unsigned int GetHoleCount() const noexcept
|
||||
{
|
||||
return m_holeCount;
|
||||
}
|
||||
|
||||
/**
|
||||
* Thee average diameter of the via holes.
|
||||
*
|
||||
* @return via hole average diameter dimension in 3D units.
|
||||
*/
|
||||
float GetAverageViaHoleDiameter() const noexcept { return m_averageViaHoleDiameter; }
|
||||
float GetAverageViaHoleDiameter() const noexcept
|
||||
{
|
||||
return m_averageViaHoleDiameter;
|
||||
}
|
||||
|
||||
/**
|
||||
* Average diameter of through holes.
|
||||
*
|
||||
* @return the average diameter of through holes in 3D units.
|
||||
*/
|
||||
float GetAverageHoleDiameter() const noexcept { return m_averageHoleDiameter; }
|
||||
float GetAverageHoleDiameter() const noexcept
|
||||
{
|
||||
return m_averageHoleDiameter;
|
||||
}
|
||||
|
||||
/**
|
||||
* Average width of the tracks.
|
||||
*
|
||||
* @return average track width in 3D units.
|
||||
*/
|
||||
float GetAverageTrackWidth() const noexcept { return m_averageTrackWidth; }
|
||||
float GetAverageTrackWidth() const noexcept
|
||||
{
|
||||
return m_averageTrackWidth;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param aDiameter3DU diameter in 3DU.
|
||||
@@ -329,12 +529,30 @@ public:
|
||||
*
|
||||
* @return the map with polygon's layers.
|
||||
*/
|
||||
const MAP_POLY& GetPolyMap() const noexcept { return m_layers_poly; }
|
||||
const MAP_POLY& GetPolyMap() const noexcept
|
||||
{
|
||||
return m_layers_poly;
|
||||
}
|
||||
|
||||
const SHAPE_POLY_SET* GetFrontPlatedPadAndGraphicPolys() { return m_frontPlatedPadAndGraphicPolys; }
|
||||
const SHAPE_POLY_SET* GetBackPlatedPadAndGraphicPolys() { return m_backPlatedPadAndGraphicPolys; }
|
||||
const MAP_POLY& GetHoleIdPolysMap() const noexcept { return m_layerHoleIdPolys; }
|
||||
const MAP_POLY& GetHoleOdPolysMap() const noexcept { return m_layerHoleOdPolys; }
|
||||
const SHAPE_POLY_SET* GetFrontPlatedPadPolys()
|
||||
{
|
||||
return m_frontPlatedPadPolys;
|
||||
}
|
||||
|
||||
const SHAPE_POLY_SET* GetBackPlatedPadPolys()
|
||||
{
|
||||
return m_backPlatedPadPolys;
|
||||
}
|
||||
|
||||
const MAP_POLY& GetHoleIdPolysMap() const noexcept
|
||||
{
|
||||
return m_layerHoleIdPolys;
|
||||
}
|
||||
|
||||
const MAP_POLY& GetHoleOdPolysMap() const noexcept
|
||||
{
|
||||
return m_layerHoleOdPolys;
|
||||
}
|
||||
|
||||
private:
|
||||
/**
|
||||
@@ -347,47 +565,51 @@ private:
|
||||
void destroyLayers();
|
||||
|
||||
// Helper functions to create the board
|
||||
void createViaWithMargin( const PCB_TRACK* aTrack, CONTAINER_2D_BASE* aDstContainer,
|
||||
int aMargin );
|
||||
void createTrack( const PCB_TRACK* aTrack, CONTAINER_2D_BASE* aDstContainer,
|
||||
int aClearanceValue );
|
||||
|
||||
void createTrack( const PCB_TRACK* aTrack, CONTAINER_2D_BASE* aDstContainer );
|
||||
void createPadWithClearance( const PAD *aPad, CONTAINER_2D_BASE* aDstContainer,
|
||||
PCB_LAYER_ID aLayer, const wxSize& aClearanceValue ) const;
|
||||
|
||||
void createPadWithMargin( const PAD *aPad, CONTAINER_2D_BASE* aDstContainer,
|
||||
PCB_LAYER_ID aLayer, const VECTOR2I& aMargin ) const;
|
||||
OBJECT_2D* createPadWithDrill( const PAD* aPad, int aInflateValue );
|
||||
|
||||
void createPadWithHole( const PAD* aPad, CONTAINER_2D_BASE* aDstContainer,
|
||||
int aInflateValue );
|
||||
void addPadsWithClearance( const FOOTPRINT* aFootprint, CONTAINER_2D_BASE* aDstContainer,
|
||||
PCB_LAYER_ID aLayerId, int aInflateValue,
|
||||
bool aSkipNPTHPadsWihNoCopper, bool aSkipPlatedPads,
|
||||
bool aSkipNonPlatedPads );
|
||||
|
||||
void addPads( const FOOTPRINT* aFootprint, CONTAINER_2D_BASE* aDstContainer,
|
||||
PCB_LAYER_ID aLayerId, bool aSkipPlatedPads, bool aSkipNonPlatedPads );
|
||||
void addFootprintShapesWithClearance( const FOOTPRINT* aFootprint,
|
||||
CONTAINER_2D_BASE* aDstContainer,
|
||||
PCB_LAYER_ID aLayerId, int aInflateValue );
|
||||
|
||||
void addFootprintShapes( const FOOTPRINT* aFootprint, CONTAINER_2D_BASE* aDstContainer,
|
||||
PCB_LAYER_ID aLayerId,
|
||||
const std::bitset<LAYER_3D_END>& aVisibilityFlags );
|
||||
void addShapeWithClearance( const PCB_TEXT* aText, CONTAINER_2D_BASE* aDstContainer,
|
||||
PCB_LAYER_ID aLayerId, int aClearanceValue );
|
||||
|
||||
void addText( const EDA_TEXT* aText, CONTAINER_2D_BASE* aDstContainer,
|
||||
const BOARD_ITEM* aOwner );
|
||||
void addShapeWithClearance( const PCB_SHAPE* aShape, CONTAINER_2D_BASE* aDstContainer,
|
||||
PCB_LAYER_ID aLayerId, int aClearanceValue );
|
||||
|
||||
void addShape( const PCB_SHAPE* aShape, CONTAINER_2D_BASE* aContainer,
|
||||
const BOARD_ITEM* aOwner );
|
||||
void addShapeWithClearance( const PCB_DIMENSION_BASE* aDimension,
|
||||
CONTAINER_2D_BASE* aDstContainer, PCB_LAYER_ID aLayerId,
|
||||
int aClearanceValue );
|
||||
|
||||
void addShape( const PCB_DIMENSION_BASE* aDimension, CONTAINER_2D_BASE* aDstContainer,
|
||||
const BOARD_ITEM* aOwner );
|
||||
|
||||
void addShape( const PCB_TEXTBOX* aTextBox, CONTAINER_2D_BASE* aContainer,
|
||||
const BOARD_ITEM* aOwner );
|
||||
|
||||
void addSolidAreasShapes( const ZONE* aZone, CONTAINER_2D_BASE* aDstContainer,
|
||||
void addSolidAreasShapes( const ZONE* aZoneContainer, CONTAINER_2D_BASE* aDstContainer,
|
||||
PCB_LAYER_ID aLayerId );
|
||||
|
||||
void createArcSegments( const VECTOR2I& aCentre, const VECTOR2I& aStart,
|
||||
const EDA_ANGLE& aArcAngle, int aCircleToSegmentsCount, int aWidth,
|
||||
CONTAINER_2D_BASE* aContainer, const BOARD_ITEM& aOwner );
|
||||
void transformArcToSegments( const wxPoint& aCentre, const wxPoint& aStart, double aArcAngle,
|
||||
int aCircleToSegmentsCount, int aWidth,
|
||||
CONTAINER_2D_BASE* aDstContainer, const BOARD_ITEM& aBoardItem );
|
||||
|
||||
void buildPadOutlineAsSegments( const PAD* aPad, CONTAINER_2D_BASE* aDstContainer, int aWidth );
|
||||
|
||||
// Helper functions to create poly contours
|
||||
void buildPadOutlineAsPolygon( const PAD* aPad, SHAPE_POLY_SET& aCornerBuffer,
|
||||
int aWidth) const;
|
||||
|
||||
void transformFPShapesToPolygon( const FOOTPRINT* aFootprint, PCB_LAYER_ID aLayer,
|
||||
SHAPE_POLY_SET& aCornerBuffer ) const;
|
||||
|
||||
public:
|
||||
static CUSTOM_COLORS_LIST g_SilkColors;
|
||||
static CUSTOM_COLORS_LIST g_SilkscreenColors;
|
||||
static CUSTOM_COLORS_LIST g_MaskColors;
|
||||
static CUSTOM_COLORS_LIST g_PasteColors;
|
||||
static CUSTOM_COLORS_LIST g_FinishColors;
|
||||
@@ -400,100 +622,154 @@ public:
|
||||
static KIGFX::COLOR4D g_DefaultSolderPaste;
|
||||
static KIGFX::COLOR4D g_DefaultSurfaceFinish;
|
||||
static KIGFX::COLOR4D g_DefaultBoardBody;
|
||||
static KIGFX::COLOR4D g_DefaultComments;
|
||||
static KIGFX::COLOR4D g_DefaultECOs;
|
||||
|
||||
public:
|
||||
EDA_3D_VIEWER_SETTINGS* m_Cfg;
|
||||
SFVEC4F m_BgColorBot; ///< background bottom color
|
||||
SFVEC4F m_BgColorTop; ///< background top color
|
||||
SFVEC4F m_BoardBodyColor; ///< in realistic mode: FR4 board color
|
||||
SFVEC4F m_SolderMaskColorBot; ///< in realistic mode: solder mask color ( bot )
|
||||
SFVEC4F m_SolderMaskColorTop; ///< in realistic mode: solder mask color ( top )
|
||||
SFVEC4F m_SolderPasteColor; ///< in realistic mode: solder paste color
|
||||
SFVEC4F m_SilkScreenColorBot; ///< in realistic mode: SilkScreen color ( bot )
|
||||
SFVEC4F m_SilkScreenColorTop; ///< in realistic mode: SilkScreen color ( top )
|
||||
SFVEC4F m_CopperColor; ///< in realistic mode: copper color
|
||||
|
||||
bool m_IsBoardView;
|
||||
bool m_MousewheelPanning;
|
||||
bool m_IsPreviewer; ///< true if we're in a 3D preview panel, false
|
||||
///< for the standard 3D viewer
|
||||
SFVEC3F m_OpenGlSelectionColor;
|
||||
|
||||
SFVEC4F m_BgColorBot; ///< background bottom color
|
||||
SFVEC4F m_BgColorTop; ///< background top color
|
||||
SFVEC4F m_BoardBodyColor; ///< in realistic mode: FR4 board color
|
||||
SFVEC4F m_SolderMaskColorBot; ///< in realistic mode: solder mask color ( bot )
|
||||
SFVEC4F m_SolderMaskColorTop; ///< in realistic mode: solder mask color ( top )
|
||||
SFVEC4F m_SolderPasteColor; ///< in realistic mode: solder paste color
|
||||
SFVEC4F m_SilkScreenColorBot; ///< in realistic mode: SilkScreen color ( bot )
|
||||
SFVEC4F m_SilkScreenColorTop; ///< in realistic mode: SilkScreen color ( top )
|
||||
SFVEC4F m_CopperColor; ///< in realistic mode: copper color
|
||||
SFVEC4F m_UserDrawingsColor;
|
||||
SFVEC4F m_UserCommentsColor;
|
||||
SFVEC4F m_ECO1Color;
|
||||
SFVEC4F m_ECO2Color;
|
||||
// Raytracing light colors
|
||||
SFVEC3F m_RtCameraLightColor;
|
||||
SFVEC3F m_RtLightColorTop;
|
||||
SFVEC3F m_RtLightColorBottom;
|
||||
|
||||
std::vector<SFVEC3F> m_RtLightColor;
|
||||
std::vector<SFVEC2F> m_RtLightSphericalCoords;
|
||||
|
||||
// Raytracing options
|
||||
int m_RtShadowSampleCount;
|
||||
int m_RtReflectionSampleCount;
|
||||
int m_RtRefractionSampleCount;
|
||||
int m_RtRecursiveReflectionCount;
|
||||
int m_RtRecursiveRefractionCount;
|
||||
|
||||
float m_RtSpreadShadows;
|
||||
float m_RtSpreadReflections;
|
||||
float m_RtSpreadRefractions;
|
||||
|
||||
private:
|
||||
BOARD* m_board;
|
||||
S3D_CACHE* m_3dModelManager;
|
||||
COLOR_SETTINGS* m_colors;
|
||||
BOARD* m_board;
|
||||
S3D_CACHE* m_3dModelManager;
|
||||
COLOR_SETTINGS* m_colors;
|
||||
|
||||
VECTOR2I m_boardPos; ///< Board center position in board internal units.
|
||||
VECTOR2I m_boardSize; ///< Board size in board internal units.
|
||||
SFVEC3F m_boardCenter; ///< 3D center position of the board in 3D units.
|
||||
BBOX_3D m_boardBoundingBox; ///< 3D bounding box of the board in 3D units.
|
||||
std::vector< bool > m_drawFlags;
|
||||
GRID3D_TYPE m_gridType;
|
||||
RENDER_ENGINE m_renderEngine;
|
||||
MATERIAL_MODE m_materialMode;
|
||||
ANTIALIASING_MODE m_antiAliasingMode;
|
||||
|
||||
MAP_POLY m_layers_poly; ///< Amalgamated polygon contours for various types
|
||||
///< of items
|
||||
|
||||
SHAPE_POLY_SET* m_frontPlatedPadAndGraphicPolys;
|
||||
SHAPE_POLY_SET* m_backPlatedPadAndGraphicPolys;
|
||||
SHAPE_POLY_SET* m_frontPlatedCopperPolys;
|
||||
SHAPE_POLY_SET* m_backPlatedCopperPolys;
|
||||
wxPoint m_boardPos; ///< Board center position in board internal units.
|
||||
wxSize m_boardSize; ///< Board size in board internal units.
|
||||
SFVEC3F m_boardCenter; ///< 3D center position of the board in 3D units.
|
||||
BBOX_3D m_boardBoundingBox; ///< 3D bounding box of the board in 3D units.
|
||||
|
||||
MAP_POLY m_layerHoleOdPolys; ///< Hole outer diameters (per layer)
|
||||
MAP_POLY m_layerHoleIdPolys; ///< Hole inner diameters (per layer)
|
||||
|
||||
SHAPE_POLY_SET m_NPTH_ODPolys; ///< NPTH outer diameters
|
||||
SHAPE_POLY_SET m_TH_ODPolys; ///< PTH outer diameters
|
||||
SHAPE_POLY_SET m_viaTH_ODPolys; ///< Via hole outer diameters
|
||||
SHAPE_POLY_SET m_viaAnnuliPolys; ///< Via annular ring outer diameters
|
||||
///< Polygon contours for each layer.
|
||||
MAP_POLY m_layers_poly;
|
||||
|
||||
SHAPE_POLY_SET m_board_poly; ///< Board outline polygon.
|
||||
SHAPE_POLY_SET* m_frontPlatedPadPolys;
|
||||
SHAPE_POLY_SET* m_backPlatedPadPolys;
|
||||
|
||||
///< Polygon contours for hole outer diameters for each layer.
|
||||
MAP_POLY m_layerHoleOdPolys;
|
||||
|
||||
///< Polygon contours for hole inner diameters for each layer.
|
||||
MAP_POLY m_layerHoleIdPolys;
|
||||
|
||||
///< Polygon contours for non plated through hole outer diameters.
|
||||
SHAPE_POLY_SET m_nonPlatedThroughHoleOdPolys;
|
||||
|
||||
///< Polygon contours for through hole outer diameters.
|
||||
SHAPE_POLY_SET m_throughHoleOdPolys;
|
||||
|
||||
///< Polygon contours for through holes via outer diameters.
|
||||
SHAPE_POLY_SET m_throughHoleViaOdPolys;
|
||||
|
||||
///< Polygon contours for through hole via annular rings.
|
||||
SHAPE_POLY_SET m_throughHoleAnnularRingPolys;
|
||||
|
||||
SHAPE_POLY_SET m_board_poly; ///< Board outline polygon.
|
||||
|
||||
MAP_CONTAINER_2D_BASE m_layerMap; ///< 2D elements for each layer.
|
||||
|
||||
MAP_CONTAINER_2D_BASE m_layerMap; ///< 2D elements for each layer.
|
||||
MAP_CONTAINER_2D_BASE m_layerHoleMap; ///< Holes for each layer.
|
||||
|
||||
BVH_CONTAINER_2D* m_platedPadsFront;
|
||||
BVH_CONTAINER_2D* m_platedPadsBack;
|
||||
BVH_CONTAINER_2D* m_offboardPadsFront;
|
||||
BVH_CONTAINER_2D* m_offboardPadsBack;
|
||||
|
||||
BVH_CONTAINER_2D m_TH_ODs; ///< List of PTH outer diameters
|
||||
BVH_CONTAINER_2D m_TH_IDs; ///< List of PTH inner diameters
|
||||
BVH_CONTAINER_2D m_viaAnnuli; ///< List of via annular rings
|
||||
BVH_CONTAINER_2D m_viaTH_ODs; ///< List of via hole outer diameters
|
||||
///< The holes per each layer.
|
||||
MAP_CONTAINER_2D_BASE m_layerHoleMap;
|
||||
|
||||
unsigned int m_copperLayersCount;
|
||||
///< List of through holes with the radius of the hole inflated with the copper thickness.
|
||||
BVH_CONTAINER_2D m_throughHoleOds;
|
||||
|
||||
double m_biuTo3Dunits; ///< Scale factor to convert board internal units
|
||||
///< to 3D units normalized between -1.0 and 1.0.
|
||||
///< List of plated through hole annular rings.
|
||||
BVH_CONTAINER_2D m_throughHoleAnnularRings;
|
||||
|
||||
std::array<float, PCB_LAYER_ID_COUNT> m_layerZcoordTop; ///< Top (End) Z position of each
|
||||
///< layer in 3D units.
|
||||
///< List of through hole inner diameters.
|
||||
BVH_CONTAINER_2D m_throughHoleIds;
|
||||
|
||||
std::array<float, PCB_LAYER_ID_COUNT> m_layerZcoordBottom; ///< Bottom (Start) Z position of
|
||||
///< each layer in 3D units.
|
||||
///< List of through hole vias with the radius of the hole inflated with the copper thickness.
|
||||
BVH_CONTAINER_2D m_throughHoleViaOds;
|
||||
|
||||
float m_frontCopperThickness3DU;
|
||||
float m_backCopperThickness3DU;
|
||||
float m_boardBodyThickness3DU;
|
||||
float m_nonCopperLayerThickness3DU;
|
||||
float m_solderPasteLayerThickness3DU;
|
||||
///< List of through hole via inner diameters.
|
||||
BVH_CONTAINER_2D m_throughHoleViaIds;
|
||||
|
||||
unsigned int m_trackCount;
|
||||
float m_averageTrackWidth;
|
||||
unsigned int m_viaCount;
|
||||
float m_averageViaHoleDiameter;
|
||||
unsigned int m_holeCount;
|
||||
float m_averageHoleDiameter;
|
||||
///< Number of copper layers actually used by the board.
|
||||
unsigned int m_copperLayersCount;
|
||||
|
||||
///< Scale factor to convert board internal units to 3D units normalized between -1.0 and 1.0.
|
||||
double m_biuTo3Dunits;
|
||||
|
||||
///< Top (End) Z position of each layer in 3D units.
|
||||
std::array<float, PCB_LAYER_ID_COUNT> m_layerZcoordTop;
|
||||
|
||||
///< Bottom (Start) Z position of each layer in 3D units.
|
||||
std::array<float, PCB_LAYER_ID_COUNT> m_layerZcoordBottom;
|
||||
|
||||
///< Copper thickness in 3D units.
|
||||
float m_copperThickness3DU;
|
||||
|
||||
///< Epoxy thickness in 3D units.
|
||||
float m_epoxyThickness3DU;
|
||||
|
||||
///< Non copper layers thickness in 3D units.
|
||||
float m_nonCopperLayerThickness3DU;
|
||||
|
||||
///< solder paste layers thickness in 3D units.
|
||||
float m_solderPasteLayerThickness3DU;
|
||||
|
||||
///< Number of tracks in the board.
|
||||
unsigned int m_trackCount;
|
||||
|
||||
///< Track average width.
|
||||
float m_averageTrackWidth;
|
||||
|
||||
///< Number of through hole vias in the board.
|
||||
unsigned int m_viaCount;
|
||||
|
||||
///< Computed average diameter of the via holes in 3D units.
|
||||
float m_averageViaHoleDiameter;
|
||||
|
||||
///< Number of holes in the board.
|
||||
unsigned int m_holeCount;
|
||||
|
||||
///< Computed average diameter of the holes in 3D units.
|
||||
float m_averageHoleDiameter;
|
||||
|
||||
/**
|
||||
* Trace mask used to enable or disable debug output for this class. Output can be turned
|
||||
* on by setting the WXTRACE environment variable to "KI_TRACE_EDA_CINFO3D_VISU". See the
|
||||
* wxWidgets documentation on wxLogTrace for more information.
|
||||
* Trace mask used to enable or disable the trace output of this class.
|
||||
* The debug output can be turned on by setting the WXTRACE environment variable to
|
||||
* "KI_TRACE_EDA_CINFO3D_VISU". See the wxWidgets documentation on wxLogTrace for
|
||||
* more information.
|
||||
*/
|
||||
static const wxChar* m_logTrace;
|
||||
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,78 @@
|
||||
/*
|
||||
* This program source code file is part of KiCad, a free EDA CAD application.
|
||||
*
|
||||
* Copyright (C) 2015-2016 Mario Luzeiro <mrluzeiro@ua.pt>
|
||||
* Copyright (C) 1992-2020 KiCad Developers, see AUTHORS.txt for contributors.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; either version 2
|
||||
* of the License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, you may find one here:
|
||||
* http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
|
||||
* or you may search the http://www.gnu.org website for the version 2 license,
|
||||
* or you may write to the Free Software Foundation, Inc.,
|
||||
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
|
||||
*/
|
||||
|
||||
/**
|
||||
* @file create_layer_poly.cpp
|
||||
* @brief This file implements the creation of the pcb board items in the poly
|
||||
* contours format.
|
||||
*/
|
||||
|
||||
#include "board_adapter.h"
|
||||
#include <convert_basic_shapes_to_polygon.h>
|
||||
#include <fp_shape.h>
|
||||
#include <footprint.h>
|
||||
|
||||
|
||||
void BOARD_ADAPTER::buildPadOutlineAsPolygon( const PAD* aPad, SHAPE_POLY_SET& aCornerBuffer,
|
||||
int aWidth ) const
|
||||
{
|
||||
if( aPad->GetShape() == PAD_SHAPE::CIRCLE ) // Draw a ring
|
||||
{
|
||||
TransformRingToPolygon( aCornerBuffer, aPad->ShapePos(), aPad->GetSize().x / 2,
|
||||
aWidth, ARC_HIGH_DEF, ERROR_INSIDE );
|
||||
return;
|
||||
}
|
||||
|
||||
// For other shapes, add outlines as thick segments in polygon buffer
|
||||
const std::shared_ptr<SHAPE_POLY_SET>& corners = aPad->GetEffectivePolygon();
|
||||
const SHAPE_LINE_CHAIN& path = corners->COutline( 0 );
|
||||
|
||||
for( int ii = 0; ii < path.PointCount(); ++ii )
|
||||
{
|
||||
const VECTOR2I& a = path.CPoint( ii );
|
||||
const VECTOR2I& b = path.CPoint( ii + 1 );
|
||||
|
||||
TransformOvalToPolygon( aCornerBuffer, (wxPoint) a, (wxPoint) b, aWidth, ARC_HIGH_DEF,
|
||||
ERROR_INSIDE );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void BOARD_ADAPTER::transformFPShapesToPolygon( const FOOTPRINT* aFootprint, PCB_LAYER_ID aLayer,
|
||||
SHAPE_POLY_SET& aCornerBuffer ) const
|
||||
{
|
||||
for( BOARD_ITEM* item : aFootprint->GraphicalItems() )
|
||||
{
|
||||
if( item->Type() == PCB_FP_SHAPE_T )
|
||||
{
|
||||
FP_SHAPE* outline = (FP_SHAPE*) item;
|
||||
|
||||
if( outline->GetLayer() == aLayer )
|
||||
{
|
||||
outline->TransformShapeWithClearanceToPolygon( aCornerBuffer, aLayer, 0,
|
||||
ARC_HIGH_DEF, ERROR_INSIDE );
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -2,7 +2,7 @@
|
||||
* This program source code file is part of KiCad, a free EDA CAD application.
|
||||
*
|
||||
* Copyright (C) 2015-2016 Mario Luzeiro <mrluzeiro@ua.pt>
|
||||
* Copyright (C) 1992-2024 KiCad Developers, see AUTHORS.txt for contributors.
|
||||
* Copyright (C) 1992-2021 KiCad Developers, see AUTHORS.txt for contributors.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
@@ -23,7 +23,7 @@
|
||||
*/
|
||||
|
||||
#include <gal/opengl/kiglew.h> // Must be included first
|
||||
#include <gal/opengl/gl_utils.h>
|
||||
#include <gl_utils.h>
|
||||
#include <wx/tokenzr.h>
|
||||
|
||||
#include "../common_ogl/ogl_utils.h"
|
||||
@@ -32,13 +32,13 @@
|
||||
#include <3d_rendering/raytracing/render_3d_raytrace.h>
|
||||
#include <3d_rendering/opengl/render_3d_opengl.h>
|
||||
#include <3d_viewer_id.h>
|
||||
#include <advanced_config.h>
|
||||
#include <board.h>
|
||||
#include <reporter.h>
|
||||
#include <gal/opengl/gl_context_mgr.h>
|
||||
#include <core/profile.h> // To use GetRunningMicroSecs or another profiling utility
|
||||
#include <gl_context_mgr.h>
|
||||
#include <profile.h> // To use GetRunningMicroSecs or another profiling utility
|
||||
#include <bitmaps.h>
|
||||
#include <macros.h>
|
||||
#include <menus_helpers.h>
|
||||
#include <pgm_base.h>
|
||||
#include <settings/settings_manager.h>
|
||||
#include <tool/tool_dispatcher.h>
|
||||
@@ -55,12 +55,14 @@
|
||||
*/
|
||||
const wxChar* EDA_3D_CANVAS::m_logTrace = wxT( "KI_TRACE_EDA_3D_CANVAS" );
|
||||
|
||||
const float EDA_3D_CANVAS::m_delta_move_step_factor = 0.7f;
|
||||
|
||||
|
||||
// A custom event, used to call DoRePaint during an idle time
|
||||
wxDEFINE_EVENT( wxEVT_REFRESH_CUSTOM_COMMAND, wxEvent );
|
||||
wxDEFINE_EVENT( wxEVT_REFRESH_CUSTOM_COMMAND, wxEvent);
|
||||
|
||||
|
||||
BEGIN_EVENT_TABLE( EDA_3D_CANVAS, HIDPI_GL_3D_CANVAS )
|
||||
BEGIN_EVENT_TABLE( EDA_3D_CANVAS, wxGLCanvas )
|
||||
EVT_PAINT( EDA_3D_CANVAS::OnPaint )
|
||||
|
||||
// mouse events
|
||||
@@ -70,10 +72,14 @@ BEGIN_EVENT_TABLE( EDA_3D_CANVAS, HIDPI_GL_3D_CANVAS )
|
||||
EVT_MIDDLE_DOWN( EDA_3D_CANVAS::OnMiddleDown)
|
||||
EVT_MOUSEWHEEL( EDA_3D_CANVAS::OnMouseWheel )
|
||||
EVT_MOTION( EDA_3D_CANVAS::OnMouseMove )
|
||||
|
||||
#if wxCHECK_VERSION( 3, 1, 0 ) || defined( USE_OSX_MAGNIFY_EVENT )
|
||||
EVT_MAGNIFY( EDA_3D_CANVAS::OnMagnify )
|
||||
#endif
|
||||
|
||||
// other events
|
||||
EVT_ERASE_BACKGROUND( EDA_3D_CANVAS::OnEraseBackground )
|
||||
//EVT_REFRESH_CUSTOM_COMMAND( ID_CUSTOM_EVENT_1, EDA_3D_CANVAS::OnRefreshRequest )
|
||||
EVT_CUSTOM(wxEVT_REFRESH_CUSTOM_COMMAND, ID_CUSTOM_EVENT_1, EDA_3D_CANVAS::OnRefreshRequest )
|
||||
|
||||
EVT_CLOSE( EDA_3D_CANVAS::OnCloseWindow )
|
||||
@@ -83,29 +89,30 @@ END_EVENT_TABLE()
|
||||
|
||||
EDA_3D_CANVAS::EDA_3D_CANVAS( wxWindow* aParent, const int* aAttribList,
|
||||
BOARD_ADAPTER& aBoardAdapter, CAMERA& aCamera,
|
||||
S3D_CACHE* a3DCachePointer ) :
|
||||
HIDPI_GL_3D_CANVAS( EDA_DRAW_PANEL_GAL::GetVcSettings(), aCamera, aParent, wxID_ANY,
|
||||
aAttribList, wxDefaultPosition,
|
||||
wxDefaultSize, wxFULL_REPAINT_ON_RESIZE ),
|
||||
m_eventDispatcher( nullptr ),
|
||||
m_parentStatusBar( nullptr ),
|
||||
m_parentInfoBar( nullptr ),
|
||||
m_glRC( nullptr ),
|
||||
m_is_opengl_initialized( false ),
|
||||
m_is_opengl_version_supported( true ),
|
||||
m_editing_timeout_timer( this, wxID_HIGHEST + 1 ),
|
||||
m_redraw_trigger_timer( this, wxID_HIGHEST + 2 ),
|
||||
m_render_pivot( false ),
|
||||
m_camera_moving_speed( 1.0f ),
|
||||
m_strtime_camera_movement( 0 ),
|
||||
m_animation_enabled( true ),
|
||||
m_moving_speed_multiplier( 3 ),
|
||||
m_boardAdapter( aBoardAdapter ),
|
||||
m_3d_render( nullptr ),
|
||||
m_opengl_supports_raytracing( true ),
|
||||
m_render_raytracing_was_requested( false ),
|
||||
m_accelerator3DShapes( nullptr ),
|
||||
m_currentRollOverItem( nullptr )
|
||||
S3D_CACHE* a3DCachePointer )
|
||||
: HIDPI_GL_CANVAS( aParent, wxID_ANY, aAttribList, wxDefaultPosition, wxDefaultSize,
|
||||
wxFULL_REPAINT_ON_RESIZE ),
|
||||
m_eventDispatcher( nullptr ),
|
||||
m_parentStatusBar( nullptr ),
|
||||
m_parentInfoBar( nullptr ),
|
||||
m_glRC( nullptr ),
|
||||
m_is_opengl_initialized( false ),
|
||||
m_is_opengl_version_supported( true ),
|
||||
m_mouse_is_moving( false ),
|
||||
m_mouse_was_moved( false ),
|
||||
m_camera_is_moving( false ),
|
||||
m_render_pivot( false ),
|
||||
m_camera_moving_speed( 1.0f ),
|
||||
m_strtime_camera_movement( 0 ),
|
||||
m_animation_enabled( true ),
|
||||
m_moving_speed_multiplier( 3 ),
|
||||
m_boardAdapter( aBoardAdapter ),
|
||||
m_camera( aCamera ),
|
||||
m_3d_render( nullptr ),
|
||||
m_opengl_supports_raytracing( true ),
|
||||
m_render_raytracing_was_requested( false ),
|
||||
m_accelerator3DShapes( nullptr ),
|
||||
m_currentRollOverItem( nullptr )
|
||||
{
|
||||
wxLogTrace( m_logTrace, wxT( "EDA_3D_CANVAS::EDA_3D_CANVAS" ) );
|
||||
|
||||
@@ -125,20 +132,14 @@ EDA_3D_CANVAS::EDA_3D_CANVAS( wxWindow* aParent, const int* aAttribList,
|
||||
wxASSERT( m_3d_render_raytracing != nullptr );
|
||||
wxASSERT( m_3d_render_opengl != nullptr );
|
||||
|
||||
auto busy_indicator_factory =
|
||||
[]()
|
||||
{
|
||||
return std::make_unique<WX_BUSY_INDICATOR>();
|
||||
};
|
||||
auto busy_indicator_factory = []() { return std::make_unique<WX_BUSY_INDICATOR>(); };
|
||||
|
||||
m_3d_render_raytracing->SetBusyIndicatorFactory( busy_indicator_factory );
|
||||
m_3d_render_opengl->SetBusyIndicatorFactory( busy_indicator_factory );
|
||||
|
||||
// We always start with the opengl engine (raytracing is avoided due to very
|
||||
// long calculation time)
|
||||
m_3d_render = m_3d_render_opengl;
|
||||
RenderEngineChanged();
|
||||
|
||||
m_boardAdapter.ReloadColorSettings();
|
||||
m_boardAdapter.SetColorSettings( Pgm().GetSettingsManager().GetColorSettings() );
|
||||
|
||||
wxASSERT( a3DCachePointer != nullptr );
|
||||
m_boardAdapter.Set3dCacheManager( a3DCachePointer );
|
||||
@@ -153,7 +154,9 @@ EDA_3D_CANVAS::EDA_3D_CANVAS( wxWindow* aParent, const int* aAttribList,
|
||||
wxEVT_RIGHT_UP, wxEVT_RIGHT_DOWN, wxEVT_RIGHT_DCLICK,
|
||||
wxEVT_MIDDLE_UP, wxEVT_MIDDLE_DOWN, wxEVT_MIDDLE_DCLICK,
|
||||
wxEVT_MOTION, wxEVT_MOUSEWHEEL, wxEVT_CHAR, wxEVT_CHAR_HOOK,
|
||||
#if wxCHECK_VERSION( 3, 1, 0 ) || defined( USE_OSX_MAGNIFY_EVENT )
|
||||
wxEVT_MAGNIFY,
|
||||
#endif
|
||||
wxEVT_MENU_OPEN, wxEVT_MENU_CLOSE, wxEVT_MENU_HIGHLIGHT
|
||||
};
|
||||
|
||||
@@ -205,7 +208,7 @@ void EDA_3D_CANVAS::OnCloseWindow( wxCloseEvent& event )
|
||||
|
||||
void EDA_3D_CANVAS::OnResize( wxSizeEvent& event )
|
||||
{
|
||||
Request_refresh();
|
||||
this->Request_refresh();
|
||||
}
|
||||
|
||||
|
||||
@@ -226,10 +229,10 @@ bool EDA_3D_CANVAS::initializeOpenGL()
|
||||
else
|
||||
{
|
||||
wxLogTrace( m_logTrace, wxT( "EDA_3D_CANVAS::initializeOpenGL Using GLEW version %s" ),
|
||||
From_UTF8( (char*) glewGetString( GLEW_VERSION ) ) );
|
||||
FROM_UTF8( (char*) glewGetString( GLEW_VERSION ) ) );
|
||||
}
|
||||
|
||||
wxString version = From_UTF8( (char *) glGetString( GL_VERSION ) );
|
||||
wxString version = FROM_UTF8( (char *) glGetString( GL_VERSION ) );
|
||||
|
||||
wxLogTrace( m_logTrace, wxT( "EDA_3D_CANVAS::%s OpenGL version string %s." ),
|
||||
__WXFUNCTION__, version );
|
||||
@@ -299,7 +302,7 @@ void EDA_3D_CANVAS::ReloadRequest( BOARD* aBoard , S3D_CACHE* aCachePointer )
|
||||
if( aBoard != nullptr )
|
||||
m_boardAdapter.SetBoard( aBoard );
|
||||
|
||||
m_boardAdapter.ReloadColorSettings();
|
||||
m_boardAdapter.SetColorSettings( Pgm().GetSettingsManager().GetColorSettings() );
|
||||
|
||||
if( m_3d_render )
|
||||
m_3d_render->ReloadRequest();
|
||||
@@ -330,9 +333,6 @@ void EDA_3D_CANVAS::DisplayStatus()
|
||||
|
||||
msg.Printf( wxT( "dy %3.2f" ), m_camera.GetCameraPos().y );
|
||||
m_parentStatusBar->SetStatusText( msg, static_cast<int>( EDA_3D_VIEWER_STATUSBAR::Y_POS ) );
|
||||
|
||||
msg.Printf( wxT( "zoom %3.2f" ), 1 / m_camera.GetZoom() );
|
||||
m_parentStatusBar->SetStatusText( msg, static_cast<int>( EDA_3D_VIEWER_STATUSBAR::ZOOM_LEVEL ) );
|
||||
}
|
||||
}
|
||||
|
||||
@@ -363,13 +363,17 @@ void EDA_3D_CANVAS::DoRePaint()
|
||||
// therefore with invalid board.
|
||||
// This is dependent of the platform.
|
||||
// Especially on OSX, but also on Windows, it frequently happens
|
||||
if( !GetParent()->GetParent()->IsShownOnScreen() )
|
||||
if( !GetParent()->GetParent()->IsShown() )
|
||||
return; // The parent board editor frame is no more alive
|
||||
|
||||
wxString err_messages;
|
||||
wxString err_messages;
|
||||
|
||||
// !TODO: implement error reporter
|
||||
INFOBAR_REPORTER warningReporter( m_parentInfoBar );
|
||||
STATUSBAR_REPORTER activityReporter( m_parentStatusBar, EDA_3D_VIEWER_STATUSBAR::ACTIVITY );
|
||||
int64_t start_time = GetRunningMicroSecs();
|
||||
STATUSBAR_REPORTER activityReporter( m_parentStatusBar,
|
||||
(int) EDA_3D_VIEWER_STATUSBAR::ACTIVITY );
|
||||
|
||||
unsigned strtime = GetRunningMicroSecs();
|
||||
|
||||
// "Makes the OpenGL state that is represented by the OpenGL rendering
|
||||
// context context current, i.e. it will be used by all subsequent OpenGL calls.
|
||||
@@ -379,15 +383,6 @@ void EDA_3D_CANVAS::DoRePaint()
|
||||
if( m_glRC == nullptr )
|
||||
m_glRC = GL_CONTEXT_MANAGER::Get().CreateCtx( this );
|
||||
|
||||
// CreateCtx could and does fail per sentry crash events, lets be graceful
|
||||
if( m_glRC == nullptr )
|
||||
{
|
||||
warningReporter.Report( _( "OpenGL context creation error" ), RPT_SEVERITY_ERROR );
|
||||
warningReporter.Finalize();
|
||||
m_is_currently_painting.clear();
|
||||
return;
|
||||
}
|
||||
|
||||
GL_CONTEXT_MANAGER::Get().LockCtx( m_glRC, this );
|
||||
|
||||
// Set the OpenGL viewport according to the client size of this canvas.
|
||||
@@ -438,11 +433,11 @@ void EDA_3D_CANVAS::DoRePaint()
|
||||
{
|
||||
m_3d_render = m_3d_render_opengl;
|
||||
m_render_raytracing_was_requested = false;
|
||||
m_boardAdapter.m_Cfg->m_Render.engine = RENDER_ENGINE::OPENGL;
|
||||
m_boardAdapter.SetRenderEngine( RENDER_ENGINE::OPENGL );
|
||||
}
|
||||
|
||||
// Check if a raytacing was requested and need to switch to raytracing mode
|
||||
if( m_boardAdapter.m_Cfg->m_Render.engine == RENDER_ENGINE::OPENGL )
|
||||
if( m_boardAdapter.GetRenderEngine() == RENDER_ENGINE::OPENGL )
|
||||
{
|
||||
const bool was_camera_changed = m_camera.ParametersChanged();
|
||||
|
||||
@@ -461,7 +456,7 @@ void EDA_3D_CANVAS::DoRePaint()
|
||||
|
||||
if( m_camera_is_moving )
|
||||
{
|
||||
const int64_t curtime_delta = GetRunningMicroSecs() - m_strtime_camera_movement;
|
||||
const unsigned curtime_delta = GetRunningMicroSecs() - m_strtime_camera_movement;
|
||||
curtime_delta_s = (curtime_delta / 1e6) * m_camera_moving_speed;
|
||||
m_camera.Interpolate( curtime_delta_s );
|
||||
|
||||
@@ -491,7 +486,7 @@ void EDA_3D_CANVAS::DoRePaint()
|
||||
|
||||
bool reloadRaytracingForCalculations = false;
|
||||
|
||||
if( m_boardAdapter.m_Cfg->m_Render.engine == RENDER_ENGINE::OPENGL
|
||||
if( m_boardAdapter.GetRenderEngine() == RENDER_ENGINE::OPENGL
|
||||
&& m_3d_render_opengl->IsReloadRequestPending() )
|
||||
{
|
||||
reloadRaytracingForCalculations = true;
|
||||
@@ -527,14 +522,6 @@ void EDA_3D_CANVAS::DoRePaint()
|
||||
render_pivot( curtime_delta_s, scale );
|
||||
}
|
||||
|
||||
// This will only be enabled by the 3d mouse plugin, so we can leave
|
||||
// it as a simple if statement
|
||||
if( m_render3dmousePivot )
|
||||
{
|
||||
const float scale = glm::min( m_camera.GetZoom(), 1.0f );
|
||||
render3dmousePivot( scale );
|
||||
}
|
||||
|
||||
// "Swaps the double-buffer of this window, making the back-buffer the
|
||||
// front-buffer and vice versa, so that the output of the previous OpenGL
|
||||
// commands is displayed on the window."
|
||||
@@ -542,13 +529,16 @@ void EDA_3D_CANVAS::DoRePaint()
|
||||
|
||||
GL_CONTEXT_MANAGER::Get().UnlockCtx( m_glRC );
|
||||
|
||||
if( m_mouse_was_moved || m_camera_is_moving )
|
||||
if( !activityReporter.HasMessage() )
|
||||
{
|
||||
// Calculation time in milliseconds
|
||||
const double calculation_time = (double)( GetRunningMicroSecs() - start_time ) / 1e3;
|
||||
if( m_mouse_was_moved || m_camera_is_moving )
|
||||
{
|
||||
// Calculation time in milliseconds
|
||||
const double calculation_time = (double)( GetRunningMicroSecs() - strtime) / 1e3;
|
||||
|
||||
activityReporter.Report( wxString::Format( _( "Last render time %.0f ms" ),
|
||||
calculation_time ) );
|
||||
activityReporter.Report( wxString::Format( _( "Last render time %.0f ms" ),
|
||||
calculation_time ) );
|
||||
}
|
||||
}
|
||||
|
||||
// This will reset the flag of camera parameters changed
|
||||
@@ -595,19 +585,72 @@ void EDA_3D_CANVAS::OnEraseBackground( wxEraseEvent& event )
|
||||
|
||||
void EDA_3D_CANVAS::OnMouseWheel( wxMouseEvent& event )
|
||||
{
|
||||
bool mouseActivity = false;
|
||||
|
||||
wxLogTrace( m_logTrace, wxT( "EDA_3D_CANVAS::OnMouseWheel" ) );
|
||||
|
||||
OnMouseWheelCamera( event, m_boardAdapter.m_MousewheelPanning );
|
||||
if( m_camera_is_moving )
|
||||
return;
|
||||
|
||||
if( m_mouse_was_moved )
|
||||
float delta_move = m_delta_move_step_factor * m_camera.GetZoom();
|
||||
|
||||
if( m_boardAdapter.GetFlag( FL_MOUSEWHEEL_PANNING ) )
|
||||
delta_move *= 0.01f * event.GetWheelRotation();
|
||||
else
|
||||
if( event.GetWheelRotation() < 0 )
|
||||
delta_move = -delta_move;
|
||||
|
||||
// mousewheel_panning enabled:
|
||||
// wheel -> pan;
|
||||
// wheel + shift -> horizontal scrolling;
|
||||
// wheel + ctrl -> zooming;
|
||||
// mousewheel_panning disabled:
|
||||
// wheel + shift -> vertical scrolling;
|
||||
// wheel + ctrl -> horizontal scrolling;
|
||||
// wheel -> zooming.
|
||||
|
||||
if( m_boardAdapter.GetFlag( FL_MOUSEWHEEL_PANNING ) && !event.ControlDown() )
|
||||
{
|
||||
if( event.GetWheelAxis() == wxMOUSE_WHEEL_HORIZONTAL || event.ShiftDown() )
|
||||
m_camera.Pan( SFVEC3F( -delta_move, 0.0f, 0.0f ) );
|
||||
else
|
||||
m_camera.Pan( SFVEC3F( 0.0f, -delta_move, 0.0f ) );
|
||||
|
||||
mouseActivity = true;
|
||||
}
|
||||
else if( event.ShiftDown() && !m_boardAdapter.GetFlag( FL_MOUSEWHEEL_PANNING ) )
|
||||
{
|
||||
m_camera.Pan( SFVEC3F( 0.0f, -delta_move, 0.0f ) );
|
||||
mouseActivity = true;
|
||||
}
|
||||
else if( event.ControlDown() && !m_boardAdapter.GetFlag( FL_MOUSEWHEEL_PANNING ) )
|
||||
{
|
||||
m_camera.Pan( SFVEC3F( delta_move, 0.0f, 0.0f ) );
|
||||
mouseActivity = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
mouseActivity = m_camera.Zoom( event.GetWheelRotation() > 0 ? 1.1f : 1/1.1f );
|
||||
}
|
||||
|
||||
// If it results on a camera movement
|
||||
if( mouseActivity )
|
||||
{
|
||||
DisplayStatus();
|
||||
Request_refresh();
|
||||
|
||||
m_mouse_is_moving = true;
|
||||
m_mouse_was_moved = true;
|
||||
|
||||
restart_editingTimeOut_Timer();
|
||||
}
|
||||
|
||||
// Update the cursor current mouse position on the camera
|
||||
m_camera.SetCurMousePosition( GetNativePosition( event.GetPosition() ) );
|
||||
}
|
||||
|
||||
|
||||
#if wxCHECK_VERSION( 3, 1, 0 ) || defined( USE_OSX_MAGNIFY_EVENT )
|
||||
void EDA_3D_CANVAS::OnMagnify( wxMouseEvent& event )
|
||||
{
|
||||
SetFocus();
|
||||
@@ -625,44 +668,49 @@ void EDA_3D_CANVAS::OnMagnify( wxMouseEvent& event )
|
||||
DisplayStatus();
|
||||
Request_refresh();
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
void EDA_3D_CANVAS::OnMouseMove( wxMouseEvent& event )
|
||||
{
|
||||
if( m_3d_render && m_3d_render->IsReloadRequestPending() )
|
||||
return; // Prevents using invalid m_3d_render_raytracing data
|
||||
//wxLogTrace( m_logTrace, wxT( "EDA_3D_CANVAS::OnMouseMove" ) );
|
||||
|
||||
if( m_camera_is_moving )
|
||||
return;
|
||||
|
||||
OnMouseMoveCamera( event );
|
||||
const wxSize& nativeWinSize = GetNativePixelSize();
|
||||
const wxPoint& nativePosition = GetNativePosition( event.GetPosition() );
|
||||
|
||||
if( m_mouse_was_moved )
|
||||
m_camera.SetCurWindowSize( nativeWinSize );
|
||||
|
||||
if( event.Dragging() )
|
||||
{
|
||||
if( event.LeftIsDown() ) // Drag
|
||||
m_camera.Drag( nativePosition );
|
||||
else if( event.MiddleIsDown() ) // Pan
|
||||
m_camera.Pan( nativePosition );
|
||||
|
||||
m_mouse_is_moving = true;
|
||||
m_mouse_was_moved = true;
|
||||
|
||||
// orientation has changed, redraw mesh
|
||||
DisplayStatus();
|
||||
Request_refresh();
|
||||
// *Do not* reactivate the timer here during the mouse move command:
|
||||
// OnMiddleUp() will do it at the end of mouse drag/move command
|
||||
}
|
||||
|
||||
if( !event.Dragging() && m_boardAdapter.m_Cfg->m_Render.engine == RENDER_ENGINE::OPENGL )
|
||||
{
|
||||
STATUSBAR_REPORTER reporter( m_parentStatusBar, EDA_3D_VIEWER_STATUSBAR::HOVERED_ITEM );
|
||||
RAY mouseRay = getRayAtCurrentMousePosition();
|
||||
BOARD_ITEM* rollOverItem = m_3d_render_raytracing->IntersectBoardItem( mouseRay );
|
||||
m_camera.SetCurMousePosition( nativePosition );
|
||||
|
||||
auto printNetInfo =
|
||||
[]( BOARD_CONNECTED_ITEM* aItem )
|
||||
{
|
||||
return wxString::Format( _( "Net %s\tNet class %s" ),
|
||||
aItem->GetNet()->GetNetname(),
|
||||
aItem->GetNet()->GetNetClass()->GetName() );
|
||||
};
|
||||
if( !event.Dragging() && m_boardAdapter.GetRenderEngine() == RENDER_ENGINE::OPENGL )
|
||||
{
|
||||
STATUSBAR_REPORTER reporter( m_parentStatusBar,
|
||||
static_cast<int>( EDA_3D_VIEWER_STATUSBAR::HOVERED_ITEM ) );
|
||||
|
||||
RAY mouseRay = getRayAtCurrrentMousePosition();
|
||||
|
||||
BOARD_ITEM *rollOverItem = m_3d_render_raytracing->IntersectBoardItem( mouseRay );
|
||||
|
||||
if( rollOverItem )
|
||||
{
|
||||
wxString msg;
|
||||
|
||||
if( rollOverItem != m_currentRollOverItem )
|
||||
{
|
||||
m_3d_render_opengl->SetCurrentRollOverItem( rollOverItem );
|
||||
@@ -675,61 +723,62 @@ void EDA_3D_CANVAS::OnMouseMove( wxMouseEvent& event )
|
||||
{
|
||||
case PCB_PAD_T:
|
||||
{
|
||||
PAD* pad = static_cast<PAD*>( rollOverItem );
|
||||
PAD* pad = dynamic_cast<PAD*>( rollOverItem );
|
||||
|
||||
if( !pad->GetNumber().IsEmpty() )
|
||||
msg += wxString::Format( _( "Pad %s\t" ), pad->GetNumber() );
|
||||
|
||||
if( pad->IsOnCopperLayer() )
|
||||
msg += printNetInfo( pad );
|
||||
|
||||
break;
|
||||
if( pad && pad->IsOnCopperLayer() )
|
||||
{
|
||||
reporter.Report( wxString::Format( _( "Net %s\tNetClass %s\tPadName %s" ),
|
||||
pad->GetNet()->GetNetname(),
|
||||
pad->GetNet()->GetNetClassName(),
|
||||
pad->GetNumber() ) );
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case PCB_FOOTPRINT_T:
|
||||
{
|
||||
FOOTPRINT* footprint = static_cast<FOOTPRINT*>( rollOverItem );
|
||||
msg += footprint->GetReference();
|
||||
break;
|
||||
FOOTPRINT* footprint = dynamic_cast<FOOTPRINT*>( rollOverItem );
|
||||
|
||||
if( footprint )
|
||||
reporter.Report( footprint->GetReference() );
|
||||
}
|
||||
break;
|
||||
|
||||
case PCB_TRACE_T:
|
||||
case PCB_VIA_T:
|
||||
case PCB_ARC_T:
|
||||
{
|
||||
PCB_TRACK* track = static_cast<PCB_TRACK*>( rollOverItem );
|
||||
msg += printNetInfo( track );
|
||||
break;
|
||||
PCB_TRACK* track = dynamic_cast<PCB_TRACK*>( rollOverItem );
|
||||
|
||||
if( track )
|
||||
{
|
||||
reporter.Report( wxString::Format( _( "Net %s\tNetClass %s" ),
|
||||
track->GetNet()->GetNetname(),
|
||||
track->GetNet()->GetNetClassName() ) );
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case PCB_ZONE_T:
|
||||
{
|
||||
ZONE* zone = static_cast<ZONE*>( rollOverItem );
|
||||
ZONE* zone = dynamic_cast<ZONE*>( rollOverItem );
|
||||
|
||||
if( !zone->GetZoneName().IsEmpty() )
|
||||
if( zone && zone->IsOnCopperLayer() )
|
||||
{
|
||||
if( zone->GetIsRuleArea() )
|
||||
msg += wxString::Format( _( "Rule area %s\t" ), zone->GetZoneName() );
|
||||
else
|
||||
msg += wxString::Format( _( "Zone %s\t" ), zone->GetZoneName() );
|
||||
reporter.Report( wxString::Format( _( "Net %s\tNetClass %s" ),
|
||||
zone->GetNet()->GetNetname(),
|
||||
zone->GetNet()->GetNetClassName() ) );
|
||||
}
|
||||
|
||||
if( zone->IsOnCopperLayer() )
|
||||
msg += printNetInfo( zone );
|
||||
|
||||
break;
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
reporter.Report( msg );
|
||||
}
|
||||
else
|
||||
{
|
||||
if( m_currentRollOverItem
|
||||
&& m_boardAdapter.m_Cfg->m_Render.engine == RENDER_ENGINE::OPENGL )
|
||||
if( m_currentRollOverItem && m_boardAdapter.GetRenderEngine() == RENDER_ENGINE::OPENGL )
|
||||
{
|
||||
m_3d_render_opengl->SetCurrentRollOverItem( nullptr );
|
||||
Request_refresh();
|
||||
@@ -750,7 +799,7 @@ void EDA_3D_CANVAS::OnLeftDown( wxMouseEvent& event )
|
||||
|
||||
if( !event.Dragging() && ( m_3d_render_raytracing != nullptr ) )
|
||||
{
|
||||
RAY mouseRay = getRayAtCurrentMousePosition();
|
||||
RAY mouseRay = getRayAtCurrrentMousePosition();
|
||||
|
||||
BOARD_ITEM *intersectedBoardItem = m_3d_render_raytracing->IntersectBoardItem( mouseRay );
|
||||
|
||||
@@ -796,14 +845,8 @@ void EDA_3D_CANVAS::OnMiddleUp( wxMouseEvent& event )
|
||||
}
|
||||
|
||||
|
||||
void EDA_3D_CANVAS::OnTimerTimeout_Editing( wxTimerEvent& aEvent )
|
||||
void EDA_3D_CANVAS::OnTimerTimeout_Editing( wxTimerEvent& /* event */ )
|
||||
{
|
||||
if( aEvent.GetId() != m_editing_timeout_timer.GetId() )
|
||||
{
|
||||
aEvent.Skip();
|
||||
return;
|
||||
}
|
||||
|
||||
m_mouse_is_moving = false;
|
||||
m_mouse_was_moved = false;
|
||||
|
||||
@@ -824,21 +867,15 @@ void EDA_3D_CANVAS::restart_editingTimeOut_Timer()
|
||||
}
|
||||
|
||||
|
||||
void EDA_3D_CANVAS::OnTimerTimeout_Redraw( wxTimerEvent& aEvent )
|
||||
void EDA_3D_CANVAS::OnTimerTimeout_Redraw( wxTimerEvent& event )
|
||||
{
|
||||
if( aEvent.GetId() != m_redraw_trigger_timer.GetId() )
|
||||
{
|
||||
aEvent.Skip();
|
||||
return;
|
||||
}
|
||||
|
||||
Request_refresh( true );
|
||||
}
|
||||
|
||||
|
||||
void EDA_3D_CANVAS::OnRefreshRequest( wxEvent& aEvent )
|
||||
{
|
||||
Refresh();
|
||||
DoRePaint();
|
||||
}
|
||||
|
||||
|
||||
@@ -894,7 +931,7 @@ void EDA_3D_CANVAS::request_start_moving_camera( float aMovingSpeed, bool aRende
|
||||
|
||||
void EDA_3D_CANVAS::move_pivot_based_on_cur_mouse_position()
|
||||
{
|
||||
RAY mouseRay = getRayAtCurrentMousePosition();
|
||||
RAY mouseRay = getRayAtCurrrentMousePosition();
|
||||
|
||||
float hit_t;
|
||||
|
||||
@@ -911,56 +948,68 @@ void EDA_3D_CANVAS::move_pivot_based_on_cur_mouse_position()
|
||||
}
|
||||
|
||||
|
||||
bool EDA_3D_CANVAS::SetView3D( VIEW3D_TYPE aRequestedView )
|
||||
bool EDA_3D_CANVAS::SetView3D( int aKeycode )
|
||||
{
|
||||
if( m_camera_is_moving )
|
||||
return false;
|
||||
|
||||
const float delta_move = m_delta_move_step_factor * m_camera.GetZoom();
|
||||
const float arrow_moving_time_speed = 8.0f;
|
||||
bool handled = false;
|
||||
|
||||
switch( aRequestedView )
|
||||
switch( aKeycode )
|
||||
{
|
||||
case VIEW3D_TYPE::VIEW3D_PIVOT_CENTER:
|
||||
case WXK_SPACE:
|
||||
move_pivot_based_on_cur_mouse_position();
|
||||
return true;
|
||||
|
||||
case VIEW3D_TYPE::VIEW3D_PAN_LEFT:
|
||||
case WXK_LEFT:
|
||||
m_camera.SetInterpolateMode( CAMERA_INTERPOLATION::LINEAR );
|
||||
m_camera.SetT0_and_T1_current_T();
|
||||
m_camera.Pan_T1( SFVEC3F( -delta_move, 0.0f, 0.0f ) );
|
||||
request_start_moving_camera( arrow_moving_time_speed, false );
|
||||
return true;
|
||||
|
||||
case VIEW3D_TYPE::VIEW3D_PAN_RIGHT:
|
||||
case WXK_RIGHT:
|
||||
m_camera.SetInterpolateMode( CAMERA_INTERPOLATION::LINEAR );
|
||||
m_camera.SetT0_and_T1_current_T();
|
||||
m_camera.Pan_T1( SFVEC3F( +delta_move, 0.0f, 0.0f ) );
|
||||
request_start_moving_camera( arrow_moving_time_speed, false );
|
||||
return true;
|
||||
|
||||
case VIEW3D_TYPE::VIEW3D_PAN_UP:
|
||||
case WXK_UP:
|
||||
m_camera.SetInterpolateMode( CAMERA_INTERPOLATION::LINEAR );
|
||||
m_camera.SetT0_and_T1_current_T();
|
||||
m_camera.Pan_T1( SFVEC3F( 0.0f, +delta_move, 0.0f ) );
|
||||
request_start_moving_camera( arrow_moving_time_speed, false );
|
||||
return true;
|
||||
|
||||
case VIEW3D_TYPE::VIEW3D_PAN_DOWN:
|
||||
case WXK_DOWN:
|
||||
m_camera.SetInterpolateMode( CAMERA_INTERPOLATION::LINEAR );
|
||||
m_camera.SetT0_and_T1_current_T();
|
||||
m_camera.Pan_T1( SFVEC3F( 0.0f, -delta_move, 0.0f ) );
|
||||
request_start_moving_camera( arrow_moving_time_speed, false );
|
||||
return true;
|
||||
|
||||
case VIEW3D_TYPE::VIEW3D_FIT_SCREEN:
|
||||
case WXK_HOME:
|
||||
m_camera.SetInterpolateMode( CAMERA_INTERPOLATION::BEZIER );
|
||||
m_camera.SetT0_and_T1_current_T();
|
||||
m_camera.Reset_T1();
|
||||
request_start_moving_camera( glm::min( glm::max( m_camera.GetZoom(), 1 / 1.26f ), 1.26f ) );
|
||||
return true;
|
||||
|
||||
case VIEW3D_TYPE::VIEW3D_ZOOM_IN:
|
||||
case WXK_END:
|
||||
break;
|
||||
|
||||
case WXK_TAB:
|
||||
m_camera.SetInterpolateMode( CAMERA_INTERPOLATION::EASING_IN_OUT );
|
||||
m_camera.SetT0_and_T1_current_T();
|
||||
m_camera.RotateZ_T1( glm::radians( 45.0f ) );
|
||||
request_start_moving_camera();
|
||||
handled = true;
|
||||
break;
|
||||
|
||||
case WXK_F1:
|
||||
m_camera.SetInterpolateMode( CAMERA_INTERPOLATION::BEZIER );
|
||||
m_camera.SetT0_and_T1_current_T();
|
||||
|
||||
@@ -969,7 +1018,7 @@ bool EDA_3D_CANVAS::SetView3D( VIEW3D_TYPE aRequestedView )
|
||||
|
||||
return true;
|
||||
|
||||
case VIEW3D_TYPE::VIEW3D_ZOOM_OUT:
|
||||
case WXK_F2:
|
||||
m_camera.SetInterpolateMode( CAMERA_INTERPOLATION::BEZIER );
|
||||
m_camera.SetT0_and_T1_current_T();
|
||||
|
||||
@@ -978,7 +1027,14 @@ bool EDA_3D_CANVAS::SetView3D( VIEW3D_TYPE aRequestedView )
|
||||
|
||||
return true;
|
||||
|
||||
case VIEW3D_TYPE::VIEW3D_RIGHT:
|
||||
case ID_VIEW3D_RESET:
|
||||
m_camera.SetInterpolateMode( CAMERA_INTERPOLATION::BEZIER );
|
||||
m_camera.SetT0_and_T1_current_T();
|
||||
m_camera.Reset_T1();
|
||||
request_start_moving_camera( glm::min( glm::max( m_camera.GetZoom(), 0.5f ), 1.125f ) );
|
||||
return true;
|
||||
|
||||
case ID_VIEW3D_RIGHT:
|
||||
m_camera.SetInterpolateMode( CAMERA_INTERPOLATION::BEZIER );
|
||||
m_camera.SetT0_and_T1_current_T();
|
||||
m_camera.Reset_T1();
|
||||
@@ -987,7 +1043,7 @@ bool EDA_3D_CANVAS::SetView3D( VIEW3D_TYPE aRequestedView )
|
||||
request_start_moving_camera();
|
||||
return true;
|
||||
|
||||
case VIEW3D_TYPE::VIEW3D_LEFT:
|
||||
case ID_VIEW3D_LEFT:
|
||||
m_camera.SetInterpolateMode( CAMERA_INTERPOLATION::BEZIER );
|
||||
m_camera.SetT0_and_T1_current_T();
|
||||
m_camera.Reset_T1();
|
||||
@@ -996,7 +1052,7 @@ bool EDA_3D_CANVAS::SetView3D( VIEW3D_TYPE aRequestedView )
|
||||
request_start_moving_camera();
|
||||
return true;
|
||||
|
||||
case VIEW3D_TYPE::VIEW3D_FRONT:
|
||||
case ID_VIEW3D_FRONT:
|
||||
m_camera.SetInterpolateMode( CAMERA_INTERPOLATION::BEZIER );
|
||||
m_camera.SetT0_and_T1_current_T();
|
||||
m_camera.Reset_T1();
|
||||
@@ -1004,7 +1060,7 @@ bool EDA_3D_CANVAS::SetView3D( VIEW3D_TYPE aRequestedView )
|
||||
request_start_moving_camera();
|
||||
return true;
|
||||
|
||||
case VIEW3D_TYPE::VIEW3D_BACK:
|
||||
case ID_VIEW3D_BACK:
|
||||
m_camera.SetInterpolateMode( CAMERA_INTERPOLATION::BEZIER );
|
||||
m_camera.SetT0_and_T1_current_T();
|
||||
m_camera.Reset_T1();
|
||||
@@ -1017,14 +1073,14 @@ bool EDA_3D_CANVAS::SetView3D( VIEW3D_TYPE aRequestedView )
|
||||
request_start_moving_camera();
|
||||
return true;
|
||||
|
||||
case VIEW3D_TYPE::VIEW3D_TOP:
|
||||
case ID_VIEW3D_TOP:
|
||||
m_camera.SetInterpolateMode( CAMERA_INTERPOLATION::BEZIER );
|
||||
m_camera.SetT0_and_T1_current_T();
|
||||
m_camera.Reset_T1();
|
||||
request_start_moving_camera( glm::min( glm::max( m_camera.GetZoom(), 0.5f ), 1.125f ) );
|
||||
return true;
|
||||
|
||||
case VIEW3D_TYPE::VIEW3D_BOTTOM:
|
||||
case ID_VIEW3D_BOTTOM:
|
||||
m_camera.SetInterpolateMode( CAMERA_INTERPOLATION::BEZIER );
|
||||
m_camera.SetT0_and_T1_current_T();
|
||||
m_camera.Reset_T1();
|
||||
@@ -1032,7 +1088,7 @@ bool EDA_3D_CANVAS::SetView3D( VIEW3D_TYPE aRequestedView )
|
||||
request_start_moving_camera( glm::min( glm::max( m_camera.GetZoom(), 0.5f ), 1.125f ) );
|
||||
return true;
|
||||
|
||||
case VIEW3D_TYPE::VIEW3D_FLIP:
|
||||
case ID_VIEW3D_FLIP:
|
||||
m_camera.SetInterpolateMode( CAMERA_INTERPOLATION::BEZIER );
|
||||
m_camera.SetT0_and_T1_current_T();
|
||||
m_camera.RotateY_T1( glm::radians( 179.999f ) );
|
||||
@@ -1042,15 +1098,21 @@ bool EDA_3D_CANVAS::SetView3D( VIEW3D_TYPE aRequestedView )
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
|
||||
m_mouse_was_moved = true;
|
||||
|
||||
restart_editingTimeOut_Timer();
|
||||
|
||||
DisplayStatus();
|
||||
Request_refresh();
|
||||
|
||||
return handled;
|
||||
}
|
||||
|
||||
|
||||
void EDA_3D_CANVAS::RenderEngineChanged()
|
||||
{
|
||||
SETTINGS_MANAGER& mgr = Pgm().GetSettingsManager();
|
||||
EDA_3D_VIEWER_SETTINGS* cfg = mgr.GetAppSettings<EDA_3D_VIEWER_SETTINGS>();
|
||||
|
||||
switch( cfg->m_Render.engine )
|
||||
switch( m_boardAdapter.GetRenderEngine() )
|
||||
{
|
||||
case RENDER_ENGINE::OPENGL: m_3d_render = m_3d_render_opengl; break;
|
||||
case RENDER_ENGINE::RAYTRACING: m_3d_render = m_3d_render_raytracing; break;
|
||||
@@ -1066,13 +1128,13 @@ void EDA_3D_CANVAS::RenderEngineChanged()
|
||||
}
|
||||
|
||||
|
||||
RAY EDA_3D_CANVAS::getRayAtCurrentMousePosition()
|
||||
RAY EDA_3D_CANVAS::getRayAtCurrrentMousePosition()
|
||||
{
|
||||
SFVEC3F rayOrigin;
|
||||
SFVEC3F rayDir;
|
||||
|
||||
// Generate a ray origin and direction based on current mouser position and camera
|
||||
m_camera.MakeRayAtCurrentMousePosition( rayOrigin, rayDir );
|
||||
m_camera.MakeRayAtCurrrentMousePosition( rayOrigin, rayDir );
|
||||
|
||||
RAY mouseRay;
|
||||
mouseRay.Init( rayOrigin, rayDir );
|
||||
|
||||
@@ -30,7 +30,7 @@
|
||||
#include "3d_rendering/raytracing/accelerators/accelerator_3d.h"
|
||||
#include "3d_rendering/render_3d_base.h"
|
||||
#include "3d_cache/3d_cache.h"
|
||||
#include <gal/hidpi_gl_3D_canvas.h>
|
||||
#include <gal/hidpi_gl_canvas.h>
|
||||
#include <wx/image.h>
|
||||
#include <wx/timer.h>
|
||||
|
||||
@@ -45,7 +45,7 @@ class RENDER_3D_OPENGL;
|
||||
/**
|
||||
* Implement a canvas based on a wxGLCanvas
|
||||
*/
|
||||
class EDA_3D_CANVAS : public HIDPI_GL_3D_CANVAS
|
||||
class EDA_3D_CANVAS : public HIDPI_GL_CANVAS
|
||||
{
|
||||
public:
|
||||
/**
|
||||
@@ -114,12 +114,12 @@ public:
|
||||
void GetScreenshot( wxImage& aDstImage );
|
||||
|
||||
/**
|
||||
* Select a specific 3D view or operation
|
||||
* Helper function to call view commands.
|
||||
*
|
||||
* @param aRequestedView the view to move to
|
||||
* @return true if the view request was handled, false if no command found for this view.
|
||||
* @param aKeycode ascii key commands.
|
||||
* @return true if the key code was handled, false if no command found for this code.
|
||||
*/
|
||||
bool SetView3D( VIEW3D_TYPE aRequestedView );
|
||||
bool SetView3D( int aKeycode );
|
||||
|
||||
/**
|
||||
* Enable or disable camera animation when switching to a pre-defined view.
|
||||
@@ -161,52 +161,11 @@ public:
|
||||
*/
|
||||
void OnEvent( wxEvent& aEvent );
|
||||
|
||||
private:
|
||||
/**
|
||||
* Get information used to display 3D board.
|
||||
* Called by a wxPaintEvent event
|
||||
*/
|
||||
const BOARD_ADAPTER& GetBoardAdapter() const { return m_boardAdapter; }
|
||||
|
||||
/**
|
||||
* Get a value indicating whether to render the pivot.
|
||||
*/
|
||||
bool GetRenderPivot() { return m_render_pivot; }
|
||||
|
||||
/**
|
||||
* Set aValue indicating whether to render the pivot.
|
||||
*
|
||||
* @param aValue true will cause the pivot to be rendered on the next redraw.
|
||||
*/
|
||||
void SetRenderPivot( bool aValue ) { m_render_pivot = aValue; }
|
||||
|
||||
/**
|
||||
* Get a value indicating whether to render the 3dmouse pivot.
|
||||
*/
|
||||
bool GetRender3dmousePivot()
|
||||
{
|
||||
return m_render3dmousePivot;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Set aValue indicating whether to render the 3dmouse pivot.
|
||||
*
|
||||
* @param aValue true will cause the pivot to be rendered on the next redraw.
|
||||
*/
|
||||
void SetRender3dmousePivot( bool aValue )
|
||||
{
|
||||
m_render3dmousePivot = aValue;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Set the position of the the 3dmouse pivot.
|
||||
*
|
||||
* @param aPos is the position of the 3dmouse rotation pivot
|
||||
*/
|
||||
void Set3dmousePivotPos( const SFVEC3F& aPos )
|
||||
{
|
||||
m_3dmousePivotPos = aPos;
|
||||
}
|
||||
void OnPaint( wxPaintEvent& aEvent );
|
||||
|
||||
/**
|
||||
* The actual function to repaint the canvas.
|
||||
@@ -216,17 +175,16 @@ public:
|
||||
*/
|
||||
void DoRePaint();
|
||||
|
||||
private:
|
||||
// The wxPaintEvent event. mainly calls DoRePaint()
|
||||
void OnPaint( wxPaintEvent& aEvent );
|
||||
|
||||
void OnEraseBackground( wxEraseEvent& event );
|
||||
|
||||
void OnRefreshRequest( wxEvent& aEvent );
|
||||
|
||||
void OnMouseWheel( wxMouseEvent& event );
|
||||
|
||||
#if wxCHECK_VERSION( 3, 1, 0 ) || defined( USE_OSX_MAGNIFY_EVENT )
|
||||
void OnMagnify( wxMouseEvent& event );
|
||||
#endif
|
||||
|
||||
void OnMouseMove( wxMouseEvent& event );
|
||||
void OnLeftDown( wxMouseEvent& event );
|
||||
void OnLeftUp( wxMouseEvent& event );
|
||||
@@ -270,13 +228,6 @@ private:
|
||||
*/
|
||||
void render_pivot( float t, float aScale );
|
||||
|
||||
/**
|
||||
* Render the 3dmouse pivot cursor.
|
||||
*
|
||||
* @param aScale scale to apply on the cursor.
|
||||
*/
|
||||
void render3dmousePivot( float aScale );
|
||||
|
||||
/**
|
||||
* @return true if OpenGL initialization succeeded.
|
||||
*/
|
||||
@@ -287,7 +238,7 @@ private:
|
||||
*/
|
||||
void releaseOpenGL();
|
||||
|
||||
RAY getRayAtCurrentMousePosition();
|
||||
RAY getRayAtCurrrentMousePosition();
|
||||
|
||||
private:
|
||||
TOOL_DISPATCHER* m_eventDispatcher;
|
||||
@@ -303,17 +254,24 @@ private:
|
||||
wxTimer m_redraw_trigger_timer; // Used to schedule a redraw event
|
||||
std::atomic_flag m_is_currently_painting; // Avoid drawing twice at the same time
|
||||
|
||||
bool m_mouse_is_moving; // Mouse activity is in progress
|
||||
bool m_mouse_was_moved;
|
||||
bool m_camera_is_moving; // Camera animation is ongoing
|
||||
bool m_render_pivot; // Render the pivot while camera moving
|
||||
float m_camera_moving_speed; // 1.0f will be 1:1
|
||||
int64_t m_strtime_camera_movement; // Ticktime of camera movement start
|
||||
unsigned m_strtime_camera_movement; // Ticktime of camera movement start
|
||||
bool m_animation_enabled; // Camera animation enabled
|
||||
int m_moving_speed_multiplier; // Camera animation speed multiplier option
|
||||
|
||||
BOARD_ADAPTER& m_boardAdapter; // Pre-computed 3D info and settings
|
||||
CAMERA& m_camera;
|
||||
RENDER_3D_BASE* m_3d_render;
|
||||
RENDER_3D_RAYTRACE* m_3d_render_raytracing;
|
||||
RENDER_3D_OPENGL* m_3d_render_opengl;
|
||||
|
||||
static const float m_delta_move_step_factor; // Step factor to used with cursor on
|
||||
// relation to the current zoom
|
||||
|
||||
bool m_opengl_supports_raytracing;
|
||||
bool m_render_raytracing_was_requested;
|
||||
|
||||
@@ -321,9 +279,6 @@ private:
|
||||
|
||||
BOARD_ITEM* m_currentRollOverItem;
|
||||
|
||||
bool m_render3dmousePivot = false; // Render the 3dmouse pivot
|
||||
SFVEC3F m_3dmousePivotPos; // The position of the 3dmouse pivot
|
||||
|
||||
/**
|
||||
* Trace mask used to enable or disable the trace output of this class.
|
||||
* The debug output can be turned on by setting the WXTRACE environment variable to
|
||||
|
||||
@@ -73,7 +73,7 @@ static void pivot_render_triangles( float t )
|
||||
}
|
||||
|
||||
|
||||
void EDA_3D_CANVAS::render_pivot( float t, float aScale )
|
||||
void EDA_3D_CANVAS::render_pivot( float t , float aScale )
|
||||
{
|
||||
wxASSERT( aScale >= 0.0f );
|
||||
wxASSERT( t >= 0.0f );
|
||||
@@ -118,44 +118,3 @@ void EDA_3D_CANVAS::render_pivot( float t, float aScale )
|
||||
pivot_render_triangles( t * 0.5f );
|
||||
glPopMatrix();
|
||||
}
|
||||
|
||||
|
||||
void EDA_3D_CANVAS::render3dmousePivot( float aScale )
|
||||
{
|
||||
wxASSERT( aScale >= 0.0f );
|
||||
|
||||
glDisable( GL_LIGHTING );
|
||||
glDisable( GL_DEPTH_TEST );
|
||||
glDisable( GL_CULL_FACE );
|
||||
|
||||
// Set projection and modelview matrixes
|
||||
glMatrixMode( GL_PROJECTION );
|
||||
glLoadMatrixf( glm::value_ptr( m_camera.GetProjectionMatrix() ) );
|
||||
|
||||
glMatrixMode( GL_MODELVIEW );
|
||||
glLoadIdentity();
|
||||
glLoadMatrixf( glm::value_ptr( m_camera.GetViewMatrix() ) );
|
||||
|
||||
glEnable( GL_COLOR_MATERIAL );
|
||||
glColor4f( 0.0f, 0.667f, 0.902f, 0.75f );
|
||||
|
||||
// Translate to the look at position
|
||||
glTranslatef( m_3dmousePivotPos.x, m_3dmousePivotPos.y, m_3dmousePivotPos.z );
|
||||
|
||||
glPointSize( 16.0f );
|
||||
glEnable( GL_POINT_SMOOTH );
|
||||
glHint( GL_POINT_SMOOTH_HINT, GL_NICEST );
|
||||
|
||||
glEnable( GL_BLEND );
|
||||
glBlendFunc( GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA );
|
||||
|
||||
glScalef( aScale, aScale, aScale );
|
||||
|
||||
// Draw a point at the look at position.
|
||||
glBegin( GL_POINTS );
|
||||
glVertex3f( 0, 0, 0 );
|
||||
glEnd();
|
||||
|
||||
glDisable( GL_BLEND );
|
||||
glDisable( GL_POINT_SMOOTH );
|
||||
}
|
||||
|
||||
+59
-35
@@ -30,6 +30,52 @@
|
||||
#ifndef _3D_ENUMS_H_
|
||||
#define _3D_ENUMS_H_
|
||||
|
||||
/// Flags used in rendering options
|
||||
enum DISPLAY3D_FLG
|
||||
{
|
||||
FL_AXIS = 0,
|
||||
FL_ZONE,
|
||||
FL_ADHESIVE,
|
||||
FL_SILKSCREEN,
|
||||
FL_SOLDERMASK,
|
||||
FL_SOLDERPASTE,
|
||||
FL_COMMENTS,
|
||||
FL_ECO,
|
||||
|
||||
FL_FP_ATTRIBUTES_NORMAL,
|
||||
FL_FP_ATTRIBUTES_NORMAL_INSERT,
|
||||
FL_FP_ATTRIBUTES_VIRTUAL,
|
||||
|
||||
FL_USE_SELECTION,
|
||||
FL_HIGHLIGHT_ROLLOVER_ITEM,
|
||||
|
||||
FL_SHOW_BOARD_BODY,
|
||||
FL_MOUSEWHEEL_PANNING,
|
||||
FL_USE_REALISTIC_MODE,
|
||||
FL_SUBTRACT_MASK_FROM_SILK,
|
||||
FL_CLIP_SILK_ON_VIA_ANNULUS,
|
||||
FL_RENDER_PLATED_PADS_AS_PLATED,
|
||||
|
||||
// OpenGL options
|
||||
FL_RENDER_OPENGL_SHOW_MODEL_BBOX,
|
||||
FL_RENDER_OPENGL_COPPER_THICKNESS,
|
||||
FL_RENDER_OPENGL_AA_DISABLE_ON_MOVE,
|
||||
FL_RENDER_OPENGL_THICKNESS_DISABLE_ON_MOVE,
|
||||
FL_RENDER_OPENGL_VIAS_DISABLE_ON_MOVE,
|
||||
FL_RENDER_OPENGL_HOLES_DISABLE_ON_MOVE,
|
||||
|
||||
// Raytracing options
|
||||
FL_RENDER_RAYTRACING_SHADOWS,
|
||||
FL_RENDER_RAYTRACING_BACKFLOOR,
|
||||
FL_RENDER_RAYTRACING_REFRACTIONS,
|
||||
FL_RENDER_RAYTRACING_REFLECTIONS,
|
||||
FL_RENDER_RAYTRACING_POST_PROCESSING,
|
||||
FL_RENDER_RAYTRACING_ANTI_ALIASING,
|
||||
FL_RENDER_RAYTRACING_PROCEDURAL_TEXTURES,
|
||||
FL_LAST
|
||||
};
|
||||
|
||||
|
||||
/// Rotation direction for the 3d canvas
|
||||
enum class ROTATION_DIR
|
||||
{
|
||||
@@ -41,61 +87,39 @@ enum class ROTATION_DIR
|
||||
Z_CCW
|
||||
};
|
||||
|
||||
|
||||
/// Camera types
|
||||
enum class CAMERA_TYPE
|
||||
{
|
||||
TRACKBALL
|
||||
};
|
||||
|
||||
// Do not modify the following enum numbers, they are saved in the config file and used in the UI
|
||||
|
||||
/// Grid types
|
||||
enum class GRID3D_TYPE
|
||||
{
|
||||
NONE = 0,
|
||||
GRID_1MM = 1,
|
||||
GRID_2P5MM = 2,
|
||||
GRID_5MM = 3,
|
||||
GRID_10MM = 4
|
||||
NONE,
|
||||
GRID_1MM,
|
||||
GRID_2P5MM,
|
||||
GRID_5MM,
|
||||
GRID_10MM
|
||||
};
|
||||
|
||||
|
||||
/// Render engine mode
|
||||
enum class RENDER_ENGINE
|
||||
{
|
||||
OPENGL = 0,
|
||||
RAYTRACING = 1,
|
||||
OPENGL,
|
||||
RAYTRACING,
|
||||
};
|
||||
|
||||
|
||||
/// Render 3d model shape materials mode
|
||||
enum class MATERIAL_MODE
|
||||
{
|
||||
NORMAL = 0, ///< Use all material properties from model file
|
||||
DIFFUSE_ONLY = 1, ///< Use only diffuse material properties
|
||||
CAD_MODE = 2 ///< Use a gray shading based on diffuse material
|
||||
};
|
||||
|
||||
enum class VIEW3D_TYPE
|
||||
{
|
||||
// Specific directions
|
||||
VIEW3D_TOP,
|
||||
VIEW3D_BOTTOM,
|
||||
VIEW3D_LEFT,
|
||||
VIEW3D_RIGHT,
|
||||
VIEW3D_FRONT,
|
||||
VIEW3D_BACK,
|
||||
VIEW3D_FLIP,
|
||||
|
||||
// Movement commands
|
||||
VIEW3D_PAN_UP,
|
||||
VIEW3D_PAN_DOWN,
|
||||
VIEW3D_PAN_LEFT,
|
||||
VIEW3D_PAN_RIGHT,
|
||||
VIEW3D_ZOOM_IN,
|
||||
VIEW3D_ZOOM_OUT,
|
||||
VIEW3D_PIVOT_CENTER,
|
||||
|
||||
// Specific levels
|
||||
VIEW3D_FIT_SCREEN
|
||||
NORMAL, ///< Use all material properties from model file
|
||||
DIFFUSE_ONLY, ///< Use only diffuse material properties
|
||||
CAD_MODE ///< Use a gray shading based on diffuse material
|
||||
};
|
||||
|
||||
#endif // _3D_ENUMS_H_
|
||||
|
||||
@@ -27,7 +27,6 @@
|
||||
* 3d models that come in the original data from the files without any transformations.
|
||||
*/
|
||||
|
||||
#include <gal/opengl/kiglew.h> // Must be included first
|
||||
#include <iostream>
|
||||
#include "3d_rendering/opengl/3d_model.h"
|
||||
#include "eda_3d_model_viewer.h"
|
||||
@@ -35,17 +34,15 @@
|
||||
#include "../3d_cache/3d_cache.h"
|
||||
#include <wx/dcclient.h>
|
||||
#include <base_units.h>
|
||||
#include <gal/opengl/gl_context_mgr.h>
|
||||
#include <gl_context_mgr.h>
|
||||
#include <settings/common_settings.h>
|
||||
#include <pgm_base.h>
|
||||
#include <dpi_scaling_common.h>
|
||||
#include <class_draw_panel_gal.h>
|
||||
#include <macros.h>
|
||||
#include <gal/dpi_scaling.h>
|
||||
|
||||
/**
|
||||
* Scale conversion from 3d model units to pcb units
|
||||
*/
|
||||
#define UNITS3D_TO_UNITSPCB ( pcbIUScale.IU_PER_MM )
|
||||
#define UNITS3D_TO_UNITSPCB (IU_PER_MM)
|
||||
|
||||
/**
|
||||
* Trace mask used to enable or disable the trace output of this class.
|
||||
@@ -87,8 +84,7 @@ END_EVENT_TABLE()
|
||||
|
||||
EDA_3D_MODEL_VIEWER::EDA_3D_MODEL_VIEWER( wxWindow* aParent, const int* aAttribList,
|
||||
S3D_CACHE* aCacheManager ) :
|
||||
HIDPI_GL_CANVAS( EDA_DRAW_PANEL_GAL::GetVcSettings(), aParent, wxID_ANY, aAttribList,
|
||||
wxDefaultPosition, wxDefaultSize,
|
||||
HIDPI_GL_CANVAS( aParent, wxID_ANY, aAttribList, wxDefaultPosition, wxDefaultSize,
|
||||
wxFULL_REPAINT_ON_RESIZE ),
|
||||
m_trackBallCamera( RANGE_SCALE_3D * 4.0f ),
|
||||
m_cacheManager( aCacheManager )
|
||||
@@ -105,7 +101,7 @@ EDA_3D_MODEL_VIEWER::EDA_3D_MODEL_VIEWER( wxWindow* aParent, const int* aAttribL
|
||||
|
||||
COMMON_SETTINGS* settings = Pgm().GetCommonSettings();
|
||||
|
||||
const DPI_SCALING_COMMON dpi{ settings, this };
|
||||
const DPI_SCALING dpi{ settings, this };
|
||||
SetScaleFactor( dpi.GetScaleFactor() );
|
||||
}
|
||||
|
||||
@@ -160,7 +156,7 @@ void EDA_3D_MODEL_VIEWER::Set3DModel( const wxString& aModelPathName)
|
||||
|
||||
if( m_cacheManager )
|
||||
{
|
||||
const S3DMODEL* model = m_cacheManager->GetModel( aModelPathName, wxEmptyString );
|
||||
const S3DMODEL* model = m_cacheManager->GetModel( aModelPathName );
|
||||
|
||||
if( model )
|
||||
Set3DModel( (const S3DMODEL &)*model );
|
||||
@@ -186,20 +182,6 @@ void EDA_3D_MODEL_VIEWER::Clear3DModel()
|
||||
|
||||
void EDA_3D_MODEL_VIEWER::ogl_initialize()
|
||||
{
|
||||
const GLenum err = glewInit();
|
||||
|
||||
if( GLEW_OK != err )
|
||||
{
|
||||
const wxString msgError = (const char*) glewGetErrorString( err );
|
||||
|
||||
wxLogMessage( msgError );
|
||||
}
|
||||
else
|
||||
{
|
||||
wxLogTrace( m_logTrace, wxT( "EDA_3D_MODEL_VIEWER::ogl_initialize Using GLEW version %s" ),
|
||||
From_UTF8( (char*) glewGetString( GLEW_VERSION ) ) );
|
||||
}
|
||||
|
||||
glHint( GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST );
|
||||
glHint( GL_LINE_SMOOTH_HINT, GL_NICEST );
|
||||
glHint( GL_POLYGON_SMOOTH_HINT, GL_NICEST );
|
||||
@@ -259,13 +241,6 @@ void EDA_3D_MODEL_VIEWER::OnPaint( wxPaintEvent& event )
|
||||
if( m_glRC == nullptr )
|
||||
m_glRC = GL_CONTEXT_MANAGER::Get().CreateCtx( this );
|
||||
|
||||
// CreateCtx could and does fail per sentry crash events, lets be graceful
|
||||
if( m_glRC == nullptr )
|
||||
{
|
||||
wxLogTrace( m_logTrace, wxT( "EDA_3D_MODEL_VIEWER::OnPaint creating gl context failed" ) );
|
||||
return;
|
||||
}
|
||||
|
||||
GL_CONTEXT_MANAGER::Get().LockCtx( m_glRC, this );
|
||||
|
||||
// Set the OpenGL viewport according to the client size of this canvas.
|
||||
@@ -332,16 +307,8 @@ void EDA_3D_MODEL_VIEWER::OnPaint( wxPaintEvent& event )
|
||||
m_ogl_3dmodel->BeginDrawMulti( true );
|
||||
|
||||
m_ogl_3dmodel->DrawOpaque( false );
|
||||
|
||||
glDepthMask( GL_FALSE );
|
||||
glEnable( GL_BLEND );
|
||||
glBlendFunc( GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA );
|
||||
|
||||
m_ogl_3dmodel->DrawTransparent( 1.0f, false );
|
||||
|
||||
glDisable( GL_BLEND );
|
||||
glDepthMask( GL_TRUE );
|
||||
|
||||
m_ogl_3dmodel->EndDrawMulti();
|
||||
|
||||
glPopMatrix();
|
||||
@@ -402,16 +369,16 @@ void EDA_3D_MODEL_VIEWER::OnMouseWheel( wxMouseEvent& event )
|
||||
if( event.ShiftDown() )
|
||||
{
|
||||
//if( event.GetWheelRotation() < 0 )
|
||||
//SetView3D( VIEW_3D_TYPE::VIEW3D_PAN_UP ); // move up
|
||||
//SetView3D( WXK_UP ); // move up
|
||||
//else
|
||||
//SetView3D( VIEW_3D_TYPE::VIEW3D_PAN_DOWN ); // move down
|
||||
//SetView3D( WXK_DOWN ); // move down
|
||||
}
|
||||
else if( event.ControlDown() )
|
||||
{
|
||||
//if( event.GetWheelRotation() > 0 )
|
||||
//SetView3D( VIEW_3D_TYPE::VIEW3D_PAN_RIGHT ); // move right
|
||||
//SetView3D( WXK_RIGHT ); // move right
|
||||
//else
|
||||
//SetView3D( VIEW_3D_TYPE::VIEW3D_PAN_LEFT ); // move left
|
||||
//SetView3D( WXK_LEFT ); // move left
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
@@ -23,7 +23,7 @@
|
||||
*/
|
||||
|
||||
/**
|
||||
* @file eda_3d_model_viewer.h
|
||||
* @file c3d_model_viewer.h
|
||||
* @brief Implements a model viewer canvas.
|
||||
*
|
||||
* The purpose of model viewer is to render 3d models that come in the original data from
|
||||
|
||||
@@ -1,25 +0,0 @@
|
||||
add_library(3d-viewer_navlib STATIC
|
||||
"nl_3d_viewer_plugin.cpp"
|
||||
"nl_3d_viewer_plugin_impl.cpp"
|
||||
)
|
||||
|
||||
# 3d-viewer_navlib depends on make_lexer outputs in common
|
||||
add_dependencies( 3d-viewer_navlib pcbcommon )
|
||||
|
||||
# Find the 3DxWare SDK component 3DxWare::NlClient
|
||||
# find_package(TDxWare_SDK 4.0 REQUIRED COMPONENTS 3DxWare::Navlib)
|
||||
target_compile_definitions(3d-viewer_navlib PRIVATE
|
||||
$<TARGET_PROPERTY:3DxWare::Navlib,INTERFACE_COMPILE_DEFINITIONS>
|
||||
)
|
||||
target_compile_options(3d-viewer_navlib PRIVATE
|
||||
$<TARGET_PROPERTY:3DxWare::Navlib,INTERFACE_COMPILE_OPTIONS>
|
||||
)
|
||||
target_include_directories(3d-viewer_navlib PRIVATE
|
||||
$<TARGET_PROPERTY:3DxWare::Navlib,INTERFACE_INCLUDE_DIRECTORIES>
|
||||
$<TARGET_PROPERTY:pcbnew_kiface_objects,INCLUDE_DIRECTORIES>
|
||||
)
|
||||
target_link_libraries(3d-viewer_navlib
|
||||
$<TARGET_PROPERTY:3DxWare::Navlib,INTERFACE_LINK_LIBRARIES>
|
||||
3DxWare::Navlib
|
||||
)
|
||||
|
||||
@@ -1,48 +0,0 @@
|
||||
/*
|
||||
* This program source code file is part of KiCad, a free EDA CAD application.
|
||||
*
|
||||
* Copyright (C) 2021 3Dconnexion
|
||||
* Copyright (C) 2021 KiCad Developers, see AUTHORS.txt for contributors.
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License as published by the
|
||||
* Free Software Foundation, either version 3 of the License, or (at your
|
||||
* option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but
|
||||
* WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along
|
||||
* with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "nl_3d_viewer_plugin.h"
|
||||
#include "nl_3d_viewer_plugin_impl.h"
|
||||
#include <advanced_config.h>
|
||||
#include <kiplatform/drivers.h>
|
||||
|
||||
|
||||
NL_3D_VIEWER_PLUGIN::NL_3D_VIEWER_PLUGIN( EDA_3D_CANVAS* aViewport )
|
||||
: m_impl( nullptr )
|
||||
{
|
||||
if( ADVANCED_CFG::GetCfg().m_Use3DConnexionDriver
|
||||
&& KIPLATFORM::DRIVERS::Valid3DConnexionDriverVersion() )
|
||||
{
|
||||
m_impl = new NL_3D_VIEWER_PLUGIN_IMPL( aViewport );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
NL_3D_VIEWER_PLUGIN::~NL_3D_VIEWER_PLUGIN()
|
||||
{
|
||||
delete m_impl;
|
||||
}
|
||||
|
||||
|
||||
void NL_3D_VIEWER_PLUGIN::SetFocus( bool focus )
|
||||
{
|
||||
if( m_impl )
|
||||
m_impl->SetFocus( focus );
|
||||
}
|
||||
@@ -1,60 +0,0 @@
|
||||
/*
|
||||
* This program source code file is part of KiCad, a free EDA CAD application.
|
||||
*
|
||||
* Copyright (C) 2021 3Dconnexion
|
||||
* Copyright (C) 2021 KiCad Developers, see AUTHORS.txt for contributors.
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License as published by the
|
||||
* Free Software Foundation, either version 3 of the License, or (at your
|
||||
* option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but
|
||||
* WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along
|
||||
* with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @file nl_3d_viewer_plugin.h
|
||||
* @brief Declaration of the NL_3D_VIEWER_PLUGIN class
|
||||
*/
|
||||
|
||||
#ifndef NL_3D_VIEWER_PLUGIN_H_
|
||||
#define NL_3D_VIEWER_PLUGIN_H_
|
||||
|
||||
// Forward declarations.
|
||||
class EDA_3D_CANVAS;
|
||||
class NL_3D_VIEWER_PLUGIN_IMPL;
|
||||
|
||||
/**
|
||||
* The class that implements the public interface to the SpaceMouse plug-in.
|
||||
*/
|
||||
class NL_3D_VIEWER_PLUGIN
|
||||
{
|
||||
public:
|
||||
/**
|
||||
* Initializes a new instance of the NL_3D_VIEWER_PLUGIN.
|
||||
*
|
||||
* @param aViewport is the viewport to be navigated.
|
||||
*/
|
||||
NL_3D_VIEWER_PLUGIN( EDA_3D_CANVAS* aViewport );
|
||||
|
||||
virtual ~NL_3D_VIEWER_PLUGIN();
|
||||
|
||||
/**
|
||||
* Set the connection to the 3Dconnexion driver to the focus state so that
|
||||
* 3DMouse data is routed here.
|
||||
*
|
||||
* @param aFocus is true to set the connection active.
|
||||
*/
|
||||
void SetFocus( bool aFocus = true );
|
||||
|
||||
private:
|
||||
NL_3D_VIEWER_PLUGIN_IMPL* m_impl;
|
||||
};
|
||||
|
||||
#endif // NL_3D_VIEWER_PLUGIN_H_
|
||||
@@ -1,662 +0,0 @@
|
||||
/*
|
||||
* This program source code file is part of KiCad, a free EDA CAD application.
|
||||
*
|
||||
* Copyright (C) 2021 3Dconnexion
|
||||
* Copyright (C) 2021 KiCad Developers, see AUTHORS.txt for contributors.
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License as published by the
|
||||
* Free Software Foundation, either version 3 of the License, or (at your
|
||||
* option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but
|
||||
* WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along
|
||||
* with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "nl_3d_viewer_plugin_impl.h"
|
||||
|
||||
// 3d-viewer
|
||||
#include <3d-viewer/3d_rendering/track_ball.h>
|
||||
#include <3d-viewer/3d_canvas/eda_3d_canvas.h>
|
||||
|
||||
// KiCAD includes
|
||||
#include <tool/action_manager.h>
|
||||
#include <tool/tool_manager.h>
|
||||
|
||||
// stdlib
|
||||
#include <map>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
#include <wx/mstream.h>
|
||||
|
||||
/**
|
||||
* Flag to enable the NL_3D_VIEWER_PLUGIN debug tracing.
|
||||
*
|
||||
* Use "KI_TRACE_NL_3D_VIEWER_PLUGIN" to enable.
|
||||
*
|
||||
* @ingroup trace_env_vars
|
||||
*/
|
||||
const wxChar* NL_3D_VIEWER_PLUGIN_IMPL::m_logTrace = wxT( "KI_TRACE_NL_3D_VIEWER_PLUGIN" );
|
||||
|
||||
|
||||
/**
|
||||
* Template to compare two glm::mat<T> values for equality within a required epsilon.
|
||||
*
|
||||
* @param aFirst value to compare.
|
||||
* @param aSecond value to compare.
|
||||
* @param aEpsilon allowed error.
|
||||
* @return true if the values considered equal within the specified epsilon, otherwise false.
|
||||
*/
|
||||
template <glm::length_t L, glm::length_t C, class T, glm::qualifier Q>
|
||||
bool equals( glm::mat<L, C, T, Q> const& aFirst, glm::mat<L, C, T, Q> const& aSecond,
|
||||
T aEpsilon = static_cast<T>( FLT_EPSILON * 10 ) )
|
||||
{
|
||||
T const* first = glm::value_ptr( aFirst );
|
||||
T const* second = glm::value_ptr( aSecond );
|
||||
|
||||
for( glm::length_t j = 0; j < L * C; ++j )
|
||||
{
|
||||
if( !equals( first[j], second[j], aEpsilon ) )
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
NL_3D_VIEWER_PLUGIN_IMPL::NL_3D_VIEWER_PLUGIN_IMPL( EDA_3D_CANVAS* aCanvas ) :
|
||||
NAV_3D( false, false ),
|
||||
m_canvas( aCanvas ),
|
||||
m_capIsMoving( false ),
|
||||
m_newWidth( 0.0 )
|
||||
{
|
||||
m_camera = dynamic_cast<TRACK_BALL*>( m_canvas->GetCamera() );
|
||||
|
||||
PutProfileHint( "KiCAD 3D" );
|
||||
|
||||
EnableNavigation( true );
|
||||
PutFrameTimingSource( TimingSource::SpaceMouse );
|
||||
|
||||
exportCommandsAndImages();
|
||||
}
|
||||
|
||||
|
||||
NL_3D_VIEWER_PLUGIN_IMPL::~NL_3D_VIEWER_PLUGIN_IMPL()
|
||||
{
|
||||
EnableNavigation( false );
|
||||
}
|
||||
|
||||
|
||||
void NL_3D_VIEWER_PLUGIN_IMPL::SetFocus( bool aFocus )
|
||||
{
|
||||
wxLogTrace( m_logTrace, wxT( "NL_3D_VIEWER_PLUGIN_IMPL::SetFocus %d" ), aFocus );
|
||||
NAV_3D::Write( navlib::focus_k, aFocus );
|
||||
}
|
||||
|
||||
// temporary store for the categories
|
||||
typedef std::map<std::string, TDx::CCommandTreeNode*> CATEGORY_STORE;
|
||||
|
||||
/**
|
||||
* Add a category to the store.
|
||||
*
|
||||
* The function adds category paths of the format "A.B" where B is a sub-category of A.
|
||||
*
|
||||
* @param aCategoryPath is the std::string representation of the category.
|
||||
* @param aCategoryStore is the CATEGORY_STORE instance to add to.
|
||||
* @return a CATEGORY_STORE::iterator where the category was added.
|
||||
*/
|
||||
CATEGORY_STORE::iterator add_category( std::string aCategoryPath, CATEGORY_STORE& aCategoryStore )
|
||||
{
|
||||
using TDx::SpaceMouse::CCategory;
|
||||
|
||||
CATEGORY_STORE::iterator parent_iter = aCategoryStore.begin();
|
||||
std::string::size_type pos = aCategoryPath.find_last_of( '.' );
|
||||
|
||||
if( pos != std::string::npos )
|
||||
{
|
||||
std::string parentPath = aCategoryPath.substr( 0, pos );
|
||||
parent_iter = aCategoryStore.find( parentPath );
|
||||
|
||||
if( parent_iter == aCategoryStore.end() )
|
||||
{
|
||||
parent_iter = add_category( parentPath, aCategoryStore );
|
||||
}
|
||||
}
|
||||
|
||||
std::string name = aCategoryPath.substr( pos + 1 );
|
||||
std::unique_ptr<CCategory> categoryNode =
|
||||
std::make_unique<CCategory>( aCategoryPath.c_str(), name.c_str() );
|
||||
|
||||
CATEGORY_STORE::iterator iter = aCategoryStore.insert(
|
||||
aCategoryStore.end(), CATEGORY_STORE::value_type( aCategoryPath, categoryNode.get() ) );
|
||||
|
||||
parent_iter->second->push_back( std::move( categoryNode ) );
|
||||
return iter;
|
||||
}
|
||||
|
||||
|
||||
void NL_3D_VIEWER_PLUGIN_IMPL::exportCommandsAndImages()
|
||||
{
|
||||
wxLogTrace( m_logTrace, wxT( "NL_3D_VIEWER_PLUGIN_IMPL::exportCommandsAndImages" ) );
|
||||
|
||||
std::list<TOOL_ACTION*> actions = ACTION_MANAGER::GetActionList();
|
||||
|
||||
if( actions.size() == 0 )
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
using TDx::SpaceMouse::CCommand;
|
||||
using TDx::SpaceMouse::CCommandSet;
|
||||
|
||||
// The root action set node
|
||||
CCommandSet commandSet( "EDA_3D_CANVAS", "3D Viewer" );
|
||||
|
||||
// Activate the command set
|
||||
NAV_3D::PutActiveCommands( commandSet.GetId() );
|
||||
|
||||
// temporary store for the categories
|
||||
CATEGORY_STORE categoryStore;
|
||||
|
||||
std::vector<TDx::CImage> vImages;
|
||||
|
||||
// add the action set to the category_store
|
||||
categoryStore.insert( categoryStore.end(), CATEGORY_STORE::value_type( ".", &commandSet ) );
|
||||
|
||||
std::list<TOOL_ACTION*>::const_iterator it;
|
||||
|
||||
for( it = actions.begin(); it != actions.end(); ++it )
|
||||
{
|
||||
const TOOL_ACTION* action = *it;
|
||||
std::string label = action->GetMenuLabel().ToStdString();
|
||||
|
||||
if( label.empty() )
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
std::string name = action->GetName();
|
||||
|
||||
// Do no export commands for the pcbnew app.
|
||||
if( name.rfind( "pcbnew.", 0 ) == 0 )
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
std::string strCategory = action->GetToolName();
|
||||
CATEGORY_STORE::iterator iter = categoryStore.find( strCategory );
|
||||
|
||||
if( iter == categoryStore.end() )
|
||||
{
|
||||
iter = add_category( std::move( strCategory ), categoryStore );
|
||||
}
|
||||
|
||||
std::string description = action->GetDescription().ToStdString();
|
||||
|
||||
// Arbitrary 8-bit data stream
|
||||
wxMemoryOutputStream imageStream;
|
||||
|
||||
if( action->GetIcon() != BITMAPS::INVALID_BITMAP )
|
||||
{
|
||||
wxImage image = KiBitmap( action->GetIcon() ).ConvertToImage();
|
||||
image.SaveFile( imageStream, wxBitmapType::wxBITMAP_TYPE_PNG );
|
||||
image.Destroy();
|
||||
|
||||
if( imageStream.GetSize() )
|
||||
{
|
||||
wxStreamBuffer* streamBuffer = imageStream.GetOutputStreamBuffer();
|
||||
TDx::CImage tdxImage = TDx::CImage::FromData( "", 0, name.c_str() );
|
||||
tdxImage.AssignImage( std::string( reinterpret_cast<const char*>(
|
||||
streamBuffer->GetBufferStart() ),
|
||||
streamBuffer->GetBufferSize() ),
|
||||
0 );
|
||||
|
||||
wxLogTrace( m_logTrace, wxT( "Adding image for : %s" ), name );
|
||||
vImages.push_back( std::move( tdxImage ) );
|
||||
}
|
||||
}
|
||||
|
||||
wxLogTrace( m_logTrace, wxT( "Inserting command: %s, description: %s, in category: %s" ),
|
||||
name, description, iter->first );
|
||||
|
||||
iter->second->push_back(
|
||||
CCommand( std::move( name ), std::move( label ), std::move( description ) ) );
|
||||
}
|
||||
|
||||
NAV_3D::AddCommandSet( commandSet );
|
||||
NAV_3D::AddImages( vImages );
|
||||
}
|
||||
|
||||
|
||||
long NL_3D_VIEWER_PLUGIN_IMPL::GetCameraMatrix( navlib::matrix_t& matrix ) const
|
||||
{
|
||||
// cache the camera matrix so that we can tell if the view has been moved and
|
||||
// calculate a delta transform if required.
|
||||
m_cameraMatrix = m_camera->GetViewMatrix();
|
||||
|
||||
std::copy_n( glm::value_ptr( glm::inverse( m_cameraMatrix ) ), 16, matrix.m );
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
long NL_3D_VIEWER_PLUGIN_IMPL::GetPointerPosition( navlib::point_t& position ) const
|
||||
{
|
||||
SFVEC3F origin, direction;
|
||||
m_camera->MakeRayAtCurrentMousePosition( origin, direction );
|
||||
|
||||
position = { origin.x, origin.y, origin.z };
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
long NL_3D_VIEWER_PLUGIN_IMPL::GetViewExtents( navlib::box_t& extents ) const
|
||||
{
|
||||
if( m_camera->GetProjection() == PROJECTION_TYPE::PERSPECTIVE )
|
||||
{
|
||||
return navlib::make_result_code( navlib::navlib_errc::invalid_operation );
|
||||
}
|
||||
|
||||
const CAMERA_FRUSTUM& f = m_camera->GetFrustum();
|
||||
|
||||
double half_width = f.fw / 2.;
|
||||
double half_height = f.fh / 2.;
|
||||
extents = { -half_width, -half_height, f.nearD, half_width, half_height, f.farD };
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
long NL_3D_VIEWER_PLUGIN_IMPL::GetViewFOV( double& aFov ) const
|
||||
{
|
||||
const CAMERA_FRUSTUM& f = m_camera->GetFrustum();
|
||||
|
||||
aFov = glm::radians( f.angle );
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
long NL_3D_VIEWER_PLUGIN_IMPL::GetViewFrustum( navlib::frustum_t& aFrustum ) const
|
||||
{
|
||||
if( m_camera->GetProjection() != PROJECTION_TYPE::PERSPECTIVE )
|
||||
{
|
||||
return navlib::make_result_code( navlib::navlib_errc::invalid_operation );
|
||||
}
|
||||
|
||||
const CAMERA_FRUSTUM& f = m_camera->GetFrustum();
|
||||
double half_width = f.nw / 2.;
|
||||
double half_height = f.nh / 2.;
|
||||
aFrustum = { -half_width, half_width, -half_height, half_height, f.nearD, f.farD };
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
long NL_3D_VIEWER_PLUGIN_IMPL::GetIsViewPerspective( navlib::bool_t& perspective ) const
|
||||
{
|
||||
perspective = m_camera->GetProjection() == PROJECTION_TYPE::PERSPECTIVE ? 1 : 0;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
long NL_3D_VIEWER_PLUGIN_IMPL::SetCameraMatrix( const navlib::matrix_t& aCameraMatrix )
|
||||
{
|
||||
long result = 0;
|
||||
|
||||
glm::mat4 cam, viewMatrix;
|
||||
std::copy_n( aCameraMatrix.m, 16, glm::value_ptr( cam ) );
|
||||
viewMatrix = glm::inverse( cam );
|
||||
|
||||
glm::mat4 camera = m_camera->GetViewMatrix();
|
||||
|
||||
// The navlib does not move the camera in its z-axis in an orthographic projection
|
||||
// as this does not change the viewed object size. However ...
|
||||
|
||||
if( m_camera->GetProjection() == PROJECTION_TYPE::ORTHO )
|
||||
{
|
||||
// ... the CAMERA class couples zoom and distance to the object: we need to
|
||||
// ensure that The CAMERA's z position relative to the lookat_pos is not changed
|
||||
// in an orthographic projection.
|
||||
glm::vec4 lookat( m_camera->GetLookAtPos(), 1.0f );
|
||||
glm::vec4 lookat_new = viewMatrix * lookat;
|
||||
glm::vec4 lookat_old = camera * lookat;
|
||||
|
||||
viewMatrix[3].z += lookat_old.z - lookat_new.z;
|
||||
}
|
||||
|
||||
if( !equals( camera, m_cameraMatrix ) )
|
||||
{
|
||||
// Some other input device has moved the camera. Apply only the intended delta
|
||||
// transform ...
|
||||
m_camera->SetViewMatrix( viewMatrix * glm::inverse( m_cameraMatrix ) * camera );
|
||||
m_camera->Update();
|
||||
|
||||
// .., cache the intended camera matrix so that we can calculate the delta
|
||||
// transform when needed ...
|
||||
m_cameraMatrix = viewMatrix;
|
||||
|
||||
// ... and let the 3DMouse controller know, that something is amiss.
|
||||
return navlib::make_result_code( navlib::navlib_errc::error );
|
||||
}
|
||||
|
||||
m_camera->SetViewMatrix( viewMatrix );
|
||||
m_camera->Update();
|
||||
|
||||
// cache the view matrix so that we know when it has changed.
|
||||
m_cameraMatrix = m_camera->GetViewMatrix();
|
||||
|
||||
// The camera has a constraint on the z position so we need to check that ...
|
||||
|
||||
if( !equals( m_cameraMatrix[3].z, viewMatrix[3].z ) )
|
||||
{
|
||||
// ... and let the 3DMouse controller know, when something is amiss.
|
||||
return navlib::make_result_code( navlib::navlib_errc::error );
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
long NL_3D_VIEWER_PLUGIN_IMPL::SetViewExtents( const navlib::box_t& extents )
|
||||
{
|
||||
const CAMERA_FRUSTUM& f = m_camera->GetFrustum();
|
||||
|
||||
float factor = f.nw / ( extents.max_x - extents.min_x );
|
||||
float zoom = m_camera->GetZoom() / factor;
|
||||
|
||||
m_camera->Zoom( factor );
|
||||
|
||||
// The camera auto positions the camera to match the zoom values. We need to
|
||||
// update our cached camera matrix to match the new z value
|
||||
m_cameraMatrix[3].z = m_camera->GetViewMatrix()[3].z;
|
||||
|
||||
// The camera has a constraint on the zoom factor so we need to check that ...
|
||||
if( zoom != m_camera->GetZoom() )
|
||||
{
|
||||
// ... and let the 3DMouse controller know, when something is amiss.
|
||||
return navlib::make_result_code( navlib::navlib_errc::error );
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
long NL_3D_VIEWER_PLUGIN_IMPL::SetViewFOV( double fov )
|
||||
{
|
||||
return navlib::make_result_code( navlib::navlib_errc::function_not_supported );
|
||||
}
|
||||
|
||||
|
||||
long NL_3D_VIEWER_PLUGIN_IMPL::SetViewFrustum( const navlib::frustum_t& frustum )
|
||||
{
|
||||
return navlib::make_result_code( navlib::navlib_errc::permission_denied );
|
||||
}
|
||||
|
||||
|
||||
long NL_3D_VIEWER_PLUGIN_IMPL::GetModelExtents( navlib::box_t& extents ) const
|
||||
{
|
||||
SFVEC3F min = m_canvas->GetBoardAdapter().GetBBox().Min();
|
||||
SFVEC3F max = m_canvas->GetBoardAdapter().GetBBox().Max();
|
||||
|
||||
extents = { min.x, min.y, min.z, max.x, max.y, max.z };
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
long NL_3D_VIEWER_PLUGIN_IMPL::GetSelectionExtents( navlib::box_t& extents ) const
|
||||
{
|
||||
return navlib::make_result_code( navlib::navlib_errc::no_data_available );
|
||||
}
|
||||
|
||||
|
||||
long NL_3D_VIEWER_PLUGIN_IMPL::GetSelectionTransform( navlib::matrix_t& transform ) const
|
||||
{
|
||||
return navlib::make_result_code( navlib::navlib_errc::no_data_available );
|
||||
}
|
||||
|
||||
|
||||
long NL_3D_VIEWER_PLUGIN_IMPL::GetIsSelectionEmpty( navlib::bool_t& empty ) const
|
||||
{
|
||||
empty = true;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
long NL_3D_VIEWER_PLUGIN_IMPL::SetSelectionTransform( const navlib::matrix_t& matrix )
|
||||
{
|
||||
return navlib::make_result_code( navlib::navlib_errc::invalid_operation );
|
||||
}
|
||||
|
||||
|
||||
long NL_3D_VIEWER_PLUGIN_IMPL::GetPivotPosition( navlib::point_t& position ) const
|
||||
{
|
||||
SFVEC3F lap = m_camera->GetLookAtPos();
|
||||
|
||||
position = { lap.x, lap.y, lap.z };
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
long NL_3D_VIEWER_PLUGIN_IMPL::IsUserPivot( navlib::bool_t& userPivot ) const
|
||||
{
|
||||
userPivot = false;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
long NL_3D_VIEWER_PLUGIN_IMPL::SetPivotPosition( const navlib::point_t& position )
|
||||
{
|
||||
SFVEC3F pivotPos = SFVEC3F( position.x, position.y, position.z );
|
||||
|
||||
// Set the 3dmouse pivot position.
|
||||
m_canvas->Set3dmousePivotPos( pivotPos );
|
||||
|
||||
// Set the camera lookat pos.
|
||||
m_camera->SetLookAtPos_T1( pivotPos );
|
||||
|
||||
m_canvas->Request_refresh();
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
long NL_3D_VIEWER_PLUGIN_IMPL::GetPivotVisible( navlib::bool_t& visible ) const
|
||||
{
|
||||
visible = m_canvas->GetRender3dmousePivot();
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
long NL_3D_VIEWER_PLUGIN_IMPL::SetPivotVisible( bool visible )
|
||||
{
|
||||
m_canvas->SetRender3dmousePivot( visible );
|
||||
|
||||
m_canvas->Request_refresh();
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
long NL_3D_VIEWER_PLUGIN_IMPL::GetHitLookAt( navlib::point_t& position ) const
|
||||
{
|
||||
RAY mouseRay;
|
||||
mouseRay.Init( m_rayOrigin, m_rayDirection );
|
||||
|
||||
float hit;
|
||||
glm::vec3 vec;
|
||||
|
||||
// Test it with the board bounding box
|
||||
|
||||
if( m_canvas->GetBoardAdapter().GetBBox().Intersect( mouseRay, &hit ) )
|
||||
{
|
||||
vec = mouseRay.at( hit );
|
||||
position = { vec.x, vec.y, vec.z };
|
||||
return 0;
|
||||
}
|
||||
|
||||
return navlib::make_result_code( navlib::navlib_errc::no_data_available );
|
||||
}
|
||||
|
||||
|
||||
long NL_3D_VIEWER_PLUGIN_IMPL::SetHitAperture( double aperture )
|
||||
{
|
||||
return navlib::make_result_code( navlib::navlib_errc::function_not_supported );
|
||||
}
|
||||
|
||||
|
||||
long NL_3D_VIEWER_PLUGIN_IMPL::SetHitDirection( const navlib::vector_t& direction )
|
||||
{
|
||||
m_rayDirection = { direction.x, direction.y, direction.z };
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
long NL_3D_VIEWER_PLUGIN_IMPL::SetHitLookFrom( const navlib::point_t& eye )
|
||||
{
|
||||
m_rayOrigin = { eye.x, eye.y, eye.z };
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
long NL_3D_VIEWER_PLUGIN_IMPL::SetHitSelectionOnly( bool onlySelection )
|
||||
{
|
||||
return navlib::make_result_code( navlib::navlib_errc::function_not_supported );
|
||||
}
|
||||
|
||||
|
||||
long NL_3D_VIEWER_PLUGIN_IMPL::SetActiveCommand( std::string commandId )
|
||||
{
|
||||
if( commandId.empty() )
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
std::list<TOOL_ACTION*> actions = ACTION_MANAGER::GetActionList();
|
||||
TOOL_ACTION* context = nullptr;
|
||||
|
||||
for( std::list<TOOL_ACTION*>::const_iterator it = actions.begin(); it != actions.end(); it++ )
|
||||
{
|
||||
TOOL_ACTION* action = *it;
|
||||
std::string nm = action->GetName();
|
||||
|
||||
if( commandId == nm )
|
||||
{
|
||||
context = action;
|
||||
}
|
||||
}
|
||||
|
||||
if( context != nullptr )
|
||||
{
|
||||
wxWindow* parent = m_canvas->GetParent();
|
||||
|
||||
// Only allow command execution if the window is enabled. i.e. there is not a modal dialog
|
||||
// currently active.
|
||||
|
||||
if( parent->IsEnabled() )
|
||||
{
|
||||
TOOL_MANAGER* tool_manager = static_cast<PCB_BASE_FRAME*>( parent )->GetToolManager();
|
||||
|
||||
if( tool_manager == nullptr )
|
||||
{
|
||||
return navlib::make_result_code( navlib::navlib_errc::invalid_operation );
|
||||
}
|
||||
|
||||
// Get the selection to use to test if the action is enabled
|
||||
SELECTION& sel = tool_manager->GetToolHolder()->GetCurrentSelection();
|
||||
|
||||
bool runAction = true;
|
||||
|
||||
if( const ACTION_CONDITIONS* aCond =
|
||||
tool_manager->GetActionManager()->GetCondition( *context ) )
|
||||
{
|
||||
runAction = aCond->enableCondition( sel );
|
||||
}
|
||||
|
||||
if( runAction )
|
||||
{
|
||||
tool_manager->RunAction( *context );
|
||||
m_canvas->Request_refresh();
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
return navlib::make_result_code( navlib::navlib_errc::invalid_operation );
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
long NL_3D_VIEWER_PLUGIN_IMPL::SetSettingsChanged( long change )
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
long NL_3D_VIEWER_PLUGIN_IMPL::SetMotionFlag( bool value )
|
||||
{
|
||||
m_capIsMoving = value;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
long NL_3D_VIEWER_PLUGIN_IMPL::SetTransaction( long value )
|
||||
{
|
||||
if( value != 0L )
|
||||
{
|
||||
}
|
||||
else
|
||||
{
|
||||
m_canvas->Request_refresh( true );
|
||||
wxLogTrace( m_logTrace, wxT( "End of transaction" ) );
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
long NL_3D_VIEWER_PLUGIN_IMPL::SetCameraTarget( const navlib::point_t& position )
|
||||
{
|
||||
return navlib::make_result_code( navlib::navlib_errc::function_not_supported );
|
||||
}
|
||||
|
||||
|
||||
long NL_3D_VIEWER_PLUGIN_IMPL::GetFrontView( navlib::matrix_t& matrix ) const
|
||||
{
|
||||
matrix = { 1, 0, 0, 0, 0, 0, 1, 0, 0, -1, 0, 0, 0, 0, 0, 1 };
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
long NL_3D_VIEWER_PLUGIN_IMPL::GetCoordinateSystem( navlib::matrix_t& matrix ) const
|
||||
{
|
||||
// Use the right-handed coordinate system X-right, Z-up, Y-in (row vectors)
|
||||
matrix = { 1, 0, 0, 0, 0, 0, -1, 0, 0, 1, 0, 0, 0, 0, 0, 1 };
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
long NL_3D_VIEWER_PLUGIN_IMPL::GetIsViewRotatable( navlib::bool_t& isRotatable ) const
|
||||
{
|
||||
isRotatable = true;
|
||||
return 0;
|
||||
}
|
||||
@@ -1,136 +0,0 @@
|
||||
/*
|
||||
* This program source code file is part of KiCad, a free EDA CAD application.
|
||||
*
|
||||
* Copyright (C) 2021 3Dconnexion
|
||||
* Copyright (C) 2021 KiCad Developers, see AUTHORS.txt for contributors.
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License as published by the
|
||||
* Free Software Foundation, either version 3 of the License, or (at your
|
||||
* option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but
|
||||
* WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along
|
||||
* with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @file nl_3d_viewer_plugin_impl.h
|
||||
* @brief Declaration of the NL_3D_VIEWER_PLUGIN_IMPL class
|
||||
*/
|
||||
|
||||
#ifndef NL_3D_VIEWER_PLUGIN_IMPL_H_
|
||||
#define NL_3D_VIEWER_PLUGIN_IMPL_H_
|
||||
|
||||
// TDxWare SDK.
|
||||
#include <SpaceMouse/CNavigation3D.hpp>
|
||||
|
||||
// KiCAD
|
||||
#include <include/plugins/3dapi/xv3d_types.h>
|
||||
|
||||
// wx
|
||||
#include <wx/chartype.h>
|
||||
|
||||
// glm
|
||||
#include <glm/glm.hpp>
|
||||
|
||||
// Forward declarations.
|
||||
class EDA_3D_CANVAS;
|
||||
class TRACK_BALL;
|
||||
|
||||
// Convenience typedef.
|
||||
typedef TDx::SpaceMouse::Navigation3D::CNavigation3D NAV_3D;
|
||||
|
||||
/**
|
||||
* The class that implements the accessors and mutators required for
|
||||
* 3D navigation in an EDA_3D_CANVAS using a SpaceMouse.
|
||||
*/
|
||||
class NL_3D_VIEWER_PLUGIN_IMPL : public NAV_3D
|
||||
{
|
||||
public:
|
||||
/**
|
||||
* Initializes a new instance of the NL_3DVIEWER_PLUGIN.
|
||||
*
|
||||
* @param aCanvas is the viewport to be navigated.
|
||||
*/
|
||||
NL_3D_VIEWER_PLUGIN_IMPL( EDA_3D_CANVAS* aCanvas );
|
||||
|
||||
virtual ~NL_3D_VIEWER_PLUGIN_IMPL();
|
||||
|
||||
/**
|
||||
* Set the connection to the 3Dconnexion driver to the focus state so that
|
||||
* 3DMouse data is routed here.
|
||||
*
|
||||
* @param aFocus is true to set the connection active.
|
||||
*/
|
||||
void SetFocus( bool aFocus = true );
|
||||
|
||||
private:
|
||||
/**
|
||||
* Export the invocable actions and images to the 3Dconnexion UI.
|
||||
*/
|
||||
void exportCommandsAndImages();
|
||||
|
||||
long GetCameraMatrix( navlib::matrix_t& aMatrix ) const override;
|
||||
long GetPointerPosition( navlib::point_t& aPosition ) const override;
|
||||
long GetViewExtents( navlib::box_t& aExtents ) const override;
|
||||
long GetViewFOV( double& aFov ) const override;
|
||||
long GetViewFrustum( navlib::frustum_t& aFrustum ) const override;
|
||||
long GetIsViewPerspective( navlib::bool_t& aPerspective ) const override;
|
||||
long SetCameraMatrix( const navlib::matrix_t& aMatrix ) override;
|
||||
long SetViewExtents( const navlib::box_t& aExtents ) override;
|
||||
long SetViewFOV( double aFov ) override;
|
||||
long SetViewFrustum( const navlib::frustum_t& aFrustum ) override;
|
||||
long GetModelExtents( navlib::box_t& aExtents ) const override;
|
||||
long GetSelectionExtents( navlib::box_t& aExtents ) const override;
|
||||
long GetSelectionTransform( navlib::matrix_t& aTransform ) const override;
|
||||
long GetIsSelectionEmpty( navlib::bool_t& aEmpty ) const override;
|
||||
long SetSelectionTransform( const navlib::matrix_t& aMatrix ) override;
|
||||
long GetPivotPosition( navlib::point_t& aPosition ) const override;
|
||||
long IsUserPivot( navlib::bool_t& aUserPivot ) const override;
|
||||
long SetPivotPosition( const navlib::point_t& aPosition ) override;
|
||||
long GetPivotVisible( navlib::bool_t& aVisible ) const override;
|
||||
long SetPivotVisible( bool aVisible ) override;
|
||||
long GetHitLookAt( navlib::point_t& aPosition ) const override;
|
||||
long SetHitAperture( double aAperture ) override;
|
||||
long SetHitDirection( const navlib::vector_t& aDirection ) override;
|
||||
long SetHitLookFrom( const navlib::point_t& aPosition ) override;
|
||||
long SetHitSelectionOnly( bool aSelectionOnly ) override;
|
||||
long SetActiveCommand( std::string aCommandId ) override;
|
||||
|
||||
long SetSettingsChanged( long aChangeNumber ) override;
|
||||
long SetMotionFlag( bool aValue ) override;
|
||||
long SetTransaction( long aValue ) override;
|
||||
long SetCameraTarget( const navlib::point_t& aPosition ) override;
|
||||
|
||||
long GetFrontView( navlib::matrix_t& aMatrix ) const override;
|
||||
long GetCoordinateSystem( navlib::matrix_t& aMatrix ) const override;
|
||||
long GetIsViewRotatable( navlib::bool_t& isRotatable ) const override;
|
||||
|
||||
private:
|
||||
EDA_3D_CANVAS* m_canvas;
|
||||
TRACK_BALL* m_camera;
|
||||
bool m_capIsMoving;
|
||||
double m_newWidth;
|
||||
SFVEC3F m_rayOrigin;
|
||||
SFVEC3F m_rayDirection;
|
||||
|
||||
// The cached CAMERA affine matrix. This is used to determine if the camera has been
|
||||
// moved. The camera matrix is the world to camera affine.
|
||||
mutable glm::mat4 m_cameraMatrix;
|
||||
|
||||
|
||||
/**
|
||||
* Trace mask used to enable or disable the trace output of this class.
|
||||
* The debug output can be turned on by setting the WXTRACE environment variable to
|
||||
* "KI_TRACE_NL_3DVIEWER_PLUGIN". See the wxWidgets documentation on wxLogTrace for
|
||||
* more information.
|
||||
*/
|
||||
static const wxChar* m_logTrace;
|
||||
};
|
||||
|
||||
#endif // NL_3D_VIEWER_PLUGIN_IMPL_H_
|
||||
@@ -26,9 +26,9 @@
|
||||
* @file camera.cpp
|
||||
*/
|
||||
|
||||
#include <gal/3d/camera.h>
|
||||
#include "camera.h"
|
||||
#include <wx/log.h>
|
||||
#include <algorithm>
|
||||
|
||||
|
||||
// A helper function to normalize aAngle between -2PI and +2PI
|
||||
inline void normalise2PI( float& aAngle )
|
||||
@@ -46,8 +46,9 @@ inline void normalise2PI( float& aAngle )
|
||||
*/
|
||||
const wxChar *CAMERA::m_logTrace = wxT( "KI_TRACE_CAMERA" );
|
||||
|
||||
const float CAMERA::DEFAULT_MIN_ZOOM = 0.020f;
|
||||
const float CAMERA::DEFAULT_MAX_ZOOM = 2.0f;
|
||||
|
||||
#define DEFAULT_MIN_ZOOM 0.10f
|
||||
#define DEFAULT_MAX_ZOOM 1.20f
|
||||
|
||||
|
||||
CAMERA::CAMERA( float aInitialDistance )
|
||||
@@ -120,21 +121,6 @@ void CAMERA::Reset_T1()
|
||||
}
|
||||
|
||||
|
||||
void CAMERA::SetBoardLookAtPos( const SFVEC3F& aBoardPos )
|
||||
{
|
||||
if( m_board_lookat_pos_init != aBoardPos )
|
||||
{
|
||||
m_board_lookat_pos_init = aBoardPos;
|
||||
m_lookat_pos = aBoardPos;
|
||||
|
||||
m_parametersChanged = true;
|
||||
|
||||
updateViewMatrix();
|
||||
updateFrustum();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void CAMERA::zoomChanged()
|
||||
{
|
||||
if( m_zoom < m_minZoom )
|
||||
@@ -179,20 +165,12 @@ void CAMERA::updateRotationMatrix()
|
||||
}
|
||||
|
||||
|
||||
glm::mat4 CAMERA::GetRotationMatrix() const
|
||||
const glm::mat4 CAMERA::GetRotationMatrix() const
|
||||
{
|
||||
return m_rotationMatrix * m_rotationMatrixAux;
|
||||
}
|
||||
|
||||
|
||||
void CAMERA::SetRotationMatrix( const glm::mat4& aRotation )
|
||||
{
|
||||
m_parametersChanged = true;
|
||||
std::copy_n( glm::value_ptr( aRotation * glm::inverse( m_rotationMatrixAux ) ), 12,
|
||||
glm::value_ptr( m_rotationMatrix ) );
|
||||
}
|
||||
|
||||
|
||||
void CAMERA::rebuildProjection()
|
||||
{
|
||||
if( ( m_windowSize.x == 0 ) || ( m_windowSize.y == 0 ) )
|
||||
@@ -208,6 +186,7 @@ void CAMERA::rebuildProjection()
|
||||
|
||||
m_frustum.nearD = 0.10f;
|
||||
|
||||
// Ratio width / height of the window display
|
||||
m_frustum.angle = 45.0f;
|
||||
|
||||
m_projectionMatrix = glm::perspective( glm::radians( m_frustum.angle ), m_frustum.ratio,
|
||||
@@ -220,22 +199,19 @@ void CAMERA::rebuildProjection()
|
||||
m_focalLen.x = ( (float)m_windowSize.y / (float)m_windowSize.x ) / m_frustum.tang;
|
||||
m_focalLen.y = 1.0f / m_frustum.tang;
|
||||
|
||||
m_frustum.nh = 2.0f * m_frustum.nearD * m_frustum.tang;
|
||||
m_frustum.nh = m_frustum.nearD * m_frustum.tang;
|
||||
m_frustum.nw = m_frustum.nh * m_frustum.ratio;
|
||||
m_frustum.fh = 2.0f * m_frustum.farD * m_frustum.tang;
|
||||
m_frustum.fh = m_frustum.farD * m_frustum.tang;
|
||||
m_frustum.fw = m_frustum.fh * m_frustum.ratio;
|
||||
break;
|
||||
|
||||
case PROJECTION_TYPE::ORTHO:
|
||||
|
||||
// Keep the viewed plane at (m_camera_pos_init * m_zoom) the same dimensions in both projections.
|
||||
m_frustum.angle = 45.0f;
|
||||
m_frustum.tang = glm::tan( glm::radians( m_frustum.angle ) * 0.5f );
|
||||
|
||||
m_frustum.nearD = -m_frustum.farD; // Use a symmetrical clip plane for ortho projection
|
||||
|
||||
const float orthoReductionFactor =
|
||||
glm::length( m_camera_pos_init ) * m_zoom * m_frustum.tang;
|
||||
// This formula was found by trial and error
|
||||
const float orthoReductionFactor = glm::length( m_camera_pos_init ) *
|
||||
m_zoom * m_zoom * 0.5f;
|
||||
|
||||
// Initialize Projection Matrix for Orthographic View
|
||||
m_projectionMatrix = glm::ortho( -m_frustum.ratio * orthoReductionFactor,
|
||||
@@ -307,26 +283,21 @@ void CAMERA::updateFrustum()
|
||||
* http://www.lighthouse3d.com/tutorials/view-frustum-culling/
|
||||
*/
|
||||
|
||||
const SFVEC3F half_right_nw = m_right * m_frustum.nw * 0.5f;
|
||||
const SFVEC3F half_right_fw = m_right * m_frustum.fw * 0.5f;
|
||||
const SFVEC3F half_up_nh = m_up * m_frustum.nh * 0.5f;
|
||||
const SFVEC3F half_up_fh = m_up * m_frustum.fh * 0.5f;
|
||||
|
||||
// compute the centers of the near and far planes
|
||||
m_frustum.nc = m_pos - m_dir * m_frustum.nearD;
|
||||
m_frustum.fc = m_pos - m_dir * m_frustum.farD;
|
||||
|
||||
// compute the 4 corners of the frustum on the near plane
|
||||
m_frustum.ntl = m_frustum.nc + half_up_nh - half_right_nw;
|
||||
m_frustum.ntr = m_frustum.nc + half_up_nh + half_right_nw;
|
||||
m_frustum.nbl = m_frustum.nc - half_up_nh - half_right_nw;
|
||||
m_frustum.nbr = m_frustum.nc - half_up_nh + half_right_nw;
|
||||
m_frustum.ntl = m_frustum.nc + m_up * m_frustum.nh - m_right * m_frustum.nw;
|
||||
m_frustum.ntr = m_frustum.nc + m_up * m_frustum.nh + m_right * m_frustum.nw;
|
||||
m_frustum.nbl = m_frustum.nc - m_up * m_frustum.nh - m_right * m_frustum.nw;
|
||||
m_frustum.nbr = m_frustum.nc - m_up * m_frustum.nh + m_right * m_frustum.nw;
|
||||
|
||||
// compute the 4 corners of the frustum on the far plane
|
||||
m_frustum.ftl = m_frustum.fc + half_up_fh - half_right_fw;
|
||||
m_frustum.ftr = m_frustum.fc + half_up_fh + half_right_fw;
|
||||
m_frustum.fbl = m_frustum.fc - half_up_fh - half_right_fw;
|
||||
m_frustum.fbr = m_frustum.fc - half_up_fh + half_right_fw;
|
||||
m_frustum.ftl = m_frustum.fc + m_up * m_frustum.fh - m_right * m_frustum.fw;
|
||||
m_frustum.ftr = m_frustum.fc + m_up * m_frustum.fh + m_right * m_frustum.fw;
|
||||
m_frustum.fbl = m_frustum.fc - m_up * m_frustum.fh - m_right * m_frustum.fw;
|
||||
m_frustum.fbr = m_frustum.fc - m_up * m_frustum.fh + m_right * m_frustum.fw;
|
||||
|
||||
if( ( m_windowSize.x > 0 ) && ( m_windowSize.y > 0 ) )
|
||||
{
|
||||
@@ -335,12 +306,16 @@ void CAMERA::updateFrustum()
|
||||
m_up_nY.resize( m_windowSize.y + 1 );
|
||||
|
||||
// Precalc X values for camera -> ray generation
|
||||
const SFVEC3F right_nw = m_right * m_frustum.nw;
|
||||
|
||||
for( unsigned int x = 0; x < ( (unsigned int) m_windowSize.x + 1 ); ++x )
|
||||
m_right_nX[x] = half_right_nw * m_scr_nX[x];
|
||||
m_right_nX[x] = right_nw * m_scr_nX[x];
|
||||
|
||||
// Precalc Y values for camera -> ray generation
|
||||
const SFVEC3F up_nh = m_up * m_frustum.nh;
|
||||
|
||||
for( unsigned int y = 0; y < ( (unsigned int) m_windowSize.y + 1 ); ++y )
|
||||
m_up_nY[y] = half_up_nh * m_scr_nY[y];
|
||||
m_up_nY[y] = up_nh * m_scr_nY[y];
|
||||
}
|
||||
}
|
||||
|
||||
@@ -351,16 +326,18 @@ void CAMERA::MakeRay( const SFVEC2I& aWindowPos, SFVEC3F& aOutOrigin,
|
||||
wxASSERT( aWindowPos.x < m_windowSize.x );
|
||||
wxASSERT( aWindowPos.y < m_windowSize.y );
|
||||
|
||||
aOutOrigin = m_frustum.nc + m_up_nY[aWindowPos.y] + m_right_nX[aWindowPos.x];
|
||||
const SFVEC3F up_plus_right = m_up_nY[aWindowPos.y] + m_right_nX[aWindowPos.x];
|
||||
|
||||
switch( m_projectionType )
|
||||
{
|
||||
default:
|
||||
case PROJECTION_TYPE::PERSPECTIVE:
|
||||
aOutOrigin = up_plus_right + m_frustum.nc;
|
||||
aOutDirection = glm::normalize( aOutOrigin - m_pos );
|
||||
break;
|
||||
|
||||
case PROJECTION_TYPE::ORTHO:
|
||||
aOutOrigin = up_plus_right * 0.5f + m_frustum.nc;
|
||||
aOutDirection = -m_dir + SFVEC3F( FLT_EPSILON );
|
||||
break;
|
||||
}
|
||||
@@ -383,23 +360,23 @@ void CAMERA::MakeRay( const SFVEC2F& aWindowPos, SFVEC3F& aOutOrigin,
|
||||
m_right_nX[floorWinPos_i.x] * (1.0f - relativeWinPos.x) +
|
||||
m_right_nX[floorWinPos_i.x + 1] * relativeWinPos.x;
|
||||
|
||||
aOutOrigin = up_plus_right + m_frustum.nc;
|
||||
|
||||
switch( m_projectionType )
|
||||
{
|
||||
default:
|
||||
case PROJECTION_TYPE::PERSPECTIVE:
|
||||
aOutOrigin = up_plus_right + m_frustum.nc;
|
||||
aOutDirection = glm::normalize( aOutOrigin - m_pos );
|
||||
break;
|
||||
|
||||
case PROJECTION_TYPE::ORTHO:
|
||||
aOutOrigin = up_plus_right * 0.5f + m_frustum.nc;
|
||||
aOutDirection = -m_dir + SFVEC3F( FLT_EPSILON );
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void CAMERA::MakeRayAtCurrentMousePosition( SFVEC3F& aOutOrigin, SFVEC3F& aOutDirection ) const
|
||||
void CAMERA::MakeRayAtCurrrentMousePosition( SFVEC3F& aOutOrigin, SFVEC3F& aOutDirection ) const
|
||||
{
|
||||
const SFVEC2I windowPos = SFVEC2I( m_lastPosition.x, m_windowSize.y - m_lastPosition.y );
|
||||
|
||||
@@ -453,38 +430,6 @@ const glm::mat4& CAMERA::GetViewMatrix() const
|
||||
}
|
||||
|
||||
|
||||
void CAMERA::SetViewMatrix( glm::mat4 aViewMatrix )
|
||||
{
|
||||
SetRotationMatrix( aViewMatrix );
|
||||
|
||||
// The look at position in the view frame.
|
||||
glm::vec4 lookat = aViewMatrix * glm::vec4( m_lookat_pos, 1.0f );
|
||||
|
||||
wxLogTrace( m_logTrace,
|
||||
wxT( "CAMERA::SetViewMatrix aViewMatrix[3].z =%f, old_zoom=%f, new_zoom=%f, "
|
||||
"m[3].z=%f" ),
|
||||
aViewMatrix[3].z, m_zoom, lookat.z / m_camera_pos_init.z, lookat.z );
|
||||
|
||||
m_zoom = lookat.z / m_camera_pos_init.z;
|
||||
|
||||
if( m_zoom > m_maxZoom )
|
||||
{
|
||||
m_zoom = m_maxZoom;
|
||||
aViewMatrix[3].z += -lookat.z + m_maxZoom * m_camera_pos_init.z;
|
||||
}
|
||||
else if( m_zoom < m_minZoom )
|
||||
{
|
||||
m_zoom = m_minZoom;
|
||||
aViewMatrix[3].z += -lookat.z + m_minZoom * m_camera_pos_init.z;
|
||||
}
|
||||
|
||||
m_viewMatrix = std::move( aViewMatrix );
|
||||
m_camera_pos = m_viewMatrix
|
||||
* glm::inverse( m_rotationMatrix * m_rotationMatrixAux
|
||||
* glm::translate( glm::mat4( 1.0f ), -m_lookat_pos ) )[3];
|
||||
}
|
||||
|
||||
|
||||
const glm::mat4& CAMERA::GetViewMatrix_Inv() const
|
||||
{
|
||||
return m_viewMatrixInverse;
|
||||
@@ -534,41 +479,24 @@ void CAMERA::ZoomReset()
|
||||
rebuildProjection();
|
||||
}
|
||||
|
||||
|
||||
bool CAMERA::Zoom( float aFactor )
|
||||
{
|
||||
if( ( m_zoom <= m_minZoom && aFactor > 1 ) || ( m_zoom >= m_maxZoom && aFactor < 1 )
|
||||
if( ( m_zoom == m_minZoom && aFactor > 1 ) || ( m_zoom == m_maxZoom && aFactor < 1 )
|
||||
|| aFactor == 1 )
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
float zoom = m_zoom;
|
||||
m_zoom /= aFactor;
|
||||
|
||||
if( m_zoom <= m_minZoom && aFactor > 1 )
|
||||
{
|
||||
aFactor = zoom / m_minZoom;
|
||||
m_zoom = m_minZoom;
|
||||
}
|
||||
else if( m_zoom >= m_maxZoom && aFactor < 1 )
|
||||
{
|
||||
aFactor = zoom / m_maxZoom;
|
||||
m_zoom = m_maxZoom;
|
||||
}
|
||||
|
||||
m_camera_pos.z /= aFactor;
|
||||
|
||||
updateViewMatrix();
|
||||
rebuildProjection();
|
||||
|
||||
zoomChanged();
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
bool CAMERA::Zoom_T1( float aFactor )
|
||||
{
|
||||
if( ( m_zoom <= m_minZoom && aFactor > 1 ) || ( m_zoom >= m_maxZoom && aFactor < 1 )
|
||||
if( ( m_zoom == m_minZoom && aFactor > 1 ) || ( m_zoom == m_maxZoom && aFactor < 1 )
|
||||
|| aFactor == 1 )
|
||||
{
|
||||
return false;
|
||||
@@ -2,7 +2,7 @@
|
||||
* This program source code file is part of KiCad, a free EDA CAD application.
|
||||
*
|
||||
* Copyright (C) 2015-2016 Mario Luzeiro <mrluzeiro@ua.pt>
|
||||
* Copyright (C) 2015-2023 KiCad Developers, see AUTHORS.txt for contributors.
|
||||
* Copyright (C) 2015-2020 KiCad Developers, see AUTHORS.txt for contributors.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
@@ -30,8 +30,7 @@
|
||||
#ifndef CAMERA_H
|
||||
#define CAMERA_H
|
||||
|
||||
#include <gal/gal.h>
|
||||
#include <plugins/3dapi/xv3d_types.h>
|
||||
#include "../3d_rendering/raytracing/ray.h"
|
||||
#include <wx/gdicmn.h> // for wxSize
|
||||
#include <vector>
|
||||
|
||||
@@ -59,29 +58,6 @@ struct CAMERA_FRUSTUM
|
||||
SFVEC3F fbr; ///< Far Bottom Right
|
||||
float nearD, farD, ratio, angle, tang;
|
||||
float nw, nh, fw, fh;
|
||||
|
||||
CAMERA_FRUSTUM() :
|
||||
nc( { 0.0, 0.0, 0.0 } ),
|
||||
fc( { 0.0, 0.0, 0.0 } ),
|
||||
ntl( { 0.0, 0.0, 0.0 } ),
|
||||
ntr( { 0.0, 0.0, 0.0 } ),
|
||||
nbl( { 0.0, 0.0, 0.0 } ),
|
||||
nbr( { 0.0, 0.0, 0.0 } ),
|
||||
ftl( { 0.0, 0.0, 0.0 } ),
|
||||
ftr( { 0.0, 0.0, 0.0 } ),
|
||||
fbl( { 0.0, 0.0, 0.0 } ),
|
||||
fbr( { 0.0, 0.0, 0.0 } ),
|
||||
nearD( 0.0 ),
|
||||
farD( 0.0 ),
|
||||
ratio( 1.0 ),
|
||||
angle( 0.0 ),
|
||||
tang( 0.0 ),
|
||||
nw( 0.0 ),
|
||||
nh( 0.0 ),
|
||||
fw( 0.0 ),
|
||||
fh( 0.0 )
|
||||
{
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
@@ -98,12 +74,9 @@ enum class CAMERA_INTERPOLATION
|
||||
*
|
||||
* It must be derived by other classes to implement a real camera object.
|
||||
*/
|
||||
class GAL_API CAMERA
|
||||
class CAMERA
|
||||
{
|
||||
public:
|
||||
static const float DEFAULT_MIN_ZOOM;
|
||||
static const float DEFAULT_MAX_ZOOM;
|
||||
|
||||
/**
|
||||
* Initialize a camera.
|
||||
*
|
||||
@@ -120,7 +93,7 @@ public:
|
||||
*
|
||||
* @return the rotation matrix of the camera
|
||||
*/
|
||||
glm::mat4 GetRotationMatrix() const;
|
||||
const glm::mat4 GetRotationMatrix() const;
|
||||
|
||||
const glm::mat4& GetViewMatrix() const;
|
||||
const glm::mat4& GetViewMatrix_Inv() const;
|
||||
@@ -135,27 +108,17 @@ public:
|
||||
const SFVEC2F& GetFocalLen() const { return m_focalLen; }
|
||||
float GetNear() const { return m_frustum.nearD; }
|
||||
float GetFar() const { return m_frustum.farD; }
|
||||
const CAMERA_FRUSTUM& GetFrustum() const { return m_frustum; }
|
||||
const SFVEC3F& GetLookAtPos() const { return m_lookat_pos; }
|
||||
|
||||
/**
|
||||
* Set the rotation matrix to be applied in a transformation camera, without
|
||||
* making any new calculations on camera.
|
||||
*
|
||||
* @param aRotation is the total rotation matrix of the camera.
|
||||
*/
|
||||
void SetRotationMatrix( const glm::mat4& aRotation );
|
||||
void SetBoardLookAtPos( const SFVEC3F& aBoardPos )
|
||||
{
|
||||
if( m_board_lookat_pos_init != aBoardPos )
|
||||
{
|
||||
m_board_lookat_pos_init = aBoardPos;
|
||||
SetLookAtPos( aBoardPos );
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the affine matrix to be applied to a transformation camera.
|
||||
*
|
||||
* @param aViewMatrix is the affine matrix of the camera. The affine matrix
|
||||
* maps coordinates in the world frame to those in the
|
||||
* camera frame.
|
||||
*/
|
||||
void SetViewMatrix( glm::mat4 aViewMatrix );
|
||||
|
||||
void SetBoardLookAtPos( const SFVEC3F& aBoardPos );
|
||||
virtual void SetLookAtPos( const SFVEC3F& aLookAtPos ) = 0;
|
||||
|
||||
void SetLookAtPos_T1( const SFVEC3F& aLookAtPos )
|
||||
{
|
||||
@@ -189,11 +152,6 @@ public:
|
||||
void ResetXYpos();
|
||||
void ResetXYpos_T1();
|
||||
|
||||
/**
|
||||
* Get the current mouse position.
|
||||
*/
|
||||
const wxPoint& GetCurMousePosition() { return m_lastPosition; }
|
||||
|
||||
/**
|
||||
* Update the current mouse position without make any new calculations on camera.
|
||||
*/
|
||||
@@ -292,12 +250,7 @@ public:
|
||||
* @param aOutOrigin out origin position of the ray.
|
||||
* @param aOutDirection out direction.
|
||||
*/
|
||||
void MakeRayAtCurrentMousePosition( SFVEC3F& aOutOrigin, SFVEC3F& aOutDirection ) const;
|
||||
|
||||
/**
|
||||
* Update the camera.
|
||||
*/
|
||||
void Update() { updateFrustum(); }
|
||||
void MakeRayAtCurrrentMousePosition( SFVEC3F& aOutOrigin, SFVEC3F& aOutDirection ) const;
|
||||
|
||||
protected:
|
||||
void zoomChanged();
|
||||
@@ -24,16 +24,16 @@
|
||||
*/
|
||||
|
||||
/**
|
||||
* @file 3d_model.cpp
|
||||
* @file c_ogl_3dmodel.cpp
|
||||
* @brief
|
||||
*/
|
||||
#include <algorithm>
|
||||
#include <stdexcept>
|
||||
#include <gal/opengl/kiglew.h> // Must be included first
|
||||
|
||||
#include "3d_model.h"
|
||||
#include "opengl_utils.h"
|
||||
#include "../common_ogl/ogl_utils.h"
|
||||
#include "../3d_math.h"
|
||||
#include <utility>
|
||||
#include <wx/debug.h>
|
||||
#include <wx/log.h>
|
||||
#include <chrono>
|
||||
@@ -149,25 +149,24 @@ MODEL_3D::MODEL_3D( const S3DMODEL& a3DModel, MATERIAL_MODE aMaterialMode )
|
||||
|
||||
for( unsigned int mesh_i = 0; mesh_i < a3DModel.m_MeshesSize; ++mesh_i )
|
||||
{
|
||||
const SMESH& mesh = a3DModel.m_Meshes[mesh_i];
|
||||
const auto& mesh = a3DModel.m_Meshes[mesh_i];
|
||||
|
||||
// silently ignore meshes that have invalid material references or invalid geometry.
|
||||
if( mesh.m_MaterialIdx >= m_materials.size()
|
||||
|| mesh.m_Positions == nullptr
|
||||
|| mesh.m_FaceIdx == nullptr
|
||||
|| mesh.m_Normals == nullptr
|
||||
|| mesh.m_FaceIdxSize == 0
|
||||
|| mesh.m_VertexSize == 0 )
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|| mesh.m_Positions == nullptr
|
||||
|| mesh.m_FaceIdx == nullptr
|
||||
|| mesh.m_Normals == nullptr
|
||||
|| mesh.m_FaceIdxSize == 0
|
||||
|| mesh.m_VertexSize == 0 )
|
||||
continue;
|
||||
|
||||
MESH_GROUP& mesh_group = mesh_groups[mesh.m_MaterialIdx];
|
||||
MATERIAL& material = m_materials[mesh.m_MaterialIdx];
|
||||
auto& mesh_group = mesh_groups[mesh.m_MaterialIdx];
|
||||
auto& material = m_materials[mesh.m_MaterialIdx];
|
||||
|
||||
if( material.IsTransparent() && m_materialMode != MATERIAL_MODE::DIFFUSE_ONLY )
|
||||
if( material.IsTransparent()
|
||||
&& m_materialMode != MATERIAL_MODE::DIFFUSE_ONLY )
|
||||
m_have_transparent_meshes = true;
|
||||
else
|
||||
else
|
||||
m_have_opaque_meshes = true;
|
||||
|
||||
const unsigned int vtx_offset = mesh_group.m_vertices.size();
|
||||
@@ -177,20 +176,19 @@ MODEL_3D::MODEL_3D( const S3DMODEL& a3DModel, MATERIAL_MODE aMaterialMode )
|
||||
// use material color for mesh bounding box or some sort of average vertex color.
|
||||
glm::vec3 avg_color = material.m_Diffuse;
|
||||
|
||||
BBOX_3D &mesh_bbox = m_meshes_bbox[mesh_i];
|
||||
|
||||
for( unsigned int vtx_i = 0; vtx_i < mesh.m_VertexSize; ++vtx_i )
|
||||
{
|
||||
mesh_bbox.Union( mesh.m_Positions[vtx_i] );
|
||||
m_meshes_bbox[mesh_i].Union( mesh.m_Positions[vtx_i] );
|
||||
|
||||
VERTEX& vtx_out = mesh_group.m_vertices[vtx_offset + vtx_i];
|
||||
auto& vtx_out = mesh_group.m_vertices[vtx_offset + vtx_i];
|
||||
|
||||
vtx_out.m_pos = mesh.m_Positions[vtx_i];
|
||||
vtx_out.m_nrm = glm::clamp( glm::vec4( mesh.m_Normals[vtx_i], 1.0f ) * 127.0f,
|
||||
-127.0f, 127.0f );
|
||||
|
||||
vtx_out.m_tex_uv = mesh.m_Texcoords != nullptr ? mesh.m_Texcoords[vtx_i]
|
||||
: glm::vec2 (0);
|
||||
vtx_out.m_tex_uv = mesh.m_Texcoords != nullptr
|
||||
? mesh.m_Texcoords[vtx_i]
|
||||
: glm::vec2 (0);
|
||||
|
||||
if( mesh.m_Color != nullptr )
|
||||
{
|
||||
@@ -224,19 +222,16 @@ MODEL_3D::MODEL_3D( const S3DMODEL& a3DModel, MATERIAL_MODE aMaterialMode )
|
||||
}
|
||||
}
|
||||
|
||||
if( mesh_bbox.IsInitialized() )
|
||||
if( m_meshes_bbox[mesh_i].IsInitialized() )
|
||||
{
|
||||
// generate geometry for the bounding box
|
||||
MakeBbox( mesh_bbox, ( mesh_i + 1 ) * bbox_vtx_count,
|
||||
MakeBbox( m_meshes_bbox[mesh_i], ( mesh_i + 1 ) * bbox_vtx_count,
|
||||
&bbox_tmp_vertices[( mesh_i + 1 ) * bbox_vtx_count],
|
||||
&bbox_tmp_indices[( mesh_i + 1 ) * bbox_idx_count],
|
||||
{ avg_color, 1.0f } );
|
||||
|
||||
// bump the outer bounding box
|
||||
m_model_bbox.Union( mesh_bbox );
|
||||
|
||||
// add to the material group
|
||||
material.m_bbox.Union( mesh_bbox );
|
||||
m_model_bbox.Union( m_meshes_bbox[mesh_i] );
|
||||
}
|
||||
|
||||
|
||||
@@ -304,7 +299,7 @@ MODEL_3D::MODEL_3D( const S3DMODEL& a3DModel, MATERIAL_MODE aMaterialMode )
|
||||
unsigned int total_vertex_count = 0;
|
||||
unsigned int total_index_count = 0;
|
||||
|
||||
for( const MESH_GROUP& mg : mesh_groups )
|
||||
for( auto& mg : mesh_groups )
|
||||
{
|
||||
total_vertex_count += mg.m_vertices.size();
|
||||
total_index_count += mg.m_indices.size();
|
||||
@@ -332,7 +327,8 @@ MODEL_3D::MODEL_3D( const S3DMODEL& a3DModel, MATERIAL_MODE aMaterialMode )
|
||||
|
||||
// temporary index buffer which will contain either GLushort or GLuint
|
||||
// type indices. allocate with a bit of meadow at the end.
|
||||
auto tmp_idx = std::make_unique<GLuint[]>( ( idx_size * total_index_count + 8 ) / sizeof( GLuint ) );
|
||||
auto tmp_idx = std::make_unique<GLuint[]>(
|
||||
( idx_size * total_index_count + 8 ) / sizeof( GLuint ) );
|
||||
|
||||
unsigned int prev_vtx_count = 0;
|
||||
unsigned int idx_offset = 0;
|
||||
@@ -340,22 +336,23 @@ MODEL_3D::MODEL_3D( const S3DMODEL& a3DModel, MATERIAL_MODE aMaterialMode )
|
||||
|
||||
for( unsigned int mg_i = 0; mg_i < mesh_groups.size (); ++mg_i )
|
||||
{
|
||||
MESH_GROUP& mg = mesh_groups[mg_i];
|
||||
MATERIAL& mat = m_materials[mg_i];
|
||||
uintptr_t tmp_idx_ptr = reinterpret_cast<uintptr_t>( tmp_idx.get() );
|
||||
auto& mg = mesh_groups[mg_i];
|
||||
auto& mat = m_materials[mg_i];
|
||||
|
||||
if( m_index_buffer_type == GL_UNSIGNED_SHORT )
|
||||
{
|
||||
GLushort* idx_out = reinterpret_cast<GLushort*>( tmp_idx_ptr + idx_offset );
|
||||
auto idx_out = reinterpret_cast<GLushort*>(
|
||||
reinterpret_cast<uintptr_t>( tmp_idx.get() ) + idx_offset );
|
||||
|
||||
for( GLuint idx : mg.m_indices )
|
||||
for( auto idx : mg.m_indices )
|
||||
*idx_out++ = static_cast<GLushort>( idx + prev_vtx_count );
|
||||
}
|
||||
else if( m_index_buffer_type == GL_UNSIGNED_INT )
|
||||
{
|
||||
GLuint* idx_out = reinterpret_cast<GLuint*>( tmp_idx_ptr + idx_offset );
|
||||
auto idx_out = reinterpret_cast<GLuint*>(
|
||||
reinterpret_cast<uintptr_t>( tmp_idx.get() ) + idx_offset );
|
||||
|
||||
for( GLuint idx : mg.m_indices )
|
||||
for( auto idx : mg.m_indices )
|
||||
*idx_out++ = static_cast<GLuint>( idx + prev_vtx_count );
|
||||
}
|
||||
|
||||
@@ -415,9 +412,7 @@ void MODEL_3D::EndDrawMulti()
|
||||
|
||||
|
||||
void MODEL_3D::Draw( bool aTransparent, float aOpacity, bool aUseSelectedMaterial,
|
||||
const SFVEC3F& aSelectionColor,
|
||||
const glm::mat4 *aModelWorldMatrix,
|
||||
const SFVEC3F *aCameraWorldPos ) const
|
||||
SFVEC3F& aSelectionColor ) const
|
||||
{
|
||||
if( aOpacity <= FLT_EPSILON )
|
||||
return;
|
||||
@@ -446,100 +441,28 @@ void MODEL_3D::Draw( bool aTransparent, float aOpacity, bool aUseSelectedMateria
|
||||
|
||||
glTexEnvfv( GL_TEXTURE_ENV, GL_TEXTURE_ENV_COLOR, (const float*)¶m.x );
|
||||
|
||||
std::vector<const MODEL_3D::MATERIAL *> materialsToRender;
|
||||
|
||||
materialsToRender.reserve( m_materials.size() );
|
||||
|
||||
if( aModelWorldMatrix && aCameraWorldPos )
|
||||
// BeginDrawMulti();
|
||||
for( const MODEL_3D::MATERIAL& mat : m_materials )
|
||||
{
|
||||
// Sort Material groups
|
||||
|
||||
std::vector<std::pair<const MODEL_3D::MATERIAL*, float>> materialsSorted;
|
||||
|
||||
// Calculate the distance to the camera for each material group
|
||||
for( const MODEL_3D::MATERIAL& mat : m_materials )
|
||||
{
|
||||
if( mat.m_render_idx_count == 0 )
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
if( ( mat.IsTransparent() != aTransparent )
|
||||
if( ( mat.IsTransparent() != aTransparent )
|
||||
&& ( aOpacity >= 1.0f )
|
||||
&& m_materialMode != MATERIAL_MODE::DIFFUSE_ONLY )
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
const BBOX_3D& bBox = mat.m_bbox;
|
||||
const SFVEC3F& bBoxCenter = bBox.GetCenter();
|
||||
const SFVEC3F bBoxWorld = *aModelWorldMatrix * glm::vec4( bBoxCenter, 1.0f );
|
||||
|
||||
const float distanceToCamera = glm::length( *aCameraWorldPos - bBoxWorld );
|
||||
|
||||
materialsSorted.emplace_back( &mat, distanceToCamera );
|
||||
}
|
||||
|
||||
// Sort from back to front
|
||||
std::sort( materialsSorted.begin(), materialsSorted.end(),
|
||||
[&]( std::pair<const MODEL_3D::MATERIAL*, float>& a,
|
||||
std::pair<const MODEL_3D::MATERIAL*, float>& b )
|
||||
{
|
||||
bool aInsideB = a.first->m_bbox.Inside( b.first->m_bbox );
|
||||
bool bInsideA = b.first->m_bbox.Inside( a.first->m_bbox );
|
||||
|
||||
// If A is inside B, then A is rendered first
|
||||
if( aInsideB != bInsideA )
|
||||
return bInsideA;
|
||||
|
||||
if( a.second != b.second )
|
||||
return a.second > b.second;
|
||||
|
||||
return a.first > b.first; // compare pointers as a last resort
|
||||
} );
|
||||
|
||||
for( const std::pair<const MODEL_3D::MATERIAL*, float>& mat : materialsSorted )
|
||||
{
|
||||
materialsToRender.push_back( mat.first );
|
||||
continue;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
for( const MODEL_3D::MATERIAL& mat : m_materials )
|
||||
{
|
||||
// There is at least one default material created in case a mesh has no declared materials.
|
||||
// Most meshes have a material, so usually the first material will have nothing to render and is skip.
|
||||
// See S3D::GetModel for more details.
|
||||
if( mat.m_render_idx_count == 0 )
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
if( ( mat.IsTransparent() != aTransparent )
|
||||
&& ( aOpacity >= 1.0f )
|
||||
&& m_materialMode != MATERIAL_MODE::DIFFUSE_ONLY )
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
materialsToRender.push_back( &mat );
|
||||
}
|
||||
}
|
||||
|
||||
for( const MODEL_3D::MATERIAL* mat : materialsToRender )
|
||||
{
|
||||
switch( m_materialMode )
|
||||
{
|
||||
case MATERIAL_MODE::NORMAL:
|
||||
OglSetMaterial( *mat, aOpacity, aUseSelectedMaterial, aSelectionColor );
|
||||
OglSetMaterial( mat, aOpacity, aUseSelectedMaterial, aSelectionColor );
|
||||
break;
|
||||
|
||||
case MATERIAL_MODE::DIFFUSE_ONLY:
|
||||
OglSetDiffuseMaterial( mat->m_Diffuse, aOpacity, aUseSelectedMaterial, aSelectionColor );
|
||||
OglSetDiffuseMaterial( mat.m_Diffuse, aOpacity, aUseSelectedMaterial, aSelectionColor );
|
||||
break;
|
||||
|
||||
case MATERIAL_MODE::CAD_MODE:
|
||||
OglSetDiffuseMaterial( MaterialDiffuseToColorCAD( mat->m_Diffuse ), aOpacity,
|
||||
OglSetDiffuseMaterial( MaterialDiffuseToColorCAD( mat.m_Diffuse ), aOpacity,
|
||||
aUseSelectedMaterial, aSelectionColor );
|
||||
break;
|
||||
|
||||
@@ -547,9 +470,9 @@ void MODEL_3D::Draw( bool aTransparent, float aOpacity, bool aUseSelectedMateria
|
||||
break;
|
||||
}
|
||||
|
||||
glDrawElements( GL_TRIANGLES, mat->m_render_idx_count, m_index_buffer_type,
|
||||
glDrawElements( GL_TRIANGLES, mat.m_render_idx_count, m_index_buffer_type,
|
||||
reinterpret_cast<const void*>(
|
||||
static_cast<uintptr_t>( mat->m_render_idx_buffer_offset ) ) );
|
||||
static_cast<uintptr_t>( mat.m_render_idx_buffer_offset ) ) );
|
||||
}
|
||||
}
|
||||
|
||||
@@ -603,7 +526,7 @@ void MODEL_3D::DrawBboxes() const
|
||||
: sizeof( GLuint );
|
||||
|
||||
glDrawElements( GL_LINES, bbox_idx_count * m_meshes_bbox.size(), m_bbox_index_buffer_type,
|
||||
reinterpret_cast<const void*>(
|
||||
reinterpret_cast<const void*>(
|
||||
static_cast<uintptr_t>( bbox_idx_count * idx_size ) ) );
|
||||
}
|
||||
|
||||
|
||||
@@ -54,7 +54,7 @@ public:
|
||||
*/
|
||||
void DrawOpaque( bool aUseSelectedMaterial, SFVEC3F aSelectionColor = SFVEC3F( 0.0f ) ) const
|
||||
{
|
||||
Draw( false, 1.0f, aUseSelectedMaterial, aSelectionColor, nullptr, nullptr );
|
||||
Draw( false, 1.0f, aUseSelectedMaterial, aSelectionColor );
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -63,19 +63,9 @@ public:
|
||||
void DrawTransparent( float aOpacity, bool aUseSelectedMaterial,
|
||||
SFVEC3F aSelectionColor = SFVEC3F( 0.0f ) ) const
|
||||
{
|
||||
Draw( true, aOpacity, aUseSelectedMaterial, aSelectionColor, nullptr, nullptr );
|
||||
Draw( true, aOpacity, aUseSelectedMaterial, aSelectionColor );
|
||||
}
|
||||
|
||||
/**
|
||||
* Render the model into the current context.
|
||||
* if aModelWorldMatrix and aCameraWorldPos is provided,
|
||||
* it renders the material groups sorted.
|
||||
*/
|
||||
void Draw( bool aTransparent, float aOpacity, bool aUseSelectedMaterial,
|
||||
const SFVEC3F& aSelectionColor,
|
||||
const glm::mat4 *aModelWorldMatrix,
|
||||
const SFVEC3F *aCameraWorldPos ) const;
|
||||
|
||||
/**
|
||||
* Return true if have opaque meshes to render.
|
||||
*/
|
||||
@@ -146,8 +136,6 @@ private:
|
||||
unsigned int m_render_idx_buffer_offset = 0;
|
||||
unsigned int m_render_idx_count = 0;
|
||||
|
||||
BBOX_3D m_bbox; ///< bounding box for this material group, used for transparent material ordering
|
||||
|
||||
MATERIAL( const SMATERIAL& aOther ) : SMATERIAL( aOther ) { }
|
||||
bool IsTransparent() const { return m_Transparency > FLT_EPSILON; }
|
||||
};
|
||||
@@ -171,6 +159,9 @@ private:
|
||||
|
||||
static void MakeBbox( const BBOX_3D& aBox, unsigned int aIdxOffset, VERTEX* aVtxOut,
|
||||
GLuint* aIdxOut, const glm::vec4& aColor );
|
||||
|
||||
void Draw( bool aTransparent, float aOpacity, bool aUseSelectedMaterial,
|
||||
SFVEC3F& aSelectionColor ) const;
|
||||
};
|
||||
|
||||
#endif // _MODEL_3D_H_
|
||||
|
||||
@@ -2,8 +2,7 @@
|
||||
* This program source code file is part of KiCad, a free EDA CAD application.
|
||||
*
|
||||
* Copyright (C) 2015-2016 Mario Luzeiro <mrluzeiro@ua.pt>
|
||||
* Copyright (C) 2023 CERN
|
||||
* Copyright (C) 2015-2023 KiCad Developers, see AUTHORS.txt for contributors.
|
||||
* Copyright (C) 2015-2020 KiCad Developers, see AUTHORS.txt for contributors.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
@@ -24,24 +23,23 @@
|
||||
*/
|
||||
|
||||
#include "render_3d_opengl.h"
|
||||
#include "opengl_utils.h"
|
||||
#include <board.h>
|
||||
#include <footprint.h>
|
||||
#include "../../3d_math.h"
|
||||
#include "convert_basic_shapes_to_polygon.h"
|
||||
#include <trigo.h>
|
||||
#include <project.h>
|
||||
#include <core/profile.h> // To use GetRunningMicroSecs or another profiling utility
|
||||
#include <fp_lib_table.h>
|
||||
#include <profile.h> // To use GetRunningMicroSecs or another profiling utility
|
||||
#include <eda_3d_canvas.h>
|
||||
#include <eda_3d_viewer_frame.h>
|
||||
#include <project_pcb.h>
|
||||
|
||||
|
||||
void RENDER_3D_OPENGL::addObjectTriangles( const FILLED_CIRCLE_2D* aCircle,
|
||||
void RENDER_3D_OPENGL::addObjectTriangles( const FILLED_CIRCLE_2D* aFilledCircle,
|
||||
TRIANGLE_DISPLAY_LIST* aDstLayer, float aZtop,
|
||||
float aZbot )
|
||||
{
|
||||
const SFVEC2F& center = aCircle->GetCenter();
|
||||
const float radius = aCircle->GetRadius() * 2.0f; // Double because the render triangle
|
||||
const SFVEC2F& center = aFilledCircle->GetCenter();
|
||||
const float radius = aFilledCircle->GetRadius() * 2.0f; // Double because the render triangle
|
||||
|
||||
// This is a small adjustment to the circle texture
|
||||
const float texture_factor = ( 8.0f / (float) SIZE_OF_CIRCLE_TEXTURE ) + 1.0f;
|
||||
@@ -303,7 +301,7 @@ OPENGL_RENDER_LIST* RENDER_3D_OPENGL::generateHoles( const LIST_OBJECT2D& aListH
|
||||
|
||||
OPENGL_RENDER_LIST* RENDER_3D_OPENGL::generateLayerList( const BVH_CONTAINER_2D* aContainer,
|
||||
const SHAPE_POLY_SET* aPolyList,
|
||||
PCB_LAYER_ID aLayer,
|
||||
PCB_LAYER_ID aLayerId,
|
||||
const BVH_CONTAINER_2D* aThroughHoles )
|
||||
{
|
||||
if( aContainer == nullptr )
|
||||
@@ -317,7 +315,7 @@ OPENGL_RENDER_LIST* RENDER_3D_OPENGL::generateLayerList( const BVH_CONTAINER_2D*
|
||||
float layer_z_bot = 0.0f;
|
||||
float layer_z_top = 0.0f;
|
||||
|
||||
getLayerZPos( aLayer, layer_z_top, layer_z_bot );
|
||||
getLayerZPos( aLayerId, layer_z_top, layer_z_bot );
|
||||
|
||||
// Calculate an estimation for the nr of triangles based on the nr of objects
|
||||
unsigned int nrTrianglesEstimation = listObject2d.size() * 8;
|
||||
@@ -376,37 +374,23 @@ OPENGL_RENDER_LIST* RENDER_3D_OPENGL::generateLayerList( const BVH_CONTAINER_2D*
|
||||
}
|
||||
|
||||
|
||||
OPENGL_RENDER_LIST* RENDER_3D_OPENGL::generateEmptyLayerList( PCB_LAYER_ID aLayer )
|
||||
{
|
||||
float layer_z_bot = 0.0f;
|
||||
float layer_z_top = 0.0f;
|
||||
|
||||
getLayerZPos( aLayer, layer_z_top, layer_z_bot );
|
||||
|
||||
TRIANGLE_DISPLAY_LIST* layerTriangles = new TRIANGLE_DISPLAY_LIST( 1 );
|
||||
|
||||
// store in a list so it will be latter deleted
|
||||
m_triangles.push_back( layerTriangles );
|
||||
|
||||
return new OPENGL_RENDER_LIST( *layerTriangles, m_circleTexture, layer_z_bot, layer_z_top );
|
||||
}
|
||||
|
||||
|
||||
OPENGL_RENDER_LIST* RENDER_3D_OPENGL::createBoard( const SHAPE_POLY_SET& aBoardPoly,
|
||||
const BVH_CONTAINER_2D* aThroughHoles )
|
||||
{
|
||||
OPENGL_RENDER_LIST* dispLists = nullptr;
|
||||
CONTAINER_2D boardContainer;
|
||||
SHAPE_POLY_SET brd_outlines = aBoardPoly;
|
||||
|
||||
ConvertPolygonToTriangles( aBoardPoly, boardContainer, m_boardAdapter.BiuTo3dUnits(),
|
||||
ConvertPolygonToTriangles( brd_outlines, boardContainer, m_boardAdapter.BiuTo3dUnits(),
|
||||
(const BOARD_ITEM &)*m_boardAdapter.GetBoard() );
|
||||
|
||||
const LIST_OBJECT2D& listBoardObject2d = boardContainer.GetList();
|
||||
|
||||
if( listBoardObject2d.size() > 0 )
|
||||
{
|
||||
// We will set a unitary Z so it will in future used with transformations since the
|
||||
// board poly will be used not only to draw itself but also the solder mask layers.
|
||||
// We will set a unitary Z so it will in future used with transformations
|
||||
// since the board poly will be used not only to draw itself but also the
|
||||
// solder mask layers.
|
||||
const float layer_z_top = 1.0f;
|
||||
const float layer_z_bot = 0.0f;
|
||||
|
||||
@@ -454,7 +438,7 @@ void RENDER_3D_OPENGL::reload( REPORTER* aStatusReporter, REPORTER* aWarningRepo
|
||||
|
||||
OBJECT_2D_STATS::Instance().ResetStats();
|
||||
|
||||
int64_t stats_startReloadTime = GetRunningMicroSecs();
|
||||
unsigned stats_startReloadTime = GetRunningMicroSecs();
|
||||
|
||||
m_boardAdapter.InitSettings( aStatusReporter, aWarningReporter );
|
||||
|
||||
@@ -465,23 +449,28 @@ void RENDER_3D_OPENGL::reload( REPORTER* aStatusReporter, REPORTER* aWarningRepo
|
||||
aStatusReporter->Report( _( "Load OpenGL: board" ) );
|
||||
|
||||
// Create Board
|
||||
m_board = createBoard( m_boardAdapter.GetBoardPoly(), &m_boardAdapter.GetTH_IDs() );
|
||||
m_board = createBoard( m_boardAdapter.GetBoardPoly(), &m_boardAdapter.GetThroughHoleIds() );
|
||||
|
||||
m_antiBoardPolys.RemoveAllContours();
|
||||
m_antiBoardPolys.NewOutline();
|
||||
m_antiBoardPolys.Append( VECTOR2I( -INT_MAX/2, -INT_MAX/2 ) );
|
||||
m_antiBoardPolys.Append( VECTOR2I( INT_MAX/2, -INT_MAX/2 ) );
|
||||
m_antiBoardPolys.Append( VECTOR2I( INT_MAX/2, INT_MAX/2 ) );
|
||||
m_antiBoardPolys.Append( VECTOR2I( -INT_MAX/2, INT_MAX/2 ) );
|
||||
m_antiBoardPolys.Outline( 0 ).SetClosed( true );
|
||||
if( m_boardAdapter.GetFlag( FL_USE_REALISTIC_MODE ) )
|
||||
{
|
||||
m_antiBoardPolys.RemoveAllContours();
|
||||
m_antiBoardPolys.NewOutline();
|
||||
m_antiBoardPolys.Append( VECTOR2I( -INT_MAX/2, -INT_MAX/2 ) );
|
||||
m_antiBoardPolys.Append( VECTOR2I( INT_MAX/2, -INT_MAX/2 ) );
|
||||
m_antiBoardPolys.Append( VECTOR2I( INT_MAX/2, INT_MAX/2 ) );
|
||||
m_antiBoardPolys.Append( VECTOR2I( -INT_MAX/2, INT_MAX/2 ) );
|
||||
m_antiBoardPolys.Outline( 0 ).SetClosed( true );
|
||||
|
||||
m_antiBoardPolys.BooleanSubtract( m_boardAdapter.GetBoardPoly(),
|
||||
SHAPE_POLY_SET::PM_STRICTLY_SIMPLE );
|
||||
m_antiBoard = createBoard( m_antiBoardPolys );
|
||||
m_antiBoardPolys.BooleanSubtract( m_boardAdapter.GetBoardPoly(),
|
||||
SHAPE_POLY_SET::PM_STRICTLY_SIMPLE );
|
||||
m_antiBoard = createBoard( m_antiBoardPolys );
|
||||
}
|
||||
|
||||
SHAPE_POLY_SET board_poly_with_holes = m_boardAdapter.GetBoardPoly().CloneDropTriangulation();
|
||||
board_poly_with_holes.BooleanSubtract( m_boardAdapter.GetTH_ODPolys(), SHAPE_POLY_SET::PM_FAST );
|
||||
board_poly_with_holes.BooleanSubtract( m_boardAdapter.GetNPTH_ODPolys(), SHAPE_POLY_SET::PM_FAST );
|
||||
SHAPE_POLY_SET board_poly_with_holes = m_boardAdapter.GetBoardPoly();
|
||||
board_poly_with_holes.BooleanSubtract( m_boardAdapter.GetThroughHoleOdPolys(),
|
||||
SHAPE_POLY_SET::PM_FAST );
|
||||
board_poly_with_holes.BooleanSubtract( m_boardAdapter.GetOuterNonPlatedThroughHolePoly(),
|
||||
SHAPE_POLY_SET::PM_FAST );
|
||||
|
||||
m_boardWithHoles = createBoard( board_poly_with_holes );
|
||||
|
||||
@@ -492,22 +481,26 @@ void RENDER_3D_OPENGL::reload( REPORTER* aStatusReporter, REPORTER* aWarningRepo
|
||||
if( aStatusReporter )
|
||||
aStatusReporter->Report( _( "Load OpenGL: holes and vias" ) );
|
||||
|
||||
SHAPE_POLY_SET outerPolyTHT = m_boardAdapter.GetTH_ODPolys().CloneDropTriangulation();
|
||||
SHAPE_POLY_SET outerPolyTHT = m_boardAdapter.GetThroughHoleOdPolys();
|
||||
|
||||
outerPolyTHT.BooleanIntersection( m_boardAdapter.GetBoardPoly(),
|
||||
SHAPE_POLY_SET::PM_STRICTLY_SIMPLE );
|
||||
if( m_boardAdapter.GetFlag( FL_USE_REALISTIC_MODE ) )
|
||||
outerPolyTHT.BooleanIntersection( m_boardAdapter.GetBoardPoly(),
|
||||
SHAPE_POLY_SET::PM_STRICTLY_SIMPLE );
|
||||
|
||||
m_outerThroughHoles = generateHoles( m_boardAdapter.GetTH_ODs().GetList(), outerPolyTHT,
|
||||
1.0f, 0.0f, false, &m_boardAdapter.GetTH_IDs() );
|
||||
m_outerThroughHoles = generateHoles( m_boardAdapter.GetThroughHoleOds().GetList(),
|
||||
outerPolyTHT, 1.0f, 0.0f, false,
|
||||
&m_boardAdapter.GetThroughHoleIds() );
|
||||
|
||||
m_outerViaThroughHoles = generateHoles( m_boardAdapter.GetViaTH_ODs().GetList(),
|
||||
m_boardAdapter.GetViaTH_ODPolys(), 1.0f, 0.0f, false );
|
||||
m_outerViaThroughHoles = generateHoles(
|
||||
m_boardAdapter.GetThroughHoleViaOds().GetList(),
|
||||
m_boardAdapter.GetThroughHoleViaOdPolys(), 1.0f, 0.0f, false );
|
||||
|
||||
if( m_boardAdapter.m_Cfg->m_Render.clip_silk_on_via_annuli )
|
||||
if( m_boardAdapter.GetFlag( FL_CLIP_SILK_ON_VIA_ANNULUS ) &&
|
||||
m_boardAdapter.GetFlag( FL_USE_REALISTIC_MODE ) )
|
||||
{
|
||||
m_outerThroughHoleRings = generateHoles( m_boardAdapter.GetViaAnnuli().GetList(),
|
||||
m_boardAdapter.GetViaAnnuliPolys(),
|
||||
1.0f, 0.0f, false );
|
||||
m_outerThroughHoleRings = generateHoles(
|
||||
m_boardAdapter.GetThroughHoleAnnularRings().GetList(),
|
||||
m_boardAdapter.GetThroughHoleAnnularRingPolys(), 1.0f, 0.0f, false );
|
||||
}
|
||||
|
||||
const MAP_POLY& innerMapHoles = m_boardAdapter.GetHoleIdPolysMap();
|
||||
@@ -522,20 +515,28 @@ void RENDER_3D_OPENGL::reload( REPORTER* aStatusReporter, REPORTER* aWarningRepo
|
||||
float layer_z_bot = 0.0f;
|
||||
float layer_z_top = 0.0f;
|
||||
|
||||
for( const auto& [ layer, poly ] : outerMapHoles )
|
||||
for( const auto ii : outerMapHoles )
|
||||
{
|
||||
getLayerZPos( layer, layer_z_top, layer_z_bot );
|
||||
const PCB_LAYER_ID layer_id = ii.first;
|
||||
const SHAPE_POLY_SET* poly = ii.second;
|
||||
const BVH_CONTAINER_2D* container = map_holes.at( layer_id );
|
||||
|
||||
m_outerLayerHoles[layer] = generateHoles( map_holes.at( layer )->GetList(), *poly,
|
||||
layer_z_top, layer_z_bot, false );
|
||||
getLayerZPos( layer_id, layer_z_top, layer_z_bot );
|
||||
|
||||
m_outerLayerHoles[layer_id] = generateHoles( container->GetList(), *poly,
|
||||
layer_z_top, layer_z_bot, false );
|
||||
}
|
||||
|
||||
for( const auto& [ layer, poly ] : innerMapHoles )
|
||||
for( const auto ii : innerMapHoles )
|
||||
{
|
||||
getLayerZPos( layer, layer_z_top, layer_z_bot );
|
||||
const PCB_LAYER_ID layer_id = ii.first;
|
||||
const SHAPE_POLY_SET* poly = ii.second;
|
||||
const BVH_CONTAINER_2D* container = map_holes.at( layer_id );
|
||||
|
||||
m_innerLayerHoles[layer] = generateHoles( map_holes.at( layer )->GetList(), *poly,
|
||||
layer_z_top, layer_z_bot, false );
|
||||
getLayerZPos( layer_id, layer_z_top, layer_z_bot );
|
||||
|
||||
m_innerLayerHoles[layer_id] = generateHoles( container->GetList(), *poly,
|
||||
layer_z_top, layer_z_bot, false );
|
||||
}
|
||||
}
|
||||
|
||||
@@ -546,114 +547,102 @@ void RENDER_3D_OPENGL::reload( REPORTER* aStatusReporter, REPORTER* aWarningRepo
|
||||
if( aStatusReporter )
|
||||
aStatusReporter->Report( _( "Load OpenGL: layers" ) );
|
||||
|
||||
std::bitset<LAYER_3D_END> visibilityFlags = m_boardAdapter.GetVisibleLayers();
|
||||
const MAP_POLY& map_poly = m_boardAdapter.GetPolyMap();
|
||||
wxString msg;
|
||||
const MAP_POLY& map_poly = m_boardAdapter.GetPolyMap();
|
||||
|
||||
for( const auto& [ layer, container2d ] : m_boardAdapter.GetLayerMap() )
|
||||
for( const auto ii : m_boardAdapter.GetLayerMap() )
|
||||
{
|
||||
if( !m_boardAdapter.Is3dLayerEnabled( layer, visibilityFlags ) )
|
||||
const PCB_LAYER_ID layer_id = ii.first;
|
||||
|
||||
if( !m_boardAdapter.Is3dLayerEnabled( layer_id ) )
|
||||
continue;
|
||||
|
||||
if( aStatusReporter )
|
||||
{
|
||||
msg = m_boardAdapter.GetBoard()->GetLayerName( layer );
|
||||
aStatusReporter->Report( wxString::Format( _( "Load OpenGL layer %s" ), msg ) );
|
||||
}
|
||||
aStatusReporter->Report( wxString::Format(
|
||||
_( "Load OpenGL layer %d" ), (int)layer_id ) );
|
||||
|
||||
const BVH_CONTAINER_2D* container2d = ii.second;
|
||||
|
||||
SHAPE_POLY_SET polyListSubtracted;
|
||||
SHAPE_POLY_SET* polyList = nullptr;
|
||||
SHAPE_POLY_SET* aPolyList = nullptr;
|
||||
|
||||
// Load the vertical (Z axis) component of shapes
|
||||
|
||||
if( m_boardAdapter.m_Cfg->m_Render.opengl_copper_thickness )
|
||||
if( map_poly.find( layer_id ) != map_poly.end() )
|
||||
{
|
||||
if( map_poly.find( layer ) != map_poly.end() )
|
||||
polyListSubtracted = *map_poly.at( layer_id );;
|
||||
|
||||
if( m_boardAdapter.GetFlag( FL_USE_REALISTIC_MODE ) )
|
||||
{
|
||||
polyListSubtracted = *map_poly.at( layer );
|
||||
polyListSubtracted.BooleanIntersection( m_boardAdapter.GetBoardPoly(),
|
||||
SHAPE_POLY_SET::PM_FAST );
|
||||
|
||||
if( LSET::PhysicalLayersMask().test( layer ) )
|
||||
if( ( layer_id != B_Mask ) && ( layer_id != F_Mask ) )
|
||||
{
|
||||
polyListSubtracted.BooleanIntersection( m_boardAdapter.GetBoardPoly(),
|
||||
SHAPE_POLY_SET::PM_FAST );
|
||||
polyListSubtracted.BooleanSubtract( m_boardAdapter.GetThroughHoleOdPolys(),
|
||||
SHAPE_POLY_SET::PM_FAST );
|
||||
polyListSubtracted.BooleanSubtract(
|
||||
m_boardAdapter.GetOuterNonPlatedThroughHolePoly(),
|
||||
SHAPE_POLY_SET::PM_FAST );
|
||||
}
|
||||
|
||||
if( layer != B_Mask && layer != F_Mask )
|
||||
if( m_boardAdapter.GetFlag( FL_SUBTRACT_MASK_FROM_SILK ) )
|
||||
{
|
||||
polyListSubtracted.BooleanSubtract( m_boardAdapter.GetTH_ODPolys(),
|
||||
SHAPE_POLY_SET::PM_FAST );
|
||||
polyListSubtracted.BooleanSubtract( m_boardAdapter.GetNPTH_ODPolys(),
|
||||
SHAPE_POLY_SET::PM_FAST );
|
||||
}
|
||||
|
||||
if( m_boardAdapter.m_Cfg->m_Render.subtract_mask_from_silk )
|
||||
{
|
||||
if( layer == B_SilkS && map_poly.find( B_Mask ) != map_poly.end() )
|
||||
if( layer_id == B_SilkS && map_poly.find( B_Mask ) != map_poly.end() )
|
||||
{
|
||||
polyListSubtracted.BooleanSubtract( *map_poly.at( B_Mask ),
|
||||
SHAPE_POLY_SET::PM_FAST );
|
||||
}
|
||||
else if( layer == F_SilkS && map_poly.find( F_Mask ) != map_poly.end() )
|
||||
else if( layer_id == F_SilkS && map_poly.find( F_Mask ) != map_poly.end() )
|
||||
{
|
||||
polyListSubtracted.BooleanSubtract( *map_poly.at( F_Mask ),
|
||||
SHAPE_POLY_SET::PM_FAST );
|
||||
}
|
||||
}
|
||||
|
||||
polyList = &polyListSubtracted;
|
||||
}
|
||||
|
||||
aPolyList = &polyListSubtracted;
|
||||
}
|
||||
|
||||
OPENGL_RENDER_LIST* oglList = generateLayerList( container2d, polyList, layer,
|
||||
&m_boardAdapter.GetTH_IDs() );
|
||||
OPENGL_RENDER_LIST* oglList = generateLayerList( container2d, aPolyList, layer_id,
|
||||
&m_boardAdapter.GetThroughHoleIds() );
|
||||
|
||||
if( oglList != nullptr )
|
||||
m_layers[layer] = oglList;
|
||||
m_layers[layer_id] = oglList;
|
||||
|
||||
}
|
||||
|
||||
if( m_boardAdapter.m_Cfg->m_Render.differentiate_plated_copper )
|
||||
if( m_boardAdapter.GetFlag( FL_RENDER_PLATED_PADS_AS_PLATED ) &&
|
||||
m_boardAdapter.GetFlag( FL_USE_REALISTIC_MODE ) )
|
||||
{
|
||||
const SHAPE_POLY_SET* frontPlatedPadAndGraphicPolys = m_boardAdapter.GetFrontPlatedPadAndGraphicPolys();
|
||||
const SHAPE_POLY_SET* backPlatedPadAndGraphicPolys = m_boardAdapter.GetBackPlatedPadAndGraphicPolys();
|
||||
|
||||
if( frontPlatedPadAndGraphicPolys )
|
||||
if( m_boardAdapter.GetFrontPlatedPadPolys() )
|
||||
{
|
||||
SHAPE_POLY_SET poly = frontPlatedPadAndGraphicPolys->CloneDropTriangulation();
|
||||
poly.BooleanIntersection( m_boardAdapter.GetBoardPoly(), SHAPE_POLY_SET::PM_FAST );
|
||||
poly.BooleanSubtract( m_boardAdapter.GetTH_ODPolys(), SHAPE_POLY_SET::PM_FAST );
|
||||
poly.BooleanSubtract( m_boardAdapter.GetNPTH_ODPolys(), SHAPE_POLY_SET::PM_FAST );
|
||||
SHAPE_POLY_SET polySubtracted = *m_boardAdapter.GetFrontPlatedPadPolys();
|
||||
polySubtracted.BooleanIntersection( m_boardAdapter.GetBoardPoly(),
|
||||
SHAPE_POLY_SET::PM_FAST );
|
||||
polySubtracted.BooleanSubtract( m_boardAdapter.GetThroughHoleOdPolys(),
|
||||
SHAPE_POLY_SET::PM_FAST );
|
||||
polySubtracted.BooleanSubtract( m_boardAdapter.GetOuterNonPlatedThroughHolePoly(),
|
||||
SHAPE_POLY_SET::PM_FAST );
|
||||
|
||||
m_platedPadsFront = generateLayerList( m_boardAdapter.GetPlatedPadsFront(), &poly, F_Cu );
|
||||
|
||||
// An entry for F_Cu must exist in m_layers or we'll never look at m_platedPadsFront
|
||||
if( m_layers.count( F_Cu ) == 0 )
|
||||
m_layers[F_Cu] = generateEmptyLayerList( F_Cu );
|
||||
m_platedPadsFront = generateLayerList( m_boardAdapter.GetPlatedPadsFront(),
|
||||
&polySubtracted, F_Cu );
|
||||
}
|
||||
|
||||
if( backPlatedPadAndGraphicPolys )
|
||||
if( m_boardAdapter.GetBackPlatedPadPolys() )
|
||||
{
|
||||
SHAPE_POLY_SET poly = backPlatedPadAndGraphicPolys->CloneDropTriangulation();
|
||||
poly.BooleanIntersection( m_boardAdapter.GetBoardPoly(), SHAPE_POLY_SET::PM_FAST );
|
||||
poly.BooleanSubtract( m_boardAdapter.GetTH_ODPolys(), SHAPE_POLY_SET::PM_FAST );
|
||||
poly.BooleanSubtract( m_boardAdapter.GetNPTH_ODPolys(), SHAPE_POLY_SET::PM_FAST );
|
||||
SHAPE_POLY_SET polySubtracted = *m_boardAdapter.GetBackPlatedPadPolys();
|
||||
polySubtracted.BooleanIntersection( m_boardAdapter.GetBoardPoly(),
|
||||
SHAPE_POLY_SET::PM_FAST );
|
||||
polySubtracted.BooleanSubtract( m_boardAdapter.GetThroughHoleOdPolys(),
|
||||
SHAPE_POLY_SET::PM_FAST );
|
||||
polySubtracted.BooleanSubtract( m_boardAdapter.GetOuterNonPlatedThroughHolePoly(),
|
||||
SHAPE_POLY_SET::PM_FAST );
|
||||
|
||||
m_platedPadsBack = generateLayerList( m_boardAdapter.GetPlatedPadsBack(), &poly, B_Cu );
|
||||
|
||||
// An entry for B_Cu must exist in m_layers or we'll never look at m_platedPadsBack
|
||||
if( m_layers.count( B_Cu ) == 0 )
|
||||
m_layers[B_Cu] = generateEmptyLayerList( B_Cu );
|
||||
m_platedPadsBack = generateLayerList( m_boardAdapter.GetPlatedPadsBack(),
|
||||
&polySubtracted, B_Cu );
|
||||
}
|
||||
}
|
||||
|
||||
if( m_boardAdapter.m_Cfg->m_Render.show_off_board_silk )
|
||||
{
|
||||
if( const BVH_CONTAINER_2D* padsFront = m_boardAdapter.GetOffboardPadsFront() )
|
||||
m_offboardPadsFront = generateLayerList( padsFront, nullptr, F_Cu );
|
||||
|
||||
if( const BVH_CONTAINER_2D* padsBack = m_boardAdapter.GetOffboardPadsBack() )
|
||||
m_offboardPadsBack = generateLayerList( padsBack, nullptr, B_Cu );
|
||||
}
|
||||
|
||||
// Load 3D models
|
||||
if( aStatusReporter )
|
||||
aStatusReporter->Report( _( "Loading 3D models..." ) );
|
||||
@@ -663,7 +652,8 @@ void RENDER_3D_OPENGL::reload( REPORTER* aStatusReporter, REPORTER* aWarningRepo
|
||||
if( aStatusReporter )
|
||||
{
|
||||
// Calculation time in seconds
|
||||
double calculation_time = (double)( GetRunningMicroSecs() - stats_startReloadTime) / 1e6;
|
||||
const double calculation_time = (double)( GetRunningMicroSecs() -
|
||||
stats_startReloadTime) / 1e6;
|
||||
|
||||
aStatusReporter->Report( wxString::Format( _( "Reload time %.3f s" ), calculation_time ) );
|
||||
}
|
||||
@@ -684,10 +674,10 @@ void RENDER_3D_OPENGL::addTopAndBottomTriangles( TRIANGLE_DISPLAY_LIST* aDst, co
|
||||
}
|
||||
|
||||
|
||||
void RENDER_3D_OPENGL::getLayerZPos( PCB_LAYER_ID aLayer, float& aOutZtop, float& aOutZbot ) const
|
||||
void RENDER_3D_OPENGL::getLayerZPos( PCB_LAYER_ID aLayerID, float& aOutZtop, float& aOutZbot ) const
|
||||
{
|
||||
aOutZbot = m_boardAdapter.GetLayerBottomZPos( aLayer );
|
||||
aOutZtop = m_boardAdapter.GetLayerTopZPos( aLayer );
|
||||
aOutZbot = m_boardAdapter.GetLayerBottomZPos( aLayerID );
|
||||
aOutZtop = m_boardAdapter.GetLayerTopZPos( aLayerID );
|
||||
|
||||
if( aOutZtop < aOutZbot )
|
||||
{
|
||||
@@ -742,11 +732,13 @@ void RENDER_3D_OPENGL::generateViasAndPads()
|
||||
|
||||
if( m_boardAdapter.GetViaCount() > 0 )
|
||||
{
|
||||
float averageDiameter = m_boardAdapter.GetAverageViaHoleDiameter();
|
||||
unsigned int averageSegCount = m_boardAdapter.GetCircleSegmentCount( averageDiameter );
|
||||
unsigned int trianglesEstimate = averageSegCount * 8 * m_boardAdapter.GetViaCount();
|
||||
const unsigned int reserve_nr_triangles_estimation =
|
||||
m_boardAdapter.GetCircleSegmentCount(
|
||||
m_boardAdapter.GetAverageViaHoleDiameter() ) * 8 *
|
||||
m_boardAdapter.GetViaCount();
|
||||
|
||||
TRIANGLE_DISPLAY_LIST* layerTriangleVIA = new TRIANGLE_DISPLAY_LIST( trianglesEstimate );
|
||||
TRIANGLE_DISPLAY_LIST* layerTriangleVIA =
|
||||
new TRIANGLE_DISPLAY_LIST( reserve_nr_triangles_estimation );
|
||||
|
||||
// Insert plated vertical holes inside the board
|
||||
|
||||
@@ -757,9 +749,6 @@ void RENDER_3D_OPENGL::generateViasAndPads()
|
||||
{
|
||||
const PCB_VIA* via = static_cast<const PCB_VIA*>( track );
|
||||
|
||||
if( via->GetViaType() == VIATYPE::THROUGH )
|
||||
continue; // handle with pad holes so castellation is taken into account
|
||||
|
||||
const float holediameter = via->GetDrillValue() * m_boardAdapter.BiuTo3dUnits();
|
||||
const int nrSegments = m_boardAdapter.GetCircleSegmentCount( via->GetDrillValue() );
|
||||
const float hole_inner_radius = holediameter / 2.0f;
|
||||
@@ -789,33 +778,14 @@ void RENDER_3D_OPENGL::generateViasAndPads()
|
||||
}
|
||||
|
||||
|
||||
if( m_boardAdapter.GetHoleCount() > 0 || m_boardAdapter.GetViaCount() > 0 )
|
||||
if( m_boardAdapter.GetHoleCount() > 0 )
|
||||
{
|
||||
SHAPE_POLY_SET tht_outer_holes_poly; // Stores the outer poly of the copper holes
|
||||
SHAPE_POLY_SET tht_inner_holes_poly; // Stores the inner poly of the copper holes
|
||||
SHAPE_POLY_SET tht_outer_holes_poly; // Stores the outer poly of the copper holes (the pad)
|
||||
SHAPE_POLY_SET tht_inner_holes_poly; // Stores the inner poly of the copper holes (the hole)
|
||||
|
||||
tht_outer_holes_poly.RemoveAllContours();
|
||||
tht_inner_holes_poly.RemoveAllContours();
|
||||
|
||||
// Insert through-via holes (vertical cylinders)
|
||||
for( const PCB_TRACK* track : m_boardAdapter.GetBoard()->Tracks() )
|
||||
{
|
||||
if( track->Type() == PCB_VIA_T )
|
||||
{
|
||||
const PCB_VIA* via = static_cast<const PCB_VIA*>( track );
|
||||
|
||||
if( via->GetViaType() == VIATYPE::THROUGH )
|
||||
{
|
||||
TransformCircleToPolygon( tht_outer_holes_poly, via->GetPosition(),
|
||||
via->GetDrill() / 2 + platingThickness,
|
||||
ARC_HIGH_DEF, ERROR_INSIDE );
|
||||
|
||||
TransformCircleToPolygon( tht_inner_holes_poly, via->GetPosition(),
|
||||
via->GetDrill() / 2, ARC_HIGH_DEF, ERROR_INSIDE );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Insert pads holes (vertical cylinders)
|
||||
for( const FOOTPRINT* footprint : m_boardAdapter.GetBoard()->Footprints() )
|
||||
{
|
||||
@@ -823,16 +793,17 @@ void RENDER_3D_OPENGL::generateViasAndPads()
|
||||
{
|
||||
if( pad->GetAttribute() != PAD_ATTRIB::NPTH )
|
||||
{
|
||||
const VECTOR2I drillsize = pad->GetDrillSize();
|
||||
const bool hasHole = drillsize.x && drillsize.y;
|
||||
const wxSize drillsize = pad->GetDrillSize();
|
||||
const bool hasHole = drillsize.x && drillsize.y;
|
||||
|
||||
if( !hasHole )
|
||||
continue;
|
||||
|
||||
pad->TransformHoleToPolygon( tht_outer_holes_poly, platingThickness,
|
||||
ARC_HIGH_DEF, ERROR_INSIDE );
|
||||
pad->TransformHoleToPolygon( tht_inner_holes_poly, 0, ARC_HIGH_DEF,
|
||||
ERROR_INSIDE );
|
||||
pad->TransformHoleWithClearanceToPolygon( tht_outer_holes_poly,
|
||||
platingThickness,
|
||||
ARC_HIGH_DEF, ERROR_INSIDE );
|
||||
pad->TransformHoleWithClearanceToPolygon( tht_inner_holes_poly, 0,
|
||||
ARC_HIGH_DEF, ERROR_INSIDE );
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -840,26 +811,29 @@ void RENDER_3D_OPENGL::generateViasAndPads()
|
||||
// Subtract the holes
|
||||
tht_outer_holes_poly.BooleanSubtract( tht_inner_holes_poly, SHAPE_POLY_SET::PM_FAST );
|
||||
|
||||
tht_outer_holes_poly.BooleanSubtract( m_antiBoardPolys, SHAPE_POLY_SET::PM_FAST );
|
||||
if( m_boardAdapter.GetFlag( FL_USE_REALISTIC_MODE ) )
|
||||
tht_outer_holes_poly.BooleanSubtract( m_antiBoardPolys, SHAPE_POLY_SET::PM_FAST );
|
||||
|
||||
CONTAINER_2D holesContainer;
|
||||
|
||||
ConvertPolygonToTriangles( tht_outer_holes_poly, holesContainer,
|
||||
m_boardAdapter.BiuTo3dUnits(), *m_boardAdapter.GetBoard() );
|
||||
m_boardAdapter.BiuTo3dUnits(),
|
||||
(const BOARD_ITEM &)*m_boardAdapter.GetBoard() );
|
||||
|
||||
const LIST_OBJECT2D& holes2D = holesContainer.GetList();
|
||||
const LIST_OBJECT2D& listHolesObject2d = holesContainer.GetList();
|
||||
|
||||
if( holes2D.size() > 0 )
|
||||
if( listHolesObject2d.size() > 0 )
|
||||
{
|
||||
float layer_z_top, layer_z_bot, dummy;
|
||||
|
||||
getLayerZPos( F_Cu, layer_z_top, dummy );
|
||||
getLayerZPos( B_Cu, dummy, layer_z_bot );
|
||||
|
||||
TRIANGLE_DISPLAY_LIST* layerTriangles = new TRIANGLE_DISPLAY_LIST( holes2D.size() );
|
||||
TRIANGLE_DISPLAY_LIST* layerTriangles =
|
||||
new TRIANGLE_DISPLAY_LIST( listHolesObject2d.size() );
|
||||
|
||||
// Convert the list of objects(triangles) to triangle layer structure
|
||||
for( const OBJECT_2D* itemOnLayer : holes2D )
|
||||
for( const OBJECT_2D* itemOnLayer : listHolesObject2d )
|
||||
{
|
||||
const OBJECT_2D* object2d_A = itemOnLayer;
|
||||
|
||||
@@ -906,9 +880,7 @@ void RENDER_3D_OPENGL::Load3dModelsIfNeeded()
|
||||
load3dModels( &activityReporter );
|
||||
}
|
||||
else
|
||||
{
|
||||
load3dModels( nullptr );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -917,71 +889,45 @@ void RENDER_3D_OPENGL::load3dModels( REPORTER* aStatusReporter )
|
||||
if( !m_boardAdapter.GetBoard() )
|
||||
return;
|
||||
|
||||
// Building the 3D models late crashes on recent versions of macOS
|
||||
// Unclear the exact mechanism, but as a workaround, just build them
|
||||
// all the time. See https://gitlab.com/kicad/code/kicad/-/issues/17198
|
||||
#ifndef __WXMAC__
|
||||
if( !m_boardAdapter.m_IsPreviewer
|
||||
&& !m_boardAdapter.m_Cfg->m_Render.show_footprints_normal
|
||||
&& !m_boardAdapter.m_Cfg->m_Render.show_footprints_insert
|
||||
&& !m_boardAdapter.m_Cfg->m_Render.show_footprints_virtual )
|
||||
if( !m_boardAdapter.GetFlag( FL_FP_ATTRIBUTES_NORMAL )
|
||||
&& !m_boardAdapter.GetFlag( FL_FP_ATTRIBUTES_NORMAL_INSERT )
|
||||
&& !m_boardAdapter.GetFlag( FL_FP_ATTRIBUTES_VIRTUAL ) )
|
||||
{
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
|
||||
// Go for all footprints
|
||||
for( const FOOTPRINT* footprint : m_boardAdapter.GetBoard()->Footprints() )
|
||||
{
|
||||
wxString libraryName = footprint->GetFPID().GetLibNickname();
|
||||
wxString footprintBasePath = wxEmptyString;
|
||||
|
||||
if( m_boardAdapter.GetBoard()->GetProject() )
|
||||
for( const FP_3DMODEL& model : footprint->Models() )
|
||||
{
|
||||
try
|
||||
{
|
||||
// FindRow() can throw an exception
|
||||
const FP_LIB_TABLE_ROW* fpRow =
|
||||
PROJECT_PCB::PcbFootprintLibs( m_boardAdapter.GetBoard()->GetProject() )
|
||||
->FindRow( libraryName, false );
|
||||
|
||||
if( fpRow )
|
||||
footprintBasePath = fpRow->GetFullURI( true );
|
||||
}
|
||||
catch( ... )
|
||||
{
|
||||
// Do nothing if the libraryName is not found in lib table
|
||||
}
|
||||
}
|
||||
|
||||
for( const FP_3DMODEL& fp_model : footprint->Models() )
|
||||
{
|
||||
if( fp_model.m_Show && !fp_model.m_Filename.empty() )
|
||||
if( model.m_Show && !model.m_Filename.empty() )
|
||||
{
|
||||
if( aStatusReporter )
|
||||
{
|
||||
// Display the short filename of the 3D fp_model loaded:
|
||||
// Display the short filename of the 3D model loaded:
|
||||
// (the full name is usually too long to be displayed)
|
||||
wxFileName fn( fp_model.m_Filename );
|
||||
wxFileName fn( model.m_Filename );
|
||||
aStatusReporter->Report( wxString::Format( _( "Loading %s..." ),
|
||||
fn.GetFullName() ) );
|
||||
}
|
||||
|
||||
// Check if the fp_model is not present in our cache map
|
||||
// Check if the model is not present in our cache map
|
||||
// (Not already loaded in memory)
|
||||
if( m_3dModelMap.find( fp_model.m_Filename ) == m_3dModelMap.end() )
|
||||
if( m_3dModelMap.find( model.m_Filename ) == m_3dModelMap.end() )
|
||||
{
|
||||
// It is not present, try get it from cache
|
||||
const S3DMODEL* modelPtr =
|
||||
m_boardAdapter.Get3dCacheManager()->GetModel( fp_model.m_Filename, footprintBasePath );
|
||||
m_boardAdapter.Get3dCacheManager()->GetModel( model.m_Filename );
|
||||
|
||||
// only add it if the return is not NULL
|
||||
if( modelPtr )
|
||||
{
|
||||
MATERIAL_MODE materialMode = m_boardAdapter.m_Cfg->m_Render.material_mode;
|
||||
MODEL_3D* model = new MODEL_3D( *modelPtr, materialMode );
|
||||
MATERIAL_MODE materialMode = m_boardAdapter.GetMaterialMode();
|
||||
MODEL_3D* ogl_model = new MODEL_3D( *modelPtr, materialMode );
|
||||
|
||||
m_3dModelMap[ fp_model.m_Filename ] = model;
|
||||
if( ogl_model )
|
||||
m_3dModelMap[ model.m_Filename ] = ogl_model;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -471,11 +471,38 @@ void OPENGL_RENDER_LIST::DrawAll( bool aDrawMiddle ) const
|
||||
}
|
||||
|
||||
|
||||
void OPENGL_RENDER_LIST::DrawCulled( bool aDrawMiddle,
|
||||
const OPENGL_RENDER_LIST* aSubtractList,
|
||||
const OPENGL_RENDER_LIST* bSubtractList,
|
||||
const OPENGL_RENDER_LIST* cSubtractList,
|
||||
const OPENGL_RENDER_LIST* dSubtractList ) const
|
||||
void OPENGL_RENDER_LIST::DrawAllCameraCulled( float zCameraPos, bool aDrawMiddle ) const
|
||||
{
|
||||
zCameraPos = m_haveTransformation
|
||||
? ( ( zCameraPos - m_zPositionTransformation ) / m_zScaleTransformation )
|
||||
: zCameraPos;
|
||||
|
||||
if( aDrawMiddle )
|
||||
DrawMiddle();
|
||||
|
||||
if( zCameraPos > m_zTop )
|
||||
{
|
||||
DrawTop();
|
||||
}
|
||||
else
|
||||
{
|
||||
if( zCameraPos < m_zBot )
|
||||
{
|
||||
DrawBot();
|
||||
}
|
||||
else
|
||||
{
|
||||
// If camera is in the middle dont draw it.
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void OPENGL_RENDER_LIST::DrawAllCameraCulledSubtractLayer( bool aDrawMiddle,
|
||||
const OPENGL_RENDER_LIST* aLayerToSubtractA,
|
||||
const OPENGL_RENDER_LIST* aLayerToSubtractB,
|
||||
const OPENGL_RENDER_LIST* aLayerToSubtractC,
|
||||
const OPENGL_RENDER_LIST* aLayerToSubtractD ) const
|
||||
{
|
||||
glClearStencil( 0x00 );
|
||||
glClear( GL_STENCIL_BUFFER_BIT );
|
||||
@@ -490,17 +517,17 @@ void OPENGL_RENDER_LIST::DrawCulled( bool aDrawMiddle,
|
||||
glStencilFunc( GL_ALWAYS, 1, 0 );
|
||||
glStencilOp( GL_KEEP, GL_KEEP, GL_REPLACE );
|
||||
|
||||
if( aSubtractList )
|
||||
aSubtractList->DrawBot();
|
||||
if( aLayerToSubtractA )
|
||||
aLayerToSubtractA->DrawBot();
|
||||
|
||||
if( bSubtractList )
|
||||
bSubtractList->DrawBot();
|
||||
if( aLayerToSubtractB )
|
||||
aLayerToSubtractB->DrawBot();
|
||||
|
||||
if( cSubtractList )
|
||||
cSubtractList->DrawBot();
|
||||
if( aLayerToSubtractC )
|
||||
aLayerToSubtractC->DrawBot();
|
||||
|
||||
if( dSubtractList )
|
||||
dSubtractList->DrawBot();
|
||||
if( aLayerToSubtractD )
|
||||
aLayerToSubtractD->DrawBot();
|
||||
|
||||
glEnable(GL_DEPTH_TEST);
|
||||
glDepthMask(GL_TRUE);
|
||||
@@ -517,17 +544,17 @@ void OPENGL_RENDER_LIST::DrawCulled( bool aDrawMiddle,
|
||||
glStencilFunc( GL_ALWAYS, 2, 0 );
|
||||
glStencilOp( GL_KEEP, GL_KEEP, GL_REPLACE );
|
||||
|
||||
if( aSubtractList )
|
||||
aSubtractList->DrawTop();
|
||||
if( aLayerToSubtractA )
|
||||
aLayerToSubtractA->DrawTop();
|
||||
|
||||
if( bSubtractList )
|
||||
bSubtractList->DrawTop();
|
||||
if( aLayerToSubtractB )
|
||||
aLayerToSubtractB->DrawTop();
|
||||
|
||||
if( cSubtractList )
|
||||
cSubtractList->DrawTop();
|
||||
if( aLayerToSubtractC )
|
||||
aLayerToSubtractC->DrawTop();
|
||||
|
||||
if( dSubtractList )
|
||||
dSubtractList->DrawTop();
|
||||
if( aLayerToSubtractD )
|
||||
aLayerToSubtractD->DrawTop();
|
||||
|
||||
glEnable(GL_DEPTH_TEST);
|
||||
glDepthMask(GL_TRUE);
|
||||
@@ -548,8 +575,8 @@ void OPENGL_RENDER_LIST::DrawCulled( bool aDrawMiddle,
|
||||
|
||||
if( aDrawMiddle )
|
||||
{
|
||||
if( aSubtractList )
|
||||
aSubtractList->DrawMiddle();
|
||||
if( aLayerToSubtractA )
|
||||
aLayerToSubtractA->DrawMiddle();
|
||||
}
|
||||
|
||||
glLightModeli( GL_LIGHT_MODEL_TWO_SIDE, GL_FALSE );
|
||||
@@ -561,7 +588,7 @@ void OPENGL_RENDER_LIST::DrawCulled( bool aDrawMiddle,
|
||||
|
||||
void OPENGL_RENDER_LIST::ApplyScalePosition( float aZposition, float aZscale )
|
||||
{
|
||||
wxCHECK2( aZscale > FLT_EPSILON, aZscale = FLT_EPSILON + 1 );
|
||||
wxASSERT( aZscale > FLT_EPSILON );
|
||||
|
||||
m_zPositionTransformation = aZposition;
|
||||
m_zScaleTransformation = aZscale;
|
||||
@@ -569,12 +596,6 @@ void OPENGL_RENDER_LIST::ApplyScalePosition( float aZposition, float aZscale )
|
||||
}
|
||||
|
||||
|
||||
void OPENGL_RENDER_LIST::ApplyScalePosition( OPENGL_RENDER_LIST* aOtherList )
|
||||
{
|
||||
ApplyScalePosition( aOtherList->GetZBot(), aOtherList->GetZTop() - aOtherList->GetZBot() );
|
||||
}
|
||||
|
||||
|
||||
void OPENGL_RENDER_LIST::SetItIsTransparent( bool aSetTransparent )
|
||||
{
|
||||
m_draw_it_transparent = aSetTransparent;
|
||||
@@ -629,7 +650,6 @@ GLuint OPENGL_RENDER_LIST::generate_top_or_bot_seg_ends(
|
||||
|
||||
glDrawArrays( GL_TRIANGLES, 0, aTriangleContainer->GetVertexSize() );
|
||||
|
||||
glBindTexture( GL_TEXTURE_2D, 0 );
|
||||
glDisable( GL_TEXTURE_2D );
|
||||
glDisable( GL_ALPHA_TEST );
|
||||
glDisable( GL_BLEND );
|
||||
|
||||
@@ -194,14 +194,15 @@ public:
|
||||
*
|
||||
* @param zCameraPos is the camera z axis position.
|
||||
*/
|
||||
void DrawCulled( bool aDrawMiddle,
|
||||
const OPENGL_RENDER_LIST* aSubtractList = nullptr,
|
||||
const OPENGL_RENDER_LIST* bSubtractList = nullptr,
|
||||
const OPENGL_RENDER_LIST* cSubtractList = nullptr,
|
||||
const OPENGL_RENDER_LIST* dSubtractList = nullptr ) const;
|
||||
void DrawAllCameraCulled( float zCameraPos, bool aDrawMiddle = true ) const;
|
||||
|
||||
void DrawAllCameraCulledSubtractLayer( bool aDrawMiddle,
|
||||
const OPENGL_RENDER_LIST* aLayerToSubtractA = nullptr,
|
||||
const OPENGL_RENDER_LIST* aLayerToSubtractB = nullptr,
|
||||
const OPENGL_RENDER_LIST* aLayerToSubtractC = nullptr,
|
||||
const OPENGL_RENDER_LIST* aLayerToSubtractD = nullptr ) const;
|
||||
|
||||
void ApplyScalePosition( float aZposition, float aZscale );
|
||||
void ApplyScalePosition( OPENGL_RENDER_LIST* aOtherList );
|
||||
|
||||
void ClearScalePosition() { m_haveTransformation = false; }
|
||||
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
* This program source code file is part of KiCad, a free EDA CAD application.
|
||||
*
|
||||
* Copyright (C) 2015-2016 Mario Luzeiro <mrluzeiro@ua.pt>
|
||||
* Copyright (C) 1992-2022 KiCad Developers, see AUTHORS.txt for contributors.
|
||||
* Copyright (C) 1992-2021 KiCad Developers, see AUTHORS.txt for contributors.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
@@ -27,7 +27,7 @@
|
||||
#include <trigo.h>
|
||||
#include <wx/debug.h> // For the wxASSERT
|
||||
|
||||
#define RADPERDEG 0.0174533f
|
||||
#define RADPERDEG 0.0174533
|
||||
|
||||
void DrawRoundArrow( SFVEC3F aPosition, SFVEC3F aTargetPos, float aSize )
|
||||
{
|
||||
@@ -144,18 +144,18 @@ void DrawHalfOpenCylinder( unsigned int aNrSidesPerCircle )
|
||||
if( aNrSidesPerCircle > 1 )
|
||||
{
|
||||
const float radius = 0.5f;
|
||||
const EDA_ANGLE delta = ANGLE_360 / aNrSidesPerCircle;
|
||||
const int delta = 3600 / aNrSidesPerCircle;
|
||||
|
||||
// Generate bottom
|
||||
glNormal3f( 0.0f, 0.0f,-1.0f );
|
||||
glBegin( GL_TRIANGLE_FAN );
|
||||
glVertex3f( 0.0, 0.0, 0.0 ); // This is the V0 of the FAN
|
||||
|
||||
for( EDA_ANGLE ii = ANGLE_0; ii < ANGLE_180; ii += delta )
|
||||
for( int ii = 0; ii < 1800; ii += delta )
|
||||
{
|
||||
SFVEC2D corner = SFVEC2D( 0.0, radius );
|
||||
RotatePoint( &corner.x, &corner.y, ii );
|
||||
glVertex3f( static_cast<GLfloat>( corner.x ), static_cast<GLfloat>( corner.y ), 0.0 );
|
||||
glVertex3f( corner.x, corner.y, 0.0 );
|
||||
}
|
||||
|
||||
glVertex3d( 0.0, -radius, 0.0 );
|
||||
@@ -166,12 +166,12 @@ void DrawHalfOpenCylinder( unsigned int aNrSidesPerCircle )
|
||||
glBegin( GL_TRIANGLE_FAN );
|
||||
glVertex3f( 0.0, 0.0, 1.0 ); // This is the V0 of the FAN
|
||||
|
||||
for( EDA_ANGLE ii = ANGLE_180; ii > ANGLE_0; ii -= delta )
|
||||
for( int ii = 1800; ii > 0; ii -= delta )
|
||||
{
|
||||
SFVEC2D corner = SFVEC2D( 0.0, radius );
|
||||
|
||||
RotatePoint( &corner.x, &corner.y, ii );
|
||||
glVertex3f( static_cast<GLfloat>( corner.x ), static_cast<GLfloat>( corner.y ), 1.0 );
|
||||
glVertex3f( corner.x, corner.y, 1.0 );
|
||||
}
|
||||
|
||||
glVertex3f( 0.0, radius, 1.0 );
|
||||
@@ -180,15 +180,14 @@ void DrawHalfOpenCylinder( unsigned int aNrSidesPerCircle )
|
||||
// Generate contours
|
||||
glBegin( GL_QUAD_STRIP );
|
||||
|
||||
for( EDA_ANGLE ii = ANGLE_180; ii > ANGLE_0; ii -= delta )
|
||||
for( int ii = 1800; ii > 0; ii -= delta )
|
||||
{
|
||||
SFVEC2D corner = SFVEC2D( 0.0, radius );
|
||||
|
||||
RotatePoint( &corner.x, &corner.y, ii );
|
||||
glNormal3f( static_cast<GLfloat>( corner.x * 2.0f ),
|
||||
static_cast<GLfloat>( corner.y * 2.0f ), 0.0f );
|
||||
glVertex3f( static_cast<GLfloat>( corner.x ), static_cast<GLfloat>( corner.y ), 1.0f );
|
||||
glVertex3f( static_cast<GLfloat>( corner.x ), static_cast<GLfloat>( corner.y ), 0.0f );
|
||||
glNormal3f( corner.x * 2.0f, corner.y * 2.0f, 0.0f );
|
||||
glVertex3f( corner.x, corner.y, 1.0 );
|
||||
glVertex3f( corner.x, corner.y, 0.0 );
|
||||
}
|
||||
|
||||
glNormal3f( 0.0, 1.0f, 0.0f );
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -41,8 +41,10 @@
|
||||
|
||||
#include <map>
|
||||
|
||||
|
||||
typedef std::map< PCB_LAYER_ID, OPENGL_RENDER_LIST* > MAP_OGL_DISP_LISTS;
|
||||
typedef std::list<TRIANGLE_DISPLAY_LIST* > LIST_TRIANGLES;
|
||||
typedef std::map< wxString, MODEL_3D* > MAP_3DMODEL;
|
||||
|
||||
#define SIZE_OF_CIRCLE_TEXTURE 1024
|
||||
|
||||
@@ -73,16 +75,15 @@ public:
|
||||
|
||||
private:
|
||||
OPENGL_RENDER_LIST* generateHoles( const LIST_OBJECT2D& aListHolesObject2d,
|
||||
const SHAPE_POLY_SET& aPoly, float aZtop, float aZbot,
|
||||
bool aInvertFaces,
|
||||
const SHAPE_POLY_SET& aPoly, float aZtop,
|
||||
float aZbot, bool aInvertFaces,
|
||||
const BVH_CONTAINER_2D* aThroughHoles = nullptr );
|
||||
|
||||
OPENGL_RENDER_LIST* generateLayerList( const BVH_CONTAINER_2D* aContainer,
|
||||
const SHAPE_POLY_SET* aPolyList, PCB_LAYER_ID aLayer,
|
||||
const SHAPE_POLY_SET* aPolyList,
|
||||
PCB_LAYER_ID aLayerId,
|
||||
const BVH_CONTAINER_2D* aThroughHoles = nullptr );
|
||||
|
||||
OPENGL_RENDER_LIST* generateEmptyLayerList( PCB_LAYER_ID aLayer );
|
||||
|
||||
void addTopAndBottomTriangles( TRIANGLE_DISPLAY_LIST* aDst, const SFVEC2F& v0,
|
||||
const SFVEC2F& v1, const SFVEC2F& v2, float top, float bot );
|
||||
|
||||
@@ -92,17 +93,17 @@ private:
|
||||
void addObjectTriangles( const POLYGON_4PT_2D* aPoly, TRIANGLE_DISPLAY_LIST* aDstLayer,
|
||||
float aZtop, float aZbot );
|
||||
|
||||
void addObjectTriangles( const FILLED_CIRCLE_2D* aCircle, TRIANGLE_DISPLAY_LIST* aDstLayer,
|
||||
float aZtop, float aZbot );
|
||||
void addObjectTriangles( const FILLED_CIRCLE_2D* aFilledCircle,
|
||||
TRIANGLE_DISPLAY_LIST* aDstLayer, float aZtop, float aZbot );
|
||||
|
||||
void addObjectTriangles( const TRIANGLE_2D* aTri, TRIANGLE_DISPLAY_LIST* aDstLayer,
|
||||
float aZtop, float aZbot );
|
||||
|
||||
void addObjectTriangles( const ROUND_SEGMENT_2D* aSeg, TRIANGLE_DISPLAY_LIST* aDstLayer,
|
||||
float aZtop, float aZbot );
|
||||
void addObjectTriangles( const ROUND_SEGMENT_2D* aSeg,
|
||||
TRIANGLE_DISPLAY_LIST* aDstLayer, float aZtop, float aZbot );
|
||||
|
||||
void renderSolderMaskLayer( PCB_LAYER_ID aLayerID, float aZPos, bool aShowThickness,
|
||||
bool aSkipRenderHoles );
|
||||
void renderSolderMaskLayer( PCB_LAYER_ID aLayerID, float aZPosition,
|
||||
bool aDrawMiddleSegments, bool aSkipRenderHoles );
|
||||
|
||||
void renderBoardBody( bool aSkipRenderHoles );
|
||||
|
||||
@@ -128,41 +129,18 @@ private:
|
||||
*/
|
||||
void load3dModels( REPORTER* aStatusReporter );
|
||||
|
||||
struct MODELTORENDER
|
||||
{
|
||||
glm::mat4 m_modelWorldMat;
|
||||
const MODEL_3D* m_model;
|
||||
float m_opacity;
|
||||
bool m_isTransparent;
|
||||
bool m_isSelected;
|
||||
/**
|
||||
* @param aRenderTopOrBot true will render Top, false will render bottom
|
||||
* @param aRenderTransparentOnly true will render only the transparent objects, false will
|
||||
* render opaque
|
||||
*/
|
||||
void render3dModels( bool aRenderTopOrBot, bool aRenderTransparentOnly );
|
||||
|
||||
MODELTORENDER( glm::mat4 aModelWorldMat,
|
||||
const MODEL_3D* aNodel,
|
||||
float aOpacity,
|
||||
bool aIsTransparent,
|
||||
bool aIsSelected ) :
|
||||
m_modelWorldMat( std::move( aModelWorldMat ) ),
|
||||
m_model( aNodel ),
|
||||
m_opacity( aOpacity ),
|
||||
m_isTransparent( aIsTransparent ),
|
||||
m_isSelected( aIsSelected )
|
||||
{
|
||||
}
|
||||
};
|
||||
void render3dModelsSelected( bool aRenderTopOrBot, bool aRenderTransparentOnly,
|
||||
bool aRenderSelectedOnly );
|
||||
|
||||
void renderOpaqueModels( const glm::mat4 &aCameraViewMatrix );
|
||||
void renderTransparentModels( const glm::mat4 &aCameraViewMatrix );
|
||||
|
||||
void renderModel( const glm::mat4 &aCameraViewMatrix, const MODELTORENDER &aModelToRender,
|
||||
const SFVEC3F &aSelColor, const SFVEC3F *aCameraWorldPos );
|
||||
|
||||
|
||||
void get3dModelsSelected( std::list<MODELTORENDER> &aDstRenderList, bool aGetTop, bool aGetBot,
|
||||
bool aRenderTransparentOnly, bool aRenderSelectedOnly );
|
||||
|
||||
void get3dModelsFromFootprint( std::list<MODELTORENDER> &aDstRenderList,
|
||||
const FOOTPRINT* aFootprint, bool aRenderTransparentOnly,
|
||||
bool aIsSelected );
|
||||
void renderFootprint( const FOOTPRINT* aFootprint, bool aRenderTransparentOnly,
|
||||
bool aIsSelected );
|
||||
|
||||
void setLightFront( bool enabled );
|
||||
void setLightTop( bool enabled );
|
||||
@@ -185,6 +163,7 @@ private:
|
||||
void unsetDepthOffset();
|
||||
|
||||
void setLayerMaterial( PCB_LAYER_ID aLayerID );
|
||||
SFVEC4F getLayerColor( PCB_LAYER_ID aLayerID );
|
||||
|
||||
bool initializeOpenGL();
|
||||
OPENGL_RENDER_LIST* createBoard( const SHAPE_POLY_SET& aBoardPoly,
|
||||
@@ -211,8 +190,6 @@ private:
|
||||
MAP_OGL_DISP_LISTS m_layers;
|
||||
OPENGL_RENDER_LIST* m_platedPadsFront;
|
||||
OPENGL_RENDER_LIST* m_platedPadsBack;
|
||||
OPENGL_RENDER_LIST* m_offboardPadsFront;
|
||||
OPENGL_RENDER_LIST* m_offboardPadsBack;
|
||||
MAP_OGL_DISP_LISTS m_outerLayerHoles;
|
||||
MAP_OGL_DISP_LISTS m_innerLayerHoles;
|
||||
OPENGL_RENDER_LIST* m_board;
|
||||
@@ -231,9 +208,7 @@ private:
|
||||
OPENGL_RENDER_LIST* m_vias;
|
||||
OPENGL_RENDER_LIST* m_padHoles;
|
||||
|
||||
// Caches
|
||||
std::map<wxString, MODEL_3D*> m_3dModelMap;
|
||||
std::map<std::vector<float>, glm::mat4> m_3dModelMatrixMap;
|
||||
MAP_3DMODEL m_3dModelMap;
|
||||
|
||||
BOARD_ITEM* m_currentRollOverItem;
|
||||
|
||||
|
||||
@@ -30,7 +30,7 @@
|
||||
#ifndef POST_SHADER_H
|
||||
#define POST_SHADER_H
|
||||
|
||||
#include <gal/3d/camera.h>
|
||||
#include "camera.h"
|
||||
|
||||
class POST_SHADER
|
||||
{
|
||||
|
||||
@@ -23,7 +23,7 @@
|
||||
*/
|
||||
|
||||
/**
|
||||
* @file bvh_pbrt.cpp
|
||||
* @file cbvh_pbrt.cpp
|
||||
* @brief This BVH implementation is based on the source code implementation
|
||||
* from the book "Physically Based Rendering" (v2 and v3)
|
||||
*
|
||||
@@ -437,7 +437,7 @@ BVHBuildNode *BVH_PBRT::recursiveBuild ( std::vector<BVHPrimitiveInfo>& primitiv
|
||||
|
||||
(*totalNodes)++;
|
||||
|
||||
// !TODO: implement a memory arena
|
||||
// !TODO: implement an memory Arena
|
||||
BVHBuildNode *node = static_cast<BVHBuildNode *>( malloc( sizeof( BVHBuildNode ) ) );
|
||||
m_nodesToFree.push_back( node );
|
||||
|
||||
|
||||
@@ -1,9 +1,8 @@
|
||||
/*
|
||||
* This program source code file is part of KiCad, a free EDA CAD application.
|
||||
*
|
||||
* Copyright (C) 2015-2022 Mario Luzeiro <mrluzeiro@ua.pt>
|
||||
* Copyright (C) 2023 CERN
|
||||
* Copyright (C) 2015-2023 KiCad Developers, see AUTHORS.txt for contributors.
|
||||
* Copyright (C) 2015-2016 Mario Luzeiro <mrluzeiro@ua.pt>
|
||||
* Copyright (C) 2015-2021 KiCad Developers, see AUTHORS.txt for contributors.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
@@ -40,12 +39,9 @@
|
||||
|
||||
#include <board.h>
|
||||
#include <footprint.h>
|
||||
#include <fp_lib_table.h>
|
||||
#include <eda_3d_viewer_frame.h>
|
||||
#include <project_pcb.h>
|
||||
|
||||
#include <base_units.h>
|
||||
#include <core/profile.h> // To use GetRunningMicroSecs or another profiling utility
|
||||
#include <profile.h> // To use GetRunningMicroSecs or another profiling utility
|
||||
|
||||
/**
|
||||
* Perform an interpolation step to easy control the transparency based on the
|
||||
@@ -69,28 +65,35 @@ static float TransparencyControl( float aGrayColorValue, float aTransparency )
|
||||
/**
|
||||
* Scale conversion from 3d model units to pcb units
|
||||
*/
|
||||
#define UNITS3D_TO_UNITSPCB ( pcbIUScale.IU_PER_MM )
|
||||
#define UNITS3D_TO_UNITSPCB ( IU_PER_MM )
|
||||
|
||||
|
||||
void RENDER_3D_RAYTRACE::setupMaterials()
|
||||
{
|
||||
MATERIAL::SetDefaultRefractionRayCount( m_boardAdapter.m_Cfg->m_Render.raytrace_nrsamples_refractions );
|
||||
MATERIAL::SetDefaultReflectionRayCount( m_boardAdapter.m_Cfg->m_Render.raytrace_nrsamples_reflections );
|
||||
MATERIAL::SetDefaultRefractionRayCount( m_boardAdapter.m_RtRefractionSampleCount );
|
||||
MATERIAL::SetDefaultReflectionRayCount( m_boardAdapter.m_RtReflectionSampleCount );
|
||||
|
||||
MATERIAL::SetDefaultRefractionRecursionCount( m_boardAdapter.m_Cfg->m_Render.raytrace_recursivelevel_refractions );
|
||||
MATERIAL::SetDefaultReflectionRecursionCount( m_boardAdapter.m_Cfg->m_Render.raytrace_recursivelevel_reflections );
|
||||
MATERIAL::SetDefaultRefractionRecursionCount( m_boardAdapter.m_RtRecursiveRefractionCount );
|
||||
MATERIAL::SetDefaultReflectionRecursionCount( m_boardAdapter.m_RtRecursiveReflectionCount );
|
||||
|
||||
double mmTo3Dunits = pcbIUScale.IU_PER_MM * m_boardAdapter.BiuTo3dUnits();
|
||||
double mmTo3Dunits = IU_PER_MM * m_boardAdapter.BiuTo3dUnits();
|
||||
|
||||
if( m_boardAdapter.m_Cfg->m_Render.raytrace_procedural_textures )
|
||||
if( m_boardAdapter.GetFlag( FL_RENDER_RAYTRACING_PROCEDURAL_TEXTURES ) )
|
||||
{
|
||||
m_boardMaterial = BOARD_NORMAL( 0.40f * mmTo3Dunits );
|
||||
|
||||
m_copperMaterial = COPPER_NORMAL( 4.0f * mmTo3Dunits, &m_boardMaterial );
|
||||
|
||||
m_platedCopperMaterial = PLATED_COPPER_NORMAL( 0.5f * mmTo3Dunits );
|
||||
|
||||
m_solderMaskMaterial = SOLDER_MASK_NORMAL( &m_boardMaterial );
|
||||
|
||||
m_plasticMaterial = PLASTIC_NORMAL( 0.05f * mmTo3Dunits );
|
||||
|
||||
m_shinyPlasticMaterial = PLASTIC_SHINE_NORMAL( 0.1f * mmTo3Dunits );
|
||||
|
||||
m_brushedMetalMaterial = BRUSHED_METAL_NORMAL( 0.05f * mmTo3Dunits );
|
||||
|
||||
m_silkScreenMaterial = SILK_SCREEN_NORMAL( 0.25f * mmTo3Dunits );
|
||||
}
|
||||
|
||||
@@ -104,14 +107,14 @@ void RENDER_3D_RAYTRACE::setupMaterials()
|
||||
ConvertSRGBToLinear( (SFVEC3F) m_boardAdapter.m_CopperColor * 0.3f ),
|
||||
SFVEC3F( 0.0f ), copperSpecularLinear, 0.4f * 128.0f, 0.0f, 0.0f );
|
||||
|
||||
if( m_boardAdapter.m_Cfg->m_Render.raytrace_procedural_textures )
|
||||
if( m_boardAdapter.GetFlag( FL_RENDER_RAYTRACING_PROCEDURAL_TEXTURES ) )
|
||||
m_materials.m_Copper.SetGenerator( &m_platedCopperMaterial );
|
||||
|
||||
m_materials.m_NonPlatedCopper = BLINN_PHONG_MATERIAL(
|
||||
ConvertSRGBToLinear( SFVEC3F( 0.191f, 0.073f, 0.022f ) ), SFVEC3F( 0.0f, 0.0f, 0.0f ),
|
||||
SFVEC3F( 0.256f, 0.137f, 0.086f ), 0.15f * 128.0f, 0.0f, 0.0f );
|
||||
|
||||
if( m_boardAdapter.m_Cfg->m_Render.raytrace_procedural_textures )
|
||||
if( m_boardAdapter.GetFlag( FL_RENDER_RAYTRACING_PROCEDURAL_TEXTURES ) )
|
||||
m_materials.m_NonPlatedCopper.SetGenerator( &m_copperMaterial );
|
||||
|
||||
m_materials.m_Paste = BLINN_PHONG_MATERIAL(
|
||||
@@ -129,7 +132,7 @@ void RENDER_3D_RAYTRACE::setupMaterials()
|
||||
(SFVEC3F) m_boardAdapter.m_SilkScreenColorTop ) ),
|
||||
SFVEC3F( 0.0f ), SFVEC3F( 0.10f ) ), 0.078125f * 128.0f, 0.0f, 0.0f );
|
||||
|
||||
if( m_boardAdapter.m_Cfg->m_Render.raytrace_procedural_textures )
|
||||
if( m_boardAdapter.GetFlag( FL_RENDER_RAYTRACING_PROCEDURAL_TEXTURES ) )
|
||||
m_materials.m_SilkS.SetGenerator( &m_silkScreenMaterial );
|
||||
|
||||
// Assume that SolderMaskTop == SolderMaskBot
|
||||
@@ -150,7 +153,7 @@ void RENDER_3D_RAYTRACE::setupMaterials()
|
||||
m_materials.m_SolderMask.SetCastShadows( true );
|
||||
m_materials.m_SolderMask.SetRefractionRayCount( 1 );
|
||||
|
||||
if( m_boardAdapter.m_Cfg->m_Render.raytrace_procedural_textures )
|
||||
if( m_boardAdapter.GetFlag( FL_RENDER_RAYTRACING_PROCEDURAL_TEXTURES ) )
|
||||
m_materials.m_SolderMask.SetGenerator( &m_solderMaskMaterial );
|
||||
|
||||
m_materials.m_EpoxyBoard =
|
||||
@@ -163,7 +166,7 @@ void RENDER_3D_RAYTRACE::setupMaterials()
|
||||
|
||||
m_materials.m_EpoxyBoard.SetAbsorvance( 10.0f );
|
||||
|
||||
if( m_boardAdapter.m_Cfg->m_Render.raytrace_procedural_textures )
|
||||
if( m_boardAdapter.GetFlag( FL_RENDER_RAYTRACING_PROCEDURAL_TEXTURES ) )
|
||||
m_materials.m_EpoxyBoard.SetGenerator( &m_boardMaterial );
|
||||
|
||||
SFVEC3F bgTop = ConvertSRGBToLinear( (SFVEC3F) m_boardAdapter.m_BgColorTop );
|
||||
@@ -236,9 +239,7 @@ void RENDER_3D_RAYTRACE::createItemsFromContainer( const BVH_CONTAINER_2D* aCont
|
||||
if( aContainer2d == nullptr )
|
||||
return;
|
||||
|
||||
EDA_3D_VIEWER_SETTINGS::RENDER_SETTINGS& cfg = m_boardAdapter.m_Cfg->m_Render;
|
||||
bool isSilk = aLayer_id == B_SilkS || aLayer_id == F_SilkS;
|
||||
const LIST_OBJECT2D& listObject2d = aContainer2d->GetList();
|
||||
const LIST_OBJECT2D& listObject2d = aContainer2d->GetList();
|
||||
|
||||
if( listObject2d.size() == 0 )
|
||||
return;
|
||||
@@ -277,8 +278,11 @@ void RENDER_3D_RAYTRACE::createItemsFromContainer( const BVH_CONTAINER_2D* aCont
|
||||
// layer and the flag is set, then clip the silk at the outer edge of the annular ring,
|
||||
// rather than the at the outer edge of the copper plating.
|
||||
const BVH_CONTAINER_2D& throughHoleOuter =
|
||||
cfg.clip_silk_on_via_annuli && isSilk ? m_boardAdapter.GetViaAnnuli()
|
||||
: m_boardAdapter.GetTH_ODs();
|
||||
( m_boardAdapter.GetFlag( FL_CLIP_SILK_ON_VIA_ANNULUS )
|
||||
&& m_boardAdapter.GetFlag( FL_USE_REALISTIC_MODE )
|
||||
&& ( ( aLayer_id == B_SilkS ) || ( aLayer_id == F_SilkS ) ) ) ?
|
||||
m_boardAdapter.GetThroughHoleAnnularRings() :
|
||||
m_boardAdapter.GetThroughHoleOds();
|
||||
|
||||
if( !throughHoleOuter.GetList().empty() )
|
||||
{
|
||||
@@ -304,13 +308,14 @@ void RENDER_3D_RAYTRACE::createItemsFromContainer( const BVH_CONTAINER_2D* aCont
|
||||
|
||||
const MAP_CONTAINER_2D_BASE& mapLayers = m_boardAdapter.GetLayerMap();
|
||||
|
||||
if( cfg.subtract_mask_from_silk
|
||||
if( m_boardAdapter.GetFlag( FL_SUBTRACT_MASK_FROM_SILK )
|
||||
&& m_boardAdapter.GetFlag( FL_USE_REALISTIC_MODE )
|
||||
&& ( ( aLayer_id == B_SilkS && mapLayers.find( B_Mask ) != mapLayers.end() )
|
||||
|| ( aLayer_id == F_SilkS && mapLayers.find( F_Mask ) != mapLayers.end() ) ) )
|
||||
{
|
||||
const PCB_LAYER_ID maskLayer = ( aLayer_id == B_SilkS ) ? B_Mask : F_Mask;
|
||||
const PCB_LAYER_ID layerMask_id = ( aLayer_id == B_SilkS ) ? B_Mask : F_Mask;
|
||||
|
||||
const BVH_CONTAINER_2D* containerMaskLayer2d = mapLayers.at( maskLayer );
|
||||
const BVH_CONTAINER_2D* containerMaskLayer2d = mapLayers.at( layerMask_id );
|
||||
|
||||
CONST_LIST_OBJECT2D intersecting;
|
||||
|
||||
@@ -330,8 +335,8 @@ void RENDER_3D_RAYTRACE::createItemsFromContainer( const BVH_CONTAINER_2D* aCont
|
||||
if( ( object2d_B == CSGITEM_EMPTY ) && ( object2d_C == CSGITEM_FULL ) )
|
||||
{
|
||||
LAYER_ITEM* objPtr = new LAYER_ITEM( object2d_A,
|
||||
m_boardAdapter.GetLayerBottomZPos( aLayer_id ) - aLayerZOffset,
|
||||
m_boardAdapter.GetLayerTopZPos( aLayer_id ) + aLayerZOffset );
|
||||
m_boardAdapter.GetLayerBottomZPos( aLayer_id ) - aLayerZOffset,
|
||||
m_boardAdapter.GetLayerTopZPos( aLayer_id ) + aLayerZOffset );
|
||||
objPtr->SetMaterial( aMaterialLayer );
|
||||
objPtr->SetColor( ConvertSRGBToLinear( aLayerColor ) );
|
||||
m_objectContainer.Add( objPtr );
|
||||
@@ -343,8 +348,8 @@ void RENDER_3D_RAYTRACE::createItemsFromContainer( const BVH_CONTAINER_2D* aCont
|
||||
m_containerWithObjectsToDelete.Add( itemCSG2d );
|
||||
|
||||
LAYER_ITEM* objPtr = new LAYER_ITEM( itemCSG2d,
|
||||
m_boardAdapter.GetLayerBottomZPos( aLayer_id ) - aLayerZOffset,
|
||||
m_boardAdapter.GetLayerTopZPos( aLayer_id ) + aLayerZOffset );
|
||||
m_boardAdapter.GetLayerBottomZPos( aLayer_id ) - aLayerZOffset,
|
||||
m_boardAdapter.GetLayerTopZPos( aLayer_id ) + aLayerZOffset );
|
||||
|
||||
objPtr->SetMaterial( aMaterialLayer );
|
||||
objPtr->SetColor( ConvertSRGBToLinear( aLayerColor ) );
|
||||
@@ -368,7 +373,7 @@ void RENDER_3D_RAYTRACE::Reload( REPORTER* aStatusReporter, REPORTER* aWarningRe
|
||||
OBJECT_2D_STATS::Instance().ResetStats();
|
||||
OBJECT_3D_STATS::Instance().ResetStats();
|
||||
|
||||
int64_t stats_startReloadTime = GetRunningMicroSecs();
|
||||
unsigned stats_startReloadTime = GetRunningMicroSecs();
|
||||
|
||||
if( !aOnlyLoadCopperAndShapes )
|
||||
{
|
||||
@@ -393,8 +398,6 @@ void RENDER_3D_RAYTRACE::Reload( REPORTER* aStatusReporter, REPORTER* aWarningRe
|
||||
m_outlineBoard2dObjects = new CONTAINER_2D;
|
||||
m_antioutlineBoard2dObjects = new BVH_CONTAINER_2D;
|
||||
|
||||
std::bitset<LAYER_3D_END> layerFlags = m_boardAdapter.GetVisibleLayers();
|
||||
|
||||
if( !aOnlyLoadCopperAndShapes )
|
||||
{
|
||||
const int outlineCount = m_boardAdapter.GetBoardPoly().OutlineCount();
|
||||
@@ -436,7 +439,7 @@ void RENDER_3D_RAYTRACE::Reload( REPORTER* aStatusReporter, REPORTER* aWarningRe
|
||||
*m_boardAdapter.GetBoard(), ii );
|
||||
}
|
||||
|
||||
if( layerFlags.test( LAYER_3D_BOARD ) )
|
||||
if( m_boardAdapter.GetFlag( FL_SHOW_BOARD_BODY ) )
|
||||
{
|
||||
const LIST_OBJECT2D& listObjects = m_outlineBoard2dObjects->GetList();
|
||||
|
||||
@@ -445,9 +448,9 @@ void RENDER_3D_RAYTRACE::Reload( REPORTER* aStatusReporter, REPORTER* aWarningRe
|
||||
std::vector<const OBJECT_2D*>* object2d_B = new std::vector<const OBJECT_2D*>();
|
||||
|
||||
// Check if there are any THT that intersects this outline object part
|
||||
if( !m_boardAdapter.GetTH_ODs().GetList().empty() )
|
||||
if( !m_boardAdapter.GetThroughHoleOds().GetList().empty() )
|
||||
{
|
||||
const BVH_CONTAINER_2D& throughHoles = m_boardAdapter.GetTH_ODs();
|
||||
const BVH_CONTAINER_2D& throughHoles = m_boardAdapter.GetThroughHoleOds();
|
||||
CONST_LIST_OBJECT2D intersecting;
|
||||
|
||||
throughHoles.GetIntersectingObjects( object2d_A->GetBBox(), intersecting );
|
||||
@@ -511,9 +514,9 @@ void RENDER_3D_RAYTRACE::Reload( REPORTER* aStatusReporter, REPORTER* aWarningRe
|
||||
// a polygon or dummy block) it will cut also the render of the hole.
|
||||
// So this will add a full hole.
|
||||
// In fact, that is not need if the hole have copper.
|
||||
if( !m_boardAdapter.GetTH_ODs().GetList().empty() )
|
||||
if( !m_boardAdapter.GetThroughHoleOds().GetList().empty() )
|
||||
{
|
||||
const LIST_OBJECT2D& holeList = m_boardAdapter.GetTH_ODs().GetList();
|
||||
const LIST_OBJECT2D& holeList = m_boardAdapter.GetThroughHoleOds().GetList();
|
||||
|
||||
for( const OBJECT_2D* hole2d : holeList )
|
||||
{
|
||||
@@ -560,9 +563,9 @@ void RENDER_3D_RAYTRACE::Reload( REPORTER* aStatusReporter, REPORTER* aWarningRe
|
||||
aStatusReporter->Report( _( "Load Raytracing: layers" ) );
|
||||
|
||||
// Add layers maps (except B_Mask and F_Mask)
|
||||
for( const std::pair<const PCB_LAYER_ID, BVH_CONTAINER_2D*>& entry : m_boardAdapter.GetLayerMap() )
|
||||
for( auto entry : m_boardAdapter.GetLayerMap() )
|
||||
{
|
||||
const PCB_LAYER_ID layer_id = entry.first;
|
||||
PCB_LAYER_ID layer_id = entry.first;
|
||||
const BVH_CONTAINER_2D* container2d = entry.second;
|
||||
|
||||
// Only process layers that exist
|
||||
@@ -588,33 +591,40 @@ void RENDER_3D_RAYTRACE::Reload( REPORTER* aStatusReporter, REPORTER* aWarningRe
|
||||
case B_Paste:
|
||||
case F_Paste:
|
||||
materialLayer = &m_materials.m_Paste;
|
||||
layerColor = m_boardAdapter.m_SolderPasteColor;
|
||||
|
||||
if( m_boardAdapter.GetFlag( FL_USE_REALISTIC_MODE ) )
|
||||
layerColor = m_boardAdapter.m_SolderPasteColor;
|
||||
else
|
||||
layerColor = m_boardAdapter.GetLayerColor( layer_id );
|
||||
|
||||
break;
|
||||
|
||||
case B_SilkS:
|
||||
materialLayer = &m_materials.m_SilkS;
|
||||
layerColor = m_boardAdapter.m_SilkScreenColorBot;
|
||||
|
||||
if( m_boardAdapter.GetFlag( FL_USE_REALISTIC_MODE ) )
|
||||
layerColor = m_boardAdapter.m_SilkScreenColorBot;
|
||||
else
|
||||
layerColor = m_boardAdapter.GetLayerColor( layer_id );
|
||||
|
||||
break;
|
||||
|
||||
case F_SilkS:
|
||||
materialLayer = &m_materials.m_SilkS;
|
||||
layerColor = m_boardAdapter.m_SilkScreenColorTop;
|
||||
|
||||
if( m_boardAdapter.GetFlag( FL_USE_REALISTIC_MODE ) )
|
||||
layerColor = m_boardAdapter.m_SilkScreenColorTop;
|
||||
else
|
||||
layerColor = m_boardAdapter.GetLayerColor( layer_id );
|
||||
|
||||
break;
|
||||
|
||||
case Dwgs_User:
|
||||
layerColor = m_boardAdapter.m_UserDrawingsColor;
|
||||
break;
|
||||
|
||||
case Cmts_User:
|
||||
layerColor = m_boardAdapter.m_UserCommentsColor;
|
||||
break;
|
||||
|
||||
case Eco1_User:
|
||||
layerColor = m_boardAdapter.m_ECO1Color;
|
||||
break;
|
||||
|
||||
case Eco2_User:
|
||||
layerColor = m_boardAdapter.m_ECO2Color;
|
||||
case Edge_Cuts:
|
||||
case Margin:
|
||||
break;
|
||||
|
||||
case B_CrtYd:
|
||||
@@ -626,17 +636,19 @@ void RENDER_3D_RAYTRACE::Reload( REPORTER* aStatusReporter, REPORTER* aWarningRe
|
||||
break;
|
||||
|
||||
default:
|
||||
if( m_boardAdapter.m_Cfg->m_Render.differentiate_plated_copper )
|
||||
if( m_boardAdapter.GetFlag( FL_USE_REALISTIC_MODE ) )
|
||||
{
|
||||
layerColor = SFVEC3F( 184.0f / 255.0f, 115.0f / 255.0f, 50.0f / 255.0f );
|
||||
materialLayer = &m_materials.m_NonPlatedCopper;
|
||||
if( m_boardAdapter.GetFlag( FL_RENDER_PLATED_PADS_AS_PLATED ) )
|
||||
layerColor = SFVEC3F( 184.0f / 255.0f, 115.0f / 255.0f, 50.0f / 255.0f );
|
||||
else
|
||||
layerColor = m_boardAdapter.m_CopperColor;
|
||||
}
|
||||
else
|
||||
{
|
||||
layerColor = m_boardAdapter.m_CopperColor;
|
||||
materialLayer = &m_materials.m_Copper;
|
||||
layerColor = m_boardAdapter.GetLayerColor( layer_id );
|
||||
}
|
||||
|
||||
materialLayer = &m_materials.m_NonPlatedCopper;
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -644,15 +656,16 @@ void RENDER_3D_RAYTRACE::Reload( REPORTER* aStatusReporter, REPORTER* aWarningRe
|
||||
} // for each layer on map
|
||||
|
||||
// Create plated copper
|
||||
if( m_boardAdapter.m_Cfg->m_Render.differentiate_plated_copper )
|
||||
if( m_boardAdapter.GetFlag( FL_RENDER_PLATED_PADS_AS_PLATED )
|
||||
&& m_boardAdapter.GetFlag( FL_USE_REALISTIC_MODE ) )
|
||||
{
|
||||
createItemsFromContainer( m_boardAdapter.GetPlatedPadsFront(), F_Cu, &m_materials.m_Copper,
|
||||
m_boardAdapter.m_CopperColor,
|
||||
m_boardAdapter.GetFrontCopperThickness() * 0.1f );
|
||||
m_boardAdapter.GetCopperThickness() * 0.1f );
|
||||
|
||||
createItemsFromContainer( m_boardAdapter.GetPlatedPadsBack(), B_Cu, &m_materials.m_Copper,
|
||||
m_boardAdapter.m_CopperColor,
|
||||
-m_boardAdapter.GetBackCopperThickness() * 0.1f );
|
||||
-m_boardAdapter.GetCopperThickness() * 0.1f );
|
||||
}
|
||||
|
||||
if( !aOnlyLoadCopperAndShapes )
|
||||
@@ -661,15 +674,13 @@ void RENDER_3D_RAYTRACE::Reload( REPORTER* aStatusReporter, REPORTER* aWarningRe
|
||||
// Solder mask layers are "negative" layers so the elements that we have in the container
|
||||
// should remove the board outline. We will check for all objects in the outline if it
|
||||
// intersects any object in the layer container and also any hole.
|
||||
if( ( layerFlags.test( LAYER_3D_SOLDERMASK_TOP )
|
||||
|| layerFlags.test( LAYER_3D_SOLDERMASK_BOTTOM ) )
|
||||
&& !m_outlineBoard2dObjects->GetList().empty() )
|
||||
if( m_boardAdapter.GetFlag( FL_SOLDERMASK ) && !m_outlineBoard2dObjects->GetList().empty() )
|
||||
{
|
||||
const MATERIAL* materialLayer = &m_materials.m_SolderMask;
|
||||
|
||||
for( const std::pair<const PCB_LAYER_ID, BVH_CONTAINER_2D*>& entry : m_boardAdapter.GetLayerMap() )
|
||||
for( auto entry : m_boardAdapter.GetLayerMap() )
|
||||
{
|
||||
const PCB_LAYER_ID layer_id = entry.first;
|
||||
PCB_LAYER_ID layer_id = entry.first;
|
||||
const BVH_CONTAINER_2D* container2d = entry.second;
|
||||
|
||||
// Only process layers that exist
|
||||
@@ -677,22 +688,22 @@ void RENDER_3D_RAYTRACE::Reload( REPORTER* aStatusReporter, REPORTER* aWarningRe
|
||||
continue;
|
||||
|
||||
// Only get the Solder mask layers (and only if the board has them)
|
||||
if( layer_id == F_Mask && !layerFlags.test( LAYER_3D_SOLDERMASK_TOP ) )
|
||||
continue;
|
||||
|
||||
if( layer_id == B_Mask && !layerFlags.test( LAYER_3D_SOLDERMASK_BOTTOM ) )
|
||||
continue;
|
||||
|
||||
// Only Mask layers are processed here because they are negative layers
|
||||
if( layer_id != F_Mask && layer_id != B_Mask )
|
||||
if( !( layer_id == B_Mask || layer_id == F_Mask ) )
|
||||
continue;
|
||||
|
||||
SFVEC3F layerColor;
|
||||
|
||||
if( layer_id == B_Mask )
|
||||
layerColor = m_boardAdapter.m_SolderMaskColorBot;
|
||||
if( m_boardAdapter.GetFlag( FL_USE_REALISTIC_MODE ) )
|
||||
{
|
||||
if( layer_id == B_Mask )
|
||||
layerColor = m_boardAdapter.m_SolderMaskColorBot;
|
||||
else
|
||||
layerColor = m_boardAdapter.m_SolderMaskColorTop;
|
||||
}
|
||||
else
|
||||
layerColor = m_boardAdapter.m_SolderMaskColorTop;
|
||||
{
|
||||
layerColor = m_boardAdapter.GetLayerColor( layer_id );
|
||||
}
|
||||
|
||||
const float zLayerMin = m_boardAdapter.GetLayerBottomZPos( layer_id );
|
||||
const float zLayerMax = m_boardAdapter.GetLayerTopZPos( layer_id );
|
||||
@@ -703,9 +714,9 @@ void RENDER_3D_RAYTRACE::Reload( REPORTER* aStatusReporter, REPORTER* aWarningRe
|
||||
std::vector<const OBJECT_2D*>* object2d_B = new std::vector<const OBJECT_2D*>();
|
||||
|
||||
// Check if there are any THT that intersects this outline object part
|
||||
if( !m_boardAdapter.GetTH_ODs().GetList().empty() )
|
||||
if( !m_boardAdapter.GetThroughHoleOds().GetList().empty() )
|
||||
{
|
||||
const BVH_CONTAINER_2D& throughHoles = m_boardAdapter.GetTH_ODs();
|
||||
const BVH_CONTAINER_2D& throughHoles = m_boardAdapter.GetThroughHoleOds();
|
||||
CONST_LIST_OBJECT2D intersecting;
|
||||
|
||||
throughHoles.GetIntersectingObjects( object2d_A->GetBBox(), intersecting );
|
||||
@@ -771,8 +782,8 @@ void RENDER_3D_RAYTRACE::Reload( REPORTER* aStatusReporter, REPORTER* aWarningRe
|
||||
}
|
||||
|
||||
#ifdef PRINT_STATISTICS_3D_VIEWER
|
||||
int64_t stats_endConvertTime = GetRunningMicroSecs();
|
||||
int64_t stats_startLoad3DmodelsTime = stats_endConvertTime;
|
||||
unsigned stats_endConvertTime = GetRunningMicroSecs();
|
||||
unsigned stats_startLoad3DmodelsTime = stats_endConvertTime;
|
||||
#endif
|
||||
|
||||
if( aStatusReporter )
|
||||
@@ -781,13 +792,13 @@ void RENDER_3D_RAYTRACE::Reload( REPORTER* aStatusReporter, REPORTER* aWarningRe
|
||||
load3DModels( m_objectContainer, aOnlyLoadCopperAndShapes );
|
||||
|
||||
#ifdef PRINT_STATISTICS_3D_VIEWER
|
||||
int64_t stats_endLoad3DmodelsTime = GetRunningMicroSecs();
|
||||
unsigned stats_endLoad3DmodelsTime = GetRunningMicroSecs();
|
||||
#endif
|
||||
|
||||
if( !aOnlyLoadCopperAndShapes )
|
||||
{
|
||||
// Add floor
|
||||
if( m_boardAdapter.m_Cfg->m_Render.raytrace_backfloor )
|
||||
if( m_boardAdapter.GetFlag( FL_RENDER_RAYTRACING_BACKFLOOR ) )
|
||||
{
|
||||
BBOX_3D boardBBox = m_boardAdapter.GetBBox();
|
||||
|
||||
@@ -867,47 +878,41 @@ void RENDER_3D_RAYTRACE::Reload( REPORTER* aStatusReporter, REPORTER* aWarningRe
|
||||
&& ( aSource.b < ( 1.0f / 255.0f ) ) );
|
||||
};
|
||||
|
||||
SFVEC3F cameraLightColor =
|
||||
m_boardAdapter.GetColor( m_boardAdapter.m_Cfg->m_Render.raytrace_lightColorCamera );
|
||||
SFVEC3F topLightColor =
|
||||
m_boardAdapter.GetColor( m_boardAdapter.m_Cfg->m_Render.raytrace_lightColorTop );
|
||||
SFVEC3F bottomLightColor =
|
||||
m_boardAdapter.GetColor( m_boardAdapter.m_Cfg->m_Render.raytrace_lightColorBottom );
|
||||
|
||||
m_cameraLight = new DIRECTIONAL_LIGHT( SFVEC3F( 0.0f, 0.0f, 0.0f ), cameraLightColor );
|
||||
m_cameraLight = new DIRECTIONAL_LIGHT( SFVEC3F( 0.0f, 0.0f, 0.0f ),
|
||||
m_boardAdapter.m_RtCameraLightColor );
|
||||
m_cameraLight->SetCastShadows( false );
|
||||
|
||||
if( !IsColorZero( cameraLightColor ) )
|
||||
if( !IsColorZero( m_boardAdapter.m_RtCameraLightColor ) )
|
||||
m_lights.push_back( m_cameraLight );
|
||||
|
||||
const SFVEC3F& boardCenter = m_boardAdapter.GetBBox().GetCenter();
|
||||
|
||||
if( !IsColorZero( topLightColor ) )
|
||||
if( !IsColorZero( m_boardAdapter.m_RtLightColorTop ) )
|
||||
{
|
||||
m_lights.push_back( new POINT_LIGHT( SFVEC3F( boardCenter.x, boardCenter.y,
|
||||
+RANGE_SCALE_3D * 2.0f ),
|
||||
topLightColor ) );
|
||||
m_boardAdapter.m_RtLightColorTop ) );
|
||||
}
|
||||
|
||||
if( !IsColorZero( bottomLightColor ) )
|
||||
if( !IsColorZero( m_boardAdapter.m_RtLightColorBottom ) )
|
||||
{
|
||||
m_lights.push_back( new POINT_LIGHT( SFVEC3F( boardCenter.x, boardCenter.y,
|
||||
-RANGE_SCALE_3D * 2.0f ),
|
||||
bottomLightColor ) );
|
||||
m_boardAdapter.m_RtLightColorBottom ) );
|
||||
}
|
||||
|
||||
for( size_t i = 0; i < m_boardAdapter.m_Cfg->m_Render.raytrace_lightColor.size(); ++i )
|
||||
{
|
||||
SFVEC3F lightColor =
|
||||
m_boardAdapter.GetColor( m_boardAdapter.m_Cfg->m_Render.raytrace_lightColor[i] );
|
||||
wxASSERT( m_boardAdapter.m_RtLightColor.size()
|
||||
== m_boardAdapter.m_RtLightSphericalCoords.size() );
|
||||
|
||||
if( !IsColorZero( lightColor ) )
|
||||
for( size_t i = 0; i < m_boardAdapter.m_RtLightColor.size(); ++i )
|
||||
{
|
||||
if( !IsColorZero( m_boardAdapter.m_RtLightColor[i] ) )
|
||||
{
|
||||
const SFVEC2F sc = m_boardAdapter.GetSphericalCoord( i );
|
||||
const SFVEC2F sc = m_boardAdapter.m_RtLightSphericalCoords[i];
|
||||
|
||||
m_lights.push_back( new DIRECTIONAL_LIGHT(
|
||||
SphericalToCartesian( glm::pi<float>() * sc.x, glm::pi<float>() * sc.y ),
|
||||
lightColor ) );
|
||||
m_boardAdapter.m_RtLightColor[i] ) );
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -919,33 +924,10 @@ void RENDER_3D_RAYTRACE::Reload( REPORTER* aStatusReporter, REPORTER* aWarningRe
|
||||
{
|
||||
float ratio =
|
||||
std::max( 1.0f, m_objectContainer.GetBBox().GetMaxDimension() / RANGE_SCALE_3D );
|
||||
m_camera.SetMaxZoom( m_camera.GetMaxZoom() * ratio );
|
||||
|
||||
float max_zoom = CAMERA::DEFAULT_MAX_ZOOM * ratio;
|
||||
float min_zoom = static_cast<float>( MIN_DISTANCE_IU * m_boardAdapter.BiuTo3dUnits()
|
||||
/ -m_camera.GetCameraInitPos().z );
|
||||
|
||||
if( min_zoom > max_zoom )
|
||||
std::swap( min_zoom, max_zoom );
|
||||
|
||||
float zoom_ratio = max_zoom / min_zoom;
|
||||
|
||||
// Set the minimum number of zoom 'steps' between max and min.
|
||||
int steps = 3 * 3;
|
||||
steps -= static_cast<int>( ceil( log( zoom_ratio ) / log( 1.26f ) ) );
|
||||
steps = std::max( steps, 0 );
|
||||
|
||||
// Resize max and min zoom to accomplish the number of steps.
|
||||
float increased_zoom = pow( 1.26f, steps / 2 );
|
||||
max_zoom *= increased_zoom;
|
||||
min_zoom /= increased_zoom;
|
||||
|
||||
if( steps & 1 )
|
||||
min_zoom /= 1.26f;
|
||||
|
||||
min_zoom = std::min( min_zoom, 1.0f );
|
||||
|
||||
m_camera.SetMaxZoom( max_zoom );
|
||||
m_camera.SetMinZoom( min_zoom );
|
||||
m_camera.SetMinZoom( static_cast<float>( MIN_DISTANCE_IU * m_boardAdapter.BiuTo3dUnits()
|
||||
/ -m_camera.GetCameraInitPos().z ) );
|
||||
}
|
||||
|
||||
// Create an accelerator
|
||||
@@ -955,7 +937,7 @@ void RENDER_3D_RAYTRACE::Reload( REPORTER* aStatusReporter, REPORTER* aWarningRe
|
||||
if( aStatusReporter )
|
||||
{
|
||||
// Calculation time in seconds
|
||||
double calculation_time = (double) ( GetRunningMicroSecs() - stats_startReloadTime ) / 1e6;
|
||||
double calculation_time = (double) GetRunningMicroSecs() - stats_startReloadTime / 1e6;
|
||||
|
||||
aStatusReporter->Report( wxString::Format( _( "Reload time %.3f s" ), calculation_time ) );
|
||||
}
|
||||
@@ -970,10 +952,10 @@ void RENDER_3D_RAYTRACE::insertHole( const PCB_VIA* aVia )
|
||||
aVia->LayerPair( &top_layer, &bottom_layer );
|
||||
|
||||
float topZ = m_boardAdapter.GetLayerBottomZPos( top_layer )
|
||||
+ m_boardAdapter.GetFrontCopperThickness();
|
||||
+ m_boardAdapter.GetCopperThickness();
|
||||
|
||||
float botZ = m_boardAdapter.GetLayerBottomZPos( bottom_layer )
|
||||
- m_boardAdapter.GetBackCopperThickness();
|
||||
- m_boardAdapter.GetCopperThickness();
|
||||
|
||||
const SFVEC2F center = SFVEC2F( aVia->GetStart().x * m_boardAdapter.BiuTo3dUnits(),
|
||||
-aVia->GetStart().y * m_boardAdapter.BiuTo3dUnits() );
|
||||
@@ -987,7 +969,15 @@ void RENDER_3D_RAYTRACE::insertHole( const PCB_VIA* aVia )
|
||||
LAYER_ITEM* objPtr = new LAYER_ITEM( ring, topZ, botZ );
|
||||
|
||||
objPtr->SetMaterial( &m_materials.m_Copper );
|
||||
objPtr->SetColor( ConvertSRGBToLinear( m_boardAdapter.m_CopperColor ) );
|
||||
|
||||
if( m_boardAdapter.GetFlag( FL_USE_REALISTIC_MODE ) )
|
||||
objPtr->SetColor( ConvertSRGBToLinear( m_boardAdapter.m_CopperColor ) );
|
||||
else if( aVia->GetViaType() == VIATYPE::MICROVIA )
|
||||
objPtr->SetColor( ConvertSRGBToLinear( m_boardAdapter.GetItemColor( LAYER_VIA_MICROVIA ) ) );
|
||||
else if( aVia->GetViaType() == VIATYPE::BLIND_BURIED )
|
||||
objPtr->SetColor( ConvertSRGBToLinear( m_boardAdapter.GetItemColor( LAYER_VIA_BBLIND ) ) );
|
||||
else
|
||||
objPtr->SetColor( ConvertSRGBToLinear( m_boardAdapter.GetItemColor( LAYER_VIAS ) ) );
|
||||
|
||||
m_objectContainer.Add( objPtr );
|
||||
}
|
||||
@@ -997,9 +987,15 @@ void RENDER_3D_RAYTRACE::insertHole( const PAD* aPad )
|
||||
{
|
||||
const OBJECT_2D* object2d_A = nullptr;
|
||||
|
||||
SFVEC3F objColor = m_boardAdapter.m_CopperColor;
|
||||
const VECTOR2I drillsize = aPad->GetDrillSize();
|
||||
const bool hasHole = drillsize.x && drillsize.y;
|
||||
SFVEC3F objColor;
|
||||
|
||||
if( m_boardAdapter.GetFlag( FL_USE_REALISTIC_MODE ) )
|
||||
objColor = m_boardAdapter.m_CopperColor;
|
||||
else
|
||||
objColor = m_boardAdapter.GetItemColor( LAYER_PADS_TH );
|
||||
|
||||
const wxSize drillsize = aPad->GetDrillSize();
|
||||
const bool hasHole = drillsize.x && drillsize.y;
|
||||
|
||||
if( !hasHole )
|
||||
return;
|
||||
@@ -1007,10 +1003,10 @@ void RENDER_3D_RAYTRACE::insertHole( const PAD* aPad )
|
||||
CONST_LIST_OBJECT2D antiOutlineIntersectionList;
|
||||
|
||||
const float topZ = m_boardAdapter.GetLayerBottomZPos( F_Cu )
|
||||
+ m_boardAdapter.GetFrontCopperThickness() * 0.99f;
|
||||
+ m_boardAdapter.GetCopperThickness() * 0.99f;
|
||||
|
||||
const float botZ = m_boardAdapter.GetLayerBottomZPos( B_Cu )
|
||||
- m_boardAdapter.GetBackCopperThickness() * 0.99f;
|
||||
- m_boardAdapter.GetCopperThickness() * 0.99f;
|
||||
|
||||
if( drillsize.x == drillsize.y ) // usual round hole
|
||||
{
|
||||
@@ -1057,7 +1053,7 @@ void RENDER_3D_RAYTRACE::insertHole( const PAD* aPad )
|
||||
}
|
||||
else // Oblong hole
|
||||
{
|
||||
VECTOR2I ends_offset;
|
||||
wxPoint ends_offset;
|
||||
int width;
|
||||
|
||||
if( drillsize.x > drillsize.y ) // Horizontal oval
|
||||
@@ -1071,10 +1067,10 @@ void RENDER_3D_RAYTRACE::insertHole( const PAD* aPad )
|
||||
width = drillsize.x;
|
||||
}
|
||||
|
||||
RotatePoint( ends_offset, aPad->GetOrientation() );
|
||||
RotatePoint( &ends_offset, aPad->GetOrientation() );
|
||||
|
||||
VECTOR2I start = VECTOR2I( aPad->GetPosition() ) + ends_offset;
|
||||
VECTOR2I end = VECTOR2I( aPad->GetPosition() ) - ends_offset;
|
||||
wxPoint start = aPad->GetPosition() + ends_offset;
|
||||
wxPoint end = aPad->GetPosition() - ends_offset;
|
||||
|
||||
ROUND_SEGMENT_2D* innerSeg =
|
||||
new ROUND_SEGMENT_2D( SFVEC2F( start.x * m_boardAdapter.BiuTo3dUnits(),
|
||||
@@ -1116,11 +1112,12 @@ void RENDER_3D_RAYTRACE::insertHole( const PAD* aPad )
|
||||
|
||||
// Check if there are any other THT that intersects this hole
|
||||
// It will use the non inflated holes
|
||||
if( !m_boardAdapter.GetTH_IDs().GetList().empty() )
|
||||
if( !m_boardAdapter.GetThroughHoleIds().GetList().empty() )
|
||||
{
|
||||
CONST_LIST_OBJECT2D intersecting;
|
||||
|
||||
m_boardAdapter.GetTH_IDs().GetIntersectingObjects( object2d_A->GetBBox(), intersecting );
|
||||
m_boardAdapter.GetThroughHoleIds().GetIntersectingObjects( object2d_A->GetBBox(),
|
||||
intersecting );
|
||||
|
||||
for( const OBJECT_2D* hole2d : intersecting )
|
||||
{
|
||||
@@ -1198,10 +1195,9 @@ void RENDER_3D_RAYTRACE::load3DModels( CONTAINER_3D& aDstContainer, bool aSkipMa
|
||||
if( !m_boardAdapter.GetBoard() )
|
||||
return;
|
||||
|
||||
if( !m_boardAdapter.m_IsPreviewer
|
||||
&& !m_boardAdapter.m_Cfg->m_Render.show_footprints_normal
|
||||
&& !m_boardAdapter.m_Cfg->m_Render.show_footprints_insert
|
||||
&& !m_boardAdapter.m_Cfg->m_Render.show_footprints_virtual )
|
||||
if( !m_boardAdapter.GetFlag( FL_FP_ATTRIBUTES_NORMAL )
|
||||
&& !m_boardAdapter.GetFlag( FL_FP_ATTRIBUTES_NORMAL_INSERT )
|
||||
&& !m_boardAdapter.GetFlag( FL_FP_ATTRIBUTES_VIRTUAL ) )
|
||||
{
|
||||
return;
|
||||
}
|
||||
@@ -1214,7 +1210,7 @@ void RENDER_3D_RAYTRACE::load3DModels( CONTAINER_3D& aDstContainer, bool aSkipMa
|
||||
{
|
||||
double zpos = m_boardAdapter.GetFootprintZPos( fp->IsFlipped() );
|
||||
|
||||
VECTOR2I pos = fp->GetPosition();
|
||||
wxPoint pos = fp->GetPosition();
|
||||
|
||||
glm::mat4 fpMatrix = glm::mat4( 1.0f );
|
||||
|
||||
@@ -1223,10 +1219,11 @@ void RENDER_3D_RAYTRACE::load3DModels( CONTAINER_3D& aDstContainer, bool aSkipMa
|
||||
-pos.y * m_boardAdapter.BiuTo3dUnits(),
|
||||
zpos ) );
|
||||
|
||||
if( !fp->GetOrientation().IsZero() )
|
||||
if( fp->GetOrientation() )
|
||||
{
|
||||
fpMatrix = glm::rotate( fpMatrix, (float) fp->GetOrientation().AsRadians(),
|
||||
SFVEC3F( 0.0f, 0.0f, 1.0f ) );
|
||||
fpMatrix = glm::rotate( fpMatrix,
|
||||
( (float) ( fp->GetOrientation() / 10.0f ) / 180.0f ) * glm::pi<float>(),
|
||||
SFVEC3F( 0.0f, 0.0f, 1.0f ) );
|
||||
}
|
||||
|
||||
if( fp->IsFlipped() )
|
||||
@@ -1250,35 +1247,13 @@ void RENDER_3D_RAYTRACE::load3DModels( CONTAINER_3D& aDstContainer, bool aSkipMa
|
||||
auto sM = fp->Models().begin();
|
||||
auto eM = fp->Models().end();
|
||||
|
||||
wxString libraryName = fp->GetFPID().GetLibNickname();
|
||||
|
||||
wxString footprintBasePath = wxEmptyString;
|
||||
if( m_boardAdapter.GetBoard()->GetProject() )
|
||||
{
|
||||
try
|
||||
{
|
||||
// FindRow() can throw an exception
|
||||
const FP_LIB_TABLE_ROW* fpRow =
|
||||
PROJECT_PCB::PcbFootprintLibs( m_boardAdapter.GetBoard()->GetProject() )
|
||||
->FindRow( libraryName, false );
|
||||
|
||||
if( fpRow )
|
||||
footprintBasePath = fpRow->GetFullURI( true );
|
||||
}
|
||||
catch( ... )
|
||||
{
|
||||
// Do nothing if the libraryName is not found in lib table
|
||||
}
|
||||
}
|
||||
|
||||
while( sM != eM )
|
||||
{
|
||||
if( ( static_cast<float>( sM->m_Opacity ) > FLT_EPSILON )
|
||||
&& ( sM->m_Show && !sM->m_Filename.empty() ) )
|
||||
{
|
||||
// get it from cache
|
||||
const S3DMODEL* modelPtr =
|
||||
cacheMgr->GetModel( sM->m_Filename, footprintBasePath );
|
||||
const S3DMODEL* modelPtr = cacheMgr->GetModel( sM->m_Filename );
|
||||
|
||||
// only add it if the return is not NULL.
|
||||
if( modelPtr )
|
||||
@@ -1337,7 +1312,7 @@ MODEL_MATERIALS* RENDER_3D_RAYTRACE::getModelMaterial( const S3DMODEL* a3DModel
|
||||
|
||||
for( unsigned int imat = 0; imat < a3DModel->m_MaterialsSize; ++imat )
|
||||
{
|
||||
if( m_boardAdapter.m_Cfg->m_Render.material_mode == MATERIAL_MODE::NORMAL )
|
||||
if( m_boardAdapter.GetMaterialMode() == MATERIAL_MODE::NORMAL )
|
||||
{
|
||||
const SMATERIAL& material = a3DModel->m_Materials[imat];
|
||||
|
||||
@@ -1359,7 +1334,7 @@ MODEL_MATERIALS* RENDER_3D_RAYTRACE::getModelMaterial( const S3DMODEL* a3DModel
|
||||
ConvertSRGBToLinear( material.m_Specular ), material.m_Shininess * 180.0f,
|
||||
material.m_Transparency, reflectionFactor );
|
||||
|
||||
if( m_boardAdapter.m_Cfg->m_Render.raytrace_procedural_textures )
|
||||
if( m_boardAdapter.GetFlag( FL_RENDER_RAYTRACING_PROCEDURAL_TEXTURES ) )
|
||||
{
|
||||
// Guess material type and apply a normal perturbator
|
||||
if( ( RGBtoGray( material.m_Diffuse ) < 0.3f )
|
||||
@@ -1527,7 +1502,7 @@ void RENDER_3D_RAYTRACE::addModels( CONTAINER_3D& aDstContainer, const S3DMODEL*
|
||||
const SFVEC3F diffuseColor =
|
||||
a3DModel->m_Materials[mesh.m_MaterialIdx].m_Diffuse;
|
||||
|
||||
if( m_boardAdapter.m_Cfg->m_Render.material_mode == MATERIAL_MODE::CAD_MODE )
|
||||
if( m_boardAdapter.GetMaterialMode() == MATERIAL_MODE::CAD_MODE )
|
||||
newTriangle->SetColor( ConvertSRGBToLinear(
|
||||
MaterialDiffuseToColorCAD( diffuseColor ) ) );
|
||||
else
|
||||
@@ -1535,8 +1510,7 @@ void RENDER_3D_RAYTRACE::addModels( CONTAINER_3D& aDstContainer, const S3DMODEL*
|
||||
}
|
||||
else
|
||||
{
|
||||
if( m_boardAdapter.m_Cfg->m_Render.material_mode == MATERIAL_MODE::CAD_MODE )
|
||||
{
|
||||
if( m_boardAdapter.GetMaterialMode() == MATERIAL_MODE::CAD_MODE )
|
||||
newTriangle->SetColor(
|
||||
ConvertSRGBToLinear( MaterialDiffuseToColorCAD(
|
||||
mesh.m_Color[idx0] ) ),
|
||||
@@ -1544,14 +1518,11 @@ void RENDER_3D_RAYTRACE::addModels( CONTAINER_3D& aDstContainer, const S3DMODEL*
|
||||
mesh.m_Color[idx1] ) ),
|
||||
ConvertSRGBToLinear( MaterialDiffuseToColorCAD(
|
||||
mesh.m_Color[idx2] ) ) );
|
||||
}
|
||||
else
|
||||
{
|
||||
newTriangle->SetColor(
|
||||
ConvertSRGBToLinear( mesh.m_Color[idx0] ),
|
||||
ConvertSRGBToLinear( mesh.m_Color[idx1] ),
|
||||
ConvertSRGBToLinear( mesh.m_Color[idx2] ) );
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
/*
|
||||
* This program source code file is part of KiCad, a free EDA CAD application.
|
||||
*
|
||||
* Copyright (C) 2015-2022 Mario Luzeiro <mrluzeiro@ua.pt>
|
||||
* Copyright (C) 2015-2022 KiCad Developers, see AUTHORS.txt for contributors.
|
||||
* Copyright (C) 2015-2020 Mario Luzeiro <mrluzeiro@ua.pt>
|
||||
* Copyright (C) 2015-2021 KiCad Developers, see AUTHORS.txt for contributors.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
@@ -223,7 +223,7 @@ SFVEC3F PLATED_COPPER_NORMAL::Generate( const RAY& aRay, const HITINFO& aHitInfo
|
||||
const float noise1 = ( s_perlinNoise.noise( hitPos.x, hitPos.y ) - 0.5f );
|
||||
const float noise2 = ( s_perlinNoise.noise( hitPos.y, hitPos.x ) - 0.5f );
|
||||
|
||||
return SFVEC3F( noise1, noise2, 0.0f ) * 0.1f;
|
||||
return SFVEC3F( noise1, noise2, -( noise1 + noise2 ) ) * 0.02f;
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -141,8 +141,8 @@ struct RAYSEG2D
|
||||
bool IntersectSegment( const SFVEC2F &aStartA, const SFVEC2F &aEnd_minus_startA,
|
||||
const SFVEC2F &aStartB, const SFVEC2F &aEnd_minus_startB );
|
||||
|
||||
/*
|
||||
#if(GLM_ARCH != GLM_ARCH_PURE)
|
||||
/*
|
||||
struct RAY4
|
||||
{
|
||||
glm::simdVec4 m_orgX; ///< x coordinate of ray origin
|
||||
@@ -155,10 +155,9 @@ struct RAY4
|
||||
|
||||
glm::simdVec4 m_tnear; ///< Start of ray segment
|
||||
glm::simdVec4 m_tfar; ///< End of ray segment
|
||||
};
|
||||
};*/
|
||||
|
||||
#endif
|
||||
*/
|
||||
|
||||
|
||||
#endif // RAY_H
|
||||
|
||||
@@ -27,7 +27,7 @@
|
||||
|
||||
#include "ray.h"
|
||||
#include "frustum.h"
|
||||
#include <gal/3d/camera.h>
|
||||
#include "../camera.h"
|
||||
|
||||
#define RAYPACKET_DIM (1 << 3)
|
||||
#define RAYPACKET_MASK (unsigned int) ( ( RAYPACKET_DIM - 1 ) )
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
* This program source code file is part of KiCad, a free EDA CAD application.
|
||||
*
|
||||
* Copyright (C) 2015-2020 Mario Luzeiro <mrluzeiro@ua.pt>
|
||||
* Copyright (C) 2015-2023 KiCad Developers, see AUTHORS.txt for contributors.
|
||||
* Copyright (C) 2015-2021 KiCad Developers, see AUTHORS.txt for contributors.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
@@ -27,6 +27,7 @@
|
||||
#include <algorithm>
|
||||
#include <atomic>
|
||||
#include <chrono>
|
||||
#include <climits>
|
||||
#include <thread>
|
||||
|
||||
#include "render_3d_raytrace.h"
|
||||
@@ -35,7 +36,7 @@
|
||||
#include "3d_fastmath.h"
|
||||
#include "3d_math.h"
|
||||
#include "../common_ogl/ogl_utils.h"
|
||||
#include <core/profile.h> // To use GetRunningMicroSecs or another profiling utility
|
||||
#include <profile.h> // To use GetRunningMicroSecs or another profiling utility
|
||||
#include <wx/log.h>
|
||||
|
||||
|
||||
@@ -91,7 +92,7 @@ RENDER_3D_RAYTRACE::~RENDER_3D_RAYTRACE()
|
||||
|
||||
int RENDER_3D_RAYTRACE::GetWaitForEditingTimeOut()
|
||||
{
|
||||
return 200; // ms
|
||||
return 1000; // ms
|
||||
}
|
||||
|
||||
|
||||
@@ -292,7 +293,7 @@ void RENDER_3D_RAYTRACE::render( GLubyte* ptrPBO, REPORTER* aStatusReporter )
|
||||
if( m_cameraLight )
|
||||
m_cameraLight->SetDirection( -m_camera.GetDir() );
|
||||
|
||||
if( m_boardAdapter.m_Cfg->m_Render.engine == RENDER_ENGINE::OPENGL )
|
||||
if( m_boardAdapter.GetRenderEngine() == RENDER_ENGINE::OPENGL )
|
||||
{
|
||||
// Set all pixels of PBO transparent (Alpha to 0)
|
||||
// This way it will draw the full buffer but only shows the updated (
|
||||
@@ -398,7 +399,7 @@ void RENDER_3D_RAYTRACE::renderTracing( GLubyte* ptrPBO, REPORTER* aStatusReport
|
||||
// or mark it as finished
|
||||
if( m_blockRenderProgressCount >= m_blockPositions.size() )
|
||||
{
|
||||
if( m_boardAdapter.m_Cfg->m_Render.raytrace_post_processing )
|
||||
if( m_boardAdapter.GetFlag( FL_RENDER_RAYTRACING_POST_PROCESSING ) )
|
||||
m_renderState = RT_RENDER_STATE_POST_PROCESS_SHADE;
|
||||
else
|
||||
m_renderState = RT_RENDER_STATE_FINISH;
|
||||
@@ -503,7 +504,7 @@ void RENDER_3D_RAYTRACE::renderAntiAliasPackets( const SFVEC3F* aBgColorY,
|
||||
const HITINFO_PACKET* aHitPck_AA_X1Y1,
|
||||
const RAY* aRayPck, SFVEC3F* aOutHitColor )
|
||||
{
|
||||
const bool is_testShadow = m_boardAdapter.m_Cfg->m_Render.raytrace_shadows;
|
||||
const bool is_testShadow = m_boardAdapter.GetFlag( FL_RENDER_RAYTRACING_SHADOWS );
|
||||
|
||||
for( unsigned int y = 0, i = 0; y < RAYPACKET_DIM; ++y )
|
||||
{
|
||||
@@ -651,7 +652,7 @@ void RENDER_3D_RAYTRACE::renderBlockTracing( GLubyte* ptrPBO, signed int iBlock
|
||||
if( !m_accelerator->Intersect( blockPacket, hitPacket_X0Y0 ) )
|
||||
{
|
||||
// If block is empty then set shades and continue
|
||||
if( m_boardAdapter.m_Cfg->m_Render.raytrace_post_processing )
|
||||
if( m_boardAdapter.GetFlag( FL_RENDER_RAYTRACING_POST_PROCESSING ) )
|
||||
{
|
||||
for( unsigned int y = 0; y < RAYPACKET_DIM; ++y )
|
||||
{
|
||||
@@ -669,9 +670,10 @@ void RENDER_3D_RAYTRACE::renderBlockTracing( GLubyte* ptrPBO, signed int iBlock
|
||||
}
|
||||
|
||||
// This will set the output color to be displayed
|
||||
// If post processing is enabled, it will not reflect the final result (as the final
|
||||
// color will be computed on post processing) but it is used for report progress
|
||||
const bool isFinalColor = !m_boardAdapter.m_Cfg->m_Render.raytrace_post_processing;
|
||||
// If post processing is enabled, it will not reflect the final result
|
||||
// (as the final color will be computed on post processing)
|
||||
// but it is used for report progress
|
||||
const bool isFinalColor = !m_boardAdapter.GetFlag( FL_RENDER_RAYTRACING_POST_PROCESSING );
|
||||
|
||||
for( unsigned int y = 0; y < RAYPACKET_DIM; ++y )
|
||||
{
|
||||
@@ -696,9 +698,9 @@ void RENDER_3D_RAYTRACE::renderBlockTracing( GLubyte* ptrPBO, signed int iBlock
|
||||
|
||||
// Shade original (0, 0) hits ("paint" the intersected objects)
|
||||
renderRayPackets( bgColor, blockPacket.m_ray, hitPacket_X0Y0,
|
||||
m_boardAdapter.m_Cfg->m_Render.raytrace_shadows, hitColor_X0Y0 );
|
||||
m_boardAdapter.GetFlag( FL_RENDER_RAYTRACING_SHADOWS ), hitColor_X0Y0 );
|
||||
|
||||
if( m_boardAdapter.m_Cfg->m_Render.raytrace_anti_aliasing )
|
||||
if( m_boardAdapter.GetFlag( FL_RENDER_RAYTRACING_ANTI_ALIASING ) )
|
||||
{
|
||||
SFVEC3F hitColor_AA_X1Y1[RAYPACKET_RAYS_PER_PACKET];
|
||||
|
||||
@@ -717,13 +719,16 @@ void RENDER_3D_RAYTRACE::renderBlockTracing( GLubyte* ptrPBO, signed int iBlock
|
||||
const SFVEC3F& outColor = bgColor[y];
|
||||
|
||||
for( unsigned int x = 0; x < RAYPACKET_DIM; ++x, ++i )
|
||||
{
|
||||
hitColor_AA_X1Y1[i] = outColor;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
renderRayPackets( bgColor, blockPacket_AA_X1Y1.m_ray, hitPacket_AA_X1Y1,
|
||||
m_boardAdapter.m_Cfg->m_Render.raytrace_shadows, hitColor_AA_X1Y1 );
|
||||
m_boardAdapter.GetFlag( FL_RENDER_RAYTRACING_SHADOWS ),
|
||||
hitColor_AA_X1Y1 );
|
||||
}
|
||||
|
||||
SFVEC3F hitColor_AA_X1Y0[RAYPACKET_RAYS_PER_PACKET];
|
||||
@@ -732,7 +737,8 @@ void RENDER_3D_RAYTRACE::renderBlockTracing( GLubyte* ptrPBO, signed int iBlock
|
||||
|
||||
for( unsigned int i = 0; i < RAYPACKET_RAYS_PER_PACKET; ++i )
|
||||
{
|
||||
SFVEC3F color_average = ( hitColor_X0Y0[i] + hitColor_AA_X1Y1[i] ) * SFVEC3F( 0.5f );
|
||||
const SFVEC3F color_average = ( hitColor_X0Y0[i] +
|
||||
hitColor_AA_X1Y1[i] ) * SFVEC3F( 0.5f );
|
||||
|
||||
hitColor_AA_X1Y0[i] = color_average;
|
||||
hitColor_AA_X0Y1[i] = color_average;
|
||||
@@ -778,7 +784,7 @@ void RENDER_3D_RAYTRACE::renderBlockTracing( GLubyte* ptrPBO, signed int iBlock
|
||||
|
||||
const uint32_t ptrInc = ( m_realBufferSize.x - RAYPACKET_DIM ) * 4;
|
||||
|
||||
if( m_boardAdapter.m_Cfg->m_Render.raytrace_post_processing )
|
||||
if( m_boardAdapter.GetFlag( FL_RENDER_RAYTRACING_POST_PROCESSING ) )
|
||||
{
|
||||
SFVEC2I bPos;
|
||||
bPos.y = blockPos.y;
|
||||
@@ -792,7 +798,6 @@ void RENDER_3D_RAYTRACE::renderBlockTracing( GLubyte* ptrPBO, signed int iBlock
|
||||
const SFVEC3F& hColor = hitColor_X0Y0[i];
|
||||
|
||||
if( hitPacket_X0Y0[i].m_hitresult == true )
|
||||
{
|
||||
m_postShaderSsao.SetPixelData( bPos.x, bPos.y,
|
||||
hitPacket_X0Y0[i].m_HitInfo.m_HitNormal,
|
||||
hColor,
|
||||
@@ -800,12 +805,9 @@ void RENDER_3D_RAYTRACE::renderBlockTracing( GLubyte* ptrPBO, signed int iBlock
|
||||
hitPacket_X0Y0[i].m_HitInfo.m_tHit ),
|
||||
hitPacket_X0Y0[i].m_HitInfo.m_tHit,
|
||||
hitPacket_X0Y0[i].m_HitInfo.m_ShadowFactor );
|
||||
}
|
||||
else
|
||||
{
|
||||
m_postShaderSsao.SetPixelData( bPos.x, bPos.y, SFVEC3F( 0.0f ), hColor,
|
||||
SFVEC3F( 0.0f ), 0, 1.0f );
|
||||
}
|
||||
|
||||
renderFinalColor( ptr, hColor, false );
|
||||
|
||||
@@ -835,12 +837,13 @@ void RENDER_3D_RAYTRACE::renderBlockTracing( GLubyte* ptrPBO, signed int iBlock
|
||||
|
||||
void RENDER_3D_RAYTRACE::postProcessShading( GLubyte* /* ptrPBO */, REPORTER* aStatusReporter )
|
||||
{
|
||||
if( m_boardAdapter.m_Cfg->m_Render.raytrace_post_processing )
|
||||
if( m_boardAdapter.GetFlag( FL_RENDER_RAYTRACING_POST_PROCESSING ) )
|
||||
{
|
||||
if( aStatusReporter )
|
||||
aStatusReporter->Report( _( "Rendering: Post processing shader" ) );
|
||||
|
||||
m_postShaderSsao.SetShadowsEnabled( m_boardAdapter.m_Cfg->m_Render.raytrace_shadows );
|
||||
m_postShaderSsao.SetShadowsEnabled(
|
||||
m_boardAdapter.GetFlag( FL_RENDER_RAYTRACING_SHADOWS ) );
|
||||
|
||||
std::atomic<size_t> nextBlock( 0 );
|
||||
std::atomic<size_t> threadsFinished( 0 );
|
||||
@@ -887,7 +890,7 @@ void RENDER_3D_RAYTRACE::postProcessShading( GLubyte* /* ptrPBO */, REPORTER* aS
|
||||
|
||||
void RENDER_3D_RAYTRACE::postProcessBlurFinish( GLubyte* ptrPBO, REPORTER* /* aStatusReporter */ )
|
||||
{
|
||||
if( m_boardAdapter.m_Cfg->m_Render.raytrace_post_processing )
|
||||
if( m_boardAdapter.GetFlag( FL_RENDER_RAYTRACING_POST_PROCESSING ) )
|
||||
{
|
||||
// Now blurs the shader result and compute the final color
|
||||
std::atomic<size_t> nextBlock( 0 );
|
||||
@@ -1557,7 +1560,8 @@ SFVEC3F RENDER_3D_RAYTRACE::shadeHit( const SFVEC3F& aBgColor, const RAY& aRay,
|
||||
const SFVEC3F diffuseColorObj = aHitInfo.pHitObject->GetDiffuseColor( aHitInfo );
|
||||
|
||||
#if USE_EXPERIMENTAL_SOFT_SHADOWS
|
||||
bool is_aa_enabled = m_boardAdapter.m_Cfg->m_Render.raytrace_anti_aliasing && !m_isPreview;
|
||||
const bool is_aa_enabled = m_boardAdapter.GetFlag( FL_RENDER_RAYTRACING_ANTI_ALIASING ) &&
|
||||
(!m_isPreview);
|
||||
#endif
|
||||
|
||||
float shadow_att_factor_sum = 0.0f;
|
||||
@@ -1603,8 +1607,9 @@ SFVEC3F RENDER_3D_RAYTRACE::shadeHit( const SFVEC3F& aBgColor, const RAY& aRay,
|
||||
}
|
||||
else // Experimental softshadow calculation
|
||||
{
|
||||
|
||||
const unsigned int shadow_number_of_samples =
|
||||
m_boardAdapter.m_Cfg->m_Render.raytrace_nrsamples_shadows;
|
||||
m_boardAdapter.m_RtShadowSampleCount;
|
||||
const float shadow_inc_factor = 1.0f / (float) ( shadow_number_of_samples );
|
||||
|
||||
for( unsigned int i = 0; i < shadow_number_of_samples; ++i )
|
||||
@@ -1620,7 +1625,7 @@ SFVEC3F RENDER_3D_RAYTRACE::shadeHit( const SFVEC3F& aBgColor, const RAY& aRay,
|
||||
const SFVEC3F unifVector = UniformRandomHemisphereDirection();
|
||||
const SFVEC3F disturbed_vector_to_light =
|
||||
glm::normalize( vectorToLight + unifVector *
|
||||
m_boardAdapter.m_Cfg->m_Render.raytrace_spread_shadows );
|
||||
m_boardAdapter.m_RtSpreadShadows );
|
||||
|
||||
rayToLight.Init( hitPoint, disturbed_vector_to_light );
|
||||
}
|
||||
@@ -1665,7 +1670,7 @@ SFVEC3F RENDER_3D_RAYTRACE::shadeHit( const SFVEC3F& aBgColor, const RAY& aRay,
|
||||
{
|
||||
// Reflections
|
||||
if( ( objMaterial->GetReflection() > 0.0f )
|
||||
&& m_boardAdapter.m_Cfg->m_Render.raytrace_reflections
|
||||
&& m_boardAdapter.GetFlag( FL_RENDER_RAYTRACING_REFLECTIONS )
|
||||
&& ( aRecursiveLevel < objMaterial->GetReflectionRecursionCount() ) )
|
||||
{
|
||||
const unsigned int reflection_number_of_samples =
|
||||
@@ -1690,7 +1695,7 @@ SFVEC3F RENDER_3D_RAYTRACE::shadeHit( const SFVEC3F& aBgColor, const RAY& aRay,
|
||||
const SFVEC3F random_reflectVector =
|
||||
glm::normalize( reflectVector +
|
||||
UniformRandomHemisphereDirection() *
|
||||
m_boardAdapter.m_Cfg->m_Render.raytrace_spread_reflections );
|
||||
m_boardAdapter.m_RtSpreadReflections );
|
||||
|
||||
reflectedRay.Init( hitPoint, random_reflectVector );
|
||||
}
|
||||
@@ -1716,7 +1721,7 @@ SFVEC3F RENDER_3D_RAYTRACE::shadeHit( const SFVEC3F& aBgColor, const RAY& aRay,
|
||||
// Refraction
|
||||
const float objTransparency = aHitInfo.pHitObject->GetModelTransparency();
|
||||
|
||||
if( ( objTransparency > 0.0f ) && m_boardAdapter.m_Cfg->m_Render.raytrace_refractions
|
||||
if( ( objTransparency > 0.0f ) && m_boardAdapter.GetFlag( FL_RENDER_RAYTRACING_REFRACTIONS )
|
||||
&& ( aRecursiveLevel < objMaterial->GetRefractionRecursionCount() ) )
|
||||
{
|
||||
const float airIndex = 1.000293f;
|
||||
@@ -1755,7 +1760,7 @@ SFVEC3F RENDER_3D_RAYTRACE::shadeHit( const SFVEC3F& aBgColor, const RAY& aRay,
|
||||
const SFVEC3F randomizeRefractedVector =
|
||||
glm::normalize( refractedVector +
|
||||
UniformRandomHemisphereDirection() *
|
||||
m_boardAdapter.m_Cfg->m_Render.raytrace_spread_refractions );
|
||||
m_boardAdapter.m_RtSpreadRefractions );
|
||||
|
||||
refractedRay.Init( startPoint, randomizeRefractedVector );
|
||||
}
|
||||
@@ -1910,19 +1915,9 @@ void RENDER_3D_RAYTRACE::initializeBlockPositions()
|
||||
|
||||
const SFVEC2UI center( m_realBufferSize.x / 2, m_realBufferSize.y / 2 );
|
||||
std::sort( m_blockPositions.begin(), m_blockPositions.end(),
|
||||
[&]( const SFVEC2UI& a, const SFVEC2UI& b )
|
||||
{
|
||||
[&]( const SFVEC2UI& a, const SFVEC2UI& b ) {
|
||||
// Sort order: inside out.
|
||||
float distanceA = distance( a, center );
|
||||
float distanceB = distance( b, center );
|
||||
|
||||
if( distanceA != distanceB )
|
||||
return distanceA < distanceB;
|
||||
|
||||
if( a[0] != b[0] )
|
||||
return a[0] < b[0];
|
||||
|
||||
return a[1] < b[1];
|
||||
return distance( a, center ) < distance( b, center );
|
||||
} );
|
||||
|
||||
// Create m_shader buffer
|
||||
|
||||
@@ -154,7 +154,7 @@ private:
|
||||
RT_RENDER_STATE m_renderState;
|
||||
|
||||
/// Time that the render starts
|
||||
int64_t m_renderStartTime;
|
||||
unsigned long int m_renderStartTime;
|
||||
|
||||
/// Save the number of blocks progress of the render
|
||||
size_t m_blockRenderProgressCount;
|
||||
|
||||
@@ -229,16 +229,6 @@ bool BBOX_2D::Inside( const SFVEC2F& aPoint ) const
|
||||
}
|
||||
|
||||
|
||||
bool BBOX_2D::Inside( const BBOX_2D& aBBox ) const
|
||||
{
|
||||
wxASSERT( IsInitialized() );
|
||||
wxASSERT( aBBox.IsInitialized() );
|
||||
|
||||
return Inside( aBBox.Min() ) &&
|
||||
Inside( aBBox.Max() );
|
||||
}
|
||||
|
||||
|
||||
float BBOX_2D::Area() const
|
||||
{
|
||||
SFVEC2F extent = GetExtent();
|
||||
|
||||
@@ -132,14 +132,6 @@ public:
|
||||
*/
|
||||
bool Inside( const SFVEC2F& aPoint ) const;
|
||||
|
||||
/**
|
||||
* Check if a bounding box is inside this bounding box.
|
||||
*
|
||||
* @param aBBox the bounding box to test if it is inside
|
||||
* @return true if aBBox is smaller and all points are inside
|
||||
*/
|
||||
bool Inside( const BBOX_2D& aBBox ) const;
|
||||
|
||||
/**
|
||||
* Calculate the area of a bounding box.
|
||||
*
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
* This program source code file is part of KiCad, a free EDA CAD application.
|
||||
*
|
||||
* Copyright (C) 2015-2020 Mario Luzeiro <mrluzeiro@ua.pt>
|
||||
* Copyright (C) 1992-2022 KiCad Developers, see AUTHORS.txt for contributors.
|
||||
* Copyright (C) 1992-2021 KiCad Developers, see AUTHORS.txt for contributors.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
@@ -22,14 +22,19 @@
|
||||
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
|
||||
*/
|
||||
|
||||
/**
|
||||
* @file object_2d.cpp
|
||||
*/
|
||||
|
||||
#include "object_2d.h"
|
||||
#include <wx/log.h>
|
||||
#include <map>
|
||||
|
||||
OBJECT_2D_STATS *OBJECT_2D_STATS::s_instance = nullptr;
|
||||
|
||||
|
||||
OBJECT_2D::OBJECT_2D( OBJECT_2D_TYPE aObjType, const BOARD_ITEM& aBoardItem ) :
|
||||
m_boardItem( aBoardItem )
|
||||
OBJECT_2D::OBJECT_2D( OBJECT_2D_TYPE aObjType, const BOARD_ITEM& aBoardItem )
|
||||
: m_boardItem(aBoardItem)
|
||||
{
|
||||
m_obj_type = aObjType;
|
||||
OBJECT_2D_STATS::Instance().AddOne( aObjType );
|
||||
|
||||
@@ -31,7 +31,6 @@
|
||||
|
||||
#include "object_2d.h"
|
||||
#include "../ray.h"
|
||||
#include "filled_circle_2d.h"
|
||||
#include <plugins/3dapi/xv3d_types.h> // SFVEC2F
|
||||
|
||||
class BOARD_ITEM;
|
||||
|
||||
@@ -118,19 +118,19 @@ bool TRIANGLE_2D::IsPointInside( const SFVEC2F& aPoint ) const
|
||||
}
|
||||
|
||||
|
||||
void ConvertPolygonToTriangles( const SHAPE_POLY_SET& aPolyList, CONTAINER_2D_BASE& aDstContainer,
|
||||
void ConvertPolygonToTriangles( SHAPE_POLY_SET& aPolyList, CONTAINER_2D_BASE& aDstContainer,
|
||||
float aBiuTo3dUnitsScale, const BOARD_ITEM& aBoardItem )
|
||||
{
|
||||
VECTOR2I a;
|
||||
VECTOR2I b;
|
||||
VECTOR2I c;
|
||||
|
||||
const_cast<SHAPE_POLY_SET&>( aPolyList ).CacheTriangulation( false );
|
||||
aPolyList.CacheTriangulation( false );
|
||||
const double conver_d = (double)aBiuTo3dUnitsScale;
|
||||
|
||||
for( unsigned int j = 0; j < aPolyList.TriangulatedPolyCount(); j++ )
|
||||
{
|
||||
const SHAPE_POLY_SET::TRIANGULATED_POLYGON* triPoly = aPolyList.TriangulatedPolygon( j );
|
||||
auto triPoly = aPolyList.TriangulatedPolygon( j );
|
||||
|
||||
for( size_t i = 0; i < triPoly->GetTriangleCount(); i++ )
|
||||
{
|
||||
|
||||
@@ -64,6 +64,6 @@ private:
|
||||
};
|
||||
|
||||
|
||||
void ConvertPolygonToTriangles( const SHAPE_POLY_SET& aPolyList, CONTAINER_2D_BASE& aDstContainer,
|
||||
void ConvertPolygonToTriangles( SHAPE_POLY_SET& aPolyList, CONTAINER_2D_BASE& aDstContainer,
|
||||
float aBiuTo3dUnitsScale, const BOARD_ITEM& aBoardItem );
|
||||
#endif // _TRIANGLE_2D_H_
|
||||
|
||||
@@ -238,16 +238,6 @@ bool BBOX_3D::Inside( const SFVEC3F& aPoint ) const
|
||||
}
|
||||
|
||||
|
||||
bool BBOX_3D::Inside( const BBOX_3D& aBBox ) const
|
||||
{
|
||||
wxASSERT( IsInitialized() );
|
||||
wxASSERT( aBBox.IsInitialized() );
|
||||
|
||||
return Inside( aBBox.Min() ) &&
|
||||
Inside( aBBox.Max() );
|
||||
}
|
||||
|
||||
|
||||
float BBOX_3D::Volume() const
|
||||
{
|
||||
wxASSERT( IsInitialized() );
|
||||
@@ -264,6 +254,47 @@ SFVEC3F BBOX_3D::Offset( const SFVEC3F& p ) const
|
||||
}
|
||||
|
||||
|
||||
/// @todo Why are we keeping both implementations of Intersect()?
|
||||
// Intersection code based on the book:
|
||||
// "Physical Based Ray Tracing" (by Matt Pharr and Greg Humphrey)
|
||||
// https://github.com/mmp/pbrt-v2/blob/master/src/core/geometry.cpp#L68
|
||||
#if 0
|
||||
bool BBOX_3D::Intersect( const RAY& aRay, float* aOutHitt0, float* aOutHitt1 ) const
|
||||
{
|
||||
float t0 = 0.0f;
|
||||
float t1 = FLT_MAX;
|
||||
|
||||
for( unsigned int i = 0; i < 3; ++i )
|
||||
{
|
||||
// Update interval for _i_th bounding box slab
|
||||
float tNear = ( m_min[i] - aRay.m_Origin[i] ) * aRay.m_InvDir[i];
|
||||
float tFar = ( m_max[i] - aRay.m_Origin[i] ) * aRay.m_InvDir[i];
|
||||
|
||||
// Update parametric interval from slab intersection
|
||||
if( tNear > tFar )
|
||||
{
|
||||
// Swap
|
||||
float ftemp = tNear;
|
||||
tNear = tFar;
|
||||
tFar = ftemp;
|
||||
}
|
||||
|
||||
t0 = tNear > t0 ? tNear : t0;
|
||||
t1 = tFar < t1 ? tFar : t1;
|
||||
|
||||
if( t0 > t1 )
|
||||
return false;
|
||||
}
|
||||
|
||||
if( aOutHitt0 )
|
||||
*aOutHitt0 = t0;
|
||||
|
||||
if( aOutHitt1 )
|
||||
*aOutHitt1 = t1;
|
||||
|
||||
return true;
|
||||
}
|
||||
#else
|
||||
// https://github.com/mmp/pbrt-v2/blob/master/src/accelerators/bvh.cpp#L126
|
||||
bool BBOX_3D::Intersect( const RAY& aRay, float* aOutHitt0, float* aOutHitt1 ) const
|
||||
{
|
||||
@@ -301,6 +332,7 @@ bool BBOX_3D::Intersect( const RAY& aRay, float* aOutHitt0, float* aOutHitt1 ) c
|
||||
|
||||
return true;
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
void BBOX_3D::ApplyTransformation( glm::mat4 aTransformMatrix )
|
||||
@@ -317,3 +349,22 @@ void BBOX_3D::ApplyTransformation( glm::mat4 aTransformMatrix )
|
||||
}
|
||||
|
||||
|
||||
void BBOX_3D::ApplyTransformationAA( glm::mat4 aTransformMatrix )
|
||||
{
|
||||
wxASSERT( IsInitialized() );
|
||||
|
||||
// apply the transformation matrix for each of vertices of the bounding box
|
||||
// and make a union with all vertices
|
||||
BBOX_3D tmpBBox = BBOX_3D(
|
||||
SFVEC3F( aTransformMatrix * glm::vec4( m_min.x, m_min.y, m_min.z, 1.0f ) ) );
|
||||
tmpBBox.Union( SFVEC3F( aTransformMatrix * glm::vec4( m_max.x, m_min.y, m_min.z, 1.0f ) ) );
|
||||
tmpBBox.Union( SFVEC3F( aTransformMatrix * glm::vec4( m_min.x, m_max.y, m_min.z, 1.0f ) ) );
|
||||
tmpBBox.Union( SFVEC3F( aTransformMatrix * glm::vec4( m_min.x, m_min.y, m_max.z, 1.0f ) ) );
|
||||
tmpBBox.Union( SFVEC3F( aTransformMatrix * glm::vec4( m_min.x, m_max.y, m_max.z, 1.0f ) ) );
|
||||
tmpBBox.Union( SFVEC3F( aTransformMatrix * glm::vec4( m_max.x, m_max.y, m_min.z, 1.0f ) ) );
|
||||
tmpBBox.Union( SFVEC3F( aTransformMatrix * glm::vec4( m_max.x, m_min.y, m_max.z, 1.0f ) ) );
|
||||
tmpBBox.Union( SFVEC3F( aTransformMatrix * glm::vec4( m_max.x, m_max.y, m_max.z, 1.0f ) ) );
|
||||
|
||||
m_min = tmpBBox.m_min;
|
||||
m_max = tmpBBox.m_max;
|
||||
}
|
||||
|
||||
@@ -125,14 +125,6 @@ public:
|
||||
*/
|
||||
bool Inside( const SFVEC3F& aPoint ) const;
|
||||
|
||||
/**
|
||||
* Check if a bounding box is inside this bounding box.
|
||||
*
|
||||
* @param aBBox the bounding box to test if it is inside
|
||||
* @return true if aBBox is smaller and all points are inside
|
||||
*/
|
||||
bool Inside( const BBOX_3D& aBBox ) const;
|
||||
|
||||
/**
|
||||
* Apply a transformation matrix to the box points.
|
||||
*
|
||||
@@ -140,6 +132,14 @@ public:
|
||||
*/
|
||||
void ApplyTransformation( glm::mat4 aTransformMatrix );
|
||||
|
||||
/**
|
||||
* Apply a transformation matrix to the box points and recalculate it
|
||||
* to fit an axis aligned bounding box.
|
||||
*
|
||||
* @param aTransformMatrix matrix to apply to the points of the bounding box.
|
||||
*/
|
||||
void ApplyTransformationAA( glm::mat4 aTransformMatrix );
|
||||
|
||||
/**
|
||||
* Calculate the volume of a bounding box.
|
||||
*
|
||||
|
||||
@@ -23,7 +23,8 @@
|
||||
*/
|
||||
|
||||
/**
|
||||
* @file cylinder_3d.cpp
|
||||
* @file ccylinder.cpp
|
||||
* @brief
|
||||
*/
|
||||
|
||||
#include "3d_fastmath.h"
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
/*
|
||||
* This program source code file is part of KiCad, a free EDA CAD application.
|
||||
*
|
||||
* Copyright (C) 2015-2022 Mario Luzeiro <mrluzeiro@ua.pt>
|
||||
* Copyright (C) 1992-2022 KiCad Developers, see AUTHORS.txt for contributors.
|
||||
* Copyright (C) 2015-2016 Mario Luzeiro <mrluzeiro@ua.pt>
|
||||
* Copyright (C) 1992-2021 KiCad Developers, see AUTHORS.txt for contributors.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
@@ -25,10 +25,6 @@
|
||||
#include "layer_item_3d.h"
|
||||
#include "3d_fastmath.h"
|
||||
#include <wx/debug.h>
|
||||
#include <advanced_config.h>
|
||||
|
||||
|
||||
extern float g_BevelThickness3DU;
|
||||
|
||||
|
||||
LAYER_ITEM::LAYER_ITEM( const OBJECT_2D* aObject2D, float aZMin, float aZMax ) :
|
||||
@@ -227,53 +223,18 @@ bool LAYER_ITEM::Intersect( const RAY& aRay, HITINFO& aHitInfo ) const
|
||||
{
|
||||
aHitInfo.m_tHit = t;
|
||||
aHitInfo.m_HitPoint = hitPoint;
|
||||
aHitInfo.pHitObject = this;
|
||||
|
||||
const float zNormalDir = hit_top?1.0f:hit_bot?-1.0f:0.0f;
|
||||
|
||||
if( ( outNormal.x == 0.0f ) && ( outNormal.y == 0.0f ) )
|
||||
{
|
||||
aHitInfo.m_HitNormal = SFVEC3F( 0.0f, 0.0f, zNormalDir );
|
||||
aHitInfo.m_HitNormal = SFVEC3F( 0.0f, 0.0f, 1.0f );
|
||||
}
|
||||
else
|
||||
{
|
||||
// Calculate smooth bevel normal
|
||||
float zBend = 0.0f;
|
||||
|
||||
if( hit_top || hit_bot )
|
||||
{
|
||||
float zDistanceToTopOrBot;
|
||||
|
||||
// Calculate the distance from hitpoint z to the Max/Min z of the layer
|
||||
if( hit_top )
|
||||
{
|
||||
zDistanceToTopOrBot = ( m_bbox.Max().z - hitPoint.z );
|
||||
}
|
||||
else
|
||||
{
|
||||
zDistanceToTopOrBot = ( hitPoint.z - m_bbox.Min().z );
|
||||
}
|
||||
|
||||
// For items that are > than g_BevelThickness3DU
|
||||
// (eg on board vias / plated holeS) use a factor based on m_bbox.GetExtent().z
|
||||
const float bevelThickness = glm::max( g_BevelThickness3DU,
|
||||
m_bbox.GetExtent().z *
|
||||
(float)ADVANCED_CFG::GetCfg().m_3DRT_BevelExtentFactor );
|
||||
|
||||
if( ( zDistanceToTopOrBot > 0.0f ) && ( zDistanceToTopOrBot < bevelThickness ) )
|
||||
{
|
||||
// Invert and Normalize the distance 0..1
|
||||
zBend = ( bevelThickness - zDistanceToTopOrBot ) / bevelThickness;
|
||||
}
|
||||
}
|
||||
|
||||
const SFVEC3F normalLateral = SFVEC3F( outNormal.x, outNormal.y, 0.0f );
|
||||
const SFVEC3F normalTopBot = SFVEC3F( 0.0f, 0.0f, zNormalDir );
|
||||
|
||||
// Interpolate between the regular lateral normal and the top/bot normal
|
||||
aHitInfo.m_HitNormal = glm::mix( normalLateral, normalTopBot, zBend );
|
||||
aHitInfo.m_HitNormal = SFVEC3F( outNormal.x, outNormal.y, 0.0f );
|
||||
}
|
||||
|
||||
aHitInfo.pHitObject = this;
|
||||
|
||||
m_material->Generate( aHitInfo.m_HitNormal, aRay, aHitInfo );
|
||||
|
||||
return true;
|
||||
|
||||
@@ -23,7 +23,8 @@
|
||||
*/
|
||||
|
||||
/**
|
||||
* @file object_3d.cpp
|
||||
* @file cobject.cpp
|
||||
* @brief
|
||||
*/
|
||||
|
||||
#include "object_3d.h"
|
||||
|
||||
@@ -52,7 +52,7 @@ class OBJECT_3D
|
||||
public:
|
||||
explicit OBJECT_3D( OBJECT_3D_TYPE aObjType );
|
||||
|
||||
void SetBoardItem( BOARD_ITEM* aBoardItem ) { m_boardItem = aBoardItem; }
|
||||
const void SetBoardItem( BOARD_ITEM* aBoardItem ) { m_boardItem = aBoardItem; }
|
||||
BOARD_ITEM* GetBoardItem() const { return m_boardItem; }
|
||||
|
||||
void SetMaterial( const MATERIAL* aMaterial )
|
||||
|
||||
@@ -98,7 +98,7 @@ protected:
|
||||
*/
|
||||
std::unique_ptr<BUSY_INDICATOR> CreateBusyIndicator() const;
|
||||
|
||||
///< the canvas to display the scene
|
||||
///< the canvas to disply the scene
|
||||
EDA_3D_CANVAS* m_canvas;
|
||||
|
||||
///< Settings reference in use for this render.
|
||||
|
||||
@@ -23,7 +23,7 @@
|
||||
*/
|
||||
|
||||
/**
|
||||
* @file track_ball.cpp
|
||||
* @file ctrack_ball.cpp
|
||||
* @brief Implementation of a track ball camera. A track ball is placed in the
|
||||
* center of the screen and rotates the camera.
|
||||
*/
|
||||
@@ -33,23 +33,22 @@
|
||||
#include "../3d_math.h"
|
||||
#include <wx/log.h>
|
||||
|
||||
#include <glm/gtc/quaternion.hpp>
|
||||
|
||||
// stdlib
|
||||
#include <algorithm>
|
||||
|
||||
TRACK_BALL::TRACK_BALL( float aInitialDistance ) :
|
||||
CAMERA( aInitialDistance )
|
||||
{
|
||||
wxLogTrace( m_logTrace, wxT( "TRACK_BALL::TRACK_BALL" ) );
|
||||
|
||||
memset( m_quat, 0, sizeof( m_quat ) );
|
||||
memset( m_quat_t0, 0, sizeof( m_quat_t0 ) );
|
||||
memset( m_quat_t1, 0, sizeof( m_quat_t1 ) );
|
||||
|
||||
trackball( m_quat, 0.0, 0.0, 0.0, 0.0 );
|
||||
trackball( m_quat_t0, 0.0, 0.0, 0.0, 0.0 );
|
||||
trackball( m_quat_t1, 0.0, 0.0, 0.0, 0.0 );
|
||||
}
|
||||
|
||||
|
||||
void TRACK_BALL::Drag( const wxPoint& aNewMousePosition )
|
||||
{
|
||||
m_parametersChanged = true;
|
||||
@@ -65,15 +64,34 @@ void TRACK_BALL::Drag( const wxPoint& aNewMousePosition )
|
||||
zoom * ( 2.0 * aNewMousePosition.x - m_windowSize.x ) / m_windowSize.x,
|
||||
zoom * ( m_windowSize.y - 2.0 * aNewMousePosition.y ) / m_windowSize.y );
|
||||
|
||||
float spin_matrix[4][4];
|
||||
build_rotmatrix( spin_matrix, spin_quat );
|
||||
m_rotationMatrix = glm::make_mat4( &spin_matrix[0][0] ) * m_rotationMatrix;
|
||||
add_quats( spin_quat, m_quat, m_quat );
|
||||
|
||||
float rotationMatrix[4][4];
|
||||
|
||||
build_rotmatrix( rotationMatrix, m_quat );
|
||||
|
||||
m_rotationMatrix = glm::make_mat4( &rotationMatrix[0][0] );
|
||||
|
||||
updateViewMatrix();
|
||||
|
||||
updateFrustum();
|
||||
}
|
||||
|
||||
|
||||
void TRACK_BALL::SetLookAtPos( const SFVEC3F& aLookAtPos )
|
||||
{
|
||||
if( m_lookat_pos != aLookAtPos )
|
||||
{
|
||||
m_lookat_pos = aLookAtPos;
|
||||
|
||||
updateViewMatrix();
|
||||
updateFrustum();
|
||||
|
||||
m_parametersChanged = true;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void TRACK_BALL::Pan( const wxPoint& aNewMousePosition )
|
||||
{
|
||||
m_parametersChanged = true;
|
||||
@@ -88,7 +106,7 @@ void TRACK_BALL::Pan( const wxPoint& aNewMousePosition )
|
||||
else // PROJECTION_TYPE::PERSPECTIVE
|
||||
{
|
||||
// Unproject the coordinates using the precomputed frustum tangent (zoom level dependent)
|
||||
const float panFactor = -m_camera_pos.z * m_frustum.tang * 2;
|
||||
const float panFactor = -m_camera_pos.z * m_frustum.tang * 2;
|
||||
m_camera_pos.x -= panFactor * m_frustum.ratio *
|
||||
( m_lastPosition.x - aNewMousePosition.x ) / m_windowSize.x;
|
||||
m_camera_pos.y -= panFactor * ( aNewMousePosition.y - m_lastPosition.y ) / m_windowSize.y;
|
||||
@@ -98,6 +116,7 @@ void TRACK_BALL::Pan( const wxPoint& aNewMousePosition )
|
||||
updateFrustum();
|
||||
}
|
||||
|
||||
|
||||
void TRACK_BALL::Pan( const SFVEC3F& aDeltaOffsetInc )
|
||||
{
|
||||
m_parametersChanged = true;
|
||||
@@ -108,11 +127,22 @@ void TRACK_BALL::Pan( const SFVEC3F& aDeltaOffsetInc )
|
||||
updateFrustum();
|
||||
}
|
||||
|
||||
|
||||
void TRACK_BALL::Pan_T1( const SFVEC3F& aDeltaOffsetInc )
|
||||
{
|
||||
m_camera_pos_t1 = m_camera_pos + aDeltaOffsetInc;
|
||||
}
|
||||
|
||||
|
||||
void TRACK_BALL::Reset()
|
||||
{
|
||||
CAMERA::Reset();
|
||||
|
||||
memset( m_quat, 0, sizeof( m_quat ) );
|
||||
trackball( m_quat, 0.0, 0.0, 0.0, 0.0 );
|
||||
}
|
||||
|
||||
|
||||
void TRACK_BALL::Reset_T1()
|
||||
{
|
||||
CAMERA::Reset_T1();
|
||||
@@ -121,20 +151,16 @@ void TRACK_BALL::Reset_T1()
|
||||
trackball( m_quat_t1, 0.0, 0.0, 0.0, 0.0 );
|
||||
}
|
||||
|
||||
|
||||
void TRACK_BALL::SetT0_and_T1_current_T()
|
||||
{
|
||||
CAMERA::SetT0_and_T1_current_T();
|
||||
|
||||
double quat[4];
|
||||
|
||||
// Charge the quaternions with the current rotation matrix to allow dual input.
|
||||
std::copy_n( glm::value_ptr( glm::conjugate( glm::quat_cast( m_rotationMatrix ) ) ),
|
||||
sizeof( quat ) / sizeof( quat[0] ), quat );
|
||||
|
||||
memcpy( m_quat_t0, quat, sizeof( quat ) );
|
||||
memcpy( m_quat_t1, quat, sizeof( quat ) );
|
||||
memcpy( m_quat_t0, m_quat, sizeof( m_quat ) );
|
||||
memcpy( m_quat_t1, m_quat, sizeof( m_quat ) );
|
||||
}
|
||||
|
||||
|
||||
void TRACK_BALL::Interpolate( float t )
|
||||
{
|
||||
wxASSERT( t >= 0.0f );
|
||||
@@ -158,15 +184,15 @@ void TRACK_BALL::Interpolate( float t )
|
||||
}
|
||||
|
||||
const float t0 = 1.0f - t;
|
||||
double quat[4];
|
||||
quat[0] = m_quat_t0[0] * t0 + m_quat_t1[0] * t;
|
||||
quat[1] = m_quat_t0[1] * t0 + m_quat_t1[1] * t;
|
||||
quat[2] = m_quat_t0[2] * t0 + m_quat_t1[2] * t;
|
||||
quat[3] = m_quat_t0[3] * t0 + m_quat_t1[3] * t;
|
||||
|
||||
m_quat[0] = m_quat_t0[0] * t0 + m_quat_t1[0] * t;
|
||||
m_quat[1] = m_quat_t0[1] * t0 + m_quat_t1[1] * t;
|
||||
m_quat[2] = m_quat_t0[2] * t0 + m_quat_t1[2] * t;
|
||||
m_quat[3] = m_quat_t0[3] * t0 + m_quat_t1[3] * t;
|
||||
|
||||
float rotationMatrix[4][4];
|
||||
|
||||
build_rotmatrix( rotationMatrix, quat );
|
||||
build_rotmatrix( rotationMatrix, m_quat );
|
||||
|
||||
m_rotationMatrix = glm::make_mat4( &rotationMatrix[0][0] );
|
||||
|
||||
|
||||
@@ -30,7 +30,7 @@
|
||||
#ifndef TRACK_BALL_H
|
||||
#define TRACK_BALL_H
|
||||
|
||||
#include <gal/3d/camera.h>
|
||||
#include "camera.h"
|
||||
|
||||
|
||||
class TRACK_BALL : public CAMERA
|
||||
@@ -50,6 +50,10 @@ public:
|
||||
|
||||
void Pan_T1( const SFVEC3F& aDeltaOffsetInc ) override;
|
||||
|
||||
void SetLookAtPos( const SFVEC3F& aLookAtPos ) override;
|
||||
|
||||
void Reset() override;
|
||||
|
||||
void Reset_T1() override;
|
||||
|
||||
void SetT0_and_T1_current_T() override;
|
||||
@@ -58,8 +62,9 @@ public:
|
||||
|
||||
private:
|
||||
/**
|
||||
* interpolate quaternions of the trackball
|
||||
* quarternion of the trackball
|
||||
*/
|
||||
double m_quat[4];
|
||||
double m_quat_t0[4];
|
||||
double m_quat_t1[4];
|
||||
};
|
||||
|
||||
@@ -4,8 +4,7 @@
|
||||
* Copyright (C) 2016 Mario Luzeiro <mrluzeiro@ua.pt>
|
||||
* Copyright (C) 2015 Jean-Pierre Charras, jp.charras at wanadoo.fr
|
||||
* Copyright (C) 2013 Wayne Stambaugh <stambaughw@gmail.com>
|
||||
* Copyright (C) 2023 CERN
|
||||
* Copyright (C) 1992-2023 KiCad Developers, see AUTHORS.txt for contributors.
|
||||
* Copyright (C) 1992-2021 KiCad Developers, see AUTHORS.txt for contributors.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
@@ -28,6 +27,7 @@
|
||||
#include <bitmaps.h>
|
||||
#include <tool/conditional_menu.h>
|
||||
#include <eda_3d_viewer_frame.h>
|
||||
#include <menus_helpers.h>
|
||||
#include <3d_viewer_id.h>
|
||||
#include <3d_viewer/tools/eda_3d_actions.h>
|
||||
#include <tool/tool_manager.h>
|
||||
@@ -35,12 +35,11 @@
|
||||
#include <widgets/wx_menubar.h>
|
||||
|
||||
|
||||
void EDA_3D_VIEWER_FRAME::doReCreateMenuBar()
|
||||
void EDA_3D_VIEWER_FRAME::CreateMenuBar()
|
||||
{
|
||||
wxLogTrace( m_logTrace, wxT( "EDA_3D_VIEWER_FRAME::CreateMenuBar" ) );
|
||||
|
||||
COMMON_CONTROL* tool = m_toolManager->GetTool<COMMON_CONTROL>();
|
||||
wxMenuBar* oldMenuBar = GetMenuBar();
|
||||
WX_MENUBAR* menuBar = new WX_MENUBAR();
|
||||
|
||||
|
||||
@@ -82,20 +81,6 @@ void EDA_3D_VIEWER_FRAME::doReCreateMenuBar()
|
||||
viewMenu->Add( ACTIONS::zoomFitScreen );
|
||||
viewMenu->Add( ACTIONS::zoomRedraw );
|
||||
|
||||
// Grid submenu
|
||||
ACTION_MENU* gridSubmenu = new ACTION_MENU( false, tool );
|
||||
gridSubmenu->SetTitle( _( "3D Grid" ) );
|
||||
gridSubmenu->SetIcon( BITMAPS::grid );
|
||||
|
||||
gridSubmenu->Add( EDA_3D_ACTIONS::noGrid, ACTION_MENU::CHECK);
|
||||
gridSubmenu->Add( EDA_3D_ACTIONS::show10mmGrid, ACTION_MENU::CHECK);
|
||||
gridSubmenu->Add( EDA_3D_ACTIONS::show5mmGrid, ACTION_MENU::CHECK);
|
||||
gridSubmenu->Add( EDA_3D_ACTIONS::show2_5mmGrid, ACTION_MENU::CHECK);
|
||||
gridSubmenu->Add( EDA_3D_ACTIONS::show1mmGrid, ACTION_MENU::CHECK);
|
||||
|
||||
viewMenu->AppendSeparator();
|
||||
viewMenu->Add( gridSubmenu );
|
||||
|
||||
viewMenu->AppendSeparator();
|
||||
viewMenu->Add( EDA_3D_ACTIONS::rotateXCW );
|
||||
viewMenu->Add( EDA_3D_ACTIONS::rotateXCCW );
|
||||
@@ -114,9 +99,6 @@ void EDA_3D_VIEWER_FRAME::doReCreateMenuBar()
|
||||
viewMenu->Add( EDA_3D_ACTIONS::moveUp );
|
||||
viewMenu->Add( EDA_3D_ACTIONS::moveDown );
|
||||
|
||||
viewMenu->AppendSeparator();
|
||||
viewMenu->Add( EDA_3D_ACTIONS::showLayersManager, ACTION_MENU::CHECK );
|
||||
|
||||
|
||||
//-- Preferences menu -----------------------------------------------
|
||||
//
|
||||
@@ -127,12 +109,36 @@ void EDA_3D_VIEWER_FRAME::doReCreateMenuBar()
|
||||
BITMAPS::tools,
|
||||
ACTION_MENU::CHECK );
|
||||
|
||||
prefsMenu->Add( ACTIONS::openPreferences );
|
||||
prefsMenu->Add( _( "Preferences..." ) + wxT( "\tCtrl+," ),
|
||||
_( "Show preferences for all open tools" ),
|
||||
wxID_PREFERENCES,
|
||||
BITMAPS::preference );
|
||||
|
||||
prefsMenu->Add( _( "Reset to Default Settings" ), ID_MENU3D_RESET_DEFAULTS, BITMAPS::tools );
|
||||
|
||||
prefsMenu->AppendSeparator();
|
||||
AddMenuLanguageList( prefsMenu, tool );
|
||||
|
||||
prefsMenu->Add( EDA_3D_ACTIONS::showTHT, ACTION_MENU::CHECK );
|
||||
prefsMenu->Add( EDA_3D_ACTIONS::showSMD, ACTION_MENU::CHECK );
|
||||
prefsMenu->Add( EDA_3D_ACTIONS::showVirtual, ACTION_MENU::CHECK );
|
||||
|
||||
prefsMenu->AppendSeparator();
|
||||
|
||||
prefsMenu->Add( EDA_3D_ACTIONS::showAxis, ACTION_MENU::CHECK );
|
||||
prefsMenu->Add( EDA_3D_ACTIONS::showBBoxes, ACTION_MENU::CHECK );
|
||||
|
||||
// Grid submenu
|
||||
ACTION_MENU* gridSubmenu = new ACTION_MENU( false, tool );
|
||||
gridSubmenu->SetTitle( _( "3D Grid" ) );
|
||||
gridSubmenu->SetIcon( BITMAPS::grid );
|
||||
|
||||
gridSubmenu->Add( EDA_3D_ACTIONS::noGrid, ACTION_MENU::CHECK);
|
||||
gridSubmenu->Add( EDA_3D_ACTIONS::show10mmGrid, ACTION_MENU::CHECK);
|
||||
gridSubmenu->Add( EDA_3D_ACTIONS::show5mmGrid, ACTION_MENU::CHECK);
|
||||
gridSubmenu->Add( EDA_3D_ACTIONS::show2_5mmGrid, ACTION_MENU::CHECK);
|
||||
gridSubmenu->Add( EDA_3D_ACTIONS::show1mmGrid, ACTION_MENU::CHECK);
|
||||
|
||||
prefsMenu->Add( gridSubmenu );
|
||||
|
||||
//-- Menubar -------------------------------------------------------------
|
||||
//
|
||||
@@ -143,5 +149,4 @@ void EDA_3D_VIEWER_FRAME::doReCreateMenuBar()
|
||||
AddStandardHelpMenu( menuBar );
|
||||
|
||||
SetMenuBar( menuBar );
|
||||
delete oldMenuBar;
|
||||
}
|
||||
|
||||
@@ -4,8 +4,7 @@
|
||||
* Copyright (C) 2016 Mario Luzeiro <mrluzeiro@ua.pt>
|
||||
* Copyright (C) 2015 Jean-Pierre Charras, jp.charras at wanadoo.fr
|
||||
* Copyright (C) 2013 Wayne Stambaugh <stambaughw@gmail.com>
|
||||
* Copyright (C) 2023 CERN
|
||||
* Copyright (C) 1992-2023 KiCad Developers, see AUTHORS.txt for contributors.
|
||||
* Copyright (C) 1992-2021 KiCad Developers, see AUTHORS.txt for contributors.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
@@ -26,11 +25,10 @@
|
||||
*/
|
||||
|
||||
#include <wx/wupdlock.h>
|
||||
#include <wx/choice.h>
|
||||
|
||||
#include <bitmaps.h>
|
||||
#include <dialogs/eda_view_switcher.h>
|
||||
#include <eda_3d_viewer_frame.h>
|
||||
#include <menus_helpers.h>
|
||||
#include <tool/action_toolbar.h>
|
||||
#include <tools/eda_3d_actions.h>
|
||||
#include <3d_viewer_id.h>
|
||||
@@ -97,9 +95,9 @@ void EDA_3D_VIEWER_FRAME::ReCreateMainToolbar()
|
||||
m_mainToolBar->Add( EDA_3D_ACTIONS::toggleOrtho, ACTION_TOOLBAR::TOGGLE );
|
||||
|
||||
m_mainToolBar->AddScaledSeparator( this );
|
||||
m_mainToolBar->Add( EDA_3D_ACTIONS::showLayersManager, ACTION_TOOLBAR::TOGGLE );
|
||||
m_mainToolBar->Add( EDA_3D_ACTIONS::showTHT, ACTION_TOOLBAR::TOGGLE );
|
||||
m_mainToolBar->Add( EDA_3D_ACTIONS::showSMD, ACTION_TOOLBAR::TOGGLE );
|
||||
m_mainToolBar->Add( EDA_3D_ACTIONS::showVirtual, ACTION_TOOLBAR::TOGGLE );
|
||||
|
||||
m_mainToolBar->KiRealize();
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -2,8 +2,7 @@
|
||||
* This program source code file is part of KiCad, a free EDA CAD application.
|
||||
*
|
||||
* Copyright (C) 2015-2016 Mario Luzeiro <mrluzeiro@ua.pt>
|
||||
* Copyright (C) 2023 CERN
|
||||
* Copyright (C) 1992-2024 KiCad Developers, see AUTHORS.txt for contributors.
|
||||
* Copyright (C) 1992-2021 KiCad Developers, see AUTHORS.txt for contributors.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
@@ -29,23 +28,19 @@
|
||||
#include <wx/wupdlock.h>
|
||||
#include <wx/clipbrd.h>
|
||||
#include <wx/filedlg.h>
|
||||
#include <wx/dialog.h>
|
||||
#include <wx/treebook.h>
|
||||
#include "eda_3d_viewer_frame.h"
|
||||
#include "dialogs/appearance_controls_3D.h"
|
||||
#include <dialogs/eda_view_switcher.h>
|
||||
#include <eda_3d_viewer_settings.h>
|
||||
#include <3d_viewer_id.h>
|
||||
#include <3d_viewer/tools/eda_3d_actions.h>
|
||||
#include <3d_viewer/tools/eda_3d_controller.h>
|
||||
#include <3d_viewer/tools/eda_3d_conditions.h>
|
||||
#include <advanced_config.h>
|
||||
#include <bitmaps.h>
|
||||
#include <board_design_settings.h>
|
||||
#include <core/arraydim.h>
|
||||
#include <dpi_scaling_common.h>
|
||||
#include <gal/dpi_scaling.h>
|
||||
#include <pgm_base.h>
|
||||
#include <project.h>
|
||||
#include <project/project_file.h>
|
||||
#include <settings/common_settings.h>
|
||||
#include <settings/settings_manager.h>
|
||||
#include <tool/action_manager.h>
|
||||
@@ -53,12 +48,14 @@
|
||||
#include <tool/tool_manager.h>
|
||||
#include <tool/tool_dispatcher.h>
|
||||
#include <tool/action_toolbar.h>
|
||||
#include <widgets/wx_infobar.h>
|
||||
#include <widgets/wx_aui_utils.h>
|
||||
#include <widgets/infobar.h>
|
||||
#include <widgets/paged_dialog.h>
|
||||
#include <dialogs/panel_3D_display_options.h>
|
||||
#include <dialogs/panel_3D_opengl_options.h>
|
||||
#include <dialogs/panel_3D_raytracing_options.h>
|
||||
#include <dialogs/panel_3D_colors.h>
|
||||
#include <panel_hotkeys_editor.h>
|
||||
#include <wildcards_and_files_ext.h>
|
||||
#include <project_pcb.h>
|
||||
|
||||
#include <3d_navlib/nl_3d_viewer_plugin.h>
|
||||
|
||||
/**
|
||||
* Flag to enable 3D viewer main frame window debug tracing.
|
||||
@@ -70,7 +67,7 @@
|
||||
const wxChar* EDA_3D_VIEWER_FRAME::m_logTrace = wxT( "KI_TRACE_EDA_3D_VIEWER" );
|
||||
|
||||
|
||||
BEGIN_EVENT_TABLE( EDA_3D_VIEWER_FRAME, KIWAY_PLAYER )
|
||||
BEGIN_EVENT_TABLE( EDA_3D_VIEWER_FRAME, EDA_BASE_FRAME )
|
||||
|
||||
EVT_ACTIVATE( EDA_3D_VIEWER_FRAME::OnActivate )
|
||||
EVT_SET_FOCUS( EDA_3D_VIEWER_FRAME::OnSetFocus )
|
||||
@@ -79,27 +76,26 @@ BEGIN_EVENT_TABLE( EDA_3D_VIEWER_FRAME, KIWAY_PLAYER )
|
||||
EDA_3D_VIEWER_FRAME::Process_Special_Functions )
|
||||
|
||||
EVT_MENU( wxID_CLOSE, EDA_3D_VIEWER_FRAME::Exit3DFrame )
|
||||
EVT_MENU( ID_RENDER_CURRENT_VIEW, EDA_3D_VIEWER_FRAME::onRenderEngineSelection )
|
||||
EVT_MENU( ID_DISABLE_RAY_TRACING, EDA_3D_VIEWER_FRAME::onDisableRayTracing )
|
||||
EVT_MENU( ID_RENDER_CURRENT_VIEW, EDA_3D_VIEWER_FRAME::OnRenderEngineSelection )
|
||||
EVT_MENU( ID_DISABLE_RAY_TRACING, EDA_3D_VIEWER_FRAME::OnDisableRayTracing )
|
||||
|
||||
EVT_CLOSE( EDA_3D_VIEWER_FRAME::OnCloseWindow )
|
||||
END_EVENT_TABLE()
|
||||
|
||||
|
||||
EDA_3D_VIEWER_FRAME::EDA_3D_VIEWER_FRAME( KIWAY* aKiway, PCB_BASE_FRAME* aParent,
|
||||
const wxString& aTitle, long style ) :
|
||||
EDA_3D_VIEWER_FRAME::EDA_3D_VIEWER_FRAME( KIWAY *aKiway, PCB_BASE_FRAME *aParent,
|
||||
const wxString &aTitle, long style ) :
|
||||
KIWAY_PLAYER( aKiway, aParent, FRAME_PCB_DISPLAY3D, aTitle, wxDefaultPosition,
|
||||
wxDefaultSize, style, QUALIFIED_VIEWER3D_FRAMENAME( aParent ), unityScale ),
|
||||
wxDefaultSize, style, QUALIFIED_VIEWER3D_FRAMENAME( aParent ) ),
|
||||
m_mainToolBar( nullptr ),
|
||||
m_canvas( nullptr ),
|
||||
m_currentCamera( m_trackBallCamera ),
|
||||
m_trackBallCamera( 2 * RANGE_SCALE_3D ),
|
||||
m_spaceMouse( nullptr )
|
||||
m_trackBallCamera( 2 * RANGE_SCALE_3D )
|
||||
{
|
||||
wxLogTrace( m_logTrace, wxT( "EDA_3D_VIEWER_FRAME::EDA_3D_VIEWER_FRAME %s" ), aTitle );
|
||||
|
||||
m_disable_ray_tracing = false;
|
||||
m_aboutTitle = _HKI( "KiCad 3D Viewer" );
|
||||
m_aboutTitle = _( "KiCad 3D Viewer" );
|
||||
|
||||
// Give it an icon
|
||||
wxIcon icon;
|
||||
@@ -107,29 +103,25 @@ EDA_3D_VIEWER_FRAME::EDA_3D_VIEWER_FRAME( KIWAY* aKiway, PCB_BASE_FRAME* aParent
|
||||
SetIcon( icon );
|
||||
|
||||
// Create the status line
|
||||
static const int status_dims[5] = { -1, 170, 130, 130, 130 };
|
||||
static const int status_dims[4] = { -1, 170, 130, 130 };
|
||||
|
||||
wxStatusBar *status_bar = CreateStatusBar( arrayDim( status_dims ) );
|
||||
SetStatusWidths( arrayDim( status_dims ), status_dims );
|
||||
|
||||
SETTINGS_MANAGER& mgr = Pgm().GetSettingsManager();
|
||||
EDA_3D_VIEWER_SETTINGS* cfg = mgr.GetAppSettings<EDA_3D_VIEWER_SETTINGS>();
|
||||
ANTIALIASING_MODE aaMode = static_cast<ANTIALIASING_MODE>( cfg->m_Render.opengl_AA_mode );
|
||||
m_canvas = new EDA_3D_CANVAS( this,
|
||||
OGL_ATT_LIST::GetAttributesList( m_boardAdapter.GetAntiAliasingMode() ),
|
||||
m_boardAdapter, m_currentCamera,
|
||||
Prj().Get3DCacheManager() );
|
||||
|
||||
m_canvas = new EDA_3D_CANVAS( this, OGL_ATT_LIST::GetAttributesList( aaMode ), m_boardAdapter,
|
||||
m_currentCamera,
|
||||
PROJECT_PCB::Get3DCacheManager( &Prj() ) );
|
||||
auto config = Pgm().GetSettingsManager().GetAppSettings<EDA_3D_VIEWER_SETTINGS>();
|
||||
LoadSettings( config );
|
||||
|
||||
m_appearancePanel = new APPEARANCE_CONTROLS_3D( this, GetCanvas() );
|
||||
|
||||
LoadSettings( cfg );
|
||||
// Some settings need the canvas
|
||||
loadCommonSettings();
|
||||
|
||||
m_appearancePanel->SetUserViewports( Prj().GetProjectFile().m_Viewports3D );
|
||||
|
||||
// Create the manager
|
||||
m_toolManager = new TOOL_MANAGER;
|
||||
m_toolManager->SetEnvironment( GetBoard(), nullptr, nullptr, cfg, this );
|
||||
m_toolManager->SetEnvironment( GetBoard(), nullptr, nullptr, config, this );
|
||||
|
||||
m_actions = new EDA_3D_ACTIONS();
|
||||
m_toolDispatcher = new TOOL_DISPATCHER( m_toolManager );
|
||||
@@ -143,56 +135,33 @@ EDA_3D_VIEWER_FRAME::EDA_3D_VIEWER_FRAME( KIWAY* aKiway, PCB_BASE_FRAME* aParent
|
||||
setupUIConditions();
|
||||
|
||||
if( EDA_3D_CONTROLLER* ctrlTool = GetToolManager()->GetTool<EDA_3D_CONTROLLER>() )
|
||||
ctrlTool->SetRotationIncrement( cfg->m_Camera.rotation_increment );
|
||||
ctrlTool->SetRotationIncrement( config->m_Camera.rotation_increment );
|
||||
|
||||
// Run the viewer control tool, it is supposed to be always active
|
||||
m_toolManager->InvokeTool( "3DViewer.Control" );
|
||||
|
||||
ReCreateMenuBar();
|
||||
CreateMenuBar();
|
||||
ReCreateMainToolbar();
|
||||
|
||||
m_infoBar = new WX_INFOBAR( this, &m_auimgr );
|
||||
|
||||
m_auimgr.SetManagedWindow( this );
|
||||
|
||||
m_auimgr.AddPane( m_mainToolBar, EDA_PANE().HToolbar().Name( wxS( "MainToolbar" ) )
|
||||
.Top().Layer( 6 ) );
|
||||
m_auimgr.AddPane( m_infoBar, EDA_PANE().InfoBar().Name( wxS( "InfoBar" ) )
|
||||
.Top().Layer( 1 ) );
|
||||
m_auimgr.AddPane( m_appearancePanel, EDA_PANE().Name( "LayersManager" )
|
||||
.Right().Layer( 3 )
|
||||
.Caption( _( "Appearance" ) ).PaneBorder( false )
|
||||
.MinSize( 180, -1 ).BestSize( 190, -1 ) );
|
||||
m_auimgr.AddPane( m_canvas, EDA_PANE().Canvas().Name( wxS( "DrawFrame" ) )
|
||||
.Center() );
|
||||
|
||||
wxAuiPaneInfo& layersManager = m_auimgr.GetPane( "LayersManager" );
|
||||
|
||||
if( cfg->m_AuiPanels.right_panel_width > 0 )
|
||||
SetAuiPaneSize( m_auimgr, layersManager, cfg->m_AuiPanels.right_panel_width, -1 );
|
||||
|
||||
layersManager.Show( cfg->m_AuiPanels.show_layer_manager );
|
||||
m_auimgr.AddPane( m_mainToolBar, EDA_PANE().HToolbar().Name( "MainToolbar" ).Top().Layer( 6 ) );
|
||||
m_auimgr.AddPane( m_infoBar, EDA_PANE().InfoBar().Name( "InfoBar" ).Top().Layer(1) );
|
||||
m_auimgr.AddPane( m_canvas, EDA_PANE().Canvas().Name( "DrawFrame" ).Center() );
|
||||
|
||||
// Call Update() to fix all pane default sizes, especially the "InfoBar" pane before
|
||||
// hiding it.
|
||||
m_auimgr.Update();
|
||||
|
||||
// We don't want the infobar displayed right away
|
||||
m_auimgr.GetPane( wxS( "InfoBar" ) ).Hide();
|
||||
m_auimgr.GetPane( "InfoBar" ).Hide();
|
||||
m_auimgr.Update();
|
||||
|
||||
m_canvas->SetInfoBar( m_infoBar );
|
||||
m_canvas->SetStatusBar( status_bar );
|
||||
|
||||
try
|
||||
{
|
||||
m_spaceMouse = new NL_3D_VIEWER_PLUGIN( m_canvas );
|
||||
}
|
||||
catch( const std::system_error& e )
|
||||
{
|
||||
wxLogTrace( wxT( "KI_TRACE_NAVLIB" ), e.what() );
|
||||
}
|
||||
|
||||
// Fixes bug in Windows (XP and possibly others) where the canvas requires the focus
|
||||
// in order to receive mouse events. Otherwise, the user has to click somewhere on
|
||||
// the canvas before it will respond to mouse wheel events.
|
||||
@@ -202,13 +171,13 @@ EDA_3D_VIEWER_FRAME::EDA_3D_VIEWER_FRAME( KIWAY* aKiway, PCB_BASE_FRAME* aParent
|
||||
|
||||
EDA_3D_VIEWER_FRAME::~EDA_3D_VIEWER_FRAME()
|
||||
{
|
||||
delete m_spaceMouse;
|
||||
|
||||
Prj().GetProjectFile().m_Viewports3D = m_appearancePanel->GetUserViewports();
|
||||
|
||||
m_canvas->SetEventDispatcher( nullptr );
|
||||
|
||||
m_auimgr.UnInit();
|
||||
|
||||
// m_canvas delete will be called by wxWidget manager
|
||||
//delete m_canvas;
|
||||
//m_canvas = nullptr;
|
||||
}
|
||||
|
||||
|
||||
@@ -220,192 +189,75 @@ void EDA_3D_VIEWER_FRAME::setupUIConditions()
|
||||
EDA_3D_CONDITIONS cond( &m_boardAdapter );
|
||||
|
||||
// Helper to define check conditions
|
||||
#define FlagCheck( x ) ACTION_CONDITIONS().Check( cond.Flag( x ) )
|
||||
#define GridSizeCheck( x ) ACTION_CONDITIONS().Check( cond.GridSize( x ) )
|
||||
|
||||
auto raytracing =
|
||||
auto raytracingCondition =
|
||||
[this]( const SELECTION& aSel )
|
||||
{
|
||||
return m_boardAdapter.m_Cfg->m_Render.engine != RENDER_ENGINE::OPENGL;
|
||||
return m_boardAdapter.GetRenderEngine() != RENDER_ENGINE::OPENGL;
|
||||
};
|
||||
auto showTH =
|
||||
[this]( const SELECTION& aSel )
|
||||
{
|
||||
return m_boardAdapter.m_Cfg->m_Render.show_footprints_normal;
|
||||
};
|
||||
auto showSMD =
|
||||
[this]( const SELECTION& aSel )
|
||||
{
|
||||
return m_boardAdapter.m_Cfg->m_Render.show_footprints_insert;
|
||||
};
|
||||
auto showVirtual =
|
||||
[this]( const SELECTION& aSel )
|
||||
{
|
||||
return m_boardAdapter.m_Cfg->m_Render.show_footprints_virtual;
|
||||
};
|
||||
auto show_NotInPosfile =
|
||||
[this]( const SELECTION& aSel )
|
||||
{
|
||||
return m_boardAdapter.m_Cfg->m_Render.show_footprints_not_in_posfile;
|
||||
};
|
||||
auto show_DNP =
|
||||
[this]( const SELECTION& aSel )
|
||||
{
|
||||
return m_boardAdapter.m_Cfg->m_Render.show_footprints_dnp;
|
||||
};
|
||||
auto showBBoxes =
|
||||
[this]( const SELECTION& aSel )
|
||||
{
|
||||
return m_boardAdapter.m_Cfg->m_Render.show_model_bbox;
|
||||
};
|
||||
auto showAxes =
|
||||
[this]( const SELECTION& aSel )
|
||||
{
|
||||
return m_boardAdapter.m_Cfg->m_Render.show_axis;
|
||||
};
|
||||
auto ortho =
|
||||
|
||||
RegisterUIUpdateHandler( ID_RENDER_CURRENT_VIEW,
|
||||
ACTION_CONDITIONS().Check( raytracingCondition ) );
|
||||
|
||||
mgr->SetConditions( EDA_3D_ACTIONS::showTHT, FlagCheck( FL_FP_ATTRIBUTES_NORMAL ) );
|
||||
mgr->SetConditions( EDA_3D_ACTIONS::showSMD, FlagCheck( FL_FP_ATTRIBUTES_NORMAL_INSERT ) );
|
||||
mgr->SetConditions( EDA_3D_ACTIONS::showVirtual, FlagCheck( FL_FP_ATTRIBUTES_VIRTUAL ) );
|
||||
|
||||
mgr->SetConditions( EDA_3D_ACTIONS::showBBoxes, FlagCheck( FL_RENDER_OPENGL_SHOW_MODEL_BBOX ) );
|
||||
mgr->SetConditions( EDA_3D_ACTIONS::showAxis, FlagCheck( FL_AXIS ) );
|
||||
|
||||
mgr->SetConditions( EDA_3D_ACTIONS::noGrid, GridSizeCheck( GRID3D_TYPE::NONE ) );
|
||||
mgr->SetConditions( EDA_3D_ACTIONS::show10mmGrid, GridSizeCheck( GRID3D_TYPE::GRID_10MM ) );
|
||||
mgr->SetConditions( EDA_3D_ACTIONS::show5mmGrid, GridSizeCheck( GRID3D_TYPE::GRID_5MM ) );
|
||||
mgr->SetConditions( EDA_3D_ACTIONS::show2_5mmGrid, GridSizeCheck( GRID3D_TYPE::GRID_2P5MM ) );
|
||||
mgr->SetConditions( EDA_3D_ACTIONS::show1mmGrid, GridSizeCheck( GRID3D_TYPE::GRID_1MM ) );
|
||||
|
||||
|
||||
auto orthoCondition =
|
||||
[this]( const SELECTION& )
|
||||
{
|
||||
return m_currentCamera.GetProjection() == PROJECTION_TYPE::ORTHO;
|
||||
};
|
||||
|
||||
auto appearances =
|
||||
[this]( const SELECTION& aSel )
|
||||
{
|
||||
return m_boardAdapter.m_Cfg->m_AuiPanels.show_layer_manager;
|
||||
};
|
||||
|
||||
RegisterUIUpdateHandler( ID_RENDER_CURRENT_VIEW, ACTION_CONDITIONS().Check( raytracing ) );
|
||||
|
||||
mgr->SetConditions( EDA_3D_ACTIONS::showTHT, ACTION_CONDITIONS().Check( showTH ) );
|
||||
mgr->SetConditions( EDA_3D_ACTIONS::showSMD, ACTION_CONDITIONS().Check( showSMD ) );
|
||||
mgr->SetConditions( EDA_3D_ACTIONS::showVirtual, ACTION_CONDITIONS().Check( showVirtual ) );
|
||||
mgr->SetConditions( EDA_3D_ACTIONS::showNotInPosFile, ACTION_CONDITIONS().Check( show_NotInPosfile ) );
|
||||
mgr->SetConditions( EDA_3D_ACTIONS::showDNP, ACTION_CONDITIONS().Check( show_DNP ) );
|
||||
|
||||
mgr->SetConditions( EDA_3D_ACTIONS::showBBoxes, ACTION_CONDITIONS().Check( showBBoxes ) );
|
||||
mgr->SetConditions( EDA_3D_ACTIONS::showAxis, ACTION_CONDITIONS().Check( showAxes ) );
|
||||
|
||||
mgr->SetConditions( EDA_3D_ACTIONS::noGrid, GridSizeCheck( GRID3D_TYPE::NONE ) );
|
||||
mgr->SetConditions( EDA_3D_ACTIONS::show10mmGrid, GridSizeCheck( GRID3D_TYPE::GRID_10MM ) );
|
||||
mgr->SetConditions( EDA_3D_ACTIONS::show5mmGrid, GridSizeCheck( GRID3D_TYPE::GRID_5MM ) );
|
||||
mgr->SetConditions( EDA_3D_ACTIONS::show2_5mmGrid, GridSizeCheck( GRID3D_TYPE::GRID_2P5MM ) );
|
||||
mgr->SetConditions( EDA_3D_ACTIONS::show1mmGrid, GridSizeCheck( GRID3D_TYPE::GRID_1MM ) );
|
||||
mgr->SetConditions( EDA_3D_ACTIONS::toggleOrtho, ACTION_CONDITIONS().Check( ortho ) );
|
||||
|
||||
mgr->SetConditions( EDA_3D_ACTIONS::showLayersManager, ACTION_CONDITIONS().Check( appearances ) );
|
||||
mgr->SetConditions( EDA_3D_ACTIONS::toggleOrtho, ACTION_CONDITIONS().Check( orthoCondition ) );
|
||||
|
||||
#undef FlagCheck
|
||||
#undef GridSizeCheck
|
||||
}
|
||||
|
||||
|
||||
bool EDA_3D_VIEWER_FRAME::TryBefore( wxEvent& aEvent )
|
||||
void EDA_3D_VIEWER_FRAME::InstallPreferences( PAGED_DIALOG* aParent,
|
||||
PANEL_HOTKEYS_EDITOR* aHotkeysPanel )
|
||||
{
|
||||
static bool s_presetSwitcherShown = false;
|
||||
static bool s_viewportSwitcherShown = false;
|
||||
wxTreebook* book = aParent->GetTreebook();
|
||||
|
||||
// wxWidgets generates no key events for the tab key when the ctrl key is held down. One
|
||||
// way around this is to look at all events and inspect the keyboard state of the tab key.
|
||||
// However, this runs into issues on some linux VMs where querying the keyboard state is
|
||||
// very slow. Fortunately we only use ctrl-tab on Mac, so we implement this lovely hack:
|
||||
#ifdef __WXMAC__
|
||||
if( wxGetKeyState( WXK_TAB ) )
|
||||
#else
|
||||
if( ( aEvent.GetEventType() == wxEVT_CHAR || aEvent.GetEventType() == wxEVT_CHAR_HOOK )
|
||||
&& static_cast<wxKeyEvent&>( aEvent ).GetKeyCode() == WXK_TAB )
|
||||
#endif
|
||||
{
|
||||
if( !s_presetSwitcherShown && wxGetKeyState( PRESET_SWITCH_KEY ) )
|
||||
{
|
||||
if( m_appearancePanel && this->IsActive() )
|
||||
{
|
||||
wxArrayString mru = m_appearancePanel->GetLayerPresetsMRU();
|
||||
book->AddPage( new wxPanel( book ), _( "3D Viewer" ) );
|
||||
book->AddSubPage( new PANEL_3D_DISPLAY_OPTIONS( this, book ), _( "General" ) );
|
||||
book->AddSubPage( new PANEL_3D_OPENGL_OPTIONS( this, book ), _( "Realtime Renderer" ) );
|
||||
book->AddSubPage( new PANEL_3D_RAYTRACING_OPTIONS( this, book ), _( "Raytracing Renderer" ) );
|
||||
book->AddSubPage( new PANEL_3D_COLORS( this, book ), _( "Colors" ) );
|
||||
|
||||
if( mru.size() > 0 )
|
||||
{
|
||||
for( wxString& str : mru )
|
||||
{
|
||||
if( str == FOLLOW_PCB )
|
||||
str = _( "Follow PCB Editor" );
|
||||
else if( str == FOLLOW_PLOT_SETTINGS )
|
||||
str = _( "Follow PCB Plot Settings" );
|
||||
}
|
||||
|
||||
EDA_VIEW_SWITCHER switcher( this, mru, PRESET_SWITCH_KEY );
|
||||
|
||||
s_presetSwitcherShown = true;
|
||||
switcher.ShowModal();
|
||||
s_presetSwitcherShown = false;
|
||||
|
||||
int idx = switcher.GetSelection();
|
||||
|
||||
if( idx >= 0 && idx < (int) mru.size() )
|
||||
{
|
||||
wxString internalName = m_appearancePanel->GetLayerPresetsMRU()[idx];
|
||||
m_appearancePanel->ApplyLayerPreset( internalName );
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
else if( !s_viewportSwitcherShown && wxGetKeyState( VIEWPORT_SWITCH_KEY ) )
|
||||
{
|
||||
if( this->IsActive() )
|
||||
{
|
||||
const wxArrayString& viewportMRU = m_appearancePanel->GetViewportsMRU();
|
||||
|
||||
if( viewportMRU.size() > 0 )
|
||||
{
|
||||
EDA_VIEW_SWITCHER switcher( this, viewportMRU, VIEWPORT_SWITCH_KEY );
|
||||
|
||||
s_viewportSwitcherShown = true;
|
||||
switcher.ShowModal();
|
||||
s_viewportSwitcherShown = false;
|
||||
|
||||
int idx = switcher.GetSelection();
|
||||
|
||||
if( idx >= 0 && idx < (int) viewportMRU.size() )
|
||||
m_appearancePanel->ApplyViewport( viewportMRU[idx] );
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return wxFrame::TryBefore( aEvent );
|
||||
}
|
||||
|
||||
|
||||
void EDA_3D_VIEWER_FRAME::handleIconizeEvent( wxIconizeEvent& aEvent )
|
||||
{
|
||||
KIWAY_PLAYER::handleIconizeEvent( aEvent );
|
||||
|
||||
if( m_spaceMouse && aEvent.IsIconized() )
|
||||
m_spaceMouse->SetFocus( false );
|
||||
aHotkeysPanel->AddHotKeys( GetToolManager() );
|
||||
}
|
||||
|
||||
|
||||
void EDA_3D_VIEWER_FRAME::ReloadRequest()
|
||||
{
|
||||
// This will schedule a request to load later
|
||||
// ReloadRequest also updates the board pointer so always call it first
|
||||
if( m_canvas )
|
||||
m_canvas->ReloadRequest( GetBoard(), PROJECT_PCB::Get3DCacheManager( &Prj() ) );
|
||||
|
||||
if( m_appearancePanel )
|
||||
m_appearancePanel->UpdateLayerCtls();
|
||||
m_canvas->ReloadRequest( GetBoard(), Prj().Get3DCacheManager() );
|
||||
}
|
||||
|
||||
|
||||
void EDA_3D_VIEWER_FRAME::NewDisplay( bool aForceImmediateRedraw )
|
||||
{
|
||||
if( m_canvas )
|
||||
m_canvas->ReloadRequest( GetBoard(), PROJECT_PCB::Get3DCacheManager( &Prj() ) );
|
||||
ReloadRequest();
|
||||
|
||||
// After the ReloadRequest call, the refresh often takes a bit of time,
|
||||
// and it is made here only on request.
|
||||
if( m_canvas && aForceImmediateRedraw )
|
||||
if( aForceImmediateRedraw )
|
||||
m_canvas->Refresh();
|
||||
}
|
||||
|
||||
@@ -413,14 +265,14 @@ void EDA_3D_VIEWER_FRAME::NewDisplay( bool aForceImmediateRedraw )
|
||||
void EDA_3D_VIEWER_FRAME::Redraw()
|
||||
{
|
||||
// Only update in OpenGL for an interactive interaction
|
||||
if( m_boardAdapter.m_Cfg->m_Render.engine == RENDER_ENGINE::OPENGL )
|
||||
if( m_boardAdapter.GetRenderEngine() == RENDER_ENGINE::OPENGL )
|
||||
m_canvas->Request_refresh( true );
|
||||
}
|
||||
|
||||
|
||||
void EDA_3D_VIEWER_FRAME::refreshRender()
|
||||
{
|
||||
if( m_boardAdapter.m_Cfg->m_Render.engine == RENDER_ENGINE::OPENGL )
|
||||
if( m_boardAdapter.GetRenderEngine() == RENDER_ENGINE::OPENGL )
|
||||
m_canvas->Request_refresh();
|
||||
else
|
||||
NewDisplay( true );
|
||||
@@ -439,14 +291,13 @@ void EDA_3D_VIEWER_FRAME::OnCloseWindow( wxCloseEvent &event )
|
||||
{
|
||||
wxLogTrace( m_logTrace, wxT( "EDA_3D_VIEWER_FRAME::OnCloseWindow" ) );
|
||||
|
||||
// Do not show the layer manager during closing to avoid flicker on some platforms (Windows)
|
||||
// that generate useless redraw of items in the Layer Manager
|
||||
if( m_auimgr.GetPane( wxS( "LayersManager" ) ).IsShown() )
|
||||
m_auimgr.GetPane( wxS( "LayersManager" ) ).Show( false );
|
||||
|
||||
if( m_canvas )
|
||||
m_canvas->Close();
|
||||
|
||||
// m_canvas delete will be called by wxWidget manager
|
||||
//delete m_canvas;
|
||||
//m_canvas = nullptr;
|
||||
|
||||
Destroy();
|
||||
event.Skip( true );
|
||||
}
|
||||
@@ -497,31 +348,31 @@ void EDA_3D_VIEWER_FRAME::Process_Special_Functions( wxCommandEvent &event )
|
||||
}
|
||||
|
||||
|
||||
void EDA_3D_VIEWER_FRAME::onRenderEngineSelection( wxCommandEvent &event )
|
||||
void EDA_3D_VIEWER_FRAME::OnRenderEngineSelection( wxCommandEvent &event )
|
||||
{
|
||||
RENDER_ENGINE& engine = m_boardAdapter.m_Cfg->m_Render.engine;
|
||||
RENDER_ENGINE old_engine = engine;
|
||||
const RENDER_ENGINE old_engine = m_boardAdapter.GetRenderEngine();
|
||||
|
||||
if( old_engine == RENDER_ENGINE::OPENGL )
|
||||
engine = RENDER_ENGINE::RAYTRACING;
|
||||
m_boardAdapter.SetRenderEngine( RENDER_ENGINE::RAYTRACING );
|
||||
else
|
||||
engine = RENDER_ENGINE::OPENGL;
|
||||
m_boardAdapter.SetRenderEngine( RENDER_ENGINE::OPENGL );
|
||||
|
||||
wxLogTrace( m_logTrace, wxT( "EDA_3D_VIEWER_FRAME::OnRenderEngineSelection type %s " ),
|
||||
engine == RENDER_ENGINE::RAYTRACING ? wxT( "raytracing" ) : wxT( "realtime" ) );
|
||||
m_boardAdapter.GetRenderEngine() == RENDER_ENGINE::RAYTRACING ? wxT( "raytracing" )
|
||||
: wxT( "realtime" ) );
|
||||
|
||||
if( old_engine != engine )
|
||||
if( old_engine != m_boardAdapter.GetRenderEngine() )
|
||||
RenderEngineChanged();
|
||||
}
|
||||
|
||||
|
||||
void EDA_3D_VIEWER_FRAME::onDisableRayTracing( wxCommandEvent& aEvent )
|
||||
void EDA_3D_VIEWER_FRAME::OnDisableRayTracing( wxCommandEvent& aEvent )
|
||||
{
|
||||
wxLogTrace( m_logTrace, wxT( "EDA_3D_VIEWER_FRAME::%s disabling ray tracing." ),
|
||||
__WXFUNCTION__ );
|
||||
|
||||
m_disable_ray_tracing = true;
|
||||
m_boardAdapter.m_Cfg->m_Render.engine = RENDER_ENGINE::OPENGL;
|
||||
m_boardAdapter.SetRenderEngine( RENDER_ENGINE::OPENGL );
|
||||
}
|
||||
|
||||
|
||||
@@ -540,9 +391,6 @@ void EDA_3D_VIEWER_FRAME::OnActivate( wxActivateEvent &aEvent )
|
||||
m_canvas->SetFocus();
|
||||
}
|
||||
|
||||
if( m_spaceMouse )
|
||||
m_spaceMouse->SetFocus( aEvent.GetActive() );
|
||||
|
||||
aEvent.Skip(); // required under wxMAC
|
||||
}
|
||||
|
||||
@@ -568,35 +416,109 @@ void EDA_3D_VIEWER_FRAME::LoadSettings( APP_SETTINGS_BASE *aCfg )
|
||||
|
||||
if( cfg )
|
||||
{
|
||||
applySettings( cfg );
|
||||
m_boardAdapter.m_RtCameraLightColor =
|
||||
m_boardAdapter.GetColor( cfg->m_Render.raytrace_lightColorCamera );
|
||||
m_boardAdapter.m_RtLightColorTop =
|
||||
m_boardAdapter.GetColor( cfg->m_Render.raytrace_lightColorTop );
|
||||
m_boardAdapter.m_RtLightColorBottom =
|
||||
m_boardAdapter.GetColor( cfg->m_Render.raytrace_lightColorBottom );
|
||||
|
||||
m_boardAdapter.SetBoard( GetBoard() );
|
||||
m_boardAdapter.m_RtLightColor.resize( cfg->m_Render.raytrace_lightColor.size() );
|
||||
m_boardAdapter.m_RtLightSphericalCoords.resize( cfg->m_Render.raytrace_lightColor.size() );
|
||||
|
||||
// When opening the 3D viewer, we use the OpenGL mode, never the ray tracing engine
|
||||
// because the ray tracing is very time consuming, and can be seen as not working
|
||||
// (freeze window) with large boards.
|
||||
m_boardAdapter.m_Cfg->m_Render.engine = RENDER_ENGINE::OPENGL;
|
||||
|
||||
if( cfg->m_CurrentPreset == LEGACY_PRESET_FLAG )
|
||||
for( size_t i = 0; i < cfg->m_Render.raytrace_lightColor.size(); ++i )
|
||||
{
|
||||
wxString legacyColorsPresetName = _( "legacy colors" );
|
||||
m_boardAdapter.m_RtLightColor[i] =
|
||||
m_boardAdapter.GetColor( cfg->m_Render.raytrace_lightColor[i] );
|
||||
|
||||
cfg->m_UseStackupColors = false;
|
||||
SFVEC2F sphericalCoord =
|
||||
SFVEC2F( ( cfg->m_Render.raytrace_lightElevation[i] + 90.0f ) / 180.0f,
|
||||
cfg->m_Render.raytrace_lightAzimuth[i] / 180.0f );
|
||||
|
||||
if( !cfg->FindPreset( legacyColorsPresetName ) )
|
||||
{
|
||||
cfg->m_LayerPresets.emplace_back( legacyColorsPresetName,
|
||||
GetAdapter().GetDefaultVisibleLayers(),
|
||||
GetAdapter().GetDefaultColors() );
|
||||
}
|
||||
sphericalCoord.x = glm::clamp( sphericalCoord.x, 0.0f, 1.0f );
|
||||
sphericalCoord.y = glm::clamp( sphericalCoord.y, 0.0f, 2.0f );
|
||||
|
||||
cfg->m_CurrentPreset = wxEmptyString;
|
||||
m_boardAdapter.m_RtLightSphericalCoords[i] = sphericalCoord;
|
||||
}
|
||||
|
||||
m_boardAdapter.InitSettings( nullptr, nullptr );
|
||||
#define TRANSFER_SETTING( flag, field ) m_boardAdapter.SetFlag( flag, cfg->m_Render.field )
|
||||
|
||||
if( m_appearancePanel )
|
||||
m_appearancePanel->CommonSettingsChanged();
|
||||
TRANSFER_SETTING( FL_USE_REALISTIC_MODE, realistic );
|
||||
TRANSFER_SETTING( FL_SUBTRACT_MASK_FROM_SILK, subtract_mask_from_silk );
|
||||
|
||||
// OpenGL options
|
||||
TRANSFER_SETTING( FL_RENDER_OPENGL_COPPER_THICKNESS, opengl_copper_thickness );
|
||||
TRANSFER_SETTING( FL_RENDER_OPENGL_SHOW_MODEL_BBOX, opengl_show_model_bbox );
|
||||
TRANSFER_SETTING( FL_HIGHLIGHT_ROLLOVER_ITEM, opengl_highlight_on_rollover );
|
||||
TRANSFER_SETTING( FL_RENDER_OPENGL_AA_DISABLE_ON_MOVE, opengl_AA_disableOnMove );
|
||||
TRANSFER_SETTING( FL_RENDER_OPENGL_THICKNESS_DISABLE_ON_MOVE, opengl_thickness_disableOnMove );
|
||||
TRANSFER_SETTING( FL_RENDER_OPENGL_VIAS_DISABLE_ON_MOVE, opengl_vias_disableOnMove );
|
||||
TRANSFER_SETTING( FL_RENDER_OPENGL_HOLES_DISABLE_ON_MOVE, opengl_holes_disableOnMove );
|
||||
|
||||
// Raytracing options
|
||||
TRANSFER_SETTING( FL_RENDER_RAYTRACING_SHADOWS, raytrace_shadows );
|
||||
TRANSFER_SETTING( FL_RENDER_RAYTRACING_BACKFLOOR, raytrace_backfloor );
|
||||
TRANSFER_SETTING( FL_RENDER_RAYTRACING_REFRACTIONS, raytrace_refractions );
|
||||
TRANSFER_SETTING( FL_RENDER_RAYTRACING_REFLECTIONS, raytrace_reflections );
|
||||
TRANSFER_SETTING( FL_RENDER_RAYTRACING_POST_PROCESSING, raytrace_post_processing );
|
||||
TRANSFER_SETTING( FL_RENDER_RAYTRACING_ANTI_ALIASING, raytrace_anti_aliasing );
|
||||
TRANSFER_SETTING( FL_RENDER_RAYTRACING_PROCEDURAL_TEXTURES, raytrace_procedural_textures );
|
||||
|
||||
TRANSFER_SETTING( FL_AXIS, show_axis );
|
||||
TRANSFER_SETTING( FL_FP_ATTRIBUTES_NORMAL, show_footprints_normal );
|
||||
TRANSFER_SETTING( FL_FP_ATTRIBUTES_NORMAL_INSERT, show_footprints_insert );
|
||||
TRANSFER_SETTING( FL_FP_ATTRIBUTES_VIRTUAL, show_footprints_virtual );
|
||||
TRANSFER_SETTING( FL_ZONE, show_zones );
|
||||
TRANSFER_SETTING( FL_ADHESIVE, show_adhesive );
|
||||
TRANSFER_SETTING( FL_SILKSCREEN, show_silkscreen );
|
||||
TRANSFER_SETTING( FL_SOLDERMASK, show_soldermask );
|
||||
TRANSFER_SETTING( FL_SOLDERPASTE, show_solderpaste );
|
||||
TRANSFER_SETTING( FL_COMMENTS, show_comments );
|
||||
TRANSFER_SETTING( FL_ECO, show_eco );
|
||||
TRANSFER_SETTING( FL_SHOW_BOARD_BODY, show_board_body );
|
||||
TRANSFER_SETTING( FL_CLIP_SILK_ON_VIA_ANNULUS, clip_silk_on_via_annulus );
|
||||
TRANSFER_SETTING( FL_RENDER_PLATED_PADS_AS_PLATED, renderPlatedPadsAsPlated );
|
||||
|
||||
m_boardAdapter.SetGridType( static_cast<GRID3D_TYPE>( cfg->m_Render.grid_type ) );
|
||||
m_boardAdapter.SetAntiAliasingMode(
|
||||
static_cast<ANTIALIASING_MODE>( cfg->m_Render.opengl_AA_mode ) );
|
||||
|
||||
m_boardAdapter.m_OpenGlSelectionColor =
|
||||
m_boardAdapter.GetColor( cfg->m_Render.opengl_selection_color );
|
||||
|
||||
m_boardAdapter.m_RtShadowSampleCount = cfg->m_Render.raytrace_nrsamples_shadows;
|
||||
m_boardAdapter.m_RtReflectionSampleCount = cfg->m_Render.raytrace_nrsamples_reflections;
|
||||
m_boardAdapter.m_RtRefractionSampleCount = cfg->m_Render.raytrace_nrsamples_refractions;
|
||||
|
||||
m_boardAdapter.m_RtSpreadShadows = cfg->m_Render.raytrace_spread_shadows;
|
||||
m_boardAdapter.m_RtSpreadReflections = cfg->m_Render.raytrace_spread_reflections;
|
||||
m_boardAdapter.m_RtSpreadRefractions = cfg->m_Render.raytrace_spread_refractions;
|
||||
|
||||
m_boardAdapter.m_RtRecursiveRefractionCount =
|
||||
cfg->m_Render.raytrace_recursivelevel_refractions;
|
||||
m_boardAdapter.m_RtRecursiveReflectionCount =
|
||||
cfg->m_Render.raytrace_recursivelevel_reflections;
|
||||
|
||||
// When opening the 3D viewer, we use the opengl mode, not the ray tracing engine
|
||||
// because the ray tracing is very time consumming, and can be seen as not working
|
||||
// (freeze window) with large boards.
|
||||
#if 0
|
||||
RENDER_ENGINE engine = static_cast<RENDER_ENGINE>( cfg->m_Render.engine );
|
||||
wxLogTrace( m_logTrace, engine == RENDER_ENGINE::RAYTRACING ?
|
||||
wxT( "EDA_3D_VIEWER_FRAME::LoadSettings render setting Ray Trace" )
|
||||
:
|
||||
wxT( "EDA_3D_VIEWER_FRAME::LoadSettings render setting OpenGL" ) );
|
||||
#else
|
||||
m_boardAdapter.SetRenderEngine( RENDER_ENGINE::OPENGL );
|
||||
#endif
|
||||
|
||||
m_boardAdapter.SetMaterialMode( static_cast<MATERIAL_MODE>( cfg->m_Render.material_mode ) );
|
||||
|
||||
m_canvas->SetAnimationEnabled( cfg->m_Camera.animation_enabled );
|
||||
m_canvas->SetMovingSpeedMultiplier( cfg->m_Camera.moving_speed_multiplier );
|
||||
m_canvas->SetProjectionMode( cfg->m_Camera.projection_mode );
|
||||
|
||||
#undef TRANSFER_SETTING
|
||||
}
|
||||
}
|
||||
|
||||
@@ -609,14 +531,53 @@ void EDA_3D_VIEWER_FRAME::SaveSettings( APP_SETTINGS_BASE *aCfg )
|
||||
|
||||
wxLogTrace( m_logTrace, wxT( "EDA_3D_VIEWER_FRAME::SaveSettings" ) );
|
||||
|
||||
wxLogTrace( m_logTrace, m_boardAdapter.m_Cfg->m_Render.engine == RENDER_ENGINE::RAYTRACING ?
|
||||
wxT( "EDA_3D_VIEWER_FRAME::SaveSettings render setting Ray Trace" )
|
||||
:
|
||||
wxT( "EDA_3D_VIEWER_FRAME::SaveSettings render setting OpenGL" ) );
|
||||
wxLogTrace( m_logTrace, m_boardAdapter.GetRenderEngine() == RENDER_ENGINE::RAYTRACING ?
|
||||
wxT( "EDA_3D_VIEWER_FRAME::SaveSettings render setting Ray Trace" ) :
|
||||
wxT( "EDA_3D_VIEWER_FRAME::SaveSettings render setting OpenGL" ) );
|
||||
|
||||
if( cfg )
|
||||
{
|
||||
cfg->m_AuiPanels.right_panel_width = m_appearancePanel->GetSize().x;
|
||||
auto save_color =
|
||||
[] ( const SFVEC3F& aSource, COLOR4D& aTarget )
|
||||
{
|
||||
aTarget = COLOR4D( aSource.r, aSource.g, aSource.b, 1.0 );
|
||||
};
|
||||
|
||||
save_color( m_boardAdapter.m_RtCameraLightColor, cfg->m_Render.raytrace_lightColorCamera );
|
||||
save_color( m_boardAdapter.m_RtLightColorTop, cfg->m_Render.raytrace_lightColorTop );
|
||||
save_color( m_boardAdapter.m_RtLightColorBottom, cfg->m_Render.raytrace_lightColorBottom );
|
||||
|
||||
for( size_t i = 0; i < cfg->m_Render.raytrace_lightColor.size(); ++i )
|
||||
{
|
||||
save_color( m_boardAdapter.m_RtLightColor[i], cfg->m_Render.raytrace_lightColor[i] );
|
||||
|
||||
cfg->m_Render.raytrace_lightElevation[i] =
|
||||
(int)( m_boardAdapter.m_RtLightSphericalCoords[i].x * 180.0f - 90.0f );
|
||||
cfg->m_Render.raytrace_lightAzimuth[i] =
|
||||
(int)( m_boardAdapter.m_RtLightSphericalCoords[i].y * 180.0f );
|
||||
}
|
||||
|
||||
cfg->m_Render.raytrace_nrsamples_shadows = m_boardAdapter.m_RtShadowSampleCount;
|
||||
cfg->m_Render.raytrace_nrsamples_reflections = m_boardAdapter.m_RtReflectionSampleCount;
|
||||
cfg->m_Render.raytrace_nrsamples_refractions = m_boardAdapter.m_RtRefractionSampleCount;
|
||||
|
||||
cfg->m_Render.raytrace_spread_shadows = m_boardAdapter.m_RtSpreadShadows;
|
||||
cfg->m_Render.raytrace_spread_reflections = m_boardAdapter.m_RtSpreadReflections;
|
||||
cfg->m_Render.raytrace_spread_refractions = m_boardAdapter.m_RtSpreadRefractions;
|
||||
|
||||
cfg->m_Render.raytrace_recursivelevel_refractions =
|
||||
m_boardAdapter.m_RtRecursiveRefractionCount;
|
||||
cfg->m_Render.raytrace_recursivelevel_reflections =
|
||||
m_boardAdapter.m_RtRecursiveReflectionCount;
|
||||
|
||||
#define TRANSFER_SETTING( field, flag ) cfg->m_Render.field = m_boardAdapter.GetFlag( flag )
|
||||
|
||||
cfg->m_Render.engine = static_cast<int>( m_boardAdapter.GetRenderEngine() );
|
||||
cfg->m_Render.grid_type = static_cast<int>( m_boardAdapter.GetGridType() );
|
||||
cfg->m_Render.material_mode = static_cast<int>( m_boardAdapter.GetMaterialMode() );
|
||||
cfg->m_Render.opengl_AA_mode = static_cast<int>( m_boardAdapter.GetAntiAliasingMode() );
|
||||
|
||||
save_color( m_boardAdapter.m_OpenGlSelectionColor, cfg->m_Render.opengl_selection_color );
|
||||
|
||||
cfg->m_Camera.animation_enabled = m_canvas->GetAnimationEnabled();
|
||||
cfg->m_Camera.moving_speed_multiplier = m_canvas->GetMovingSpeedMultiplier();
|
||||
@@ -624,6 +585,41 @@ void EDA_3D_VIEWER_FRAME::SaveSettings( APP_SETTINGS_BASE *aCfg )
|
||||
|
||||
if( EDA_3D_CONTROLLER* ctrlTool = GetToolManager()->GetTool<EDA_3D_CONTROLLER>() )
|
||||
cfg->m_Camera.rotation_increment = ctrlTool->GetRotationIncrement();
|
||||
|
||||
TRANSFER_SETTING( opengl_AA_disableOnMove, FL_RENDER_OPENGL_AA_DISABLE_ON_MOVE );
|
||||
TRANSFER_SETTING( opengl_copper_thickness, FL_RENDER_OPENGL_COPPER_THICKNESS );
|
||||
TRANSFER_SETTING( opengl_show_model_bbox, FL_RENDER_OPENGL_SHOW_MODEL_BBOX );
|
||||
TRANSFER_SETTING( opengl_highlight_on_rollover, FL_HIGHLIGHT_ROLLOVER_ITEM );
|
||||
TRANSFER_SETTING( opengl_thickness_disableOnMove, FL_RENDER_OPENGL_THICKNESS_DISABLE_ON_MOVE );
|
||||
TRANSFER_SETTING( opengl_vias_disableOnMove, FL_RENDER_OPENGL_VIAS_DISABLE_ON_MOVE );
|
||||
TRANSFER_SETTING( opengl_holes_disableOnMove, FL_RENDER_OPENGL_HOLES_DISABLE_ON_MOVE );
|
||||
|
||||
TRANSFER_SETTING( raytrace_anti_aliasing, FL_RENDER_RAYTRACING_ANTI_ALIASING );
|
||||
TRANSFER_SETTING( raytrace_backfloor, FL_RENDER_RAYTRACING_BACKFLOOR );
|
||||
TRANSFER_SETTING( raytrace_post_processing, FL_RENDER_RAYTRACING_POST_PROCESSING );
|
||||
TRANSFER_SETTING( raytrace_procedural_textures, FL_RENDER_RAYTRACING_PROCEDURAL_TEXTURES );
|
||||
TRANSFER_SETTING( raytrace_reflections, FL_RENDER_RAYTRACING_REFLECTIONS );
|
||||
TRANSFER_SETTING( raytrace_refractions, FL_RENDER_RAYTRACING_REFRACTIONS );
|
||||
TRANSFER_SETTING( raytrace_shadows, FL_RENDER_RAYTRACING_SHADOWS );
|
||||
|
||||
TRANSFER_SETTING( realistic, FL_USE_REALISTIC_MODE );
|
||||
TRANSFER_SETTING( show_adhesive, FL_ADHESIVE );
|
||||
TRANSFER_SETTING( show_axis, FL_AXIS );
|
||||
TRANSFER_SETTING( show_board_body, FL_SHOW_BOARD_BODY );
|
||||
TRANSFER_SETTING( clip_silk_on_via_annulus, FL_CLIP_SILK_ON_VIA_ANNULUS );
|
||||
TRANSFER_SETTING( renderPlatedPadsAsPlated, FL_RENDER_PLATED_PADS_AS_PLATED );
|
||||
TRANSFER_SETTING( show_comments, FL_COMMENTS );
|
||||
TRANSFER_SETTING( show_eco, FL_ECO );
|
||||
TRANSFER_SETTING( show_footprints_insert, FL_FP_ATTRIBUTES_NORMAL_INSERT );
|
||||
TRANSFER_SETTING( show_footprints_normal, FL_FP_ATTRIBUTES_NORMAL );
|
||||
TRANSFER_SETTING( show_footprints_virtual, FL_FP_ATTRIBUTES_VIRTUAL );
|
||||
TRANSFER_SETTING( show_silkscreen, FL_SILKSCREEN );
|
||||
TRANSFER_SETTING( show_soldermask, FL_SOLDERMASK );
|
||||
TRANSFER_SETTING( show_solderpaste, FL_SOLDERPASTE );
|
||||
TRANSFER_SETTING( show_zones, FL_ZONE );
|
||||
TRANSFER_SETTING( subtract_mask_from_silk, FL_SUBTRACT_MASK_FROM_SILK );
|
||||
|
||||
#undef TRANSFER_SETTING
|
||||
}
|
||||
}
|
||||
|
||||
@@ -639,64 +635,11 @@ void EDA_3D_VIEWER_FRAME::CommonSettingsChanged( bool aEnvVarsChanged, bool aTex
|
||||
ReCreateMainToolbar();
|
||||
|
||||
loadCommonSettings();
|
||||
applySettings( Pgm().GetSettingsManager().GetAppSettings<EDA_3D_VIEWER_SETTINGS>() );
|
||||
|
||||
m_appearancePanel->CommonSettingsChanged();
|
||||
|
||||
NewDisplay( true );
|
||||
}
|
||||
|
||||
|
||||
void EDA_3D_VIEWER_FRAME::ShowChangedLanguage()
|
||||
{
|
||||
EDA_BASE_FRAME::ShowChangedLanguage();
|
||||
|
||||
SetTitle( _( "3D Viewer" ) );
|
||||
ReCreateMainToolbar();
|
||||
|
||||
if( m_appearancePanel )
|
||||
{
|
||||
wxAuiPaneInfo& lm_pane_info = m_auimgr.GetPane( m_appearancePanel );
|
||||
lm_pane_info.Caption( _( "Appearance" ) );
|
||||
|
||||
m_appearancePanel->OnLanguageChanged();
|
||||
}
|
||||
|
||||
SetStatusText( wxEmptyString, ACTIVITY );
|
||||
SetStatusText( wxEmptyString, HOVERED_ITEM );
|
||||
}
|
||||
|
||||
|
||||
void EDA_3D_VIEWER_FRAME::ToggleAppearanceManager()
|
||||
{
|
||||
SETTINGS_MANAGER& mgr = Pgm().GetSettingsManager();
|
||||
EDA_3D_VIEWER_SETTINGS* cfg = mgr.GetAppSettings<EDA_3D_VIEWER_SETTINGS>();
|
||||
wxAuiPaneInfo& layersManager = m_auimgr.GetPane( "LayersManager" );
|
||||
|
||||
// show auxiliary Vertical layers and visibility manager toolbar
|
||||
cfg->m_AuiPanels.show_layer_manager = !cfg->m_AuiPanels.show_layer_manager;
|
||||
|
||||
layersManager.Show( cfg->m_AuiPanels.show_layer_manager );
|
||||
|
||||
if( cfg->m_AuiPanels.show_layer_manager )
|
||||
{
|
||||
SetAuiPaneSize( m_auimgr, layersManager, cfg->m_AuiPanels.right_panel_width, -1 );
|
||||
}
|
||||
else
|
||||
{
|
||||
cfg->m_AuiPanels.right_panel_width = m_appearancePanel->GetSize().x;
|
||||
m_auimgr.Update();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void EDA_3D_VIEWER_FRAME::OnDarkModeToggle()
|
||||
{
|
||||
if( m_appearancePanel )
|
||||
m_appearancePanel->OnDarkModeToggle();
|
||||
}
|
||||
|
||||
|
||||
void EDA_3D_VIEWER_FRAME::takeScreenshot( wxCommandEvent& event )
|
||||
{
|
||||
wxString fullFileName;
|
||||
@@ -708,8 +651,8 @@ void EDA_3D_VIEWER_FRAME::takeScreenshot( wxCommandEvent& event )
|
||||
if( event.GetId() != ID_TOOL_SCREENCOPY_TOCLIBBOARD )
|
||||
{
|
||||
// Remember path between saves during this session only.
|
||||
const wxString wildcard = fmt_is_jpeg ? FILEEXT::JpegFileWildcard() : FILEEXT::PngFileWildcard();
|
||||
const wxString ext = fmt_is_jpeg ? FILEEXT::JpegFileExtension : FILEEXT::PngFileExtension;
|
||||
const wxString wildcard = fmt_is_jpeg ? JpegFileWildcard() : PngFileWildcard();
|
||||
const wxString ext = fmt_is_jpeg ? JpegFileExtension : PngFileExtension;
|
||||
|
||||
// First time path is set to the project path.
|
||||
if( !m_defaultSaveScreenshotFileName.IsOk() )
|
||||
@@ -750,13 +693,8 @@ void EDA_3D_VIEWER_FRAME::takeScreenshot( wxCommandEvent& event )
|
||||
}
|
||||
|
||||
// Be sure we have the latest 3D view (remember 3D view is buffered)
|
||||
// Also ensure any highlighted item is not highlighted when creating screen shot
|
||||
EDA_3D_VIEWER_SETTINGS::RENDER_SETTINGS& cfg = m_boardAdapter.m_Cfg->m_Render;
|
||||
bool allow_highlight = cfg.highlight_on_rollover;
|
||||
cfg.highlight_on_rollover = false;
|
||||
|
||||
m_canvas->DoRePaint(); // init first buffer
|
||||
m_canvas->DoRePaint(); // init second buffer
|
||||
m_canvas->Request_refresh( true );
|
||||
wxYield();
|
||||
|
||||
// Build image from the 3D buffer
|
||||
wxWindowUpdateLocker noUpdates( this );
|
||||
@@ -766,8 +704,6 @@ void EDA_3D_VIEWER_FRAME::takeScreenshot( wxCommandEvent& event )
|
||||
if( m_canvas )
|
||||
m_canvas->GetScreenshot( screenshotImage );
|
||||
|
||||
cfg.highlight_on_rollover = allow_highlight;
|
||||
|
||||
if( event.GetId() == ID_TOOL_SCREENCOPY_TOCLIBBOARD )
|
||||
{
|
||||
wxBitmap bitmap( screenshotImage );
|
||||
@@ -812,21 +748,8 @@ void EDA_3D_VIEWER_FRAME::loadCommonSettings()
|
||||
|
||||
COMMON_SETTINGS* settings = Pgm().GetCommonSettings();
|
||||
|
||||
const DPI_SCALING_COMMON dpi{ settings, this };
|
||||
const DPI_SCALING dpi{ settings, this };
|
||||
m_canvas->SetScaleFactor( dpi.GetScaleFactor() );
|
||||
|
||||
// TODO(JE) use all control options
|
||||
m_boardAdapter.m_MousewheelPanning = settings->m_Input.scroll_modifier_zoom != 0;
|
||||
}
|
||||
|
||||
|
||||
void EDA_3D_VIEWER_FRAME::applySettings( EDA_3D_VIEWER_SETTINGS* cfg )
|
||||
{
|
||||
m_boardAdapter.m_Cfg = cfg;
|
||||
|
||||
m_canvas->SetAnimationEnabled( cfg->m_Camera.animation_enabled );
|
||||
m_canvas->SetMovingSpeedMultiplier( cfg->m_Camera.moving_speed_multiplier );
|
||||
m_canvas->SetProjectionMode( cfg->m_Camera.projection_mode );
|
||||
|
||||
m_canvas->SetVcSettings( EDA_DRAW_PANEL_GAL::GetVcSettings() );
|
||||
m_boardAdapter.SetFlag( FL_MOUSEWHEEL_PANNING, settings->m_Input.scroll_modifier_zoom != 0 );
|
||||
}
|
||||
|
||||
@@ -4,8 +4,7 @@
|
||||
* Copyright (C) 2015-2016 Mario Luzeiro <mrluzeiro@ua.pt>
|
||||
* Copyright (C) 2014 Jean-Pierre Charras, jp.charras at wanadoo.fr
|
||||
* Copyright (C) 2011 Wayne Stambaugh <stambaughw@gmail.com>
|
||||
* Copyright (C) 2023 CERN
|
||||
* Copyright (C) 1992-2024 KiCad Developers, see AUTHORS.txt for contributors.
|
||||
* Copyright (C) 1992-2020 KiCad Developers, see AUTHORS.txt for contributors.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
@@ -26,7 +25,7 @@
|
||||
*/
|
||||
|
||||
/**
|
||||
* @file eda_3d_viewer_frame.h
|
||||
* @file eda_3d_viewer.h
|
||||
* @brief Declaration of the eda_3d_viewer class
|
||||
*/
|
||||
|
||||
@@ -41,11 +40,12 @@
|
||||
#include <dialogs/dialog_color_picker.h> // for CUSTOM_COLORS_LIST definition
|
||||
|
||||
|
||||
#define KICAD_DEFAULT_3D_DRAWFRAME_STYLE (wxDEFAULT_FRAME_STYLE | wxWANTS_CHARS)
|
||||
/// A variable name whose value holds the path of 3D shape files.
|
||||
/// Currently an environment variable, eventually a project variable.
|
||||
#define KICAD6_3DMODEL_DIR wxT( "KICAD6_3DMODEL_DIR" )
|
||||
|
||||
// Forward declarations
|
||||
class NL_3D_VIEWER_PLUGIN;
|
||||
class APPEARANCE_CONTROLS_3D;
|
||||
|
||||
#define KICAD_DEFAULT_3D_DRAWFRAME_STYLE (wxDEFAULT_FRAME_STYLE | wxWANTS_CHARS)
|
||||
|
||||
|
||||
enum EDA_3D_VIEWER_STATUSBAR
|
||||
@@ -54,7 +54,6 @@ enum EDA_3D_VIEWER_STATUSBAR
|
||||
HOVERED_ITEM,
|
||||
X_POS,
|
||||
Y_POS,
|
||||
ZOOM_LEVEL,
|
||||
};
|
||||
|
||||
/**
|
||||
@@ -74,6 +73,8 @@ public:
|
||||
|
||||
wxWindow* GetToolCanvas() const override { return m_canvas; }
|
||||
|
||||
void InstallPreferences( PAGED_DIALOG* aParent, PANEL_HOTKEYS_EDITOR* aHotkeysPanel ) override;
|
||||
|
||||
/**
|
||||
* Request reloading the 3D view.
|
||||
*
|
||||
@@ -115,36 +116,28 @@ public:
|
||||
* from the PCB frame because the 3D viewer isn't updated via the #KIWAY.
|
||||
*/
|
||||
void CommonSettingsChanged( bool aEnvVarsChanged, bool aTextVarsChanged ) override;
|
||||
void ShowChangedLanguage() override;
|
||||
|
||||
APPEARANCE_CONTROLS_3D* GetAppearanceManager() { return m_appearancePanel; }
|
||||
|
||||
void ToggleAppearanceManager();
|
||||
|
||||
void OnDarkModeToggle();
|
||||
|
||||
protected:
|
||||
void setupUIConditions() override;
|
||||
|
||||
void handleIconizeEvent( wxIconizeEvent& aEvent ) override;
|
||||
|
||||
private:
|
||||
/// Called when user press the File->Exit
|
||||
void Exit3DFrame( wxCommandEvent& event );
|
||||
|
||||
void OnCloseWindow( wxCloseEvent& event );
|
||||
|
||||
bool TryBefore( wxEvent& aEvent ) override;
|
||||
|
||||
void Process_Special_Functions( wxCommandEvent& event );
|
||||
|
||||
void onRenderEngineSelection( wxCommandEvent& event );
|
||||
void onDisableRayTracing( wxCommandEvent& aEvent );
|
||||
void OnRenderEngineSelection( wxCommandEvent& event );
|
||||
void OnDisableRayTracing( wxCommandEvent& aEvent );
|
||||
|
||||
void OnActivate( wxActivateEvent& event );
|
||||
|
||||
void OnSetFocus( wxFocusEvent& event );
|
||||
|
||||
void doReCreateMenuBar() override;
|
||||
void Install3DViewOptionDialog( wxCommandEvent& event );
|
||||
|
||||
void CreateMenuBar();
|
||||
void ReCreateMainToolbar();
|
||||
|
||||
/**
|
||||
@@ -167,20 +160,15 @@ private:
|
||||
*/
|
||||
void loadCommonSettings();
|
||||
|
||||
void applySettings( EDA_3D_VIEWER_SETTINGS* aSettings );
|
||||
wxFileName m_defaultSaveScreenshotFileName;
|
||||
|
||||
private:
|
||||
wxFileName m_defaultSaveScreenshotFileName;
|
||||
ACTION_TOOLBAR* m_mainToolBar;
|
||||
EDA_3D_CANVAS* m_canvas;
|
||||
BOARD_ADAPTER m_boardAdapter;
|
||||
CAMERA& m_currentCamera;
|
||||
TRACK_BALL m_trackBallCamera;
|
||||
|
||||
ACTION_TOOLBAR* m_mainToolBar;
|
||||
EDA_3D_CANVAS* m_canvas;
|
||||
BOARD_ADAPTER m_boardAdapter;
|
||||
CAMERA& m_currentCamera;
|
||||
TRACK_BALL m_trackBallCamera;
|
||||
|
||||
bool m_disable_ray_tracing;
|
||||
|
||||
NL_3D_VIEWER_PLUGIN* m_spaceMouse;
|
||||
bool m_disable_ray_tracing;
|
||||
|
||||
/**
|
||||
* Trace mask used to enable or disable the trace output of this class.
|
||||
|
||||
@@ -2,8 +2,7 @@
|
||||
* This program source code file is part of KiCad, a free EDA CAD application.
|
||||
*
|
||||
* Copyright (C) 2020 Jon Evans <jon@craftyjon.com>
|
||||
* Copyright (C) 2023 CERN
|
||||
* Copyright (C) 2020-2023 KiCad Developers, see AUTHORS.txt for contributors.
|
||||
* Copyright (C) 2020 KiCad Developers, see AUTHORS.txt for contributors.
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License as published by the
|
||||
@@ -23,193 +22,40 @@
|
||||
#include <common_ogl/ogl_attr_list.h>
|
||||
#include <settings/parameters.h>
|
||||
#include <settings/json_settings_internals.h>
|
||||
#include <3d_canvas/board_adapter.h>
|
||||
#include <wx/config.h>
|
||||
|
||||
#include "eda_3d_viewer_settings.h"
|
||||
|
||||
using KIGFX::COLOR4D;
|
||||
|
||||
using namespace std::placeholders;
|
||||
|
||||
|
||||
LAYER_PRESET_3D::LAYER_PRESET_3D( const wxString& aName ) :
|
||||
name( aName )
|
||||
{
|
||||
layers.set( LAYER_3D_BOARD );
|
||||
layers.set( LAYER_3D_COPPER_TOP );
|
||||
layers.set( LAYER_3D_COPPER_BOTTOM );
|
||||
layers.set( LAYER_3D_SILKSCREEN_TOP );
|
||||
layers.set( LAYER_3D_SILKSCREEN_BOTTOM );
|
||||
layers.set( LAYER_3D_SOLDERMASK_TOP );
|
||||
layers.set( LAYER_3D_SOLDERMASK_BOTTOM );
|
||||
layers.set( LAYER_3D_SOLDERPASTE );
|
||||
layers.set( LAYER_3D_ADHESIVE );
|
||||
|
||||
layers.set( LAYER_3D_TH_MODELS );
|
||||
layers.set( LAYER_3D_SMD_MODELS );
|
||||
|
||||
layers.set( LAYER_FP_REFERENCES );
|
||||
layers.set( LAYER_FP_TEXT );
|
||||
|
||||
layers.set( LAYER_GRID_AXES );
|
||||
|
||||
// Preload colors vector so we don't have to worry about exceptions using colors.at()
|
||||
colors[ LAYER_3D_BACKGROUND_TOP ] = BOARD_ADAPTER::g_DefaultBackgroundTop;
|
||||
colors[ LAYER_3D_BACKGROUND_BOTTOM ] = BOARD_ADAPTER::g_DefaultBackgroundBot;
|
||||
colors[ LAYER_3D_BOARD ] = BOARD_ADAPTER::g_DefaultBoardBody;
|
||||
colors[ LAYER_3D_COPPER_TOP ] = BOARD_ADAPTER::g_DefaultSurfaceFinish;
|
||||
colors[ LAYER_3D_COPPER_BOTTOM ] = BOARD_ADAPTER::g_DefaultSurfaceFinish;
|
||||
colors[ LAYER_3D_SILKSCREEN_TOP ] = BOARD_ADAPTER::g_DefaultSilkscreen;
|
||||
colors[ LAYER_3D_SILKSCREEN_BOTTOM ] = BOARD_ADAPTER::g_DefaultSilkscreen;
|
||||
colors[ LAYER_3D_SOLDERMASK_TOP ] = BOARD_ADAPTER::g_DefaultSolderMask;
|
||||
colors[ LAYER_3D_SOLDERMASK_BOTTOM ] = BOARD_ADAPTER::g_DefaultSolderMask;
|
||||
colors[ LAYER_3D_SOLDERPASTE ] = BOARD_ADAPTER::g_DefaultSolderPaste;
|
||||
colors[ LAYER_3D_USER_DRAWINGS ] = BOARD_ADAPTER::g_DefaultComments;
|
||||
colors[ LAYER_3D_USER_COMMENTS ] = BOARD_ADAPTER::g_DefaultComments;
|
||||
colors[ LAYER_3D_USER_ECO1 ] = BOARD_ADAPTER::g_DefaultECOs;
|
||||
colors[ LAYER_3D_USER_ECO2 ] = BOARD_ADAPTER::g_DefaultECOs;
|
||||
}
|
||||
|
||||
|
||||
PARAM_LAYER_PRESET_3D::PARAM_LAYER_PRESET_3D( const std::string& aPath,
|
||||
std::vector<LAYER_PRESET_3D>* aPresetList ) :
|
||||
PARAM_LAMBDA<nlohmann::json>( aPath,
|
||||
std::bind( &PARAM_LAYER_PRESET_3D::presetsToJson, this ),
|
||||
std::bind( &PARAM_LAYER_PRESET_3D::jsonToPresets, this, _1 ),
|
||||
{} ),
|
||||
m_presets( aPresetList )
|
||||
{
|
||||
wxASSERT( aPresetList );
|
||||
}
|
||||
|
||||
|
||||
nlohmann::json PARAM_LAYER_PRESET_3D::presetsToJson()
|
||||
{
|
||||
nlohmann::json ret = nlohmann::json::array();
|
||||
|
||||
for( const LAYER_PRESET_3D& preset : *m_presets )
|
||||
{
|
||||
nlohmann::json js = {
|
||||
{ "name", preset.name }
|
||||
};
|
||||
|
||||
nlohmann::json layers = nlohmann::json::array();
|
||||
|
||||
for( int layer = 0; layer < LAYER_3D_END; ++layer )
|
||||
{
|
||||
if( preset.layers.test( layer ) )
|
||||
layers.push_back( layer );
|
||||
}
|
||||
|
||||
js["layers"] = layers;
|
||||
|
||||
nlohmann::json colors = nlohmann::json::array();
|
||||
|
||||
for( const auto& [ layer, color ] : preset.colors )
|
||||
{
|
||||
nlohmann::json layerColor = {
|
||||
{ "layer", layer },
|
||||
{ "color", color.ToCSSString() }
|
||||
};
|
||||
|
||||
colors.push_back( layerColor );
|
||||
}
|
||||
|
||||
js["colors"] = colors;
|
||||
|
||||
ret.push_back( js );
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
void PARAM_LAYER_PRESET_3D::jsonToPresets( const nlohmann::json& aJson )
|
||||
{
|
||||
if( aJson.empty() || !aJson.is_array() )
|
||||
return;
|
||||
|
||||
m_presets->clear();
|
||||
|
||||
for( const nlohmann::json& preset : aJson )
|
||||
{
|
||||
if( preset.contains( "name" ) )
|
||||
{
|
||||
LAYER_PRESET_3D p( preset.at( "name" ).get<wxString>() );
|
||||
|
||||
if( preset.contains( "layers" ) && preset.at( "layers" ).is_array() )
|
||||
{
|
||||
p.layers.reset();
|
||||
|
||||
for( const nlohmann::json& layer : preset.at( "layers" ) )
|
||||
{
|
||||
if( layer.is_number_integer() )
|
||||
{
|
||||
int layerNum = layer.get<int>();
|
||||
|
||||
if( layerNum >= 0 && layerNum < LAYER_3D_END )
|
||||
p.layers.set( layerNum );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if( preset.contains( "colors" ) && preset.at( "colors" ).is_array() )
|
||||
{
|
||||
for( const nlohmann::json& layerColor : preset.at( "colors" ) )
|
||||
{
|
||||
if( layerColor.contains( "layer" ) && layerColor.contains( "color" )
|
||||
&& layerColor.at( "layer" ).is_number_integer() )
|
||||
{
|
||||
int layerNum = layerColor.at( "layer" ).get<int>();
|
||||
COLOR4D color = layerColor.at( "color" ).get<COLOR4D>();
|
||||
p.colors[ layerNum ] = color;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
m_presets->emplace_back( p );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
///! Update the schema version whenever a migration is required
|
||||
const int viewer3dSchemaVersion = 3;
|
||||
const int viewer3dSchemaVersion = 2;
|
||||
|
||||
|
||||
EDA_3D_VIEWER_SETTINGS::EDA_3D_VIEWER_SETTINGS() :
|
||||
APP_SETTINGS_BASE( "3d_viewer", viewer3dSchemaVersion ),
|
||||
m_Render(),
|
||||
m_Camera()
|
||||
EDA_3D_VIEWER_SETTINGS::EDA_3D_VIEWER_SETTINGS()
|
||||
: APP_SETTINGS_BASE( "3d_viewer", viewer3dSchemaVersion ),
|
||||
m_Render(),
|
||||
m_Camera()
|
||||
{
|
||||
m_params.emplace_back( new PARAM<bool>( "aui.show_layer_manager",
|
||||
&m_AuiPanels.show_layer_manager, true ) );
|
||||
m_params.emplace_back( new PARAM<int>( "render.engine", &m_Render.engine,
|
||||
static_cast<int>( RENDER_ENGINE::OPENGL ),
|
||||
static_cast<int>( RENDER_ENGINE::OPENGL ),
|
||||
static_cast<int>( RENDER_ENGINE::RAYTRACING ) ) );
|
||||
|
||||
m_params.emplace_back( new PARAM<int>( "aui.right_panel_width",
|
||||
&m_AuiPanels.right_panel_width, -1 ) );
|
||||
m_params.emplace_back( new PARAM<int>( "render.grid_type", &m_Render.grid_type,
|
||||
static_cast<int>( GRID3D_TYPE::NONE ),
|
||||
static_cast<int>( GRID3D_TYPE::NONE ),
|
||||
static_cast<int>( GRID3D_TYPE::GRID_10MM ) ) );
|
||||
|
||||
m_params.emplace_back( new PARAM_ENUM<RENDER_ENGINE>( "render.engine", &m_Render.engine,
|
||||
RENDER_ENGINE::OPENGL,
|
||||
RENDER_ENGINE::OPENGL,
|
||||
RENDER_ENGINE::RAYTRACING ) );
|
||||
m_params.emplace_back( new PARAM<int>( "render.material_mode", &m_Render.material_mode,
|
||||
static_cast<int>( MATERIAL_MODE::NORMAL ),
|
||||
static_cast<int>( MATERIAL_MODE::NORMAL ),
|
||||
static_cast<int>( MATERIAL_MODE::CAD_MODE ) ) );
|
||||
|
||||
m_params.emplace_back( new PARAM_ENUM<GRID3D_TYPE>( "render.grid_type", &m_Render.grid_type,
|
||||
GRID3D_TYPE::NONE,
|
||||
GRID3D_TYPE::NONE,
|
||||
GRID3D_TYPE::GRID_10MM ) );
|
||||
|
||||
m_params.emplace_back( new PARAM_ENUM<MATERIAL_MODE>( "render.material_mode",
|
||||
&m_Render.material_mode,
|
||||
MATERIAL_MODE::NORMAL,
|
||||
MATERIAL_MODE::NORMAL,
|
||||
MATERIAL_MODE::CAD_MODE ) );
|
||||
|
||||
m_params.emplace_back( new PARAM_ENUM<ANTIALIASING_MODE>( "render.opengl_AA_mode",
|
||||
&m_Render.opengl_AA_mode,
|
||||
ANTIALIASING_MODE::AA_8X,
|
||||
ANTIALIASING_MODE::AA_NONE,
|
||||
ANTIALIASING_MODE::AA_8X ) );
|
||||
m_params.emplace_back( new PARAM<int>( "render.opengl_AA_mode", &m_Render.opengl_AA_mode,
|
||||
static_cast<int>( ANTIALIASING_MODE::AA_8X ),
|
||||
static_cast<int>( ANTIALIASING_MODE::AA_NONE ),
|
||||
static_cast<int>( ANTIALIASING_MODE::AA_8X ) ) );
|
||||
|
||||
m_params.emplace_back( new PARAM<COLOR4D>( "render.opengl_selection_color",
|
||||
&m_Render.opengl_selection_color,
|
||||
@@ -219,11 +65,9 @@ EDA_3D_VIEWER_SETTINGS::EDA_3D_VIEWER_SETTINGS() :
|
||||
m_params.emplace_back( new PARAM<bool>( "render.opengl_copper_thickness",
|
||||
&m_Render.opengl_copper_thickness, false ) );
|
||||
m_params.emplace_back( new PARAM<bool>( "render.opengl_show_model_bbox",
|
||||
&m_Render.show_model_bbox, false ) );
|
||||
m_params.emplace_back( new PARAM<bool>( "render.opengl_show_off_board_silk",
|
||||
&m_Render.show_off_board_silk, false ) );
|
||||
&m_Render.opengl_show_model_bbox, false ) );
|
||||
m_params.emplace_back( new PARAM<bool>( "render.opengl_highlight_on_rollover",
|
||||
&m_Render.highlight_on_rollover, true ) );
|
||||
&m_Render.opengl_highlight_on_rollover, true ) );
|
||||
m_params.emplace_back( new PARAM<bool>( "render.opengl_AA_disableOnMove",
|
||||
&m_Render.opengl_AA_disableOnMove, false ) );
|
||||
m_params.emplace_back( new PARAM<bool>( "render.opengl_thickness_disableOnMove",
|
||||
@@ -242,7 +86,7 @@ EDA_3D_VIEWER_SETTINGS::EDA_3D_VIEWER_SETTINGS() :
|
||||
&m_Render.raytrace_backfloor, false ) );
|
||||
m_params.emplace_back( new PARAM<bool>( "render.raytrace_post_processing",
|
||||
&m_Render.raytrace_post_processing, true ) );
|
||||
m_params.emplace_back( new PARAM<bool>( "render.raytrace_procedural_textures",
|
||||
m_params.emplace_back( new PARAM<bool>( "render.raytrace_procedural_textures",
|
||||
&m_Render.raytrace_procedural_textures, true ) );
|
||||
m_params.emplace_back( new PARAM<bool>( "render.raytrace_reflections",
|
||||
&m_Render.raytrace_reflections, true ) );
|
||||
@@ -316,6 +160,8 @@ EDA_3D_VIEWER_SETTINGS::EDA_3D_VIEWER_SETTINGS() :
|
||||
&m_Render.raytrace_lightAzimuth,
|
||||
default_azimuth ) );
|
||||
|
||||
m_params.emplace_back( new PARAM<bool>( "render.realistic",
|
||||
&m_Render.realistic, true ) );
|
||||
m_params.emplace_back( new PARAM<bool>( "render.show_adhesive",
|
||||
&m_Render.show_adhesive, true ) );
|
||||
m_params.emplace_back( new PARAM<bool>( "render.show_axis",
|
||||
@@ -324,50 +170,28 @@ EDA_3D_VIEWER_SETTINGS::EDA_3D_VIEWER_SETTINGS() :
|
||||
&m_Render.show_board_body, true ) );
|
||||
m_params.emplace_back( new PARAM<bool>( "render.show_comments",
|
||||
&m_Render.show_comments, true ) );
|
||||
m_params.emplace_back( new PARAM<bool>( "render.show_drawings",
|
||||
&m_Render.show_drawings, true ) );
|
||||
m_params.emplace_back( new PARAM<bool>( "render.show_eco1",
|
||||
&m_Render.show_eco1, true ) );
|
||||
m_params.emplace_back( new PARAM<bool>( "render.show_eco2",
|
||||
&m_Render.show_eco2, true ) );
|
||||
m_params.emplace_back( new PARAM<bool>( "render.show_eco",
|
||||
&m_Render.show_eco, true ) );
|
||||
m_params.emplace_back( new PARAM<bool>( "render.show_footprints_insert",
|
||||
&m_Render.show_footprints_insert, true ) );
|
||||
m_params.emplace_back( new PARAM<bool>( "render.show_footprints_normal",
|
||||
&m_Render.show_footprints_normal, true ) );
|
||||
m_params.emplace_back( new PARAM<bool>( "render.show_footprints_virtual",
|
||||
&m_Render.show_footprints_virtual, true ) );
|
||||
m_params.emplace_back( new PARAM<bool>( "render.show_footprints_not_in_posfile",
|
||||
&m_Render.show_footprints_not_in_posfile, true ) );
|
||||
m_params.emplace_back( new PARAM<bool>( "render.show_footprints_dnp",
|
||||
&m_Render.show_footprints_dnp, false ) );
|
||||
m_params.emplace_back( new PARAM<bool>( "render.show_silkscreen_top",
|
||||
&m_Render.show_silkscreen_top, true ) );
|
||||
m_params.emplace_back( new PARAM<bool>( "render.show_silkscreen_bottom",
|
||||
&m_Render.show_silkscreen_bottom, true ) );
|
||||
m_params.emplace_back( new PARAM<bool>( "render.show_soldermask_top",
|
||||
&m_Render.show_soldermask_top, true ) );
|
||||
m_params.emplace_back( new PARAM<bool>( "render.show_soldermask_bottom",
|
||||
&m_Render.show_soldermask_bottom, true ) );
|
||||
m_params.emplace_back( new PARAM<bool>( "render.show_silkscreen",
|
||||
&m_Render.show_silkscreen, true ) );
|
||||
m_params.emplace_back( new PARAM<bool>( "render.show_soldermask",
|
||||
&m_Render.show_soldermask, true ) );
|
||||
m_params.emplace_back( new PARAM<bool>( "render.show_solderpaste",
|
||||
&m_Render.show_solderpaste, true ) );
|
||||
m_params.emplace_back( new PARAM<bool>( "render.show_copper_top",
|
||||
&m_Render.show_copper_bottom, true ) );
|
||||
m_params.emplace_back( new PARAM<bool>( "render.show_copper_bottom",
|
||||
&m_Render.show_copper_top, true ) );
|
||||
m_params.emplace_back( new PARAM<bool>( "render.show_zones",
|
||||
&m_Render.show_zones, true ) );
|
||||
m_params.emplace_back( new PARAM<bool>( "render.show_fp_references",
|
||||
&m_Render.show_fp_references, true ) );
|
||||
m_params.emplace_back( new PARAM<bool>( "render.show_fp_values",
|
||||
&m_Render.show_fp_values, true ) );
|
||||
m_params.emplace_back( new PARAM<bool>( "render.show_fp_text",
|
||||
&m_Render.show_fp_text, true ) );
|
||||
m_params.emplace_back( new PARAM<bool>( "render.subtract_mask_from_silk",
|
||||
&m_Render.subtract_mask_from_silk, false ) );
|
||||
m_params.emplace_back( new PARAM<bool>( "render.clip_silk_on_via_annulus",
|
||||
&m_Render.clip_silk_on_via_annuli, false ) );
|
||||
&m_Render.clip_silk_on_via_annulus, false ) );
|
||||
m_params.emplace_back( new PARAM<bool>( "render.plated_and_bare_copper",
|
||||
&m_Render.differentiate_plated_copper, false ) );
|
||||
&m_Render.renderPlatedPadsAsPlated, false ) );
|
||||
m_params.emplace_back( new PARAM<bool>( "camera.animation_enabled",
|
||||
&m_Camera.animation_enabled, true ) );
|
||||
m_params.emplace_back( new PARAM<int>( "camera.moving_speed_multiplier",
|
||||
@@ -377,66 +201,13 @@ EDA_3D_VIEWER_SETTINGS::EDA_3D_VIEWER_SETTINGS() :
|
||||
m_params.emplace_back( new PARAM<int>( "camera.projection_mode",
|
||||
&m_Camera.projection_mode, 1 ) );
|
||||
|
||||
m_params.emplace_back( new PARAM<bool>( "use_stackup_colors",
|
||||
&m_UseStackupColors, true ) );
|
||||
m_params.emplace_back( new PARAM_LAYER_PRESET_3D( "layer_presets",
|
||||
&m_LayerPresets ) );
|
||||
m_params.emplace_back( new PARAM<wxString>( "current_layer_preset",
|
||||
&m_CurrentPreset, LEGACY_PRESET_FLAG ) );
|
||||
|
||||
registerMigration( 0, 1, std::bind( &EDA_3D_VIEWER_SETTINGS::migrateSchema0to1, this ) );
|
||||
|
||||
registerMigration( 1, 2,
|
||||
[&]() -> bool
|
||||
{
|
||||
Set( "render.opengl_copper_thickness", false );
|
||||
return true;
|
||||
} );
|
||||
|
||||
registerMigration( 2, 3,
|
||||
[&]() -> bool
|
||||
{
|
||||
if( std::optional<bool> optval = Get<bool>( "render.show_copper" ) )
|
||||
{
|
||||
Set( "render.show_copper_top", *optval );
|
||||
Set( "render.show_copper_bottom", *optval );
|
||||
}
|
||||
|
||||
if( std::optional<bool> optval = Get<bool>( "render.show_silkscreen" ) )
|
||||
{
|
||||
Set( "render.show_silkscreen_top", *optval );
|
||||
Set( "render.show_silkscreen_bottom", *optval );
|
||||
}
|
||||
|
||||
if( std::optional<bool> optval = Get<bool>( "render.show_soldermask" ) )
|
||||
{
|
||||
Set( "render.show_soldermask_top", *optval );
|
||||
Set( "render.show_soldermask_bottom", *optval );
|
||||
}
|
||||
|
||||
if( std::optional<bool> optval = Get<bool>( "render.show_comments" ) )
|
||||
Set( "render.show_drawings", *optval );
|
||||
|
||||
if( std::optional<bool> optval = Get<bool>( "render.show_eco" ) )
|
||||
{
|
||||
Set( "render.show_eco1", *optval );
|
||||
Set( "render.show_eco2", *optval );
|
||||
}
|
||||
|
||||
return true;
|
||||
} );
|
||||
}
|
||||
|
||||
|
||||
LAYER_PRESET_3D* EDA_3D_VIEWER_SETTINGS::FindPreset( const wxString& aName )
|
||||
{
|
||||
for( LAYER_PRESET_3D& preset : m_LayerPresets )
|
||||
registerMigration( 1, 2, [&]() -> bool
|
||||
{
|
||||
if( preset.name == aName )
|
||||
return &preset;
|
||||
}
|
||||
|
||||
return nullptr;
|
||||
Set( "render.opengl_copper_thickness", false );
|
||||
return true;
|
||||
} );
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -2,8 +2,7 @@
|
||||
* This program source code file is part of KiCad, a free EDA CAD application.
|
||||
*
|
||||
* Copyright (C) 2020 Jon Evans <jon@craftyjon.com>
|
||||
* Copyright (C) 2023 CERN
|
||||
* Copyright (C) 2020-2023 KiCad Developers, see AUTHORS.txt for contributors.
|
||||
* Copyright (C) 2020 KiCad Developers, see AUTHORS.txt for contributors.
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License as published by the
|
||||
@@ -22,76 +21,27 @@
|
||||
#ifndef EDA_3D_VIEWER_SETTINGS_H_
|
||||
#define EDA_3D_VIEWER_SETTINGS_H_
|
||||
|
||||
#include <3d_enums.h>
|
||||
#include <common_ogl/ogl_attr_list.h>
|
||||
#include <plugins/3dapi/xv3d_types.h>
|
||||
#include <settings/app_settings.h>
|
||||
#include <settings/parameters.h>
|
||||
#include <project/board_project_settings.h>
|
||||
#include "render_settings.h"
|
||||
|
||||
#define FOLLOW_PCB wxT( "follow_pcb_editor" )
|
||||
#define FOLLOW_PLOT_SETTINGS wxT( "follow_plot_settings" )
|
||||
#define LEGACY_PRESET_FLAG wxT( "legacy_preset_flag" )
|
||||
|
||||
|
||||
struct LAYER_PRESET_3D
|
||||
{
|
||||
LAYER_PRESET_3D( const wxString& aName = wxEmptyString );
|
||||
|
||||
LAYER_PRESET_3D( const wxString& aName, const std::bitset<LAYER_3D_END>& aLayers,
|
||||
const std::map<int, KIGFX::COLOR4D>& aColors ) :
|
||||
name( aName ),
|
||||
layers( aLayers ),
|
||||
colors( aColors )
|
||||
{
|
||||
}
|
||||
|
||||
wxString name; ///< A name for this layer set
|
||||
std::bitset<LAYER_3D_END> layers;
|
||||
std::map<int, KIGFX::COLOR4D> colors;
|
||||
};
|
||||
|
||||
|
||||
class PARAM_LAYER_PRESET_3D : public PARAM_LAMBDA<nlohmann::json>
|
||||
{
|
||||
public:
|
||||
PARAM_LAYER_PRESET_3D( const std::string& aPath, std::vector<LAYER_PRESET_3D>* aPresetList );
|
||||
|
||||
private:
|
||||
nlohmann::json presetsToJson();
|
||||
|
||||
void jsonToPresets( const nlohmann::json& aJson );
|
||||
|
||||
std::vector<LAYER_PRESET_3D>* m_presets;
|
||||
};
|
||||
|
||||
#include <plugins/3dapi/xv3d_types.h>
|
||||
|
||||
class EDA_3D_VIEWER_SETTINGS : public APP_SETTINGS_BASE
|
||||
{
|
||||
public:
|
||||
struct AUI_PANELS
|
||||
{
|
||||
int right_panel_width;
|
||||
bool show_layer_manager;
|
||||
};
|
||||
|
||||
struct RENDER_SETTINGS
|
||||
{
|
||||
RENDER_ENGINE engine;
|
||||
GRID3D_TYPE grid_type;
|
||||
ANTIALIASING_MODE opengl_AA_mode;
|
||||
MATERIAL_MODE material_mode;
|
||||
|
||||
int engine;
|
||||
int grid_type;
|
||||
int opengl_AA_mode;
|
||||
int material_mode;
|
||||
bool opengl_AA_disableOnMove;
|
||||
bool opengl_thickness_disableOnMove;
|
||||
bool opengl_vias_disableOnMove;
|
||||
bool opengl_holes_disableOnMove;
|
||||
bool opengl_render_bbox_only_OnMove;
|
||||
bool opengl_copper_thickness;
|
||||
bool show_model_bbox;
|
||||
bool show_off_board_silk;
|
||||
bool highlight_on_rollover;
|
||||
bool opengl_show_model_bbox;
|
||||
bool opengl_highlight_on_rollover;
|
||||
KIGFX::COLOR4D opengl_selection_color;
|
||||
|
||||
bool raytrace_anti_aliasing;
|
||||
@@ -120,32 +70,22 @@ public:
|
||||
std::vector<int> raytrace_lightElevation; // -90 .. 90
|
||||
std::vector<int> raytrace_lightAzimuth; // 0 .. 359
|
||||
|
||||
bool realistic;
|
||||
bool show_adhesive;
|
||||
bool show_axis;
|
||||
bool show_board_body;
|
||||
bool show_comments;
|
||||
bool show_drawings;
|
||||
bool show_eco1;
|
||||
bool show_eco2;
|
||||
bool show_eco;
|
||||
bool show_footprints_insert;
|
||||
bool show_footprints_normal;
|
||||
bool show_footprints_virtual;
|
||||
bool show_footprints_not_in_posfile;
|
||||
bool show_footprints_dnp;
|
||||
bool show_silkscreen_top;
|
||||
bool show_silkscreen_bottom;
|
||||
bool show_soldermask_top;
|
||||
bool show_soldermask_bottom;
|
||||
bool show_silkscreen;
|
||||
bool show_soldermask;
|
||||
bool show_solderpaste;
|
||||
bool show_copper_top;
|
||||
bool show_copper_bottom;
|
||||
bool show_zones;
|
||||
bool show_fp_references;
|
||||
bool show_fp_values;
|
||||
bool show_fp_text;
|
||||
bool subtract_mask_from_silk;
|
||||
bool clip_silk_on_via_annuli;
|
||||
bool differentiate_plated_copper;
|
||||
bool clip_silk_on_via_annulus;
|
||||
bool renderPlatedPadsAsPlated;
|
||||
};
|
||||
|
||||
struct CAMERA_SETTINGS
|
||||
@@ -160,19 +100,11 @@ public:
|
||||
|
||||
virtual ~EDA_3D_VIEWER_SETTINGS() {}
|
||||
|
||||
LAYER_PRESET_3D* FindPreset( const wxString& aName );
|
||||
|
||||
virtual bool MigrateFromLegacy( wxConfigBase* aLegacyConfig ) override;
|
||||
|
||||
public:
|
||||
AUI_PANELS m_AuiPanels;
|
||||
RENDER_SETTINGS m_Render;
|
||||
CAMERA_SETTINGS m_Camera;
|
||||
|
||||
bool m_UseStackupColors;
|
||||
std::vector<LAYER_PRESET_3D> m_LayerPresets;
|
||||
wxString m_CurrentPreset;
|
||||
|
||||
protected:
|
||||
virtual std::string getLegacyFrameName() const override { return "Viewer3DFrameName"; }
|
||||
|
||||
|
||||
@@ -2,8 +2,7 @@
|
||||
* This program source code file is part of KiCad, a free EDA CAD application.
|
||||
*
|
||||
* Copyright (C) 2017 Jon Evans <jon@craftyjon.com>
|
||||
* Copyright (C) 2023 CERN
|
||||
* Copyright (C) 2017-2023 KiCad Developers, see AUTHORS.txt for contributors.
|
||||
* Copyright (C) 2017-2020 KiCad Developers, see AUTHORS.txt for contributors.
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License as published by the
|
||||
@@ -24,7 +23,6 @@
|
||||
#include <3d_viewer_id.h>
|
||||
#include <3d_enums.h>
|
||||
#include "eda_3d_actions.h"
|
||||
#include "tool/tool_action.h"
|
||||
|
||||
|
||||
// Actions, being statically-defined, require specialized I18N handling. We continue to
|
||||
@@ -34,308 +32,248 @@
|
||||
#undef _
|
||||
#define _(s) s
|
||||
|
||||
// No description, it is not supposed to be shown anywhere
|
||||
TOOL_ACTION EDA_3D_ACTIONS::controlActivate( TOOL_ACTION_ARGS()
|
||||
.Name( "3DViewer.Control" )
|
||||
.Scope( AS_GLOBAL )
|
||||
.Flags( AF_ACTIVATE ) );
|
||||
|
||||
TOOL_ACTION EDA_3D_ACTIONS::pivotCenter( TOOL_ACTION_ARGS()
|
||||
.Name( "3DViewer.Control.pivotCenter" )
|
||||
.Scope( AS_ACTIVE )
|
||||
.DefaultHotkey( ' ' )
|
||||
.FriendlyName( _( "Set Pivot" ) )
|
||||
.Tooltip( _( "Place point around which the board will be rotated (middle mouse click)" ) )
|
||||
.Flags( AF_NONE )
|
||||
.Parameter( VIEW3D_TYPE::VIEW3D_PIVOT_CENTER ) );
|
||||
TOOL_ACTION EDA_3D_ACTIONS::controlActivate( "3DViewer.Control", AS_GLOBAL,
|
||||
0, "", "", "",
|
||||
BITMAPS::INVALID_BITMAP, AF_ACTIVATE ); // No description, it is not supposed to be shown anywhere
|
||||
|
||||
TOOL_ACTION EDA_3D_ACTIONS::rotateXCW( TOOL_ACTION_ARGS()
|
||||
.Name( "3DViewer.Control.rotateXclockwise" )
|
||||
.Scope( AS_GLOBAL )
|
||||
.FriendlyName( _( "Rotate X Clockwise" ) )
|
||||
.Icon( BITMAPS::rotate_cw_x )
|
||||
.Flags( AF_NONE )
|
||||
.Parameter( ROTATION_DIR::X_CW ) );
|
||||
TOOL_ACTION EDA_3D_ACTIONS::pivotCenter( "3DViewer.Control.pivotCenter",
|
||||
AS_ACTIVE,
|
||||
' ', "",
|
||||
_( "Center pivot rotation" ), _( "Center pivot rotation (middle mouse click)" ),
|
||||
BITMAPS::INVALID_BITMAP, AF_NONE, (void*) WXK_SPACE );
|
||||
|
||||
TOOL_ACTION EDA_3D_ACTIONS::rotateXCCW( TOOL_ACTION_ARGS()
|
||||
.Name( "3DViewer.Control.rotateXcounterclockwise" )
|
||||
.Scope( AS_GLOBAL )
|
||||
.FriendlyName( _( "Rotate X Counterclockwise" ) )
|
||||
.Icon( BITMAPS::rotate_ccw_x )
|
||||
.Flags( AF_NONE )
|
||||
.Parameter( ROTATION_DIR::X_CCW ) );
|
||||
TOOL_ACTION EDA_3D_ACTIONS::rotateXCW( "3DViewer.Control.rotateXclockwise",
|
||||
AS_GLOBAL, 0, "",
|
||||
_( "Rotate X Clockwise" ), _( "Rotate X Clockwise" ),
|
||||
BITMAPS::rotate_cw_x, AF_NONE, (void*) ROTATION_DIR::X_CW );
|
||||
|
||||
TOOL_ACTION EDA_3D_ACTIONS::rotateYCW( TOOL_ACTION_ARGS()
|
||||
.Name( "3DViewer.Control.rotateYclockwise" )
|
||||
.Scope( AS_GLOBAL )
|
||||
.FriendlyName( _( "Rotate Y Clockwise" ) )
|
||||
.Icon( BITMAPS::rotate_cw_y )
|
||||
.Flags( AF_NONE )
|
||||
.Parameter( ROTATION_DIR::Y_CW ) );
|
||||
TOOL_ACTION EDA_3D_ACTIONS::rotateXCCW( "3DViewer.Control.rotateXcounterclockwise",
|
||||
AS_GLOBAL, 0, "",
|
||||
_( "Rotate X Counterclockwise" ), _( "Rotate X Counterclockwise" ),
|
||||
BITMAPS::rotate_ccw_x, AF_NONE, (void*) ROTATION_DIR::X_CCW );
|
||||
|
||||
TOOL_ACTION EDA_3D_ACTIONS::rotateYCCW( TOOL_ACTION_ARGS()
|
||||
.Name( "3DViewer.Control.rotateYcounterclockwise" )
|
||||
.Scope( AS_GLOBAL )
|
||||
.FriendlyName( _( "Rotate Y Counterclockwise" ) )
|
||||
.Icon( BITMAPS::rotate_ccw_y )
|
||||
.Flags( AF_NONE )
|
||||
.Parameter( ROTATION_DIR::Y_CCW ) );
|
||||
TOOL_ACTION EDA_3D_ACTIONS::rotateYCW( "3DViewer.Control.rotateYclockwise",
|
||||
AS_GLOBAL, 0, "",
|
||||
_( "Rotate Y Clockwise" ), _( "Rotate Y Clockwise" ),
|
||||
BITMAPS::rotate_cw_y, AF_NONE, (void*) ROTATION_DIR::Y_CW );
|
||||
|
||||
TOOL_ACTION EDA_3D_ACTIONS::rotateZCW( TOOL_ACTION_ARGS()
|
||||
.Name( "3DViewer.Control.rotateZclockwise" )
|
||||
.Scope( AS_GLOBAL )
|
||||
.FriendlyName( _( "Rotate Z Clockwise" ) )
|
||||
.Icon( BITMAPS::rotate_cw_z )
|
||||
.Flags( AF_NONE )
|
||||
.Parameter( ROTATION_DIR::Z_CW ) );
|
||||
TOOL_ACTION EDA_3D_ACTIONS::rotateYCCW( "3DViewer.Control.rotateYcounterclockwise",
|
||||
AS_GLOBAL, 0, "",
|
||||
_( "Rotate Y Counterclockwise" ), _( "Rotate Y Counterclockwise" ),
|
||||
BITMAPS::rotate_ccw_y, AF_NONE, (void*) ROTATION_DIR::Y_CCW );
|
||||
|
||||
TOOL_ACTION EDA_3D_ACTIONS::rotateZCCW( TOOL_ACTION_ARGS()
|
||||
.Name( "3DViewer.Control.rotateZcounterclockwise" )
|
||||
.Scope( AS_GLOBAL )
|
||||
.FriendlyName( _( "Rotate Z Counterclockwise" ) )
|
||||
.Icon( BITMAPS::rotate_ccw_z )
|
||||
.Flags( AF_NONE )
|
||||
.Parameter( ROTATION_DIR::Z_CCW ) );
|
||||
TOOL_ACTION EDA_3D_ACTIONS::rotateZCW( "3DViewer.Control.rotateZclockwise",
|
||||
AS_GLOBAL, 0, "",
|
||||
_( "Rotate Z Clockwise" ), _( "Rotate Z Clockwise" ),
|
||||
BITMAPS::rotate_cw_z, AF_NONE, (void*) ROTATION_DIR::Z_CW );
|
||||
|
||||
TOOL_ACTION EDA_3D_ACTIONS::moveLeft( TOOL_ACTION_ARGS()
|
||||
.Name( "3DViewer.Control.moveLeft" )
|
||||
.Scope( AS_ACTIVE )
|
||||
.DefaultHotkey( WXK_LEFT )
|
||||
.FriendlyName( _( "Move Board Left" ) )
|
||||
.Icon( BITMAPS::left )
|
||||
.Flags( AF_NONE )
|
||||
.Parameter( CURSOR_LEFT ) );
|
||||
TOOL_ACTION EDA_3D_ACTIONS::rotateZCCW( "3DViewer.Control.rotateZcounterclockwise",
|
||||
AS_GLOBAL, 0, "",
|
||||
_( "Rotate Z Counterclockwise" ), _( "Rotate Z Counterclockwise" ),
|
||||
BITMAPS::rotate_ccw_z, AF_NONE, (void*) ROTATION_DIR::Z_CCW );
|
||||
|
||||
TOOL_ACTION EDA_3D_ACTIONS::moveRight( TOOL_ACTION_ARGS()
|
||||
.Name( "3DViewer.Control.moveRight" )
|
||||
.Scope( AS_ACTIVE )
|
||||
.DefaultHotkey( WXK_RIGHT )
|
||||
.FriendlyName( _( "Move Board Right" ) )
|
||||
.Icon( BITMAPS::right )
|
||||
.Flags( AF_NONE )
|
||||
.Parameter( CURSOR_RIGHT ) );
|
||||
TOOL_ACTION EDA_3D_ACTIONS::moveLeft( "3DViewer.Control.moveLeft",
|
||||
AS_ACTIVE,
|
||||
WXK_LEFT, "",
|
||||
_( "Move board Left" ), _( "Move board Left" ),
|
||||
BITMAPS::left, AF_NONE, (void*) CURSOR_LEFT );
|
||||
|
||||
TOOL_ACTION EDA_3D_ACTIONS::moveUp( TOOL_ACTION_ARGS()
|
||||
.Name( "3DViewer.Control.moveUp" )
|
||||
.Scope( AS_ACTIVE )
|
||||
.DefaultHotkey( WXK_UP )
|
||||
.FriendlyName( _( "Move Board Up" ) )
|
||||
.Icon( BITMAPS::up )
|
||||
.Flags( AF_NONE )
|
||||
.Parameter( CURSOR_UP ) );
|
||||
TOOL_ACTION EDA_3D_ACTIONS::moveRight( "3DViewer.Control.moveRight",
|
||||
AS_ACTIVE,
|
||||
WXK_RIGHT, "",
|
||||
_( "Move board Right" ), _( "Move board Right" ),
|
||||
BITMAPS::right, AF_NONE, (void*) CURSOR_RIGHT );
|
||||
|
||||
TOOL_ACTION EDA_3D_ACTIONS::moveDown( TOOL_ACTION_ARGS()
|
||||
.Name( "3DViewer.Control.moveDown" )
|
||||
.Scope( AS_ACTIVE )
|
||||
.DefaultHotkey( WXK_DOWN )
|
||||
.FriendlyName( _( "Move Board Down" ) )
|
||||
.Icon( BITMAPS::down )
|
||||
.Flags( AF_NONE )
|
||||
.Parameter( CURSOR_DOWN ) );
|
||||
TOOL_ACTION EDA_3D_ACTIONS::moveUp( "3DViewer.Control.moveUp",
|
||||
AS_ACTIVE,
|
||||
WXK_UP, "",
|
||||
_( "Move board Up" ), _( "Move board Up" ),
|
||||
BITMAPS::up, AF_NONE, (void*) CURSOR_UP );
|
||||
|
||||
TOOL_ACTION EDA_3D_ACTIONS::homeView( TOOL_ACTION_ARGS()
|
||||
.Name( "3DViewer.Control.homeView" )
|
||||
.Scope( AS_ACTIVE )
|
||||
.DefaultHotkey( WXK_HOME )
|
||||
.FriendlyName ( _( "Home View" ) )
|
||||
.Tooltip( _( "Redraw at the home position and zoom" ) )
|
||||
.Flags( AF_NONE )
|
||||
.Parameter( VIEW3D_TYPE::VIEW3D_FIT_SCREEN ) );
|
||||
TOOL_ACTION EDA_3D_ACTIONS::moveDown( "3DViewer.Control.moveDown",
|
||||
AS_ACTIVE,
|
||||
WXK_DOWN, "",
|
||||
_( "Move board Down" ), _( "Move board Down" ),
|
||||
BITMAPS::down, AF_NONE, (void*) CURSOR_DOWN );
|
||||
|
||||
TOOL_ACTION EDA_3D_ACTIONS::flipView( TOOL_ACTION_ARGS()
|
||||
.Name( "3DViewer.Control.flipView" )
|
||||
.Scope( AS_ACTIVE )
|
||||
.DefaultHotkey( 'F' )
|
||||
.FriendlyName( _( "Flip Board" ) )
|
||||
.Tooltip( _( "Flip the board view" ) )
|
||||
.Icon( BITMAPS::flip_board )
|
||||
.Flags( AF_NONE )
|
||||
.Parameter( VIEW3D_TYPE::VIEW3D_FLIP ) );
|
||||
TOOL_ACTION EDA_3D_ACTIONS::homeView( "3DViewer.Control.homeView",
|
||||
AS_ACTIVE,
|
||||
WXK_HOME, "",
|
||||
_( "Home view" ), _( "Home view" ),
|
||||
BITMAPS::INVALID_BITMAP, AF_NONE, (void*) WXK_HOME );
|
||||
|
||||
TOOL_ACTION EDA_3D_ACTIONS::toggleOrtho( TOOL_ACTION_ARGS()
|
||||
.Name( "3DViewer.Control.toggleOrtho" )
|
||||
.Scope( AS_GLOBAL )
|
||||
.FriendlyName( _( "Toggle Orthographic Projection" ) )
|
||||
.Tooltip( _( "Enable/disable orthographic projection" ) )
|
||||
.Icon( BITMAPS::ortho ) );
|
||||
TOOL_ACTION EDA_3D_ACTIONS::resetView( "3DViewer.Control.resetView",
|
||||
AS_ACTIVE,
|
||||
'R', "",
|
||||
_( "Reset view" ), _( "Reset view" ),
|
||||
BITMAPS::INVALID_BITMAP, AF_NONE, (void*) ID_VIEW3D_RESET );
|
||||
|
||||
TOOL_ACTION EDA_3D_ACTIONS::viewFront( TOOL_ACTION_ARGS()
|
||||
.Name( "3DViewer.Control.viewFront" )
|
||||
.Scope( AS_ACTIVE )
|
||||
.DefaultHotkey( 'Y' )
|
||||
.FriendlyName( _( "View Front" ) )
|
||||
.Icon( BITMAPS::axis3d_front )
|
||||
.Flags( AF_NONE )
|
||||
.Parameter( VIEW3D_TYPE::VIEW3D_FRONT ) );
|
||||
TOOL_ACTION EDA_3D_ACTIONS::flipView( "3DViewer.Control.flipView",
|
||||
AS_ACTIVE,
|
||||
0, "",
|
||||
_( "Flip Board" ), _( "Flip the board view" ),
|
||||
BITMAPS::flip_board, AF_NONE, (void*) ID_VIEW3D_FLIP );
|
||||
|
||||
TOOL_ACTION EDA_3D_ACTIONS::viewBack( TOOL_ACTION_ARGS()
|
||||
.Name( "3DViewer.Control.viewBack" )
|
||||
.Scope( AS_ACTIVE )
|
||||
.DefaultHotkey( MD_SHIFT + 'Y' )
|
||||
.FriendlyName( _( "View Back" ) )
|
||||
.Icon( BITMAPS::axis3d_back )
|
||||
.Flags( AF_NONE )
|
||||
.Parameter( VIEW3D_TYPE::VIEW3D_BACK ) );
|
||||
TOOL_ACTION EDA_3D_ACTIONS::toggleOrtho( "3DViewer.Control.toggleOrtho",
|
||||
AS_GLOBAL, 0, "",
|
||||
_( "Toggle orthographic projection" ), _( "Enable/disable orthographic projection" ),
|
||||
BITMAPS::ortho );
|
||||
|
||||
TOOL_ACTION EDA_3D_ACTIONS::viewLeft( TOOL_ACTION_ARGS()
|
||||
.Name( "3DViewer.Control.viewLeft" )
|
||||
.Scope( AS_ACTIVE )
|
||||
.DefaultHotkey( MD_SHIFT + 'X' )
|
||||
.FriendlyName( _( "View Left" ) )
|
||||
.Icon( BITMAPS::axis3d_left )
|
||||
.Flags( AF_NONE )
|
||||
.Parameter( VIEW3D_TYPE::VIEW3D_LEFT ) );
|
||||
TOOL_ACTION EDA_3D_ACTIONS::viewFront( "3DViewer.Control.viewFront",
|
||||
AS_ACTIVE,
|
||||
'Y', "",
|
||||
_( "View Front" ), _( "View Front" ),
|
||||
BITMAPS::axis3d_front, AF_NONE, (void*) ID_VIEW3D_FRONT );
|
||||
|
||||
TOOL_ACTION EDA_3D_ACTIONS::viewRight( TOOL_ACTION_ARGS()
|
||||
.Name( "3DViewer.Control.viewRight" )
|
||||
.Scope( AS_ACTIVE )
|
||||
.DefaultHotkey( 'X' )
|
||||
.FriendlyName( _( "View Right" ) )
|
||||
.Icon( BITMAPS::axis3d_right )
|
||||
.Flags( AF_NONE )
|
||||
.Parameter( VIEW3D_TYPE::VIEW3D_RIGHT ) );
|
||||
TOOL_ACTION EDA_3D_ACTIONS::viewBack( "3DViewer.Control.viewBack",
|
||||
AS_ACTIVE,
|
||||
MD_SHIFT + 'Y', "",
|
||||
_( "View Back" ), _( "View Back" ),
|
||||
BITMAPS::axis3d_back, AF_NONE, (void*) ID_VIEW3D_BACK );
|
||||
|
||||
TOOL_ACTION EDA_3D_ACTIONS::viewTop( TOOL_ACTION_ARGS()
|
||||
.Name( "3DViewer.Control.viewTop" )
|
||||
.Scope( AS_ACTIVE )
|
||||
.DefaultHotkey( 'Z' )
|
||||
.FriendlyName( _( "View Top" ) )
|
||||
.Icon( BITMAPS::axis3d_top )
|
||||
.Flags( AF_NONE )
|
||||
.Parameter( VIEW3D_TYPE::VIEW3D_TOP ) );
|
||||
TOOL_ACTION EDA_3D_ACTIONS::viewLeft( "3DViewer.Control.viewLeft",
|
||||
AS_ACTIVE,
|
||||
MD_SHIFT + 'X', "",
|
||||
_( "View Left" ), _( "View Left" ),
|
||||
BITMAPS::axis3d_left, AF_NONE, (void*) ID_VIEW3D_LEFT );
|
||||
|
||||
TOOL_ACTION EDA_3D_ACTIONS::viewBottom( TOOL_ACTION_ARGS()
|
||||
.Name( "3DViewer.Control.viewBottom" )
|
||||
.Scope( AS_ACTIVE )
|
||||
.DefaultHotkey( MD_SHIFT + 'Z' )
|
||||
.FriendlyName( _( "View Bottom" ) )
|
||||
.Icon( BITMAPS::axis3d_bottom )
|
||||
.Flags( AF_NONE )
|
||||
.Parameter( VIEW3D_TYPE::VIEW3D_BOTTOM ) );
|
||||
TOOL_ACTION EDA_3D_ACTIONS::viewRight( "3DViewer.Control.viewRight",
|
||||
AS_ACTIVE,
|
||||
'X', "",
|
||||
_( "View Right" ), _( "View Right" ),
|
||||
BITMAPS::axis3d_right, AF_NONE, (void*) ID_VIEW3D_RIGHT );
|
||||
|
||||
TOOL_ACTION EDA_3D_ACTIONS::noGrid( TOOL_ACTION_ARGS()
|
||||
.Name( "3DViewer.Control.noGrid" )
|
||||
.Scope( AS_GLOBAL )
|
||||
.FriendlyName( _( "No 3D Grid" ) )
|
||||
.Flags( AF_NONE )
|
||||
.Parameter( GRID3D_TYPE::NONE ) );
|
||||
TOOL_ACTION EDA_3D_ACTIONS::viewTop( "3DViewer.Control.viewTop",
|
||||
AS_ACTIVE,
|
||||
'Z', "",
|
||||
_( "View Top" ), _( "View Top" ),
|
||||
BITMAPS::axis3d_top, AF_NONE, (void*) ID_VIEW3D_TOP );
|
||||
|
||||
TOOL_ACTION EDA_3D_ACTIONS::show10mmGrid( TOOL_ACTION_ARGS()
|
||||
.Name( "3DViewer.Control.show10mmGrid" )
|
||||
.Scope( AS_GLOBAL )
|
||||
.FriendlyName( _( "3D Grid 10mm" ) )
|
||||
.Flags( AF_NONE )
|
||||
.Parameter( GRID3D_TYPE::GRID_10MM ) );
|
||||
TOOL_ACTION EDA_3D_ACTIONS::viewBottom( "3DViewer.Control.viewBottom",
|
||||
AS_ACTIVE,
|
||||
MD_SHIFT + 'Z', "",
|
||||
_( "View Bottom" ), _( "View Bottom" ),
|
||||
BITMAPS::axis3d_bottom, AF_NONE, (void*) ID_VIEW3D_BOTTOM );
|
||||
|
||||
TOOL_ACTION EDA_3D_ACTIONS::show5mmGrid( TOOL_ACTION_ARGS()
|
||||
.Name( "3DViewer.Control.show5mmGrid" )
|
||||
.Scope( AS_GLOBAL )
|
||||
.FriendlyName( _( "3D Grid 5mm" ) )
|
||||
.Flags( AF_NONE )
|
||||
.Parameter( GRID3D_TYPE::GRID_5MM ) );
|
||||
TOOL_ACTION EDA_3D_ACTIONS::noGrid( "3DViewer.Control.noGrid",
|
||||
AS_GLOBAL, 0, "",
|
||||
_( "No 3D Grid" ), _( "No 3D Grid" ),
|
||||
BITMAPS::INVALID_BITMAP, AF_NONE, (void*) GRID3D_TYPE::NONE );
|
||||
|
||||
TOOL_ACTION EDA_3D_ACTIONS::show2_5mmGrid( TOOL_ACTION_ARGS()
|
||||
.Name( "3DViewer.Control.show2_5mmGrid" )
|
||||
.Scope( AS_GLOBAL )
|
||||
.FriendlyName( _( "3D Grid 2.5mm" ) )
|
||||
.Flags( AF_NONE )
|
||||
.Parameter( GRID3D_TYPE::GRID_2P5MM ) );
|
||||
TOOL_ACTION EDA_3D_ACTIONS::show10mmGrid( "3DViewer.Control.show10mmGrid",
|
||||
AS_GLOBAL, 0, "",
|
||||
_( "3D Grid 10mm" ), _( "3D Grid 10mm" ),
|
||||
BITMAPS::INVALID_BITMAP, AF_NONE, (void*) GRID3D_TYPE::GRID_10MM );
|
||||
|
||||
TOOL_ACTION EDA_3D_ACTIONS::show1mmGrid( TOOL_ACTION_ARGS()
|
||||
.Name( "3DViewer.Control.show1mmGrid" )
|
||||
.Scope( AS_GLOBAL )
|
||||
.FriendlyName( _( "3D Grid 1mm" ) )
|
||||
.Flags( AF_NONE )
|
||||
.Parameter( GRID3D_TYPE::GRID_1MM ) );
|
||||
TOOL_ACTION EDA_3D_ACTIONS::show5mmGrid( "3DViewer.Control.show5mmGrid",
|
||||
AS_GLOBAL, 0, "",
|
||||
_( "3D Grid 5mm" ), _( "3D Grid 5mm" ),
|
||||
BITMAPS::INVALID_BITMAP, AF_NONE, (void*) GRID3D_TYPE::GRID_5MM );
|
||||
|
||||
TOOL_ACTION EDA_3D_ACTIONS::materialNormal( TOOL_ACTION_ARGS()
|
||||
.Name( "3DViewer.Control.materialNormal" )
|
||||
.Scope( AS_ACTIVE )
|
||||
.FriendlyName( _( "Render Realistic Materials" ) )
|
||||
.Tooltip( _( "Use all material properties from each 3D model file" ) )
|
||||
.Flags( AF_NONE )
|
||||
.Parameter( MATERIAL_MODE::NORMAL ) );
|
||||
TOOL_ACTION EDA_3D_ACTIONS::show2_5mmGrid( "3DViewer.Control.show2_5mmGrid",
|
||||
AS_GLOBAL, 0, "",
|
||||
_( "3D Grid 2.5mm" ), _( "3D Grid 2.5mm" ),
|
||||
BITMAPS::INVALID_BITMAP, AF_NONE, (void*) GRID3D_TYPE::GRID_2P5MM );
|
||||
|
||||
TOOL_ACTION EDA_3D_ACTIONS::materialDiffuse( TOOL_ACTION_ARGS()
|
||||
.Name( "3DViewer.Control.materialDiffuse" )
|
||||
.Scope( AS_ACTIVE )
|
||||
.FriendlyName( _( "Render Solid Colors" ) )
|
||||
.Tooltip( _( "Use only the diffuse color property from 3D model file" ) )
|
||||
.Flags( AF_NONE )
|
||||
.Parameter( MATERIAL_MODE::DIFFUSE_ONLY ) );
|
||||
TOOL_ACTION EDA_3D_ACTIONS::show1mmGrid( "3DViewer.Control.show1mmGrid",
|
||||
AS_GLOBAL, 0, "",
|
||||
_( "3D Grid 1mm" ), _( "3D Grid 1mm" ),
|
||||
BITMAPS::INVALID_BITMAP, AF_NONE, (void*) GRID3D_TYPE::GRID_1MM );
|
||||
|
||||
TOOL_ACTION EDA_3D_ACTIONS::materialCAD( TOOL_ACTION_ARGS()
|
||||
.Name( "3DViewer.Control.materialCAD" )
|
||||
.Scope( AS_ACTIVE )
|
||||
.FriendlyName( _( "Render CAD Colors" ) )
|
||||
.Tooltip( _( "Use a CAD color style based on the diffuse color of the material" ) )
|
||||
.Flags( AF_NONE )
|
||||
.Parameter( MATERIAL_MODE::CAD_MODE ) );
|
||||
TOOL_ACTION EDA_3D_ACTIONS::materialNormal( "3DViewer.Control.materialNormal",
|
||||
AS_ACTIVE,
|
||||
0, "",
|
||||
_( "Render Realistic Materials" ),
|
||||
_( "Use all material properties from each 3D model file" ),
|
||||
BITMAPS::INVALID_BITMAP, AF_NONE, (void*) MATERIAL_MODE::NORMAL );
|
||||
|
||||
TOOL_ACTION EDA_3D_ACTIONS::showTHT( TOOL_ACTION_ARGS()
|
||||
.Name( "3DViewer.Control.attributesTHT" )
|
||||
.Scope( AS_ACTIVE )
|
||||
.DefaultHotkey( 'T' )
|
||||
.FriendlyName( _( "Show Through Hole 3D Models" ) )
|
||||
.Tooltip( _( "Show 3D models for 'Through hole' type footprints" ) )
|
||||
.Icon( BITMAPS::show_tht )
|
||||
.Flags( AF_NONE ) );
|
||||
TOOL_ACTION EDA_3D_ACTIONS::materialDiffuse( "3DViewer.Control.materialDiffuse",
|
||||
AS_ACTIVE,
|
||||
0, "",
|
||||
_( "Render Solid Colors" ),
|
||||
_( "Use only the diffuse color property from model 3D model file" ),
|
||||
BITMAPS::INVALID_BITMAP, AF_NONE, (void*) MATERIAL_MODE::DIFFUSE_ONLY );
|
||||
|
||||
TOOL_ACTION EDA_3D_ACTIONS::showSMD( TOOL_ACTION_ARGS()
|
||||
.Name( "3DViewer.Control.attributesSMD" )
|
||||
.Scope( AS_ACTIVE )
|
||||
.DefaultHotkey( 'S' )
|
||||
.FriendlyName( _( "Show SMD 3D Models" ) )
|
||||
.Tooltip( _( "Show 3D models for 'Surface mount' type footprints" ) )
|
||||
.Icon( BITMAPS::show_smt )
|
||||
.Flags( AF_NONE ) );
|
||||
TOOL_ACTION EDA_3D_ACTIONS::materialCAD( "3DViewer.Control.materialCAD",
|
||||
AS_ACTIVE,
|
||||
0, "",
|
||||
_( "Render CAD Colors" ),
|
||||
_( "Use a CAD color style based on the diffuse color of the material" ),
|
||||
BITMAPS::INVALID_BITMAP, AF_NONE, (void*) MATERIAL_MODE::CAD_MODE );
|
||||
|
||||
TOOL_ACTION EDA_3D_ACTIONS::showVirtual( TOOL_ACTION_ARGS()
|
||||
.Name( "3DViewer.Control.attributesOther" )
|
||||
.Scope( AS_ACTIVE )
|
||||
.DefaultHotkey( 'V' )
|
||||
.FriendlyName( _( "Show Unspecified 3D Models" ) )
|
||||
.Tooltip( _( "Show 3D models for 'unspecified' type footprints" ) )
|
||||
.Icon( BITMAPS::show_other )
|
||||
.Flags( AF_NONE ) );
|
||||
TOOL_ACTION EDA_3D_ACTIONS::showTHT( "3DViewer.Control.attributesTHT",
|
||||
AS_ACTIVE,
|
||||
'T', "",
|
||||
_( "Toggle Through Hole 3D models" ),
|
||||
_( "Toggle 3D models for 'Through hole' type components" ),
|
||||
BITMAPS::show_tht, AF_NONE, (void*) FL_FP_ATTRIBUTES_NORMAL );
|
||||
|
||||
TOOL_ACTION EDA_3D_ACTIONS::showNotInPosFile( TOOL_ACTION_ARGS()
|
||||
.Name( "3DViewer.Control.attribute_not_in_posfile" )
|
||||
.Scope( AS_ACTIVE )
|
||||
.DefaultHotkey( 'P' )
|
||||
.FriendlyName( _( "Show 3D Models not in POS File" ) )
|
||||
.Tooltip( _( "Show 3D models even if not found in .pos file" ) )
|
||||
.Icon( BITMAPS::show_not_in_posfile )
|
||||
.Flags( AF_NONE ) );
|
||||
TOOL_ACTION EDA_3D_ACTIONS::showSMD( "3DViewer.Control.attributesSMD",
|
||||
AS_ACTIVE,
|
||||
'S', "",
|
||||
_( "Toggle SMD 3D models" ),
|
||||
_( "Toggle 3D models for 'Surface mount' type components" ),
|
||||
BITMAPS::show_smt, AF_NONE, (void*) FL_FP_ATTRIBUTES_NORMAL_INSERT );
|
||||
|
||||
TOOL_ACTION EDA_3D_ACTIONS::showDNP( TOOL_ACTION_ARGS()
|
||||
.Name( "3DViewer.Control.attribute_dnp" )
|
||||
.Scope( AS_ACTIVE )
|
||||
.DefaultHotkey( 'D' )
|
||||
.FriendlyName( _( "Show 3D Models marked DNP" ) )
|
||||
.Tooltip( _( "Show 3D models even if marked 'Do Not Place'" ) )
|
||||
.Icon( BITMAPS::show_dnp )
|
||||
.Flags( AF_NONE ) );
|
||||
TOOL_ACTION EDA_3D_ACTIONS::showVirtual( "3DViewer.Control.attributesOther",
|
||||
AS_ACTIVE,
|
||||
'V', "",
|
||||
_( "Toggle Other 3D models" ), _( "Toggle 3D models for 'Other' type components" ),
|
||||
BITMAPS::show_other, AF_NONE, (void*) FL_FP_ATTRIBUTES_VIRTUAL );
|
||||
|
||||
TOOL_ACTION EDA_3D_ACTIONS::showBBoxes( TOOL_ACTION_ARGS()
|
||||
.Name( "3DViewer.Control.showBoundingBoxes" )
|
||||
.Scope( AS_GLOBAL )
|
||||
.FriendlyName( _( "Show Model Bounding Boxes" ) )
|
||||
.Tooltip( _( "Show 3D model bounding boxes in realtime renderer" ) )
|
||||
.Icon( BITMAPS::ortho )
|
||||
.Flags( AF_NONE ) );
|
||||
TOOL_ACTION EDA_3D_ACTIONS::showBBoxes( "3DViewer.Control.showBoundingBoxes",
|
||||
AS_GLOBAL, 0, "",
|
||||
_( "Show Model Bounding Boxes" ), _( "Show Model Bounding Boxes" ),
|
||||
BITMAPS::ortho, AF_NONE, (void*) FL_RENDER_OPENGL_SHOW_MODEL_BBOX );
|
||||
|
||||
TOOL_ACTION EDA_3D_ACTIONS::showAxis( TOOL_ACTION_ARGS()
|
||||
.Name( "3DViewer.Control.showAxis" )
|
||||
.Scope( AS_GLOBAL )
|
||||
.FriendlyName( _( "Show 3D Axis" ) )
|
||||
.Icon( BITMAPS::axis3d_front )
|
||||
.Flags( AF_NONE ) );
|
||||
TOOL_ACTION EDA_3D_ACTIONS::toggleRealisticMode( "3DViewer.Control.toggleRealisticMode",
|
||||
AS_GLOBAL, 0, "",
|
||||
_( "Toggle realistic mode" ), _( "Toggle realistic mode" ),
|
||||
BITMAPS::INVALID_BITMAP, AF_NONE, (void*) FL_USE_REALISTIC_MODE );
|
||||
|
||||
TOOL_ACTION EDA_3D_ACTIONS::showLayersManager( TOOL_ACTION_ARGS()
|
||||
.Name( "3DViewer.Control.showLayersManager" )
|
||||
.Scope( AS_GLOBAL )
|
||||
.FriendlyName( _( "Show Appearance Manager" ) )
|
||||
.Tooltip( _( "Show/hide the appearance manager" ) )
|
||||
.Icon( BITMAPS::layers_manager ) );
|
||||
TOOL_ACTION EDA_3D_ACTIONS::toggleBoardBody( "3DViewer.Control.toggleBoardBody",
|
||||
AS_GLOBAL, 0, "",
|
||||
_( "Toggle board body display" ), _( "Toggle board body display" ),
|
||||
BITMAPS::INVALID_BITMAP, AF_NONE, (void*) FL_SHOW_BOARD_BODY );
|
||||
|
||||
TOOL_ACTION EDA_3D_ACTIONS::showAxis( "3DViewer.Control.showAxis",
|
||||
AS_GLOBAL, 0, "",
|
||||
_( "Show 3D Axis" ), _( "Show 3D Axis" ),
|
||||
BITMAPS::axis3d_front, AF_NONE, (void*) FL_AXIS );
|
||||
|
||||
TOOL_ACTION EDA_3D_ACTIONS::toggleZones( "3DViewer.Control.toggleZones",
|
||||
AS_GLOBAL, 0, "",
|
||||
_( "Toggle zone display" ), _( "Toggle zone display" ),
|
||||
BITMAPS::INVALID_BITMAP, AF_NONE, (void*) FL_ZONE );
|
||||
|
||||
TOOL_ACTION EDA_3D_ACTIONS::toggleAdhesive( "3DViewer.Control.toggleAdhesive",
|
||||
AS_GLOBAL, 0, "",
|
||||
_( "Toggle adhesive display" ), _( "Toggle display of adhesive layers" ),
|
||||
BITMAPS::INVALID_BITMAP, AF_NONE, (void*) FL_ADHESIVE );
|
||||
|
||||
TOOL_ACTION EDA_3D_ACTIONS::toggleSilk( "3DViewer.Control.toggleSilk",
|
||||
AS_GLOBAL, 0, "",
|
||||
_( "Toggle silkscreen display" ), _( "Toggle display of silkscreen layers" ),
|
||||
BITMAPS::INVALID_BITMAP, AF_NONE, (void*) FL_SILKSCREEN );
|
||||
|
||||
TOOL_ACTION EDA_3D_ACTIONS::toggleSolderMask( "3DViewer.Control.toggleSolderMask",
|
||||
AS_GLOBAL, 0, "",
|
||||
_( "Toggle solder mask display" ), _( "Toggle display of solder mask layers" ),
|
||||
BITMAPS::INVALID_BITMAP, AF_NONE, (void*) FL_SOLDERMASK );
|
||||
|
||||
TOOL_ACTION EDA_3D_ACTIONS::toggleSolderPaste( "3DViewer.Control.toggleSolderPaste",
|
||||
AS_GLOBAL, 0, "",
|
||||
_( "Toggle solder paste display" ), _( "Toggle display of solder paste layers" ),
|
||||
BITMAPS::INVALID_BITMAP, AF_NONE, (void*) FL_SOLDERPASTE );
|
||||
|
||||
TOOL_ACTION EDA_3D_ACTIONS::toggleComments( "3DViewer.Control.toggleComments",
|
||||
AS_GLOBAL, 0, "",
|
||||
_( "Toggle comments display" ), _( "Toggle display of comments and drawings layers" ),
|
||||
BITMAPS::INVALID_BITMAP, AF_NONE, (void*) FL_COMMENTS );
|
||||
|
||||
TOOL_ACTION EDA_3D_ACTIONS::toggleECO( "3DViewer.Control.toggleECO",
|
||||
AS_GLOBAL, 0, "",
|
||||
_( "Toggle ECO display" ), _( "Toggle display of ECO layers" ),
|
||||
BITMAPS::INVALID_BITMAP, AF_NONE, (void*) FL_ECO );
|
||||
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
/*
|
||||
* This program source code file is part of KiCad, a free EDA CAD application.
|
||||
*
|
||||
* Copyright (C) 2013-2023 CERN
|
||||
* Copyright (C) 2020-2023 KiCad Developers, see AUTHORS.txt for contributors.
|
||||
* Copyright (C) 2013-2016 CERN
|
||||
* Copyright (C) 2020-2021 KiCad Developers, see AUTHORS.txt for contributors.
|
||||
* @author Maciej Suminski <maciej.suminski@cern.ch>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
@@ -54,6 +54,7 @@ public:
|
||||
static TOOL_ACTION moveUp;
|
||||
static TOOL_ACTION moveDown;
|
||||
static TOOL_ACTION homeView;
|
||||
static TOOL_ACTION resetView;
|
||||
static TOOL_ACTION flipView;
|
||||
static TOOL_ACTION toggleOrtho;
|
||||
|
||||
@@ -77,11 +78,17 @@ public:
|
||||
static TOOL_ACTION showTHT;
|
||||
static TOOL_ACTION showSMD;
|
||||
static TOOL_ACTION showVirtual;
|
||||
static TOOL_ACTION showNotInPosFile;
|
||||
static TOOL_ACTION showDNP;
|
||||
static TOOL_ACTION showBBoxes;
|
||||
static TOOL_ACTION toggleRealisticMode;
|
||||
static TOOL_ACTION toggleBoardBody;
|
||||
static TOOL_ACTION showAxis;
|
||||
static TOOL_ACTION showLayersManager;
|
||||
static TOOL_ACTION toggleZones;
|
||||
static TOOL_ACTION toggleAdhesive;
|
||||
static TOOL_ACTION toggleSilk;
|
||||
static TOOL_ACTION toggleSolderMask;
|
||||
static TOOL_ACTION toggleSolderPaste;
|
||||
static TOOL_ACTION toggleComments;
|
||||
static TOOL_ACTION toggleECO;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
@@ -30,15 +30,43 @@
|
||||
using namespace std::placeholders;
|
||||
|
||||
|
||||
SELECTION_CONDITION EDA_3D_CONDITIONS::MaterialMode( MATERIAL_MODE aMaterial )
|
||||
{
|
||||
return std::bind( &EDA_3D_CONDITIONS::materialModeFunction, _1, m_adapter, aMaterial );
|
||||
}
|
||||
|
||||
|
||||
SELECTION_CONDITION EDA_3D_CONDITIONS::Flag( DISPLAY3D_FLG aFlag )
|
||||
{
|
||||
return std::bind( &EDA_3D_CONDITIONS::flagFunction, _1, m_adapter, aFlag );
|
||||
}
|
||||
|
||||
|
||||
SELECTION_CONDITION EDA_3D_CONDITIONS::GridSize( GRID3D_TYPE aGridSize )
|
||||
{
|
||||
return std::bind( &EDA_3D_CONDITIONS::gridSizeFunction, _1, m_adapter, aGridSize );
|
||||
}
|
||||
|
||||
|
||||
bool EDA_3D_CONDITIONS::materialModeFunction( const SELECTION& aSelection,
|
||||
BOARD_ADAPTER* aAdapter,
|
||||
MATERIAL_MODE aMaterial )
|
||||
{
|
||||
return aAdapter->GetMaterialMode() == aMaterial;
|
||||
}
|
||||
|
||||
|
||||
bool EDA_3D_CONDITIONS::flagFunction( const SELECTION& aSelection,
|
||||
BOARD_ADAPTER* aAdapter,
|
||||
DISPLAY3D_FLG aFlag )
|
||||
{
|
||||
return aAdapter->GetFlag( aFlag );
|
||||
}
|
||||
|
||||
|
||||
bool EDA_3D_CONDITIONS::gridSizeFunction( const SELECTION& aSelection,
|
||||
BOARD_ADAPTER* aAdapter,
|
||||
GRID3D_TYPE aGridSize )
|
||||
{
|
||||
return aAdapter->m_Cfg->m_Render.grid_type == aGridSize;
|
||||
return aAdapter->GetGridType() == aGridSize;
|
||||
}
|
||||
|
||||
@@ -44,6 +44,24 @@ public:
|
||||
m_adapter( aAdapter )
|
||||
{}
|
||||
|
||||
/**
|
||||
* Creates a functor that tests if a specific material mode is active.
|
||||
*
|
||||
* @param aAdapter is the board adapter the setting is in
|
||||
* @param aMaterial is the material mode to test for.
|
||||
* @return Functor testing if a material mode is active.
|
||||
*/
|
||||
SELECTION_CONDITION MaterialMode( MATERIAL_MODE aMaterial );
|
||||
|
||||
/**
|
||||
* Creates a functor that tests if the board adapter has a flag set currently.
|
||||
*
|
||||
* @param aAdapter is the board adapter the setting is in
|
||||
* @param aFlag is the flag to test for.
|
||||
* @return Functor testing if the flag is set.
|
||||
*/
|
||||
SELECTION_CONDITION Flag( DISPLAY3D_FLG aFlag );
|
||||
|
||||
/**
|
||||
* Creates a functor that tests the current grid size.
|
||||
*
|
||||
@@ -54,6 +72,14 @@ public:
|
||||
SELECTION_CONDITION GridSize( GRID3D_TYPE aGridSize );
|
||||
|
||||
private:
|
||||
///< Helper function used by MaterialMode()
|
||||
static bool materialModeFunction( const SELECTION& aSelection, BOARD_ADAPTER* aAdapter,
|
||||
MATERIAL_MODE aMaterial );
|
||||
|
||||
///< Helper function used by Flag()
|
||||
static bool flagFunction( const SELECTION& aSelection, BOARD_ADAPTER* aAdapter,
|
||||
DISPLAY3D_FLG aFlag );
|
||||
|
||||
///< Helper function used by GridDize()
|
||||
static bool gridSizeFunction( const SELECTION& aSelection, BOARD_ADAPTER* aAdapter,
|
||||
GRID3D_TYPE aGridSize );
|
||||
|
||||
@@ -1,8 +1,7 @@
|
||||
/*
|
||||
* This program source code file is part of KiCad, a free EDA CAD application.
|
||||
*
|
||||
* Copyright (C) 2023 CERN
|
||||
* Copyright (C) 2020-2023 KiCad Developers, see AUTHORS.txt for contributors.
|
||||
* Copyright (C) 2020 KiCad Developers, see AUTHORS.txt for contributors.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
@@ -29,9 +28,7 @@
|
||||
#include <id.h>
|
||||
#include <kiface_base.h>
|
||||
#include <tools/eda_3d_controller.h>
|
||||
#include <tools/eda_3d_actions.h>
|
||||
#include <dialogs/panel_preview_3d_model.h>
|
||||
#include <dialogs/appearance_controls_3D.h>
|
||||
#include "eda_3d_actions.h"
|
||||
#include <3d_rendering/opengl/render_3d_opengl.h>
|
||||
|
||||
|
||||
@@ -81,7 +78,8 @@ void EDA_3D_CONTROLLER::Reset( RESET_REASON aReason )
|
||||
{
|
||||
m_canvas = dynamic_cast<EDA_3D_CANVAS*>( holder->GetToolCanvas() );
|
||||
|
||||
EDA_3D_BOARD_HOLDER* holder3d = dynamic_cast<EDA_3D_BOARD_HOLDER*>( holder );
|
||||
EDA_3D_BOARD_HOLDER* holder3d =
|
||||
dynamic_cast<EDA_3D_BOARD_HOLDER*>( holder );
|
||||
|
||||
wxASSERT( holder3d );
|
||||
|
||||
@@ -115,33 +113,10 @@ int EDA_3D_CONTROLLER::Main( const TOOL_EVENT& aEvent )
|
||||
// Main loop: keep receiving events
|
||||
while( TOOL_EVENT* evt = Wait() )
|
||||
{
|
||||
if( evt->IsCancelInteractive() )
|
||||
{
|
||||
wxWindow* canvas = m_toolMgr->GetToolHolder()->GetToolCanvas();
|
||||
wxWindow* topLevelParent = wxGetTopLevelParent( canvas->GetParent() );
|
||||
|
||||
if( topLevelParent && dynamic_cast<DIALOG_SHIM*>( topLevelParent ) )
|
||||
{
|
||||
DIALOG_SHIM* dialog = static_cast<DIALOG_SHIM*>( topLevelParent );
|
||||
|
||||
if( dialog->IsQuasiModal() )
|
||||
dialog->EndQuasiModal( wxID_CANCEL );
|
||||
else
|
||||
dialog->EndModal( wxID_CANCEL );
|
||||
}
|
||||
else
|
||||
{
|
||||
evt->SetPassEvent();
|
||||
}
|
||||
}
|
||||
else if( evt->IsClick( BUT_RIGHT ) )
|
||||
{
|
||||
if( evt->IsClick( BUT_RIGHT ) )
|
||||
m_menu.ShowContextMenu();
|
||||
}
|
||||
else
|
||||
{
|
||||
evt->SetPassEvent();
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
@@ -150,7 +125,7 @@ int EDA_3D_CONTROLLER::Main( const TOOL_EVENT& aEvent )
|
||||
|
||||
int EDA_3D_CONTROLLER::ViewControl( const TOOL_EVENT& aEvent )
|
||||
{
|
||||
m_canvas->SetView3D( aEvent.Parameter<VIEW3D_TYPE>() );
|
||||
m_canvas->SetView3D( aEvent.Parameter<intptr_t>() );
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -158,13 +133,13 @@ int EDA_3D_CONTROLLER::ViewControl( const TOOL_EVENT& aEvent )
|
||||
|
||||
int EDA_3D_CONTROLLER::PanControl( const TOOL_EVENT& aEvent )
|
||||
{
|
||||
switch( aEvent.Parameter<ACTIONS::CURSOR_EVENT_TYPE>() )
|
||||
switch( aEvent.Parameter<intptr_t>() )
|
||||
{
|
||||
case ACTIONS::CURSOR_UP: m_canvas->SetView3D( VIEW3D_TYPE::VIEW3D_PAN_UP ); break;
|
||||
case ACTIONS::CURSOR_DOWN: m_canvas->SetView3D( VIEW3D_TYPE::VIEW3D_PAN_DOWN ); break;
|
||||
case ACTIONS::CURSOR_LEFT: m_canvas->SetView3D( VIEW3D_TYPE::VIEW3D_PAN_LEFT ); break;
|
||||
case ACTIONS::CURSOR_RIGHT: m_canvas->SetView3D( VIEW3D_TYPE::VIEW3D_PAN_RIGHT ); break;
|
||||
default: wxFAIL; break;
|
||||
case ACTIONS::CURSOR_UP: m_canvas->SetView3D( WXK_UP ); break;
|
||||
case ACTIONS::CURSOR_DOWN: m_canvas->SetView3D( WXK_DOWN ); break;
|
||||
case ACTIONS::CURSOR_LEFT: m_canvas->SetView3D( WXK_LEFT ); break;
|
||||
case ACTIONS::CURSOR_RIGHT: m_canvas->SetView3D( WXK_RIGHT ); break;
|
||||
default: wxFAIL; break;
|
||||
}
|
||||
|
||||
return 0;
|
||||
@@ -177,17 +152,17 @@ int EDA_3D_CONTROLLER::RotateView( const TOOL_EVENT& aEvent )
|
||||
|
||||
switch( aEvent.Parameter<ROTATION_DIR>() )
|
||||
{
|
||||
case ROTATION_DIR::X_CW: m_camera->RotateX( -rotIncrement ); break;
|
||||
case ROTATION_DIR::X_CW: m_camera->RotateX( -rotIncrement ); break;
|
||||
case ROTATION_DIR::X_CCW: m_camera->RotateX( rotIncrement ); break;
|
||||
/// Y rotations are backward b/c the RHR has Y pointing into the screen
|
||||
case ROTATION_DIR::Y_CW: m_camera->RotateY( rotIncrement ); break;
|
||||
case ROTATION_DIR::Y_CCW: m_camera->RotateY( -rotIncrement ); break;
|
||||
case ROTATION_DIR::Z_CW: m_camera->RotateZ( -rotIncrement ); break;
|
||||
case ROTATION_DIR::Y_CW: m_camera->RotateY( rotIncrement ); break;
|
||||
case ROTATION_DIR::Y_CCW: m_camera->RotateY( -rotIncrement ); break;
|
||||
case ROTATION_DIR::Z_CW: m_camera->RotateZ( -rotIncrement ); break;
|
||||
case ROTATION_DIR::Z_CCW: m_camera->RotateZ( rotIncrement ); break;
|
||||
default: wxFAIL; break;
|
||||
default: wxFAIL; break;
|
||||
}
|
||||
|
||||
if( m_boardAdapter->m_Cfg->m_Render.engine == RENDER_ENGINE::OPENGL )
|
||||
if( m_boardAdapter->GetRenderEngine() == RENDER_ENGINE::OPENGL )
|
||||
m_canvas->Request_refresh();
|
||||
else
|
||||
m_canvas->RenderRaytracingRequest();
|
||||
@@ -198,7 +173,9 @@ int EDA_3D_CONTROLLER::RotateView( const TOOL_EVENT& aEvent )
|
||||
|
||||
int EDA_3D_CONTROLLER::SetMaterial( const TOOL_EVENT& aEvent )
|
||||
{
|
||||
m_boardAdapter->m_Cfg->m_Render.material_mode = aEvent.Parameter<MATERIAL_MODE>();
|
||||
MATERIAL_MODE mode = aEvent.Parameter<MATERIAL_MODE>();
|
||||
|
||||
m_boardAdapter->SetMaterialMode( mode );
|
||||
|
||||
if( auto* viewer = dynamic_cast<EDA_3D_VIEWER_FRAME*>( m_toolMgr->GetToolHolder() ) )
|
||||
viewer->NewDisplay( true );
|
||||
@@ -213,7 +190,7 @@ int EDA_3D_CONTROLLER::ToggleOrtho( const TOOL_EVENT& aEvent )
|
||||
{
|
||||
m_camera->ToggleProjection();
|
||||
|
||||
if( m_boardAdapter->m_Cfg->m_Render.engine == RENDER_ENGINE::OPENGL )
|
||||
if( m_boardAdapter->GetRenderEngine() == RENDER_ENGINE::OPENGL )
|
||||
m_canvas->Request_refresh();
|
||||
else
|
||||
m_canvas->RenderRaytracingRequest();
|
||||
@@ -221,46 +198,57 @@ int EDA_3D_CONTROLLER::ToggleOrtho( const TOOL_EVENT& aEvent )
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
int EDA_3D_CONTROLLER::ToggleVisibility( const TOOL_EVENT& aEvent )
|
||||
{
|
||||
std::bitset<LAYER_3D_END> visibilityFlags = m_boardAdapter->GetVisibleLayers();
|
||||
APPEARANCE_CONTROLS_3D* appearanceManager = nullptr;
|
||||
DISPLAY3D_FLG flag = aEvent.Parameter<DISPLAY3D_FLG>();
|
||||
|
||||
auto flipLayer =
|
||||
[&]( int layer )
|
||||
{
|
||||
appearanceManager->OnLayerVisibilityChanged( layer, !visibilityFlags.test( layer ) );
|
||||
};
|
||||
m_boardAdapter->SetFlag( flag, !m_boardAdapter->GetFlag( flag ) );
|
||||
|
||||
if( auto viewer = dynamic_cast<EDA_3D_VIEWER_FRAME*>( m_toolMgr->GetToolHolder() ) )
|
||||
appearanceManager = viewer->GetAppearanceManager();
|
||||
|
||||
if( appearanceManager )
|
||||
switch( flag )
|
||||
{
|
||||
if( aEvent.IsAction( &EDA_3D_ACTIONS::showTHT ) )
|
||||
flipLayer( LAYER_3D_TH_MODELS );
|
||||
else if( aEvent.IsAction( &EDA_3D_ACTIONS::showSMD ) )
|
||||
flipLayer( LAYER_3D_SMD_MODELS );
|
||||
else if( aEvent.IsAction( &EDA_3D_ACTIONS::showVirtual ) )
|
||||
flipLayer( LAYER_3D_VIRTUAL_MODELS );
|
||||
else if( aEvent.IsAction( &EDA_3D_ACTIONS::showNotInPosFile ) )
|
||||
flipLayer( LAYER_3D_MODELS_NOT_IN_POS );
|
||||
else if( aEvent.IsAction( &EDA_3D_ACTIONS::showDNP ) )
|
||||
flipLayer( LAYER_3D_MODELS_MARKED_DNP );
|
||||
else if( aEvent.IsAction( &EDA_3D_ACTIONS::showAxis ) )
|
||||
flipLayer( LAYER_3D_AXES );
|
||||
else if( aEvent.IsAction( &EDA_3D_ACTIONS::showBBoxes ) )
|
||||
flipLayer( LAYER_3D_BOUNDING_BOXES );
|
||||
// These commands do not request a 3D scene rebuild (and do not exist in raytracing):
|
||||
case FL_RENDER_OPENGL_SHOW_MODEL_BBOX:
|
||||
case FL_AXIS:
|
||||
m_canvas->Request_refresh();
|
||||
break;
|
||||
|
||||
// These commands do not request a 3D scene rebuild and exist in raytracing:
|
||||
case FL_RENDER_RAYTRACING_SHADOWS:
|
||||
case FL_RENDER_RAYTRACING_REFRACTIONS:
|
||||
case FL_RENDER_RAYTRACING_REFLECTIONS:
|
||||
case FL_RENDER_RAYTRACING_ANTI_ALIASING:
|
||||
if( m_boardAdapter->GetRenderEngine() == RENDER_ENGINE::OPENGL )
|
||||
m_canvas->Request_refresh();
|
||||
else
|
||||
m_canvas->RenderRaytracingRequest();
|
||||
|
||||
break;
|
||||
|
||||
case FL_FP_ATTRIBUTES_NORMAL:
|
||||
case FL_FP_ATTRIBUTES_NORMAL_INSERT:
|
||||
case FL_FP_ATTRIBUTES_VIRTUAL:
|
||||
// Loading 3D shapes can be needed if not yet loaded
|
||||
if( m_boardAdapter->GetRenderEngine() == RENDER_ENGINE::OPENGL )
|
||||
{
|
||||
RENDER_3D_OPENGL* render = static_cast<RENDER_3D_OPENGL*>( m_canvas->GetCurrentRender() );
|
||||
render->Load3dModelsIfNeeded();
|
||||
m_canvas->Request_refresh();
|
||||
}
|
||||
else
|
||||
m_canvas->RenderRaytracingRequest();
|
||||
|
||||
break;
|
||||
|
||||
default:
|
||||
{
|
||||
if( auto viewer = dynamic_cast<EDA_3D_VIEWER_FRAME*>( m_toolMgr->GetToolHolder() ) )
|
||||
viewer->NewDisplay( true );
|
||||
else
|
||||
m_canvas->Request_refresh();
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
int EDA_3D_CONTROLLER::ToggleLayersManager( const TOOL_EVENT& aEvent )
|
||||
{
|
||||
if( auto* viewer = dynamic_cast<EDA_3D_VIEWER_FRAME*>( m_toolMgr->GetToolHolder() ) )
|
||||
viewer->ToggleAppearanceManager();
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -268,7 +256,8 @@ int EDA_3D_CONTROLLER::ToggleLayersManager( const TOOL_EVENT& aEvent )
|
||||
|
||||
int EDA_3D_CONTROLLER::On3DGridSelection( const TOOL_EVENT& aEvent )
|
||||
{
|
||||
m_boardAdapter->m_Cfg->m_Render.grid_type = aEvent.Parameter<GRID3D_TYPE>();
|
||||
GRID3D_TYPE grid = aEvent.Parameter<GRID3D_TYPE>();
|
||||
m_boardAdapter->SetGridType( grid );
|
||||
|
||||
if( m_canvas )
|
||||
m_canvas->Request_refresh();
|
||||
@@ -302,7 +291,7 @@ int EDA_3D_CONTROLLER::doZoomInOut( bool aDirection, bool aCenterOnCursor )
|
||||
{
|
||||
if( m_canvas )
|
||||
{
|
||||
m_canvas->SetView3D( aDirection ? VIEW3D_TYPE::VIEW3D_ZOOM_IN : VIEW3D_TYPE::VIEW3D_ZOOM_OUT );
|
||||
m_canvas->SetView3D( aDirection ? WXK_F1 : WXK_F2 );
|
||||
m_canvas->DisplayStatus();
|
||||
}
|
||||
|
||||
@@ -314,7 +303,7 @@ int EDA_3D_CONTROLLER::ZoomFitScreen( const TOOL_EVENT& aEvent )
|
||||
{
|
||||
if( m_canvas )
|
||||
{
|
||||
m_canvas->SetView3D( VIEW3D_TYPE::VIEW3D_FIT_SCREEN );
|
||||
m_canvas->SetView3D( WXK_HOME );
|
||||
m_canvas->DisplayStatus();
|
||||
}
|
||||
|
||||
@@ -346,6 +335,7 @@ void EDA_3D_CONTROLLER::setTransitions()
|
||||
Go( &EDA_3D_CONTROLLER::ViewControl, EDA_3D_ACTIONS::viewBack.MakeEvent() );
|
||||
Go( &EDA_3D_CONTROLLER::ViewControl, EDA_3D_ACTIONS::pivotCenter.MakeEvent() );
|
||||
Go( &EDA_3D_CONTROLLER::ViewControl, EDA_3D_ACTIONS::homeView.MakeEvent() );
|
||||
Go( &EDA_3D_CONTROLLER::ViewControl, EDA_3D_ACTIONS::resetView.MakeEvent() );
|
||||
Go( &EDA_3D_CONTROLLER::ViewControl, EDA_3D_ACTIONS::flipView.MakeEvent() );
|
||||
Go( &EDA_3D_CONTROLLER::RotateView, EDA_3D_ACTIONS::rotateXCW.MakeEvent() );
|
||||
Go( &EDA_3D_CONTROLLER::RotateView, EDA_3D_ACTIONS::rotateXCCW.MakeEvent() );
|
||||
@@ -382,9 +372,17 @@ void EDA_3D_CONTROLLER::setTransitions()
|
||||
Go( &EDA_3D_CONTROLLER::ToggleVisibility, EDA_3D_ACTIONS::showTHT.MakeEvent() );
|
||||
Go( &EDA_3D_CONTROLLER::ToggleVisibility, EDA_3D_ACTIONS::showSMD.MakeEvent() );
|
||||
Go( &EDA_3D_CONTROLLER::ToggleVisibility, EDA_3D_ACTIONS::showVirtual.MakeEvent() );
|
||||
Go( &EDA_3D_CONTROLLER::ToggleVisibility, EDA_3D_ACTIONS::showNotInPosFile.MakeEvent() );
|
||||
Go( &EDA_3D_CONTROLLER::ToggleVisibility, EDA_3D_ACTIONS::showDNP.MakeEvent() );
|
||||
Go( &EDA_3D_CONTROLLER::ToggleLayersManager,EDA_3D_ACTIONS::showLayersManager.MakeEvent() );
|
||||
Go( &EDA_3D_CONTROLLER::ToggleVisibility, EDA_3D_ACTIONS::showBBoxes.MakeEvent() );
|
||||
Go( &EDA_3D_CONTROLLER::ToggleVisibility, EDA_3D_ACTIONS::toggleRealisticMode.MakeEvent() );
|
||||
Go( &EDA_3D_CONTROLLER::ToggleVisibility, EDA_3D_ACTIONS::toggleBoardBody.MakeEvent() );
|
||||
Go( &EDA_3D_CONTROLLER::ToggleVisibility, EDA_3D_ACTIONS::showAxis.MakeEvent() );
|
||||
Go( &EDA_3D_CONTROLLER::ToggleVisibility, EDA_3D_ACTIONS::toggleZones.MakeEvent() );
|
||||
Go( &EDA_3D_CONTROLLER::ToggleVisibility, EDA_3D_ACTIONS::toggleAdhesive.MakeEvent() );
|
||||
Go( &EDA_3D_CONTROLLER::ToggleVisibility, EDA_3D_ACTIONS::toggleSilk.MakeEvent() );
|
||||
Go( &EDA_3D_CONTROLLER::ToggleVisibility, EDA_3D_ACTIONS::toggleSolderMask.MakeEvent() );
|
||||
Go( &EDA_3D_CONTROLLER::ToggleVisibility, EDA_3D_ACTIONS::toggleSolderPaste.MakeEvent() );
|
||||
Go( &EDA_3D_CONTROLLER::ToggleVisibility, EDA_3D_ACTIONS::toggleComments.MakeEvent() );
|
||||
Go( &EDA_3D_CONTROLLER::ToggleVisibility, EDA_3D_ACTIONS::toggleECO.MakeEvent() );
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -1,8 +1,7 @@
|
||||
/*
|
||||
* This program source code file is part of KiCad, a free EDA CAD application.
|
||||
*
|
||||
* Copyright (C) 2023 CERN
|
||||
* Copyright (C) 2020-2023 KiCad Developers, see AUTHORS.txt for contributors.
|
||||
* Copyright (C) 2020-2021 KiCad Developers, see AUTHORS.txt for contributors.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
@@ -96,7 +95,6 @@ public:
|
||||
|
||||
int ToggleOrtho( const TOOL_EVENT& aEvent );
|
||||
int ToggleVisibility( const TOOL_EVENT& aEvent );
|
||||
int ToggleLayersManager( const TOOL_EVENT& aEvent );
|
||||
|
||||
private:
|
||||
///< Sets up handlers for various events.
|
||||
|
||||
+10
-19
@@ -1,21 +1,5 @@
|
||||
/*
|
||||
* This program source code file is part of KiCad, a free EDA CAD application.
|
||||
*
|
||||
* Copyright (C) 2023 <author>
|
||||
* Copyright (C) 2023 KiCad Developers, see AUTHORS.txt for contributors.
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License as published by the
|
||||
* Free Software Foundation, either version 3 of the License, or (at your
|
||||
* option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but
|
||||
* WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along
|
||||
* with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
/**
|
||||
* @file 3d_viewer_id.h
|
||||
*/
|
||||
|
||||
/**
|
||||
@@ -27,7 +11,6 @@
|
||||
* However the number of IDs should be < ROOM_FOR_3D_VIEWER, defined in id.h
|
||||
* Please change the value of ROOM_FOR_3D_VIEWER if too small.
|
||||
*/
|
||||
#pragma once
|
||||
|
||||
#include <id.h> // Generic Id.
|
||||
|
||||
@@ -35,6 +18,14 @@ enum id_3dview_frm
|
||||
{
|
||||
ID_START_COMMAND_3D = ID_KICAD_3D_VIEWER_START,
|
||||
ID_RELOAD3D_BOARD,
|
||||
ID_VIEW3D_TOP,
|
||||
ID_VIEW3D_BOTTOM,
|
||||
ID_VIEW3D_LEFT,
|
||||
ID_VIEW3D_RIGHT,
|
||||
ID_VIEW3D_FRONT,
|
||||
ID_VIEW3D_BACK,
|
||||
ID_VIEW3D_RESET,
|
||||
ID_VIEW3D_FLIP,
|
||||
ID_TOOL_SCREENCOPY_TOCLIBBOARD,
|
||||
|
||||
ID_MENU_SCREENCOPY_PNG,
|
||||
|
||||
+27
-29
@@ -1,5 +1,5 @@
|
||||
#add_definitions(-DPRINT_STATISTICS_3D_VIEWER)
|
||||
add_compile_definitions( PCBNEW )
|
||||
add_definitions(-DPCBNEW)
|
||||
|
||||
include_directories(BEFORE ${INC_BEFORE})
|
||||
include_directories(
|
||||
@@ -11,11 +11,11 @@ include_directories(
|
||||
3d_viewer
|
||||
${CMAKE_SOURCE_DIR}
|
||||
${CMAKE_SOURCE_DIR}/include/gal/opengl
|
||||
${CMAKE_SOURCE_DIR}/common/dialogs
|
||||
${INC_AFTER}
|
||||
)
|
||||
|
||||
# directories
|
||||
set( DIR_DLG dialogs )
|
||||
set( DIR_RAY 3d_rendering/raytracing )
|
||||
set( DIR_RAY_ACC ${DIR_RAY}/accelerators )
|
||||
set( DIR_RAY_2D ${DIR_RAY}/shapes2D )
|
||||
@@ -27,9 +27,15 @@ set(3D-VIEWER_SRCS
|
||||
${DIR_3D_PLUGINS}/3d/pluginldr3D.cpp
|
||||
3d_cache/3d_cache.cpp
|
||||
3d_cache/3d_plugin_manager.cpp
|
||||
${DIR_DLG}/3d_cache_dialogs.cpp
|
||||
${DIR_DLG}/dialog_select_3d_model_base.cpp
|
||||
${DIR_DLG}/dialog_select_3d_model.cpp
|
||||
${DIR_DLG}/panel_preview_3d_model_base.cpp
|
||||
${DIR_DLG}/panel_preview_3d_model.cpp
|
||||
3d_canvas/board_adapter.cpp
|
||||
3d_canvas/create_layer_items.cpp
|
||||
3d_canvas/create_3Dgraphic_brd_items.cpp
|
||||
3d_canvas/create_layer_poly.cpp
|
||||
3d_canvas/eda_3d_canvas.cpp
|
||||
3d_canvas/eda_3d_canvas_pivot.cpp
|
||||
3d_model_viewer/eda_3d_model_viewer.cpp
|
||||
@@ -71,6 +77,7 @@ set(3D-VIEWER_SRCS
|
||||
${DIR_RAY_3D}/triangle_3d.cpp
|
||||
3d_rendering/buffers_debug.cpp
|
||||
3d_rendering/render_3d_base.cpp
|
||||
3d_rendering/camera.cpp
|
||||
3d_rendering/color_rgb.cpp
|
||||
3d_rendering/image.cpp
|
||||
3d_rendering/post_shader.cpp
|
||||
@@ -80,6 +87,14 @@ set(3D-VIEWER_SRCS
|
||||
3d_rendering/trackball.cpp
|
||||
3d_viewer/3d_menubar.cpp
|
||||
3d_viewer/3d_toolbar.cpp
|
||||
dialogs/panel_3D_colors.cpp
|
||||
dialogs/panel_3D_colors_base.cpp
|
||||
dialogs/panel_3D_display_options.cpp
|
||||
dialogs/panel_3D_display_options_base.cpp
|
||||
dialogs/panel_3D_opengl_options.cpp
|
||||
dialogs/panel_3D_opengl_options_base.cpp
|
||||
dialogs/panel_3D_raytracing_options.cpp
|
||||
dialogs/panel_3D_raytracing_options_base.cpp
|
||||
3d_viewer/tools/eda_3d_actions.cpp
|
||||
3d_viewer/tools/eda_3d_conditions.cpp
|
||||
3d_viewer/tools/eda_3d_controller.cpp
|
||||
@@ -89,38 +104,21 @@ set(3D-VIEWER_SRCS
|
||||
common_ogl/ogl_utils.cpp
|
||||
3d_fastmath.cpp
|
||||
3d_math.cpp
|
||||
dialogs/3d_cache_dialogs.cpp
|
||||
dialogs/appearance_controls_3D.cpp
|
||||
dialogs/appearance_controls_3D_base.cpp
|
||||
dialogs/dialog_select_3d_model_base.cpp
|
||||
dialogs/dialog_select_3d_model.cpp
|
||||
dialogs/panel_preview_3d_model_base.cpp
|
||||
dialogs/panel_preview_3d_model.cpp
|
||||
dialogs/panel_3D_display_options.cpp
|
||||
dialogs/panel_3D_display_options_base.cpp
|
||||
dialogs/panel_3D_opengl_options.cpp
|
||||
dialogs/panel_3D_opengl_options_base.cpp
|
||||
dialogs/panel_3D_raytracing_options.cpp
|
||||
dialogs/panel_3D_raytracing_options_base.cpp
|
||||
)
|
||||
|
||||
add_library(3d-viewer STATIC ${3D-VIEWER_SRCS})
|
||||
add_dependencies( 3d-viewer pcbcommon )
|
||||
|
||||
target_link_libraries( 3d-viewer
|
||||
PRIVATE
|
||||
gal
|
||||
kimath
|
||||
core
|
||||
common
|
||||
nlohmann_json
|
||||
Boost::headers
|
||||
${wxWidgets_LIBRARIES}
|
||||
${OPENGL_LIBRARIES}
|
||||
kicad_3dsg )
|
||||
gal
|
||||
kimath
|
||||
${Boost_LIBRARIES}
|
||||
${wxWidgets_LIBRARIES}
|
||||
${OPENGL_LIBRARIES}
|
||||
kicad_3dsg )
|
||||
|
||||
target_include_directories( 3d-viewer PRIVATE
|
||||
$<TARGET_PROPERTY:nlohmann_json,INTERFACE_INCLUDE_DIRECTORIES>
|
||||
)
|
||||
|
||||
add_subdirectory( 3d_cache )
|
||||
|
||||
message( STATUS "Including 3Dconnexion SpaceMouse navigation support in 3d-viewer" )
|
||||
add_subdirectory( 3d_navlib )
|
||||
target_link_libraries( 3d-viewer PRIVATE 3d-viewer_navlib)
|
||||
|
||||
@@ -33,11 +33,10 @@
|
||||
/// Anti-aliasing options
|
||||
enum class ANTIALIASING_MODE
|
||||
{
|
||||
// Do not change these numbers, they are stored in the config file
|
||||
AA_NONE = 0,
|
||||
AA_2X = 1,
|
||||
AA_4X = 2,
|
||||
AA_8X = 3
|
||||
AA_NONE,
|
||||
AA_2X,
|
||||
AA_4X,
|
||||
AA_8X
|
||||
};
|
||||
|
||||
/**
|
||||
|
||||
@@ -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,8 +1,7 @@
|
||||
Credits
|
||||
=======
|
||||
|
||||
The 3D-viewer contains parts, source code or adaptations or implementations that should give the following
|
||||
aknowledgments:
|
||||
The 3D-viewer contains parts, source code or adaptations or implementations that should give the following aknowledge:
|
||||
|
||||
|
||||
cbvh_packet_traversal.cpp
|
||||
|
||||
@@ -45,7 +45,7 @@ bool S3D::Select3DModel( wxWindow* aParent, S3D_CACHE* aCache, wxString& prevMod
|
||||
|
||||
bool S3D::Configure3DPaths( wxWindow* aParent, FILENAME_RESOLVER* aResolver )
|
||||
{
|
||||
DIALOG_CONFIGURE_PATHS dlg( aParent );
|
||||
DIALOG_CONFIGURE_PATHS dlg( aParent, aResolver );
|
||||
|
||||
// Use QuasiModal so that HTML help window will work
|
||||
return( dlg.ShowQuasiModal() == wxID_OK );
|
||||
|
||||
@@ -1,978 +0,0 @@
|
||||
/*
|
||||
* This program source code file is part of KiCad, a free EDA CAD application.
|
||||
*
|
||||
* Copyright (C) 2023 CERN
|
||||
* Copyright (C) 2023-2024 KiCad Developers, see AUTHORS.txt for contributors.
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License as published by the
|
||||
* Free Software Foundation, either version 3 of the License, or (at your
|
||||
* option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but
|
||||
* WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along
|
||||
* with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include <dialogs/appearance_controls_3D.h>
|
||||
|
||||
#include <bitmaps.h>
|
||||
#include <confirm.h>
|
||||
#include <pgm_base.h>
|
||||
#include <dpi_scaling_common.h>
|
||||
#include <eda_list_dialog.h>
|
||||
#include <pcb_display_options.h>
|
||||
#include <eda_3d_viewer_frame.h>
|
||||
#include <pcbnew_settings.h>
|
||||
#include <project.h>
|
||||
#include <settings/settings_manager.h>
|
||||
#include <settings/color_settings.h>
|
||||
#include <tool/tool_manager.h>
|
||||
#include <tools/pcb_actions.h>
|
||||
#include <tools/eda_3d_actions.h>
|
||||
#include <widgets/bitmap_toggle.h>
|
||||
#include <widgets/color_swatch.h>
|
||||
#include <widgets/grid_bitmap_toggle.h>
|
||||
#include <dialogs/eda_view_switcher.h>
|
||||
#include <wx/bmpbuttn.h>
|
||||
#include <wx/sizer.h>
|
||||
#include <wx/textdlg.h>
|
||||
#include <wx/checkbox.h>
|
||||
|
||||
#include <../3d_rendering/opengl/render_3d_opengl.h>
|
||||
|
||||
|
||||
#define RR APPEARANCE_CONTROLS_3D::APPEARANCE_SETTING_3D // Render Row abbreviation to reduce source width
|
||||
|
||||
/// Template for object appearance settings
|
||||
const APPEARANCE_CONTROLS_3D::APPEARANCE_SETTING_3D APPEARANCE_CONTROLS_3D::s_layerSettings[] = {
|
||||
|
||||
// text id tooltip
|
||||
RR( _HKI( "Board Body" ), LAYER_3D_BOARD, _HKI( "Show board body" ) ),
|
||||
RR( _HKI( "F.Cu" ), LAYER_3D_COPPER_TOP, _HKI( "Show front copper / surface finish color" ) ),
|
||||
RR( _HKI( "B.Cu" ), LAYER_3D_COPPER_BOTTOM, _HKI( "Show back copper / surface finish color" ) ),
|
||||
RR( _HKI( "Adhesive" ), LAYER_3D_ADHESIVE, _HKI( "Show adhesive" ) ),
|
||||
RR( _HKI( "Solder Paste" ), LAYER_3D_SOLDERPASTE, _HKI( "Show solder paste" ) ),
|
||||
RR( _HKI( "F.Silkscreen" ), LAYER_3D_SILKSCREEN_TOP, _HKI( "Show front silkscreen" ) ),
|
||||
RR( _HKI( "B.Silkscreen" ), LAYER_3D_SILKSCREEN_BOTTOM, _HKI( "Show back silkscreen" ) ),
|
||||
RR( _HKI( "F.Mask" ), LAYER_3D_SOLDERMASK_TOP, _HKI( "Show front solder mask" ) ),
|
||||
RR( _HKI( "B.Mask" ), LAYER_3D_SOLDERMASK_BOTTOM, _HKI( "Show back solder mask" ) ),
|
||||
RR( _HKI( "User.Drawings" ), LAYER_3D_USER_DRAWINGS, _HKI( "Show user drawings layer" ) ),
|
||||
RR( _HKI( "User.Comments" ), LAYER_3D_USER_COMMENTS, _HKI( "Show user comments layer" ) ),
|
||||
RR( _HKI( "User.Eco1" ), LAYER_3D_USER_ECO1, _HKI( "Show user ECO1 layer" ) ),
|
||||
RR( _HKI( "User.Eco2" ), LAYER_3D_USER_ECO2, _HKI( "Show user ECO2 layer" ) ),
|
||||
RR(),
|
||||
RR( _HKI( "Through-hole Models" ), LAYER_3D_TH_MODELS, EDA_3D_ACTIONS::showTHT ),
|
||||
RR( _HKI( "SMD Models" ), LAYER_3D_SMD_MODELS, EDA_3D_ACTIONS::showSMD ),
|
||||
RR( _HKI( "Virtual Models" ), LAYER_3D_VIRTUAL_MODELS, EDA_3D_ACTIONS::showVirtual ),
|
||||
RR( _HKI( "Models not in POS File" ), LAYER_3D_MODELS_NOT_IN_POS, EDA_3D_ACTIONS::showNotInPosFile ),
|
||||
RR( _HKI( "Models marked DNP" ), LAYER_3D_MODELS_MARKED_DNP, EDA_3D_ACTIONS::showDNP ),
|
||||
RR( _HKI( "Model Bounding Boxes" ), LAYER_3D_BOUNDING_BOXES, EDA_3D_ACTIONS::showBBoxes ),
|
||||
RR(),
|
||||
RR( _HKI( "Values" ), LAYER_FP_VALUES, _HKI( "Show footprint values" ) ),
|
||||
RR( _HKI( "References" ), LAYER_FP_REFERENCES, _HKI( "Show footprint references" ) ),
|
||||
RR( _HKI( "Footprint Text" ), LAYER_FP_TEXT, _HKI( "Show all footprint text" ) ),
|
||||
RR( _HKI( "Off-board Silkscreen" ), LAYER_3D_OFF_BOARD_SILK, _HKI( "Do not clip silk layers to board outline" ) ),
|
||||
RR(),
|
||||
RR( _HKI( "3D Axis" ), LAYER_3D_AXES, EDA_3D_ACTIONS::showAxis ),
|
||||
RR( _HKI( "Background Start" ), LAYER_3D_BACKGROUND_TOP, _HKI( "Background gradient start color" ) ),
|
||||
RR( _HKI( "Background End" ), LAYER_3D_BACKGROUND_BOTTOM, _HKI( "Background gradient end color" ) ),
|
||||
};
|
||||
|
||||
// The list of IDs that can have colors coming from the board stackup, and cannot be
|
||||
// modified if use colors from stackup is activated
|
||||
static std::vector<int> inStackupColors{ LAYER_3D_BOARD, LAYER_3D_COPPER_TOP,
|
||||
LAYER_3D_COPPER_BOTTOM, LAYER_3D_SOLDERPASTE,
|
||||
LAYER_3D_SILKSCREEN_TOP, LAYER_3D_SILKSCREEN_BOTTOM,
|
||||
LAYER_3D_SOLDERMASK_TOP, LAYER_3D_SOLDERMASK_BOTTOM
|
||||
};
|
||||
|
||||
APPEARANCE_CONTROLS_3D::APPEARANCE_CONTROLS_3D( EDA_3D_VIEWER_FRAME* aParent,
|
||||
wxWindow* aFocusOwner ) :
|
||||
APPEARANCE_CONTROLS_3D_BASE( aParent ),
|
||||
m_frame( aParent ),
|
||||
m_focusOwner( aFocusOwner ),
|
||||
m_lastSelectedViewport( nullptr )
|
||||
{
|
||||
DPI_SCALING_COMMON dpi( nullptr, m_frame );
|
||||
|
||||
int indicatorSize = ConvertDialogToPixels( wxSize( 6, 6 ) ).x / dpi.GetContentScaleFactor();
|
||||
int screenHeight = wxSystemSettings::GetMetric( wxSYS_SCREEN_Y );
|
||||
m_pointSize = wxSystemSettings::GetFont( wxSYS_DEFAULT_GUI_FONT ).GetPointSize();
|
||||
|
||||
m_layerPanelColour = m_panelLayers->GetBackgroundColour().ChangeLightness( 110 );
|
||||
SetBorders( true, false, false, false );
|
||||
|
||||
m_layersOuterSizer = new wxBoxSizer( wxVERTICAL );
|
||||
m_windowLayers->SetSizer( m_layersOuterSizer );
|
||||
m_windowLayers->SetScrollRate( 0, 5 );
|
||||
m_windowLayers->Bind( wxEVT_SET_FOCUS, &APPEARANCE_CONTROLS_3D::OnSetFocus, this );
|
||||
|
||||
m_envOuterSizer = new wxBoxSizer( wxVERTICAL );
|
||||
|
||||
wxFont infoFont = KIUI::GetInfoFont( this );
|
||||
m_panelLayers->SetFont( infoFont );
|
||||
m_windowLayers->SetFont( infoFont );
|
||||
m_presetsLabel->SetFont( infoFont );
|
||||
m_viewportsLabel->SetFont( infoFont );
|
||||
|
||||
// Create display options
|
||||
m_cbUseBoardStackupColors = new wxCheckBox( m_panelLayers, wxID_ANY,
|
||||
_( "Use board stackup colors" ) );
|
||||
m_cbUseBoardStackupColors->SetFont( infoFont );
|
||||
|
||||
m_cbUseBoardStackupColors->Bind( wxEVT_CHECKBOX,
|
||||
[this]( wxCommandEvent& aEvent )
|
||||
{
|
||||
EDA_3D_VIEWER_SETTINGS* cfg = m_frame->GetAdapter().m_Cfg;
|
||||
cfg->m_UseStackupColors = aEvent.IsChecked();
|
||||
|
||||
UpdateLayerCtls();
|
||||
syncLayerPresetSelection();
|
||||
m_frame->NewDisplay( true );
|
||||
} );
|
||||
|
||||
m_panelLayersSizer->Add( m_cbUseBoardStackupColors, 0, wxEXPAND | wxTOP | wxLEFT | wxRIGHT, 7 );
|
||||
|
||||
m_cbLayerPresets->SetToolTip( wxString::Format( _( "Save and restore color and visibility "
|
||||
"combinations.\n"
|
||||
"Use %s+Tab to activate selector.\n"
|
||||
"Successive Tabs while holding %s down will "
|
||||
"cycle through presets in the popup." ),
|
||||
KeyNameFromKeyCode( PRESET_SWITCH_KEY ),
|
||||
KeyNameFromKeyCode( PRESET_SWITCH_KEY ) ) );
|
||||
|
||||
m_cbViewports->SetToolTip( wxString::Format( _( "Save and restore camera position and zoom.\n"
|
||||
"Use %s+Tab to activate selector.\n"
|
||||
"Successive Tabs while holding %s down will "
|
||||
"cycle through viewports in the popup." ),
|
||||
KeyNameFromKeyCode( VIEWPORT_SWITCH_KEY ),
|
||||
KeyNameFromKeyCode( VIEWPORT_SWITCH_KEY ) ) );
|
||||
|
||||
if( screenHeight <= 900 && m_pointSize >= indicatorSize )
|
||||
m_pointSize = m_pointSize * 8 / 10;
|
||||
|
||||
m_cbLayerPresets->Bind( wxEVT_CHOICE, &APPEARANCE_CONTROLS_3D::onLayerPresetChanged, this );
|
||||
|
||||
m_toggleGridRenderer = new GRID_BITMAP_TOGGLE_RENDERER( KiBitmap( BITMAPS::visibility ),
|
||||
KiBitmap( BITMAPS::visibility_off ) );
|
||||
}
|
||||
|
||||
|
||||
APPEARANCE_CONTROLS_3D::~APPEARANCE_CONTROLS_3D()
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
wxSize APPEARANCE_CONTROLS_3D::GetBestSize() const
|
||||
{
|
||||
DPI_SCALING_COMMON dpi( nullptr, m_frame );
|
||||
wxSize size( 220 * dpi.GetScaleFactor(), 480 * dpi.GetScaleFactor() );
|
||||
return size;
|
||||
}
|
||||
|
||||
|
||||
void APPEARANCE_CONTROLS_3D::OnSetFocus( wxFocusEvent& aEvent )
|
||||
{
|
||||
#ifdef __WXMSW__
|
||||
// In wxMSW, buttons won't process events unless they have focus, so we'll let it take the
|
||||
// focus and give it back to the parent in the button event handler.
|
||||
if( wxBitmapButton* btn = dynamic_cast<wxBitmapButton*>( aEvent.GetEventObject() ) )
|
||||
{
|
||||
wxCommandEvent evt( wxEVT_BUTTON );
|
||||
wxPostEvent( btn, evt );
|
||||
}
|
||||
#endif
|
||||
|
||||
passOnFocus();
|
||||
aEvent.Skip();
|
||||
}
|
||||
|
||||
|
||||
void APPEARANCE_CONTROLS_3D::OnSize( wxSizeEvent& aEvent )
|
||||
{
|
||||
aEvent.Skip();
|
||||
}
|
||||
|
||||
|
||||
void APPEARANCE_CONTROLS_3D::OnLanguageChanged()
|
||||
{
|
||||
Freeze();
|
||||
|
||||
rebuildLayers();
|
||||
m_cbUseBoardStackupColors->SetLabel( _( "Use board stackup colors" ) );
|
||||
rebuildLayerPresetsWidget();
|
||||
rebuildViewportsWidget();
|
||||
|
||||
Thaw();
|
||||
Refresh();
|
||||
}
|
||||
|
||||
|
||||
void APPEARANCE_CONTROLS_3D::OnDarkModeToggle()
|
||||
{
|
||||
// This is essentially a list of hacks because DarkMode isn't yet implemented inside
|
||||
// wxWidgets.
|
||||
//
|
||||
// The individual wxPanels, COLOR_SWATCHes and GRID_CELL_COLOR_RENDERERs should really be
|
||||
// overriding some virtual method or responding to some wxWidgets event so that the parent
|
||||
// doesn't have to know what it contains. But, that's not where we are, so... :shrug:
|
||||
|
||||
m_layerPanelColour = m_panelLayers->GetBackgroundColour().ChangeLightness( 110 );
|
||||
|
||||
m_windowLayers->SetBackgroundColour( m_layerPanelColour );
|
||||
|
||||
for( wxSizerItem* child : m_layersOuterSizer->GetChildren() )
|
||||
{
|
||||
if( child && child->GetWindow() )
|
||||
child->GetWindow()->SetBackgroundColour( m_layerPanelColour );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void APPEARANCE_CONTROLS_3D::CommonSettingsChanged()
|
||||
{
|
||||
OnLanguageChanged();
|
||||
|
||||
UpdateLayerCtls();
|
||||
syncLayerPresetSelection();
|
||||
}
|
||||
|
||||
|
||||
void APPEARANCE_CONTROLS_3D::ApplyLayerPreset( const wxString& aPresetName )
|
||||
{
|
||||
if( aPresetName == FOLLOW_PCB || aPresetName == FOLLOW_PLOT_SETTINGS )
|
||||
{
|
||||
m_frame->GetAdapter().m_Cfg->m_CurrentPreset = aPresetName;
|
||||
UpdateLayerCtls();
|
||||
m_frame->NewDisplay( true );
|
||||
}
|
||||
else if( LAYER_PRESET_3D* preset = m_frame->GetAdapter().m_Cfg->FindPreset( aPresetName ) )
|
||||
{
|
||||
doApplyLayerPreset( *preset );
|
||||
}
|
||||
|
||||
// Move to front of MRU list
|
||||
if( m_presetMRU.Index( aPresetName ) != wxNOT_FOUND )
|
||||
m_presetMRU.Remove( aPresetName );
|
||||
|
||||
m_presetMRU.Insert( aPresetName, 0 );
|
||||
|
||||
updateLayerPresetWidget( aPresetName );
|
||||
}
|
||||
|
||||
|
||||
std::vector<VIEWPORT3D> APPEARANCE_CONTROLS_3D::GetUserViewports() const
|
||||
{
|
||||
std::vector<VIEWPORT3D> ret;
|
||||
|
||||
for( const auto& [name, viewport] : m_viewports )
|
||||
ret.emplace_back( viewport );
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
void APPEARANCE_CONTROLS_3D::SetUserViewports( std::vector<VIEWPORT3D>& aViewportList )
|
||||
{
|
||||
m_viewports.clear();
|
||||
|
||||
for( const VIEWPORT3D& viewport : aViewportList )
|
||||
{
|
||||
if( m_viewports.count( viewport.name ) )
|
||||
continue;
|
||||
|
||||
m_viewports[viewport.name] = viewport;
|
||||
|
||||
m_viewportMRU.Add( viewport.name );
|
||||
}
|
||||
|
||||
rebuildViewportsWidget();
|
||||
|
||||
// Now is as good a time as any to initialize the layer presets as well.
|
||||
rebuildLayerPresetsWidget();
|
||||
|
||||
m_presetMRU.Add( FOLLOW_PCB );
|
||||
m_presetMRU.Add( FOLLOW_PLOT_SETTINGS );
|
||||
|
||||
for( const LAYER_PRESET_3D& preset : m_frame->GetAdapter().m_Cfg->m_LayerPresets )
|
||||
m_presetMRU.Add( preset.name );
|
||||
}
|
||||
|
||||
|
||||
void APPEARANCE_CONTROLS_3D::ApplyViewport( const wxString& aViewportName )
|
||||
{
|
||||
int idx = m_cbViewports->FindString( aViewportName );
|
||||
|
||||
if( idx >= 0 && idx < (int)m_cbViewports->GetCount() - 3 /* separator */ )
|
||||
{
|
||||
m_cbViewports->SetSelection( idx );
|
||||
m_lastSelectedViewport = static_cast<VIEWPORT3D*>( m_cbViewports->GetClientData( idx ) );
|
||||
}
|
||||
else
|
||||
{
|
||||
m_cbViewports->SetSelection( m_cbViewports->GetCount() - 3 ); // separator
|
||||
m_lastSelectedViewport = nullptr;
|
||||
}
|
||||
|
||||
if( m_lastSelectedViewport )
|
||||
doApplyViewport( *m_lastSelectedViewport );
|
||||
}
|
||||
|
||||
|
||||
void APPEARANCE_CONTROLS_3D::OnLayerVisibilityChanged( int aLayer, bool isVisible )
|
||||
{
|
||||
std::bitset<LAYER_3D_END> visibleLayers = m_frame->GetAdapter().GetVisibleLayers();
|
||||
const std::map<int, COLOR4D>& colors = m_frame->GetAdapter().GetLayerColors();
|
||||
bool killFollow = false;
|
||||
bool doFastRefresh = false; // true to just refresh the display
|
||||
|
||||
// Special-case controls
|
||||
switch( aLayer )
|
||||
{
|
||||
case LAYER_FP_TEXT:
|
||||
// Because Footprint Text is a meta-control that also can disable values/references,
|
||||
// drag them along here so that the user is less likely to be confused.
|
||||
if( !isVisible )
|
||||
{
|
||||
visibleLayers.set( LAYER_FP_REFERENCES, false );
|
||||
visibleLayers.set( LAYER_FP_VALUES, false );
|
||||
}
|
||||
|
||||
visibleLayers.set( LAYER_FP_TEXT, isVisible );
|
||||
killFollow = true;
|
||||
break;
|
||||
|
||||
case LAYER_FP_REFERENCES:
|
||||
case LAYER_FP_VALUES:
|
||||
// In case that user changes Footprint Value/References when the Footprint Text
|
||||
// meta-control is disabled, we should put it back on.
|
||||
if( isVisible )
|
||||
visibleLayers.set( LAYER_FP_TEXT, true );
|
||||
|
||||
visibleLayers.set( aLayer, isVisible );
|
||||
killFollow = true;
|
||||
break;
|
||||
|
||||
case LAYER_3D_BOARD:
|
||||
case LAYER_3D_COPPER_TOP:
|
||||
case LAYER_3D_COPPER_BOTTOM:
|
||||
case LAYER_3D_SILKSCREEN_BOTTOM:
|
||||
case LAYER_3D_SILKSCREEN_TOP:
|
||||
case LAYER_3D_SOLDERMASK_BOTTOM:
|
||||
case LAYER_3D_SOLDERMASK_TOP:
|
||||
case LAYER_3D_SOLDERPASTE:
|
||||
case LAYER_3D_ADHESIVE:
|
||||
case LAYER_3D_USER_COMMENTS:
|
||||
case LAYER_3D_USER_DRAWINGS:
|
||||
case LAYER_3D_USER_ECO1:
|
||||
case LAYER_3D_USER_ECO2:
|
||||
visibleLayers.set( aLayer, isVisible );
|
||||
killFollow = true;
|
||||
break;
|
||||
|
||||
case LAYER_3D_TH_MODELS:
|
||||
case LAYER_3D_SMD_MODELS:
|
||||
case LAYER_3D_VIRTUAL_MODELS:
|
||||
case LAYER_3D_MODELS_NOT_IN_POS:
|
||||
case LAYER_3D_MODELS_MARKED_DNP:
|
||||
doFastRefresh = true;
|
||||
visibleLayers.set( aLayer, isVisible );
|
||||
break;
|
||||
|
||||
default:
|
||||
visibleLayers.set( aLayer, isVisible );
|
||||
break;
|
||||
}
|
||||
|
||||
m_frame->GetAdapter().SetVisibleLayers( visibleLayers );
|
||||
m_frame->GetAdapter().SetLayerColors( colors );
|
||||
|
||||
const wxString& currentPreset = m_frame->GetAdapter().m_Cfg->m_CurrentPreset;
|
||||
|
||||
if( ( currentPreset != FOLLOW_PCB && currentPreset != FOLLOW_PLOT_SETTINGS ) || killFollow )
|
||||
syncLayerPresetSelection();
|
||||
|
||||
UpdateLayerCtls();
|
||||
|
||||
if( doFastRefresh && m_frame->GetAdapter().m_Cfg->m_Render.engine == RENDER_ENGINE::OPENGL )
|
||||
{
|
||||
RENDER_3D_OPENGL* renderer =
|
||||
static_cast<RENDER_3D_OPENGL*>( m_frame->GetCanvas()->GetCurrentRender() );
|
||||
renderer->Load3dModelsIfNeeded();
|
||||
m_frame->GetCanvas()->Request_refresh();
|
||||
}
|
||||
else
|
||||
{
|
||||
m_frame->NewDisplay( true );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void APPEARANCE_CONTROLS_3D::onColorSwatchChanged( COLOR_SWATCH* aSwatch )
|
||||
{
|
||||
std::bitset<LAYER_3D_END> visibleLayers = m_frame->GetAdapter().GetVisibleLayers();
|
||||
std::map<int, COLOR4D> colors = m_frame->GetAdapter().GetLayerColors();
|
||||
|
||||
m_frame->GetAdapter().SetVisibleLayers( visibleLayers );
|
||||
m_frame->GetAdapter().SetLayerColors( colors );
|
||||
|
||||
int layer = aSwatch->GetId();
|
||||
COLOR4D newColor = aSwatch->GetSwatchColor();
|
||||
|
||||
colors[ layer ] = newColor;
|
||||
|
||||
if( layer == LAYER_3D_COPPER_TOP )
|
||||
colors[ LAYER_3D_COPPER_BOTTOM ] = newColor;
|
||||
else if( layer == LAYER_3D_COPPER_BOTTOM )
|
||||
colors[ LAYER_3D_COPPER_TOP ] = newColor;
|
||||
|
||||
m_frame->GetAdapter().SetLayerColors( colors );
|
||||
|
||||
syncLayerPresetSelection();
|
||||
|
||||
m_frame->NewDisplay( true );
|
||||
}
|
||||
|
||||
|
||||
void APPEARANCE_CONTROLS_3D::rebuildLayers()
|
||||
{
|
||||
int swatchWidth = m_windowLayers->ConvertDialogToPixels( wxSize( 8, 0 ) ).x;
|
||||
|
||||
std::bitset<LAYER_3D_END> visibleLayers = m_frame->GetAdapter().GetVisibleLayers();
|
||||
std::map<int, COLOR4D> colors = m_frame->GetAdapter().GetLayerColors();
|
||||
std::map<int, COLOR4D> defaultColors = m_frame->GetAdapter().GetDefaultColors();
|
||||
|
||||
m_layerSettings.clear();
|
||||
m_layersOuterSizer->Clear( true );
|
||||
m_layersOuterSizer->AddSpacer( 5 );
|
||||
|
||||
m_envOuterSizer->Clear( true );
|
||||
|
||||
auto appendLayer =
|
||||
[&]( const std::unique_ptr<APPEARANCE_SETTING_3D>& aSetting )
|
||||
{
|
||||
wxBoxSizer* sizer = new wxBoxSizer( wxHORIZONTAL );
|
||||
int layer = aSetting->m_Id;
|
||||
|
||||
aSetting->m_Visible = visibleLayers.test( layer );
|
||||
|
||||
if( colors.count( layer ) )
|
||||
{
|
||||
COLOR_SWATCH* swatch = new COLOR_SWATCH( m_windowLayers, colors[ layer ], layer,
|
||||
COLOR4D::WHITE, defaultColors[ layer ],
|
||||
SWATCH_SMALL );
|
||||
swatch->SetToolTip( _( "Left double click or middle click to change color" ) );
|
||||
|
||||
swatch->SetReadOnlyCallback(
|
||||
[this]()
|
||||
{
|
||||
WX_INFOBAR* infobar = m_frame->GetInfoBar();
|
||||
|
||||
infobar->RemoveAllButtons();
|
||||
infobar->AddCloseButton();
|
||||
|
||||
infobar->ShowMessageFor( _( "Uncheck 'Use board stackup colors' to "
|
||||
"allow color editing." ),
|
||||
10000, wxICON_INFORMATION );
|
||||
} );
|
||||
|
||||
sizer->Add( swatch, 0, wxALIGN_CENTER_VERTICAL, 0 );
|
||||
aSetting->m_Ctl_color = swatch;
|
||||
|
||||
swatch->Bind( COLOR_SWATCH_CHANGED,
|
||||
[this]( wxCommandEvent& event )
|
||||
{
|
||||
auto swatch = static_cast<COLOR_SWATCH*>( event.GetEventObject() );
|
||||
onColorSwatchChanged( swatch );
|
||||
|
||||
passOnFocus();
|
||||
} );
|
||||
}
|
||||
else
|
||||
{
|
||||
sizer->AddSpacer( swatchWidth );
|
||||
}
|
||||
|
||||
sizer->AddSpacer( 5 );
|
||||
|
||||
wxStaticText* label = new wxStaticText( m_windowLayers, layer, aSetting->GetLabel() );
|
||||
label->Wrap( -1 );
|
||||
label->SetToolTip( aSetting->GetTooltip() );
|
||||
|
||||
if( layer == LAYER_3D_BACKGROUND_TOP || layer == LAYER_3D_BACKGROUND_BOTTOM )
|
||||
{
|
||||
sizer->AddSpacer( swatchWidth );
|
||||
}
|
||||
else
|
||||
{
|
||||
BITMAP_TOGGLE* btn_visible = new BITMAP_TOGGLE( m_windowLayers, layer,
|
||||
KiBitmap( BITMAPS::visibility ),
|
||||
KiBitmap( BITMAPS::visibility_off ),
|
||||
aSetting->m_Visible );
|
||||
|
||||
btn_visible->Bind( TOGGLE_CHANGED,
|
||||
[this]( wxCommandEvent& aEvent )
|
||||
{
|
||||
int id = static_cast<wxWindow*>( aEvent.GetEventObject() )->GetId();
|
||||
bool isVisible = aEvent.GetInt();
|
||||
OnLayerVisibilityChanged( id, isVisible );
|
||||
|
||||
passOnFocus();
|
||||
} );
|
||||
|
||||
wxString tip;
|
||||
tip.Printf( _( "Show or hide %s" ), aSetting->GetLabel().Lower() );
|
||||
btn_visible->SetToolTip( tip );
|
||||
|
||||
aSetting->m_Ctl_visibility = btn_visible;
|
||||
sizer->Add( btn_visible, 0, wxALIGN_CENTER_VERTICAL, 0 );
|
||||
}
|
||||
|
||||
sizer->AddSpacer( 5 );
|
||||
sizer->Add( label, 0, wxALIGN_CENTER_VERTICAL, 0 );
|
||||
|
||||
m_layersOuterSizer->Add( sizer, 0, wxEXPAND | wxLEFT | wxRIGHT, 5 );
|
||||
m_layersOuterSizer->AddSpacer( 2 );
|
||||
};
|
||||
|
||||
for( const APPEARANCE_SETTING_3D& s_setting : s_layerSettings )
|
||||
{
|
||||
m_layerSettings.emplace_back( std::make_unique<APPEARANCE_SETTING_3D>( s_setting ) );
|
||||
std::unique_ptr<APPEARANCE_SETTING_3D>& setting = m_layerSettings.back();
|
||||
|
||||
if( setting->m_Spacer )
|
||||
m_layersOuterSizer->AddSpacer( m_pointSize );
|
||||
else
|
||||
appendLayer( setting );
|
||||
|
||||
m_layerSettingsMap[setting->m_Id] = setting.get();
|
||||
}
|
||||
|
||||
m_sizerOuter->Layout();
|
||||
}
|
||||
|
||||
|
||||
void APPEARANCE_CONTROLS_3D::UpdateLayerCtls()
|
||||
{
|
||||
EDA_3D_VIEWER_SETTINGS* cfg = m_frame->GetAdapter().m_Cfg;
|
||||
std::bitset<LAYER_3D_END> visibleLayers = m_frame->GetAdapter().GetVisibleLayers();
|
||||
std::map<int, COLOR4D> colors = m_frame->GetAdapter().GetLayerColors();
|
||||
|
||||
for( std::unique_ptr<APPEARANCE_SETTING_3D>& setting : m_layerSettings )
|
||||
{
|
||||
if( setting->m_Spacer )
|
||||
continue;
|
||||
|
||||
if( setting->m_Ctl_visibility )
|
||||
setting->m_Ctl_visibility->SetValue( visibleLayers.test( setting->m_Id ) );
|
||||
|
||||
if( setting->m_Ctl_color )
|
||||
{
|
||||
setting->m_Ctl_color->SetSwatchColor( colors[ setting->m_Id ], false );
|
||||
|
||||
// if cfg->m_UseStackupColors is set, board colors cannot be modified locally, but
|
||||
// other colors can be
|
||||
if( std::find( inStackupColors.begin(), inStackupColors.end(), setting->m_Id )
|
||||
!= inStackupColors.end() )
|
||||
{
|
||||
if( cfg )
|
||||
setting->m_Ctl_color->SetReadOnly( cfg->m_UseStackupColors );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if( cfg )
|
||||
m_cbUseBoardStackupColors->SetValue( cfg->m_UseStackupColors );
|
||||
}
|
||||
|
||||
|
||||
void APPEARANCE_CONTROLS_3D::rebuildLayerPresetsWidget()
|
||||
{
|
||||
m_presetsLabel->SetLabel( wxString::Format( _( "Presets (%s+Tab):" ),
|
||||
KeyNameFromKeyCode( PRESET_SWITCH_KEY ) ) );
|
||||
|
||||
m_cbLayerPresets->Clear();
|
||||
|
||||
// Build the layers preset list.
|
||||
|
||||
m_cbLayerPresets->Append( _( "Follow PCB Editor" ) );
|
||||
m_cbLayerPresets->Append( _( "Follow PCB Plot Settings" ) );
|
||||
|
||||
for( const LAYER_PRESET_3D& preset : m_frame->GetAdapter().m_Cfg->m_LayerPresets )
|
||||
m_cbLayerPresets->Append( preset.name );
|
||||
|
||||
m_cbLayerPresets->Append( wxT( "---" ) );
|
||||
m_cbLayerPresets->Append( _( "Save preset..." ) );
|
||||
m_cbLayerPresets->Append( _( "Delete preset..." ) );
|
||||
|
||||
updateLayerPresetWidget( m_frame->GetAdapter().m_Cfg->m_CurrentPreset );
|
||||
}
|
||||
|
||||
|
||||
void APPEARANCE_CONTROLS_3D::syncLayerPresetSelection()
|
||||
{
|
||||
m_frame->GetAdapter().m_Cfg->m_CurrentPreset = wxEmptyString;
|
||||
|
||||
std::vector<LAYER_PRESET_3D>& presets = m_frame->GetAdapter().m_Cfg->m_LayerPresets;
|
||||
std::bitset<LAYER_3D_END> visibleLayers = m_frame->GetAdapter().GetVisibleLayers();
|
||||
std::map<int, COLOR4D> colors = m_frame->GetAdapter().GetLayerColors();
|
||||
|
||||
auto it = std::find_if(
|
||||
presets.begin(), presets.end(),
|
||||
[&]( const LAYER_PRESET_3D& aPreset )
|
||||
{
|
||||
if( aPreset.name.Lower() == _( "legacy colors" )
|
||||
&& m_cbUseBoardStackupColors->GetValue() )
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
for( int layer = LAYER_3D_BOARD; layer < LAYER_3D_END; ++layer )
|
||||
{
|
||||
if( aPreset.layers.test( layer ) != visibleLayers.test( layer ) )
|
||||
return false;
|
||||
}
|
||||
|
||||
for( int layer : { LAYER_FP_REFERENCES, LAYER_FP_VALUES, LAYER_FP_TEXT } )
|
||||
{
|
||||
if( aPreset.layers.test( layer ) != visibleLayers.test( layer ) )
|
||||
return false;
|
||||
}
|
||||
|
||||
for( int layer = LAYER_3D_START + 1; layer < LAYER_3D_END; ++layer )
|
||||
{
|
||||
auto it1 = aPreset.colors.find( layer );
|
||||
auto it2 = colors.find( layer );
|
||||
|
||||
if( it1 != aPreset.colors.end() && it2 != colors.end() && *it1 != *it2 )
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
} );
|
||||
|
||||
if( it != presets.end() )
|
||||
{
|
||||
m_frame->GetAdapter().m_Cfg->m_CurrentPreset = it->name;
|
||||
m_cbLayerPresets->SetStringSelection( it->name );
|
||||
}
|
||||
else
|
||||
{
|
||||
m_cbLayerPresets->SetSelection( m_cbLayerPresets->GetCount() - 3 ); // separator
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void APPEARANCE_CONTROLS_3D::updateLayerPresetWidget( const wxString& aName )
|
||||
{
|
||||
if( aName == FOLLOW_PCB )
|
||||
m_cbLayerPresets->SetSelection( 0 );
|
||||
else if( aName == FOLLOW_PLOT_SETTINGS )
|
||||
m_cbLayerPresets->SetSelection( 1 );
|
||||
else if( !m_cbLayerPresets->SetStringSelection( aName ) )
|
||||
m_cbLayerPresets->SetSelection( m_cbLayerPresets->GetCount() - 3 ); // separator
|
||||
}
|
||||
|
||||
|
||||
void APPEARANCE_CONTROLS_3D::onLayerPresetChanged( wxCommandEvent& aEvent )
|
||||
{
|
||||
EDA_3D_VIEWER_SETTINGS* cfg = m_frame->GetAdapter().m_Cfg;
|
||||
int count = m_cbLayerPresets->GetCount();
|
||||
int index = m_cbLayerPresets->GetSelection();
|
||||
wxString name;
|
||||
|
||||
auto resetSelection =
|
||||
[&]()
|
||||
{
|
||||
updateLayerPresetWidget( cfg->m_CurrentPreset );
|
||||
};
|
||||
|
||||
if( index == 0 )
|
||||
{
|
||||
name = FOLLOW_PCB;
|
||||
cfg->m_CurrentPreset = name;
|
||||
UpdateLayerCtls();
|
||||
m_frame->NewDisplay( true );
|
||||
}
|
||||
else if( index == 1 )
|
||||
{
|
||||
name = FOLLOW_PLOT_SETTINGS;
|
||||
cfg->m_CurrentPreset = name;
|
||||
UpdateLayerCtls();
|
||||
m_frame->NewDisplay( true );
|
||||
}
|
||||
else if( index == count - 3 )
|
||||
{
|
||||
// Separator: reject the selection
|
||||
resetSelection();
|
||||
return;
|
||||
}
|
||||
else if( index == count - 2 )
|
||||
{
|
||||
wxTextEntryDialog dlg( wxGetTopLevelParent( this ), _( "Layer preset name:" ),
|
||||
_( "Save Layer Preset" ) );
|
||||
|
||||
if( dlg.ShowModal() != wxID_OK )
|
||||
{
|
||||
resetSelection();
|
||||
return;
|
||||
}
|
||||
|
||||
std::bitset<LAYER_3D_END> visibleLayers = m_frame->GetAdapter().GetVisibleLayers();
|
||||
std::map<int, COLOR4D> colors = m_frame->GetAdapter().GetLayerColors();
|
||||
|
||||
name = dlg.GetValue();
|
||||
|
||||
if( LAYER_PRESET_3D* preset = cfg->FindPreset( name ) )
|
||||
{
|
||||
if( !IsOK( wxGetTopLevelParent( this ), _( "Overwrite existing preset?" ) ) )
|
||||
{
|
||||
resetSelection();
|
||||
return;
|
||||
}
|
||||
|
||||
preset->layers = visibleLayers;
|
||||
preset->colors = colors;
|
||||
m_cbLayerPresets->SetSelection( m_cbLayerPresets->FindString( name ) );
|
||||
}
|
||||
else
|
||||
{
|
||||
cfg->m_LayerPresets.emplace_back( name, visibleLayers, colors );
|
||||
m_cbLayerPresets->SetSelection( m_cbLayerPresets->Insert( name, index - 1 ) );
|
||||
}
|
||||
|
||||
cfg->m_CurrentPreset = name;
|
||||
m_presetMRU.Insert( name, 0 );
|
||||
|
||||
return;
|
||||
}
|
||||
else if( index == count - 1 )
|
||||
{
|
||||
wxArrayString headers;
|
||||
std::vector<wxArrayString> items;
|
||||
|
||||
headers.Add( _( "Presets" ) );
|
||||
|
||||
for( LAYER_PRESET_3D& preset : cfg->m_LayerPresets )
|
||||
{
|
||||
wxArrayString item;
|
||||
item.Add( preset.name );
|
||||
items.emplace_back( item );
|
||||
}
|
||||
|
||||
EDA_LIST_DIALOG dlg( m_frame, _( "Delete Preset" ), headers, items );
|
||||
dlg.SetListLabel( _( "Select preset:" ) );
|
||||
|
||||
if( dlg.ShowModal() == wxID_OK )
|
||||
{
|
||||
name = dlg.GetTextSelection();
|
||||
|
||||
if( m_cbLayerPresets->FindString( name ) != wxNOT_FOUND )
|
||||
m_cbLayerPresets->Delete( m_cbLayerPresets->FindString( name ) );
|
||||
|
||||
alg::delete_if( cfg->m_LayerPresets,
|
||||
[name]( const LAYER_PRESET_3D& preset )
|
||||
{
|
||||
return preset.name == name;
|
||||
} );
|
||||
|
||||
if( cfg->m_CurrentPreset == name )
|
||||
cfg->m_CurrentPreset = wxEmptyString;
|
||||
|
||||
m_presetMRU.Remove( name );
|
||||
}
|
||||
|
||||
resetSelection();
|
||||
return;
|
||||
}
|
||||
else if( LAYER_PRESET_3D* preset = cfg->FindPreset( m_cbLayerPresets->GetStringSelection() ) )
|
||||
{
|
||||
name = preset->name;
|
||||
doApplyLayerPreset( *preset );
|
||||
}
|
||||
|
||||
// Move to front of MRU list
|
||||
if( m_presetMRU.Index( name ) != wxNOT_FOUND )
|
||||
m_presetMRU.Remove( name );
|
||||
|
||||
m_presetMRU.Insert( name, 0 );
|
||||
|
||||
passOnFocus();
|
||||
}
|
||||
|
||||
|
||||
void APPEARANCE_CONTROLS_3D::doApplyLayerPreset( const LAYER_PRESET_3D& aPreset )
|
||||
{
|
||||
BOARD_ADAPTER& adapter = m_frame->GetAdapter();
|
||||
|
||||
adapter.m_Cfg->m_CurrentPreset = aPreset.name;
|
||||
adapter.SetVisibleLayers( aPreset.layers );
|
||||
adapter.SetLayerColors( aPreset.colors );
|
||||
|
||||
if( aPreset.name.Lower() == _( "legacy colors" ) )
|
||||
adapter.m_Cfg->m_UseStackupColors = false;
|
||||
|
||||
UpdateLayerCtls();
|
||||
m_frame->NewDisplay( true );
|
||||
}
|
||||
|
||||
|
||||
void APPEARANCE_CONTROLS_3D::rebuildViewportsWidget()
|
||||
{
|
||||
m_viewportsLabel->SetLabel( wxString::Format( _( "Viewports (%s+Tab):" ),
|
||||
KeyNameFromKeyCode( VIEWPORT_SWITCH_KEY ) ) );
|
||||
|
||||
m_cbViewports->Clear();
|
||||
|
||||
for( std::pair<const wxString, VIEWPORT3D>& pair : m_viewports )
|
||||
m_cbViewports->Append( pair.first, static_cast<void*>( &pair.second ) );
|
||||
|
||||
m_cbViewports->Append( wxT( "---" ) );
|
||||
m_cbViewports->Append( _( "Save viewport..." ) );
|
||||
m_cbViewports->Append( _( "Delete viewport..." ) );
|
||||
|
||||
m_cbViewports->SetSelection( m_cbViewports->GetCount() - 3 );
|
||||
m_lastSelectedViewport = nullptr;
|
||||
}
|
||||
|
||||
|
||||
void APPEARANCE_CONTROLS_3D::onViewportChanged( wxCommandEvent& aEvent )
|
||||
{
|
||||
int count = m_cbViewports->GetCount();
|
||||
int index = m_cbViewports->GetSelection();
|
||||
|
||||
if( index >= 0 && index < count - 3 )
|
||||
{
|
||||
VIEWPORT3D* viewport = static_cast<VIEWPORT3D*>( m_cbViewports->GetClientData( index ) );
|
||||
|
||||
wxCHECK( viewport, /* void */ );
|
||||
|
||||
doApplyViewport( *viewport );
|
||||
|
||||
if( !viewport->name.IsEmpty() )
|
||||
{
|
||||
m_viewportMRU.Remove( viewport->name );
|
||||
m_viewportMRU.Insert( viewport->name, 0 );
|
||||
}
|
||||
}
|
||||
else if( index == count - 2 )
|
||||
{
|
||||
// Save current state to new preset
|
||||
wxString name;
|
||||
|
||||
wxTextEntryDialog dlg( wxGetTopLevelParent( this ), _( "Viewport name:" ),
|
||||
_( "Save Viewport" ), name );
|
||||
|
||||
if( dlg.ShowModal() != wxID_OK )
|
||||
{
|
||||
if( m_lastSelectedViewport )
|
||||
m_cbViewports->SetStringSelection( m_lastSelectedViewport->name );
|
||||
else
|
||||
m_cbViewports->SetSelection( m_cbViewports->GetCount() - 3 );
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
name = dlg.GetValue();
|
||||
bool exists = m_viewports.count( name );
|
||||
|
||||
if( !exists )
|
||||
{
|
||||
m_viewports[name] = VIEWPORT3D( name, m_frame->GetCurrentCamera().GetViewMatrix() );
|
||||
|
||||
index = m_cbViewports->Insert( name, index-1, static_cast<void*>( &m_viewports[name] ) );
|
||||
}
|
||||
else
|
||||
{
|
||||
m_viewports[name].matrix = m_frame->GetCurrentCamera().GetViewMatrix();
|
||||
index = m_cbViewports->FindString( name );
|
||||
m_viewportMRU.Remove( name );
|
||||
}
|
||||
|
||||
m_cbViewports->SetSelection( index );
|
||||
m_viewportMRU.Insert( name, 0 );
|
||||
|
||||
return;
|
||||
}
|
||||
else if( index == count - 1 )
|
||||
{
|
||||
// Delete an existing viewport
|
||||
wxArrayString headers;
|
||||
std::vector<wxArrayString> items;
|
||||
|
||||
headers.Add( _( "Viewports" ) );
|
||||
|
||||
for( std::pair<const wxString, VIEWPORT3D>& pair : m_viewports )
|
||||
{
|
||||
wxArrayString item;
|
||||
item.Add( pair.first );
|
||||
items.emplace_back( item );
|
||||
}
|
||||
|
||||
EDA_LIST_DIALOG dlg( m_frame, _( "Delete Viewport" ), headers, items );
|
||||
dlg.SetListLabel( _( "Select viewport:" ) );
|
||||
|
||||
if( dlg.ShowModal() == wxID_OK )
|
||||
{
|
||||
wxString viewportName = dlg.GetTextSelection();
|
||||
int idx = m_cbViewports->FindString( viewportName );
|
||||
|
||||
if( idx != wxNOT_FOUND )
|
||||
{
|
||||
m_viewports.erase( viewportName );
|
||||
m_cbViewports->Delete( idx );
|
||||
m_viewportMRU.Remove( viewportName );
|
||||
}
|
||||
}
|
||||
|
||||
if( m_lastSelectedViewport )
|
||||
m_cbViewports->SetStringSelection( m_lastSelectedViewport->name );
|
||||
else
|
||||
m_cbViewports->SetSelection( m_cbViewports->GetCount() - 3 );
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
passOnFocus();
|
||||
}
|
||||
|
||||
|
||||
void APPEARANCE_CONTROLS_3D::onUpdateViewportsCb( wxUpdateUIEvent& aEvent )
|
||||
{
|
||||
int count = m_cbViewports->GetCount();
|
||||
int index = m_cbViewports->GetSelection();
|
||||
|
||||
if( index >= 0 && index < count - 3 )
|
||||
{
|
||||
VIEWPORT3D* viewport = static_cast<VIEWPORT3D*>( m_cbViewports->GetClientData( index ) );
|
||||
|
||||
wxCHECK( viewport, /* void */ );
|
||||
|
||||
if( m_frame->GetCurrentCamera().GetViewMatrix() != viewport->matrix )
|
||||
m_cbViewports->SetSelection( -1 );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void APPEARANCE_CONTROLS_3D::doApplyViewport( const VIEWPORT3D& aViewport )
|
||||
{
|
||||
m_frame->GetCurrentCamera().SetViewMatrix( aViewport.matrix );
|
||||
|
||||
if( m_frame->GetAdapter().m_Cfg->m_Render.engine == RENDER_ENGINE::OPENGL )
|
||||
m_frame->GetCanvas()->Request_refresh();
|
||||
else
|
||||
m_frame->GetCanvas()->RenderRaytracingRequest();
|
||||
}
|
||||
|
||||
|
||||
void APPEARANCE_CONTROLS_3D::passOnFocus()
|
||||
{
|
||||
m_focusOwner->SetFocus();
|
||||
}
|
||||
|
||||
|
||||
@@ -1,191 +0,0 @@
|
||||
/*
|
||||
* This program source code file is part of KiCad, a free EDA CAD application.
|
||||
*
|
||||
* Copyright (C) 2023 CERN
|
||||
* Copyright (C) 2023 KiCad Developers, see AUTHORS.txt for contributors.
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License as published by the
|
||||
* Free Software Foundation, either version 3 of the License, or (at your
|
||||
* option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but
|
||||
* WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along
|
||||
* with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef APPEARANCE_CONTROLS_3D_H
|
||||
#define APPEARANCE_CONTROLS_3D_H
|
||||
|
||||
#include <vector>
|
||||
|
||||
#include <gal/color4d.h>
|
||||
#include <layer_ids.h>
|
||||
#include <3d_canvas/board_adapter.h>
|
||||
#include <dialogs/appearance_controls_3D_base.h>
|
||||
#include <tool/tool_action.h>
|
||||
#include <wx/intl.h>
|
||||
|
||||
|
||||
class BITMAP_TOGGLE;
|
||||
class COLOR_SWATCH;
|
||||
class EDA_3D_VIEWER_FRAME;
|
||||
class ROW_ICON_PROVIDER;
|
||||
class GRID_BITMAP_TOGGLE_RENDERER;
|
||||
|
||||
using KIGFX::COLOR4D;
|
||||
|
||||
|
||||
class APPEARANCE_CONTROLS_3D : public APPEARANCE_CONTROLS_3D_BASE
|
||||
{
|
||||
public:
|
||||
|
||||
/**
|
||||
* Container for an appearance setting (can control a layer class, object type, etc.)
|
||||
*/
|
||||
class APPEARANCE_SETTING_3D
|
||||
{
|
||||
public:
|
||||
int m_Id;
|
||||
bool m_Visible;
|
||||
bool m_Spacer;
|
||||
|
||||
BITMAP_TOGGLE* m_Ctl_visibility;
|
||||
COLOR_SWATCH* m_Ctl_color;
|
||||
|
||||
APPEARANCE_SETTING_3D( const wxString& aLabel, int aId, const wxString& aTooltip ) :
|
||||
m_Id( aId ),
|
||||
m_Visible( true ),
|
||||
m_Spacer( false ),
|
||||
m_Ctl_visibility( nullptr ),
|
||||
m_Ctl_color( nullptr ),
|
||||
m_tooltip( aTooltip ),
|
||||
m_label( aLabel )
|
||||
{
|
||||
}
|
||||
|
||||
APPEARANCE_SETTING_3D( const wxString& aLabel, int aId, const TOOL_ACTION& aAction ) :
|
||||
m_Id( aId ),
|
||||
m_Visible( true ),
|
||||
m_Spacer( false ),
|
||||
m_Ctl_visibility( nullptr ),
|
||||
m_Ctl_color( nullptr ),
|
||||
m_label( aLabel ),
|
||||
m_action( &aAction )
|
||||
{
|
||||
}
|
||||
|
||||
APPEARANCE_SETTING_3D() :
|
||||
m_Id( -1 ),
|
||||
m_Visible( false ),
|
||||
m_Spacer( true ),
|
||||
m_Ctl_visibility( nullptr ),
|
||||
m_Ctl_color( nullptr )
|
||||
{
|
||||
}
|
||||
|
||||
wxString GetTooltip() const
|
||||
{
|
||||
if( m_tooltip.has_value() )
|
||||
return wxGetTranslation( m_tooltip.value() );
|
||||
else if( m_action.has_value() )
|
||||
return m_action.value()->GetTooltip( true );
|
||||
else
|
||||
return wxEmptyString;
|
||||
}
|
||||
|
||||
wxString GetLabel() const
|
||||
{
|
||||
return wxGetTranslation( m_label );
|
||||
}
|
||||
|
||||
private:
|
||||
wxString m_label;
|
||||
|
||||
std::optional<wxString> m_tooltip;
|
||||
std::optional<const TOOL_ACTION*> m_action;
|
||||
};
|
||||
|
||||
APPEARANCE_CONTROLS_3D( EDA_3D_VIEWER_FRAME* aParent, wxWindow* aFocusOwner );
|
||||
~APPEARANCE_CONTROLS_3D();
|
||||
|
||||
wxSize GetBestSize() const;
|
||||
|
||||
void OnLanguageChanged();
|
||||
void OnDarkModeToggle();
|
||||
void OnLayerVisibilityChanged( int aLayer, bool isVisible );
|
||||
|
||||
void CommonSettingsChanged();
|
||||
|
||||
void UpdateLayerCtls();
|
||||
|
||||
void ApplyLayerPreset( const wxString& aPresetName );
|
||||
|
||||
const wxArrayString& GetLayerPresetsMRU() { return m_presetMRU; }
|
||||
|
||||
///< Return a list of viewports created by the user.
|
||||
std::vector<VIEWPORT3D> GetUserViewports() const;
|
||||
|
||||
///< Update the current viewports from those saved in the project file.
|
||||
void SetUserViewports( std::vector<VIEWPORT3D>& aPresetList );
|
||||
|
||||
void ApplyViewport( const wxString& aPresetName );
|
||||
|
||||
const wxArrayString& GetViewportsMRU() { return m_viewportMRU; }
|
||||
|
||||
protected:
|
||||
void OnSetFocus( wxFocusEvent& aEvent ) override;
|
||||
void OnSize( wxSizeEvent& aEvent ) override;
|
||||
|
||||
private:
|
||||
void rebuildLayers();
|
||||
|
||||
void rebuildLayerPresetsWidget();
|
||||
|
||||
void syncLayerPresetSelection();
|
||||
|
||||
void rebuildViewportsWidget();
|
||||
|
||||
void onColorSwatchChanged( COLOR_SWATCH* aSwatch );
|
||||
|
||||
void updateLayerPresetWidget( const wxString& aName );
|
||||
|
||||
void onLayerPresetChanged( wxCommandEvent& aEvent ) override;
|
||||
|
||||
void doApplyLayerPreset( const LAYER_PRESET_3D& aPreset );
|
||||
|
||||
void onViewportChanged( wxCommandEvent& aEvent ) override;
|
||||
void onUpdateViewportsCb( wxUpdateUIEvent& aEvent ) override;
|
||||
|
||||
void doApplyViewport( const VIEWPORT3D& aViewport );
|
||||
|
||||
void passOnFocus();
|
||||
|
||||
private:
|
||||
static const APPEARANCE_SETTING_3D s_layerSettings[];
|
||||
|
||||
EDA_3D_VIEWER_FRAME* m_frame;
|
||||
wxWindow* m_focusOwner;
|
||||
|
||||
std::vector<std::unique_ptr<APPEARANCE_SETTING_3D>> m_layerSettings;
|
||||
std::map<int, APPEARANCE_SETTING_3D*> m_layerSettingsMap;
|
||||
|
||||
wxArrayString m_presetMRU;
|
||||
|
||||
std::map<wxString, VIEWPORT3D> m_viewports;
|
||||
VIEWPORT3D* m_lastSelectedViewport;
|
||||
wxArrayString m_viewportMRU;
|
||||
|
||||
wxBoxSizer* m_layersOuterSizer;
|
||||
wxBoxSizer* m_envOuterSizer;
|
||||
int m_pointSize;
|
||||
wxColour m_layerPanelColour;
|
||||
GRID_BITMAP_TOGGLE_RENDERER* m_toggleGridRenderer;
|
||||
wxCheckBox* m_cbUseBoardStackupColors;
|
||||
};
|
||||
|
||||
#endif
|
||||
@@ -1,98 +0,0 @@
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
// C++ code generated with wxFormBuilder (version 4.0.0-0-g0efcecf)
|
||||
// http://www.wxformbuilder.org/
|
||||
//
|
||||
// PLEASE DO *NOT* EDIT THIS FILE!
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#include "appearance_controls_3D_base.h"
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
|
||||
APPEARANCE_CONTROLS_3D_BASE::APPEARANCE_CONTROLS_3D_BASE( wxWindow* parent, wxWindowID id, const wxPoint& pos, const wxSize& size, long style, const wxString& name ) : WX_PANEL( parent, id, pos, size, style, name )
|
||||
{
|
||||
this->SetMinSize( wxSize( 200,360 ) );
|
||||
|
||||
m_sizerOuter = new wxBoxSizer( wxVERTICAL );
|
||||
|
||||
m_panelLayers = new wxPanel( this, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxTAB_TRAVERSAL );
|
||||
m_panelLayersSizer = new wxBoxSizer( wxVERTICAL );
|
||||
|
||||
m_windowLayers = new wxScrolledCanvas( m_panelLayers, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxVSCROLL );
|
||||
m_panelLayersSizer->Add( m_windowLayers, 1, wxEXPAND, 5 );
|
||||
|
||||
|
||||
m_panelLayers->SetSizer( m_panelLayersSizer );
|
||||
m_panelLayers->Layout();
|
||||
m_panelLayersSizer->Fit( m_panelLayers );
|
||||
m_sizerOuter->Add( m_panelLayers, 1, wxEXPAND, 5 );
|
||||
|
||||
wxBoxSizer* bBottomMargin;
|
||||
bBottomMargin = new wxBoxSizer( wxVERTICAL );
|
||||
|
||||
m_staticline1 = new wxStaticLine( this, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxLI_HORIZONTAL );
|
||||
bBottomMargin->Add( m_staticline1, 0, wxEXPAND|wxBOTTOM, 3 );
|
||||
|
||||
wxBoxSizer* bPresets;
|
||||
bPresets = new wxBoxSizer( wxVERTICAL );
|
||||
|
||||
m_presetsLabel = new wxStaticText( this, wxID_ANY, _("Presets (Ctrl+Tab):"), wxDefaultPosition, wxDefaultSize, 0 );
|
||||
m_presetsLabel->Wrap( -1 );
|
||||
bPresets->Add( m_presetsLabel, 1, wxRIGHT|wxLEFT, 2 );
|
||||
|
||||
wxString m_cbLayerPresetsChoices[] = { _("Follow PCB Editor"), _("Follow PCB Plot Settings") };
|
||||
int m_cbLayerPresetsNChoices = sizeof( m_cbLayerPresetsChoices ) / sizeof( wxString );
|
||||
m_cbLayerPresets = new wxChoice( this, wxID_ANY, wxDefaultPosition, wxDefaultSize, m_cbLayerPresetsNChoices, m_cbLayerPresetsChoices, 0 );
|
||||
m_cbLayerPresets->SetSelection( 1 );
|
||||
bPresets->Add( m_cbLayerPresets, 0, wxALL|wxEXPAND, 2 );
|
||||
|
||||
|
||||
bBottomMargin->Add( bPresets, 0, wxEXPAND|wxTOP|wxRIGHT|wxLEFT, 5 );
|
||||
|
||||
|
||||
bBottomMargin->Add( 0, 2, 0, wxEXPAND, 5 );
|
||||
|
||||
wxBoxSizer* bViewports;
|
||||
bViewports = new wxBoxSizer( wxVERTICAL );
|
||||
|
||||
m_viewportsLabel = new wxStaticText( this, wxID_ANY, _("Viewports (Alt+Tab):"), wxDefaultPosition, wxDefaultSize, 0 );
|
||||
m_viewportsLabel->Wrap( -1 );
|
||||
bViewports->Add( m_viewportsLabel, 1, wxRIGHT|wxLEFT, 2 );
|
||||
|
||||
wxString m_cbViewportsChoices[] = { _("(unsaved)") };
|
||||
int m_cbViewportsNChoices = sizeof( m_cbViewportsChoices ) / sizeof( wxString );
|
||||
m_cbViewports = new wxChoice( this, wxID_ANY, wxDefaultPosition, wxDefaultSize, m_cbViewportsNChoices, m_cbViewportsChoices, 0 );
|
||||
m_cbViewports->SetSelection( 1 );
|
||||
bViewports->Add( m_cbViewports, 0, wxEXPAND|wxTOP|wxRIGHT|wxLEFT, 2 );
|
||||
|
||||
|
||||
bBottomMargin->Add( bViewports, 1, wxEXPAND|wxBOTTOM|wxRIGHT|wxLEFT, 5 );
|
||||
|
||||
|
||||
m_sizerOuter->Add( bBottomMargin, 0, wxEXPAND|wxTOP|wxBOTTOM, 2 );
|
||||
|
||||
|
||||
this->SetSizer( m_sizerOuter );
|
||||
this->Layout();
|
||||
m_sizerOuter->Fit( this );
|
||||
|
||||
// Connect Events
|
||||
this->Connect( wxEVT_SET_FOCUS, wxFocusEventHandler( APPEARANCE_CONTROLS_3D_BASE::OnSetFocus ) );
|
||||
this->Connect( wxEVT_SIZE, wxSizeEventHandler( APPEARANCE_CONTROLS_3D_BASE::OnSize ) );
|
||||
m_panelLayers->Connect( wxEVT_SET_FOCUS, wxFocusEventHandler( APPEARANCE_CONTROLS_3D_BASE::OnSetFocus ), NULL, this );
|
||||
m_cbLayerPresets->Connect( wxEVT_COMMAND_CHOICE_SELECTED, wxCommandEventHandler( APPEARANCE_CONTROLS_3D_BASE::onLayerPresetChanged ), NULL, this );
|
||||
m_cbViewports->Connect( wxEVT_COMMAND_CHOICE_SELECTED, wxCommandEventHandler( APPEARANCE_CONTROLS_3D_BASE::onViewportChanged ), NULL, this );
|
||||
m_cbViewports->Connect( wxEVT_UPDATE_UI, wxUpdateUIEventHandler( APPEARANCE_CONTROLS_3D_BASE::onUpdateViewportsCb ), NULL, this );
|
||||
}
|
||||
|
||||
APPEARANCE_CONTROLS_3D_BASE::~APPEARANCE_CONTROLS_3D_BASE()
|
||||
{
|
||||
// Disconnect Events
|
||||
this->Disconnect( wxEVT_SET_FOCUS, wxFocusEventHandler( APPEARANCE_CONTROLS_3D_BASE::OnSetFocus ) );
|
||||
this->Disconnect( wxEVT_SIZE, wxSizeEventHandler( APPEARANCE_CONTROLS_3D_BASE::OnSize ) );
|
||||
m_panelLayers->Disconnect( wxEVT_SET_FOCUS, wxFocusEventHandler( APPEARANCE_CONTROLS_3D_BASE::OnSetFocus ), NULL, this );
|
||||
m_cbLayerPresets->Disconnect( wxEVT_COMMAND_CHOICE_SELECTED, wxCommandEventHandler( APPEARANCE_CONTROLS_3D_BASE::onLayerPresetChanged ), NULL, this );
|
||||
m_cbViewports->Disconnect( wxEVT_COMMAND_CHOICE_SELECTED, wxCommandEventHandler( APPEARANCE_CONTROLS_3D_BASE::onViewportChanged ), NULL, this );
|
||||
m_cbViewports->Disconnect( wxEVT_UPDATE_UI, wxUpdateUIEventHandler( APPEARANCE_CONTROLS_3D_BASE::onUpdateViewportsCb ), NULL, this );
|
||||
|
||||
}
|
||||
@@ -1,553 +0,0 @@
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
|
||||
<wxFormBuilder_Project>
|
||||
<FileVersion major="1" minor="17"/>
|
||||
<object class="Project" expanded="true">
|
||||
<property name="class_decoration">; </property>
|
||||
<property name="code_generation">C++</property>
|
||||
<property name="disconnect_events">1</property>
|
||||
<property name="disconnect_mode">source_name</property>
|
||||
<property name="disconnect_php_events">0</property>
|
||||
<property name="disconnect_python_events">0</property>
|
||||
<property name="embedded_files_path">res</property>
|
||||
<property name="encoding">UTF-8</property>
|
||||
<property name="event_generation">connect</property>
|
||||
<property name="file">appearance_controls_3D_base</property>
|
||||
<property name="first_id">1000</property>
|
||||
<property name="help_provider">none</property>
|
||||
<property name="image_path_wrapper_function_name"></property>
|
||||
<property name="indent_with_spaces"></property>
|
||||
<property name="internationalize">1</property>
|
||||
<property name="name">Appearance Panel 3D</property>
|
||||
<property name="namespace"></property>
|
||||
<property name="path">.</property>
|
||||
<property name="precompiled_header"></property>
|
||||
<property name="relative_path">1</property>
|
||||
<property name="skip_lua_events">1</property>
|
||||
<property name="skip_php_events">1</property>
|
||||
<property name="skip_python_events">1</property>
|
||||
<property name="ui_table">UI</property>
|
||||
<property name="use_array_enum">0</property>
|
||||
<property name="use_enum">0</property>
|
||||
<property name="use_microsoft_bom">0</property>
|
||||
<object class="Panel" expanded="true">
|
||||
<property name="aui_managed">0</property>
|
||||
<property name="aui_manager_style">wxAUI_MGR_DEFAULT</property>
|
||||
<property name="bg"></property>
|
||||
<property name="context_help"></property>
|
||||
<property name="context_menu">1</property>
|
||||
<property name="drag_accept_files">0</property>
|
||||
<property name="enabled">1</property>
|
||||
<property name="event_handler">impl_virtual</property>
|
||||
<property name="fg"></property>
|
||||
<property name="font"></property>
|
||||
<property name="hidden">0</property>
|
||||
<property name="id">wxID_ANY</property>
|
||||
<property name="maximum_size"></property>
|
||||
<property name="minimum_size">200,360</property>
|
||||
<property name="name">APPEARANCE_CONTROLS_3D_BASE</property>
|
||||
<property name="pos"></property>
|
||||
<property name="size">-1,-1</property>
|
||||
<property name="subclass">WX_PANEL; widgets/wx_panel.h; forward_declare</property>
|
||||
<property name="tooltip"></property>
|
||||
<property name="two_step_creation">0</property>
|
||||
<property name="window_extra_style"></property>
|
||||
<property name="window_name"></property>
|
||||
<property name="window_style">wxTAB_TRAVERSAL</property>
|
||||
<event name="OnSetFocus">OnSetFocus</event>
|
||||
<event name="OnSize">OnSize</event>
|
||||
<object class="wxBoxSizer" expanded="true">
|
||||
<property name="minimum_size"></property>
|
||||
<property name="name">m_sizerOuter</property>
|
||||
<property name="orient">wxVERTICAL</property>
|
||||
<property name="permission">protected</property>
|
||||
<object class="sizeritem" expanded="true">
|
||||
<property name="border">5</property>
|
||||
<property name="flag">wxEXPAND</property>
|
||||
<property name="proportion">1</property>
|
||||
<object class="wxPanel" expanded="true">
|
||||
<property name="BottomDockable">1</property>
|
||||
<property name="LeftDockable">1</property>
|
||||
<property name="RightDockable">1</property>
|
||||
<property name="TopDockable">1</property>
|
||||
<property name="aui_layer"></property>
|
||||
<property name="aui_name"></property>
|
||||
<property name="aui_position"></property>
|
||||
<property name="aui_row"></property>
|
||||
<property name="best_size"></property>
|
||||
<property name="bg"></property>
|
||||
<property name="caption"></property>
|
||||
<property name="caption_visible">1</property>
|
||||
<property name="center_pane">0</property>
|
||||
<property name="close_button">1</property>
|
||||
<property name="context_help"></property>
|
||||
<property name="context_menu">1</property>
|
||||
<property name="default_pane">0</property>
|
||||
<property name="dock">Dock</property>
|
||||
<property name="dock_fixed">0</property>
|
||||
<property name="docking">Left</property>
|
||||
<property name="drag_accept_files">0</property>
|
||||
<property name="enabled">1</property>
|
||||
<property name="fg"></property>
|
||||
<property name="floatable">1</property>
|
||||
<property name="font"></property>
|
||||
<property name="gripper">0</property>
|
||||
<property name="hidden">0</property>
|
||||
<property name="id">wxID_ANY</property>
|
||||
<property name="max_size"></property>
|
||||
<property name="maximize_button">0</property>
|
||||
<property name="maximum_size"></property>
|
||||
<property name="min_size"></property>
|
||||
<property name="minimize_button">0</property>
|
||||
<property name="minimum_size"></property>
|
||||
<property name="moveable">1</property>
|
||||
<property name="name">m_panelLayers</property>
|
||||
<property name="pane_border">1</property>
|
||||
<property name="pane_position"></property>
|
||||
<property name="pane_size"></property>
|
||||
<property name="permission">protected</property>
|
||||
<property name="pin_button">1</property>
|
||||
<property name="pos"></property>
|
||||
<property name="resize">Resizable</property>
|
||||
<property name="show">1</property>
|
||||
<property name="size"></property>
|
||||
<property name="subclass">; ; forward_declare</property>
|
||||
<property name="toolbar_pane">0</property>
|
||||
<property name="tooltip"></property>
|
||||
<property name="window_extra_style"></property>
|
||||
<property name="window_name"></property>
|
||||
<property name="window_style">wxTAB_TRAVERSAL</property>
|
||||
<event name="OnSetFocus">OnSetFocus</event>
|
||||
<object class="wxBoxSizer" expanded="true">
|
||||
<property name="minimum_size"></property>
|
||||
<property name="name">m_panelLayersSizer</property>
|
||||
<property name="orient">wxVERTICAL</property>
|
||||
<property name="permission">protected</property>
|
||||
<object class="sizeritem" expanded="true">
|
||||
<property name="border">5</property>
|
||||
<property name="flag">wxEXPAND</property>
|
||||
<property name="proportion">1</property>
|
||||
<object class="CustomControl" expanded="true">
|
||||
<property name="BottomDockable">1</property>
|
||||
<property name="LeftDockable">1</property>
|
||||
<property name="RightDockable">1</property>
|
||||
<property name="TopDockable">1</property>
|
||||
<property name="aui_layer"></property>
|
||||
<property name="aui_name"></property>
|
||||
<property name="aui_position"></property>
|
||||
<property name="aui_row"></property>
|
||||
<property name="best_size"></property>
|
||||
<property name="bg"></property>
|
||||
<property name="caption"></property>
|
||||
<property name="caption_visible">1</property>
|
||||
<property name="center_pane">0</property>
|
||||
<property name="class">wxScrolledCanvas</property>
|
||||
<property name="close_button">1</property>
|
||||
<property name="construction"></property>
|
||||
<property name="context_help"></property>
|
||||
<property name="context_menu">1</property>
|
||||
<property name="declaration"></property>
|
||||
<property name="default_pane">0</property>
|
||||
<property name="dock">Dock</property>
|
||||
<property name="dock_fixed">0</property>
|
||||
<property name="docking">Left</property>
|
||||
<property name="drag_accept_files">0</property>
|
||||
<property name="enabled">1</property>
|
||||
<property name="fg"></property>
|
||||
<property name="floatable">1</property>
|
||||
<property name="font"></property>
|
||||
<property name="gripper">0</property>
|
||||
<property name="hidden">0</property>
|
||||
<property name="id">wxID_ANY</property>
|
||||
<property name="include">#include <wx/scrolwin.h>
#include <wx/grid.h> // 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">"Follow PCB Editor" "Follow PCB Plot Settings"</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">"(unsaved)"</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();
|
||||
|
||||
};
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
*
|
||||
* Copyright (C) 2016 Mario Luzeiro <mrluzeiro@ua.pt>
|
||||
* Copyright (C) 2016 Cirilo Bernardo <cirilo.bernardo@gmail.com>
|
||||
* Copyright (C) 2017-2022 KiCad Developers, see AUTHORS.txt for contributors.
|
||||
* Copyright (C) 2017-2021 KiCad Developers, see AUTHORS.txt for contributors.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
@@ -34,7 +34,6 @@
|
||||
#include <common_ogl/ogl_attr_list.h>
|
||||
#include <filename_resolver.h>
|
||||
#include <pcbnew/footprint.h>
|
||||
#include <wx_filename.h>
|
||||
|
||||
#include <wx/filedlg.h>
|
||||
|
||||
@@ -165,7 +164,7 @@ bool DIALOG_SELECT_3DMODEL::TransferDataFromWindow()
|
||||
// file selection mode: retrieve the filename and specify a
|
||||
// path relative to one of the config paths
|
||||
wxFileName fname = m_FileTree->GetFilePath();
|
||||
fname.Normalize( FN_NORMALIZE_FLAGS | wxPATH_NORM_ENV_VARS );
|
||||
fname.Normalize();
|
||||
m_model->m_Filename = m_resolver->ShortenPath( fname.GetFullPath() );
|
||||
|
||||
return true;
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
// C++ code generated with wxFormBuilder (version 3.10.1-0-g8feb16b)
|
||||
// C++ code generated with wxFormBuilder (version Oct 26 2018)
|
||||
// http://www.wxformbuilder.org/
|
||||
//
|
||||
// PLEASE DO *NOT* EDIT THIS FILE!
|
||||
@@ -57,7 +57,7 @@ DIALOG_SELECT_3D_MODEL_BASE::DIALOG_SELECT_3D_MODEL_BASE( wxWindow* parent, wxWi
|
||||
|
||||
m_stDirChoice = new wxStaticText( this, wxID_ANY, _("Available paths:"), wxDefaultPosition, wxDefaultSize, 0 );
|
||||
m_stDirChoice->Wrap( -1 );
|
||||
bSizerLower->Add( m_stDirChoice, 0, wxALIGN_CENTER_VERTICAL|wxBOTTOM|wxLEFT|wxRIGHT|wxTOP, 5 );
|
||||
bSizerLower->Add( m_stDirChoice, 0, wxALIGN_CENTER_VERTICAL|wxTOP|wxBOTTOM|wxLEFT, 5 );
|
||||
|
||||
wxArrayString m_dirChoicesChoices;
|
||||
m_dirChoices = new wxChoice( this, wxID_ANY, wxDefaultPosition, wxDefaultSize, m_dirChoicesChoices, 0 );
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="yes" ?>
|
||||
<wxFormBuilder_Project>
|
||||
<FileVersion major="1" minor="16" />
|
||||
<FileVersion major="1" minor="15" />
|
||||
<object class="Project" expanded="1">
|
||||
<property name="class_decoration">; </property>
|
||||
<property name="code_generation">C++</property>
|
||||
@@ -14,7 +14,6 @@
|
||||
<property name="file">dialog_select_3d_model_base</property>
|
||||
<property name="first_id">1000</property>
|
||||
<property name="help_provider">none</property>
|
||||
<property name="image_path_wrapper_function_name"></property>
|
||||
<property name="indent_with_spaces"></property>
|
||||
<property name="internationalize">1</property>
|
||||
<property name="name">dialog_select_3d_model_base</property>
|
||||
@@ -26,7 +25,6 @@
|
||||
<property name="skip_php_events">1</property>
|
||||
<property name="skip_python_events">1</property>
|
||||
<property name="ui_table">UI</property>
|
||||
<property name="use_array_enum">0</property>
|
||||
<property name="use_enum">0</property>
|
||||
<property name="use_microsoft_bom">0</property>
|
||||
<object class="Dialog" expanded="1">
|
||||
@@ -52,7 +50,6 @@
|
||||
<property name="subclass">DIALOG_SHIM; dialog_shim.h; forward_declare</property>
|
||||
<property name="title">Select 3D Model</property>
|
||||
<property name="tooltip"></property>
|
||||
<property name="two_step_creation">0</property>
|
||||
<property name="window_extra_style"></property>
|
||||
<property name="window_name"></property>
|
||||
<property name="window_style"></property>
|
||||
@@ -330,7 +327,7 @@
|
||||
<property name="permission">none</property>
|
||||
<object class="sizeritem" expanded="1">
|
||||
<property name="border">5</property>
|
||||
<property name="flag">wxALIGN_CENTER_VERTICAL|wxBOTTOM|wxLEFT|wxRIGHT|wxTOP</property>
|
||||
<property name="flag">wxALIGN_CENTER_VERTICAL|wxTOP|wxBOTTOM|wxLEFT</property>
|
||||
<property name="proportion">0</property>
|
||||
<object class="wxStaticText" expanded="1">
|
||||
<property name="BottomDockable">1</property>
|
||||
@@ -467,7 +464,6 @@
|
||||
<property name="aui_name"></property>
|
||||
<property name="aui_position"></property>
|
||||
<property name="aui_row"></property>
|
||||
<property name="auth_needed">0</property>
|
||||
<property name="best_size"></property>
|
||||
<property name="bg"></property>
|
||||
<property name="bitmap"></property>
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
// C++ code generated with wxFormBuilder (version 3.10.1-0-g8feb16b)
|
||||
// C++ code generated with wxFormBuilder (version Oct 26 2018)
|
||||
// http://www.wxformbuilder.org/
|
||||
//
|
||||
// PLEASE DO *NOT* EDIT THIS FILE!
|
||||
@@ -22,10 +22,10 @@
|
||||
#include <wx/splitter.h>
|
||||
#include <wx/stattext.h>
|
||||
#include <wx/choice.h>
|
||||
#include <wx/button.h>
|
||||
#include <wx/bitmap.h>
|
||||
#include <wx/image.h>
|
||||
#include <wx/icon.h>
|
||||
#include <wx/button.h>
|
||||
#include <wx/dialog.h>
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
@@ -51,7 +51,7 @@ class DIALOG_SELECT_3D_MODEL_BASE : public DIALOG_SHIM
|
||||
wxButton* m_sdbSizerOK;
|
||||
wxButton* m_sdbSizerCancel;
|
||||
|
||||
// Virtual event handlers, override them in your derived class
|
||||
// Virtual event handlers, overide them in your derived class
|
||||
virtual void OnFileActivated( wxCommandEvent& event ) { event.Skip(); }
|
||||
virtual void OnSelectionChanged( wxCommandEvent& event ) { event.Skip(); }
|
||||
virtual void SetRootDir( wxCommandEvent& event ) { event.Skip(); }
|
||||
@@ -61,7 +61,6 @@ class DIALOG_SELECT_3D_MODEL_BASE : public DIALOG_SHIM
|
||||
public:
|
||||
|
||||
DIALOG_SELECT_3D_MODEL_BASE( wxWindow* parent, wxWindowID id = wxID_ANY, const wxString& title = _("Select 3D Model"), const wxPoint& pos = wxDefaultPosition, const wxSize& size = wxSize( -1,-1 ), long style = wxDEFAULT_DIALOG_STYLE|wxRESIZE_BORDER );
|
||||
|
||||
~DIALOG_SELECT_3D_MODEL_BASE();
|
||||
|
||||
void m_splitterWinOnIdle( wxIdleEvent& )
|
||||
|
||||
@@ -0,0 +1,110 @@
|
||||
/*
|
||||
* This program source code file is part of KiCad, a free EDA CAD application.
|
||||
*
|
||||
* Copyright (C) 2021 KiCad Developers, see AUTHORS.txt for contributors.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; either version 2
|
||||
* of the License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, you may find one here:
|
||||
* http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
|
||||
* or you may search the http://www.gnu.org website for the version 2 license,
|
||||
* or you may write to the Free Software Foundation, Inc.,
|
||||
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
|
||||
*/
|
||||
|
||||
#include "panel_3D_colors.h"
|
||||
#include <widgets/color_swatch.h>
|
||||
#include <settings/settings_manager.h>
|
||||
#include <pgm_base.h>
|
||||
|
||||
|
||||
PANEL_3D_COLORS::PANEL_3D_COLORS( EDA_3D_VIEWER_FRAME* aFrame, wxWindow* aParent ) :
|
||||
PANEL_3D_COLORS_BASE( aParent ),
|
||||
m_boardAdapter( aFrame->GetAdapter() )
|
||||
{
|
||||
m_backgroundTop->SetDefaultColor( m_boardAdapter.g_DefaultBackgroundTop );
|
||||
m_backgroundBottom->SetDefaultColor( m_boardAdapter.g_DefaultBackgroundBot );
|
||||
|
||||
m_silkscreenTop->SetUserColors( &m_boardAdapter.g_SilkscreenColors );
|
||||
m_silkscreenTop->SetDefaultColor( m_boardAdapter.g_DefaultSilkscreen );
|
||||
m_silkscreenBottom->SetUserColors( &m_boardAdapter.g_SilkscreenColors );
|
||||
m_silkscreenBottom->SetDefaultColor( m_boardAdapter.g_DefaultSilkscreen );
|
||||
|
||||
m_solderMaskTop->SetUserColors( &m_boardAdapter.g_MaskColors );
|
||||
m_solderMaskTop->SetDefaultColor( m_boardAdapter.g_DefaultSolderMask );
|
||||
m_solderMaskBottom->SetUserColors( &m_boardAdapter.g_MaskColors );
|
||||
m_solderMaskBottom->SetDefaultColor( m_boardAdapter.g_DefaultSolderMask );
|
||||
|
||||
m_solderPaste->SetUserColors( &m_boardAdapter.g_PasteColors );
|
||||
m_solderPaste->SetDefaultColor( m_boardAdapter.g_DefaultSolderPaste );
|
||||
|
||||
m_surfaceFinish->SetUserColors( &m_boardAdapter.g_FinishColors );
|
||||
m_surfaceFinish->SetDefaultColor( m_boardAdapter.g_DefaultSurfaceFinish );
|
||||
|
||||
m_boardBody->SetUserColors( &m_boardAdapter.g_BoardColors );
|
||||
m_boardBody->SetDefaultColor( m_boardAdapter.g_DefaultBoardBody );
|
||||
}
|
||||
|
||||
|
||||
bool PANEL_3D_COLORS::TransferDataToWindow()
|
||||
{
|
||||
COLOR_SETTINGS* colors = Pgm().GetSettingsManager().GetColorSettings();
|
||||
|
||||
m_backgroundTop->SetSupportsOpacity( false );
|
||||
m_backgroundBottom->SetSupportsOpacity( false );
|
||||
m_silkscreenTop->SetSupportsOpacity( false );
|
||||
m_silkscreenBottom->SetSupportsOpacity( false );
|
||||
m_solderMaskTop->SetBackgroundColour( *wxWHITE );
|
||||
m_solderMaskBottom->SetBackgroundColour( *wxWHITE );
|
||||
m_solderPaste->SetSupportsOpacity( false );
|
||||
m_surfaceFinish->SetSupportsOpacity( false );
|
||||
m_boardBody->SetBackgroundColour( *wxWHITE );
|
||||
|
||||
m_backgroundTop->SetSwatchColor( colors->GetColor( LAYER_3D_BACKGROUND_TOP ), false );
|
||||
m_backgroundBottom->SetSwatchColor( colors->GetColor( LAYER_3D_BACKGROUND_BOTTOM ), false );
|
||||
m_silkscreenTop->SetSwatchColor( colors->GetColor( LAYER_3D_SILKSCREEN_TOP ), false );
|
||||
m_silkscreenBottom->SetSwatchColor( colors->GetColor( LAYER_3D_SILKSCREEN_BOTTOM ), false );
|
||||
m_solderMaskTop->SetSwatchColor( colors->GetColor( LAYER_3D_SOLDERMASK_TOP ), false );
|
||||
m_solderMaskBottom->SetSwatchColor( colors->GetColor( LAYER_3D_SOLDERMASK_BOTTOM ), false );
|
||||
m_solderPaste->SetSwatchColor( colors->GetColor( LAYER_3D_SOLDERPASTE ), false );
|
||||
m_surfaceFinish->SetSwatchColor( colors->GetColor( LAYER_3D_COPPER ), false );
|
||||
m_boardBody->SetSwatchColor( colors->GetColor( LAYER_3D_BOARD ), false );
|
||||
|
||||
if( colors->GetUseBoardStackupColors() )
|
||||
m_boardStackupRB->SetValue( true );
|
||||
else
|
||||
m_specificColorsRB->SetValue( true );
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
bool PANEL_3D_COLORS::TransferDataFromWindow()
|
||||
{
|
||||
COLOR_SETTINGS* colors = Pgm().GetSettingsManager().GetColorSettings();
|
||||
|
||||
colors->SetColor( LAYER_3D_BACKGROUND_TOP, m_backgroundTop->GetSwatchColor() );
|
||||
colors->SetColor( LAYER_3D_BACKGROUND_BOTTOM, m_backgroundBottom->GetSwatchColor() );
|
||||
colors->SetColor( LAYER_3D_SILKSCREEN_TOP, m_silkscreenTop->GetSwatchColor() );
|
||||
colors->SetColor( LAYER_3D_SILKSCREEN_BOTTOM, m_silkscreenBottom->GetSwatchColor() );
|
||||
colors->SetColor( LAYER_3D_SOLDERMASK_TOP, m_solderMaskTop->GetSwatchColor() );
|
||||
colors->SetColor( LAYER_3D_SOLDERMASK_BOTTOM, m_solderMaskBottom->GetSwatchColor() );
|
||||
colors->SetColor( LAYER_3D_SOLDERPASTE, m_solderPaste->GetSwatchColor() );
|
||||
colors->SetColor( LAYER_3D_COPPER, m_surfaceFinish->GetSwatchColor() );
|
||||
colors->SetColor( LAYER_3D_BOARD, m_boardBody->GetSwatchColor() );
|
||||
|
||||
colors->SetUseBoardStackupColors( m_boardStackupRB->GetValue() );
|
||||
|
||||
Pgm().GetSettingsManager().SaveColorSettings( colors, "3d_viewer" );
|
||||
|
||||
return true;
|
||||
}
|
||||
@@ -0,0 +1,46 @@
|
||||
/*
|
||||
* This program source code file is part of KiCad, a free EDA CAD application.
|
||||
*
|
||||
* Copyright (C) 2021 KiCad Developers, see AUTHORS.txt for contributors.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; either version 2
|
||||
* of the License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, you may find one here:
|
||||
* http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
|
||||
* or you may search the http://www.gnu.org website for the version 2 license,
|
||||
* or you may write to the Free Software Foundation, Inc.,
|
||||
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
|
||||
*/
|
||||
|
||||
#ifndef PANEL_3D_COLORS_H
|
||||
#define PANEL_3D_COLORS_H
|
||||
|
||||
#include "panel_3D_colors_base.h"
|
||||
#include <3d_viewer/eda_3d_viewer_frame.h>
|
||||
|
||||
class PANEL_3D_COLORS : public PANEL_3D_COLORS_BASE
|
||||
{
|
||||
public:
|
||||
explicit PANEL_3D_COLORS( EDA_3D_VIEWER_FRAME* aFrame, wxWindow* aParent );
|
||||
|
||||
/// Automatically called when clicking on the OK button
|
||||
bool TransferDataFromWindow() override;
|
||||
|
||||
/// Automatically called after creating the dialog
|
||||
bool TransferDataToWindow() override;
|
||||
|
||||
private:
|
||||
BOARD_ADAPTER& m_boardAdapter;
|
||||
};
|
||||
|
||||
|
||||
#endif // PANEL_3D_COLORS_H
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user