Compare commits
221 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| ec5ed68af8 | |||
| f66ccfb64f | |||
| 7eac7dcdcb | |||
| 1b1a3763d2 | |||
| 50eedcf0b3 | |||
| 62561292e9 | |||
| 03132cabee | |||
| 82c9e54735 | |||
| c0d9b9ab81 | |||
| daf4985a60 | |||
| b1805dd254 | |||
| 66b0aca696 | |||
| 22fbf30f22 | |||
| f3d1f31e1d | |||
| 9610f8f208 | |||
| 76adf7dbe8 | |||
| 3f32f0be9e | |||
| a77caa6baa | |||
| 0b5ca1a883 | |||
| 839ade2c05 | |||
| 922ce89643 | |||
| 78f7ba10ef | |||
| dd39599903 | |||
| dba32717b1 | |||
| 57800b934e | |||
| 4daaaa373c | |||
| 36bb92f844 | |||
| d95ab28db9 | |||
| 09616fff7a | |||
| f87a22fefb | |||
| 2701bdbbac | |||
| 49753d9dad | |||
| 272b477e91 | |||
| e453b5b87b | |||
| c08d3baf8c | |||
| 3d9e6867cf | |||
| bd1b15ded7 | |||
| 8f87aae99e | |||
| 43987cc50c | |||
| 6106210c87 | |||
| b37bc69476 | |||
| cccf4cf20b | |||
| 99549f816f | |||
| e34dc4abb1 | |||
| 82b37a5cbe | |||
| 561dc052ff | |||
| 553b529fd4 | |||
| 7573c6a4e4 | |||
| c000d70a51 | |||
| 234b01905d | |||
| a5bdee747a | |||
| 9977d0d737 | |||
| 46f7011463 | |||
| 876232aa7a | |||
| 39c38fb386 | |||
| 99f25b0895 | |||
| a43ec3e3f0 | |||
| 7b596f0365 | |||
| dd22c73666 | |||
| d15b34988d | |||
| 5e0ef36719 | |||
| 6994291997 | |||
| 9837d1624f | |||
| 13a41f11eb | |||
| 59723ce3ab | |||
| 79d19d9055 | |||
| 115f318976 | |||
| 51a74b53cb | |||
| f591f8741a | |||
| f56ea6bf3c | |||
| e3f12ec0d9 | |||
| c26311918e | |||
| 1f19903e7e | |||
| 1e223b9027 | |||
| 036288d18f | |||
| 8efdcbfaf1 | |||
| 6c3b4e5824 | |||
| 9831a14ef3 | |||
| f3400e03c6 | |||
| 04e699f789 | |||
| 9e61ebfb0b | |||
| 9e355c29f1 | |||
| 5ce0c2065c | |||
| 3f58dce1de | |||
| c5c89fd216 | |||
| 1820e81f5e | |||
| 4fcd80eda1 | |||
| e7a9643b37 | |||
| 3e28ac9c7c | |||
| 4c37defd35 | |||
| a4564db082 | |||
| dd3c24faf8 | |||
| 0a9aedda8b | |||
| 48b4a897af | |||
| 4c409fbac9 | |||
| b4fc7575a5 | |||
| 4560d4ef69 | |||
| 3a03c79255 | |||
| fca0785754 | |||
| 30d398b108 | |||
| dd7ce9f00a | |||
| 4f2f8e7f67 | |||
| c7e511c919 | |||
| d769d1649a | |||
| 2ae8f6337d | |||
| 97c5e0a835 | |||
| c722ea7a0c | |||
| 5c600e992a | |||
| a055916f92 | |||
| e3d5734f76 | |||
| 3d0915a33e | |||
| a67bfa6207 | |||
| a454adb3ba | |||
| 5019fd0aab | |||
| 2c6d0ffe27 | |||
| 0ff84865ca | |||
| 36746a0941 | |||
| 22df4e301b | |||
| ac0c7441b4 | |||
| 2196959539 | |||
| 06ac172c27 | |||
| e7c51a6a6c | |||
| 079d6b2009 | |||
| 8cbe5c2184 | |||
| a7d7ab32c6 | |||
| 61715a8df5 | |||
| a149960faa | |||
| 650ff5e5fe | |||
| 0c42d988f7 | |||
| a84de7cccf | |||
| e9b1552b16 | |||
| 27b88be61f | |||
| 280573e9af | |||
| 14e42fec7e | |||
| 7e8c5b9574 | |||
| 500abd0ac4 | |||
| e29e7ff95d | |||
| fb580d3694 | |||
| b987126b7d | |||
| 3919345003 | |||
| 1df99c264f | |||
| 4d094da2fa | |||
| 2c5154c630 | |||
| f85dc57642 | |||
| 3da86dc24b | |||
| 5e9b4dd6a5 | |||
| 1f60d8fdbf | |||
| 7012226284 | |||
| 48bbde65b3 | |||
| bdcae5f593 | |||
| b7b125d83c | |||
| 9eec296b0a | |||
| ec81f3267f | |||
| f0e9e3b9d5 | |||
| ee12fe6eff | |||
| d6b95236a4 | |||
| fbe677e46e | |||
| f84bd0d836 | |||
| 25b6604fc5 | |||
| fbd6654f9a | |||
| b8ae4e0195 | |||
| 9527034e0f | |||
| 6754aa8a74 | |||
| 0c659eda78 | |||
| 20ea486378 | |||
| 0c94b3239d | |||
| d8e276bc4f | |||
| b7a321d143 | |||
| f6d9c3a733 | |||
| 7ed07cae70 | |||
| 8bb0fabcba | |||
| da4d9ee392 | |||
| a4ddbff321 | |||
| 3c87ab94a2 | |||
| e424f29bbb | |||
| 3587789ae2 | |||
| 8cb389d95c | |||
| 0f78fe5a5a | |||
| 333ba4b9a2 | |||
| 7e2e39ce30 | |||
| b167c41d1b | |||
| dc022dcdae | |||
| e2c6422838 | |||
| 182b8a32df | |||
| 831978293f | |||
| 64f46448ea | |||
| ca1f50a023 | |||
| 626f5ac45a | |||
| a45a8e8797 | |||
| c7d39d22db | |||
| b764bb1d6d | |||
| 64eaaa4f58 | |||
| 0e946dad1a | |||
| 1c2f06106d | |||
| edbf34c2b2 | |||
| 26cbdbf103 | |||
| f163d9ff2a | |||
| 9230189f62 | |||
| 9d241ba812 | |||
| 57c3e98f8c | |||
| 349d1562af | |||
| d81bcee10d | |||
| 016c02a42d | |||
| 80e7a83fb0 | |||
| d2aa976017 | |||
| 9476b53533 | |||
| 5e19ed29b8 | |||
| aa340e6b85 | |||
| 9a80ebf387 | |||
| df1fa37fd8 | |||
| 370a412f49 | |||
| d63c1a2118 | |||
| 35576adb73 | |||
| 4ff426275f | |||
| 7dc9f99165 | |||
| 30da1a3b02 | |||
| 3dcf04fdb8 | |||
| 6fbc7bb4ce | |||
| 3af2026061 | |||
| 6bd8cb9b8f | |||
| b23b48b9a7 |
@@ -1,31 +0,0 @@
|
||||
|
||||
# Custom attribute to mark source files using KiCad C++ formatting
|
||||
[attr]kicad-cpp-source whitepace=tab-in-indent format.clang-format-kicad
|
||||
|
||||
# Custom attribute to mark KiCad's own CMake files
|
||||
[attr]kicad-cmake-source whitespace=tab-in-indent
|
||||
|
||||
# Custom attribute for auto-generated sources:
|
||||
# * Do not perform whitespace checking
|
||||
# * Do not format
|
||||
[attr]generated whitespace=-tab-in-indent,-indent-with-non-tab -format.clang-format-kicad
|
||||
|
||||
# By default, all C and C++ files conform to KiCad formatting,
|
||||
# unless overridden
|
||||
*.c kicad-cpp-source
|
||||
*.cpp kicad-cpp-source
|
||||
*.h kicad-cpp-source
|
||||
|
||||
*.cmake kicad-cmake-source
|
||||
*.txt kicad-cmake-source
|
||||
|
||||
# Compiled bitmap sources
|
||||
bitmaps_png/cpp_*/*.cpp generated
|
||||
|
||||
# wxFormBuilder-generated files
|
||||
**/dialog*/*_base.cpp generated
|
||||
**/dialog*/*_base.h generated
|
||||
|
||||
# Lemon grammars
|
||||
common/libeval/grammar.c generated
|
||||
common/libeval/grammar.h generated
|
||||
@@ -1,49 +0,0 @@
|
||||
#!/usr/bin/env bash
|
||||
#
|
||||
# Git "hook chain", used to execute multiple scripts per hook.
|
||||
# To use:
|
||||
# * create a directory called <hookname>.d
|
||||
# * add scripts to this directory (executable)
|
||||
# * ln -s hook-chain <hookname>
|
||||
#
|
||||
# Now the scripts in that directory should be called in order.
|
||||
#
|
||||
# Set $HOOKCHAIN_DEBUG to see the names of invoked scripts.
|
||||
#
|
||||
# Based on script by Oliver Reflalo:
|
||||
# https://stackoverflow.com/questions/8730514/chaining-git-hooks
|
||||
#
|
||||
|
||||
hookname=`basename $0`
|
||||
|
||||
# Temp file for stdin, cleared at exit
|
||||
FILE=`mktemp`
|
||||
trap 'rm -f $FILE' EXIT
|
||||
cat - > $FILE
|
||||
|
||||
# Git hooks directory (this dir)
|
||||
DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" >/dev/null && pwd )"
|
||||
|
||||
# Execute hooks in the directory one by one
|
||||
for hook in $DIR/$hookname.d/*;
|
||||
do
|
||||
if [ -x "$hook" ]; then
|
||||
|
||||
if [ "$HOOKCHAIN_DEBUG" ]; then
|
||||
echo "Running hook $hook"
|
||||
fi
|
||||
|
||||
cat $FILE | $hook "$@"
|
||||
status=$?
|
||||
|
||||
if [ $status -ne 0 ]; then
|
||||
echo "Hook $hook failed with error code $status"
|
||||
echo "To commit anyway, use --no-verify"
|
||||
exit $status
|
||||
else
|
||||
if [ "$HOOKCHAIN_DEBUG" ]; then
|
||||
echo "Hook passed: $hook"
|
||||
fi
|
||||
fi
|
||||
fi
|
||||
done
|
||||
@@ -1 +0,0 @@
|
||||
hook-chain
|
||||
@@ -1,91 +0,0 @@
|
||||
#!/usr/bin/env bash
|
||||
#
|
||||
# Runs clang-format on changed regions before commit.
|
||||
#
|
||||
# Remaining installation checks/instructions will be printed when you commit.
|
||||
#
|
||||
# Based on clang-format pre-commit hook by Alex Eagle
|
||||
# https://gist.github.com/alexeagle/c8ed91b14a407342d9a8e112b5ac7dab
|
||||
|
||||
# Set kicad.check-format to allow this hook to run
|
||||
# If not set, the hook always succeeds.
|
||||
|
||||
do_format=false
|
||||
|
||||
# Check if formatting is configured
|
||||
if [ "$(git config --get kicad.check-format)" = true ]; then
|
||||
do_format=true
|
||||
fi
|
||||
|
||||
# Older env variable method
|
||||
if [ ! -z "$KICAD_CHECK_FORMAT" ]; then
|
||||
do_format=true
|
||||
fi
|
||||
|
||||
if [ ! ${do_format} = true ]; then
|
||||
# No formatting required
|
||||
exit 0;
|
||||
fi
|
||||
|
||||
check_clang_format() {
|
||||
if hash git-clang-format 2>/dev/null; then
|
||||
return
|
||||
else
|
||||
echo "SETUP ERROR: no git-clang-format executable found, or it is not executable"
|
||||
exit 1
|
||||
fi
|
||||
}
|
||||
|
||||
check_git_config() {
|
||||
if [[ "$(git config --get clangFormat.style)" != "file" ]]; then
|
||||
echo "SETUP ERROR: git config clangFormat.style is wrong (should be 'file'). Fix this with:"
|
||||
echo "git config clangFormat.style file"
|
||||
exit 1
|
||||
fi
|
||||
}
|
||||
|
||||
get_filtered_filenames()
|
||||
{
|
||||
format_attr='clang-format-kicad'
|
||||
|
||||
# command to get list of candidate files
|
||||
git_list_files='git diff --cached --name-only --diff-filter=ACM'
|
||||
|
||||
files=$(${git_list_files} |
|
||||
|
||||
# Filter for format-controlled files
|
||||
git check-attr --stdin format.${format_attr} |
|
||||
|
||||
# output only the file names
|
||||
grep ": set$" |
|
||||
cut -d: -f1)
|
||||
|
||||
echo ${files}
|
||||
}
|
||||
|
||||
check_clang_format
|
||||
check_git_config
|
||||
|
||||
files_to_check=$(get_filtered_filenames)
|
||||
|
||||
if [ -z "${files_to_check}" ]; then
|
||||
# No controlled files to check
|
||||
exit 0;
|
||||
fi
|
||||
|
||||
git_clang_format_cmd="git clang-format -v --diff -- ${files_to_check}"
|
||||
|
||||
readonly out=$(${git_clang_format_cmd})
|
||||
|
||||
# In these cases, there is no formatting issues, so we succeed
|
||||
if [[ "$out" == *"no modified files to format"* ]]; then exit 0; fi
|
||||
if [[ "$out" == *"clang-format did not modify any files"* ]]; then exit 0; fi
|
||||
|
||||
# Any other case implies formatting results
|
||||
echo "ERROR: you need to run clang-format (e.g. using tools/check_coding.sh) on your commit"
|
||||
|
||||
# print the errors to show what's the issue
|
||||
${git_clang_format_cmd}
|
||||
|
||||
# fail the pre-commit
|
||||
exit 1
|
||||
+2
-22
@@ -20,6 +20,7 @@ eeschema/dialogs/dialog_bom_cfg_lexer.h
|
||||
eeschema/dialogs/dialog_bom_help_html.h
|
||||
eeschema/template_fieldnames_keywords.*
|
||||
eeschema/template_fieldnames_lexer.h
|
||||
pcbnew/dialogs/dialog_freeroute_exchange_help_html.h
|
||||
pcbnew/pcb_plot_params_keywords.cpp
|
||||
pcbnew/pcb_plot_params_lexer.h
|
||||
pcb_calculator/attenuators/bridget_tee_formula.h
|
||||
@@ -52,22 +53,10 @@ bitmaps_png/png*
|
||||
bitmaps_png/tmp
|
||||
common/pcb_keywords.cpp
|
||||
include/pcb_lexer.h
|
||||
fp-info-cache
|
||||
|
||||
# demo project auxillary files
|
||||
demos/**/*-bak
|
||||
demos/**/_autosave-*
|
||||
demos/**/fp-info-cache
|
||||
|
||||
# MacOS package info created by CMake
|
||||
bitmap2component/Info.plist
|
||||
cvpcb/Info.plist
|
||||
eeschema/Info.plist
|
||||
gerbview/Info.plist
|
||||
kicad/Info.plist
|
||||
pagelayout_editor/Info.plist
|
||||
pcb_calculator/Info.plist
|
||||
pcbnew/Info.plist
|
||||
|
||||
# editor/OS fluff
|
||||
.*.swp
|
||||
@@ -85,13 +74,4 @@ pcbnew/Info.plist
|
||||
*.old
|
||||
*.gch
|
||||
*.orig
|
||||
*.patch
|
||||
|
||||
# These CMake files are wanted
|
||||
!CMakeModules/*.cmake
|
||||
|
||||
# Eclipse IDE
|
||||
.project
|
||||
.cproject
|
||||
.pydevproject
|
||||
__pycache__
|
||||
*.patch
|
||||
@@ -50,7 +50,7 @@
|
||||
#include "3d_cache.h"
|
||||
#include "3d_info.h"
|
||||
#include "sg/scenegraph.h"
|
||||
#include "filename_resolver.h"
|
||||
#include "3d_filename_resolver.h"
|
||||
#include "3d_plugin_manager.h"
|
||||
#include "plugins/3dapi/ifsg_api.h"
|
||||
|
||||
@@ -184,7 +184,7 @@ const wxString S3D_CACHE_ENTRY::GetCacheBaseName( void )
|
||||
S3D_CACHE::S3D_CACHE()
|
||||
{
|
||||
m_DirtyCache = false;
|
||||
m_FNResolver = new FILENAME_RESOLVER;
|
||||
m_FNResolver = new S3D_FILENAME_RESOLVER;
|
||||
m_Plugins = new S3D_PLUGIN_MANAGER;
|
||||
|
||||
return;
|
||||
@@ -222,7 +222,7 @@ SCENEGRAPH* S3D_CACHE::load( const wxString& aModelFile, S3D_CACHE_ENTRY** aCach
|
||||
|
||||
// check cache if file is already loaded
|
||||
wxCriticalSectionLocker lock( lock3D_cache );
|
||||
std::map< wxString, S3D_CACHE_ENTRY*, rsort_wxString >::iterator mi;
|
||||
std::map< wxString, S3D_CACHE_ENTRY*, S3D::rsort_wxString >::iterator mi;
|
||||
mi = m_CacheMap.find( full3Dpath );
|
||||
|
||||
if( mi != m_CacheMap.end() )
|
||||
@@ -369,7 +369,7 @@ bool S3D_CACHE::getSHA1( const wxString& aFileName, unsigned char* aSHA1Sum )
|
||||
return false;
|
||||
}
|
||||
|
||||
#ifdef _WIN32
|
||||
#ifdef WIN32
|
||||
FILE* fp = _wfopen( aFileName.wc_str(), L"rb" );
|
||||
#else
|
||||
FILE* fp = fopen( aFileName.ToUTF8(), "rb" );
|
||||
@@ -680,7 +680,7 @@ wxString S3D_CACHE::GetProjectDir( void )
|
||||
}
|
||||
|
||||
|
||||
FILENAME_RESOLVER* S3D_CACHE::GetResolver( void )
|
||||
S3D_FILENAME_RESOLVER* S3D_CACHE::GetResolver( void )
|
||||
{
|
||||
return m_FNResolver;
|
||||
}
|
||||
@@ -757,7 +757,7 @@ wxString S3D_CACHE::GetModelHash( const wxString& aModelFileName )
|
||||
return wxEmptyString;
|
||||
|
||||
// check cache if file is already loaded
|
||||
std::map< wxString, S3D_CACHE_ENTRY*, rsort_wxString >::iterator mi;
|
||||
std::map< wxString, S3D_CACHE_ENTRY*, S3D::rsort_wxString >::iterator mi;
|
||||
mi = m_CacheMap.find( full3Dpath );
|
||||
|
||||
if( mi != m_CacheMap.end() )
|
||||
|
||||
@@ -32,8 +32,8 @@
|
||||
#include <list>
|
||||
#include <map>
|
||||
#include <wx/string.h>
|
||||
#include "kicad_string.h"
|
||||
#include "filename_resolver.h"
|
||||
#include "str_rsort.h"
|
||||
#include "3d_filename_resolver.h"
|
||||
#include "3d_info.h"
|
||||
#include "plugins/3dapi/c3dmodel.h"
|
||||
|
||||
@@ -42,7 +42,7 @@ class PGM_BASE;
|
||||
class S3D_CACHE;
|
||||
class S3D_CACHE_ENTRY;
|
||||
class SCENEGRAPH;
|
||||
class FILENAME_RESOLVER;
|
||||
class S3D_FILENAME_RESOLVER;
|
||||
class S3D_PLUGIN_MANAGER;
|
||||
|
||||
|
||||
@@ -53,10 +53,10 @@ private:
|
||||
std::list< S3D_CACHE_ENTRY* > m_CacheList;
|
||||
|
||||
/// mapping of file names to cache names and data
|
||||
std::map< wxString, S3D_CACHE_ENTRY*, rsort_wxString > m_CacheMap;
|
||||
std::map< wxString, S3D_CACHE_ENTRY*, S3D::rsort_wxString > m_CacheMap;
|
||||
|
||||
/// object to resolve file names
|
||||
FILENAME_RESOLVER* m_FNResolver;
|
||||
S3D_FILENAME_RESOLVER* m_FNResolver;
|
||||
|
||||
/// plugin manager
|
||||
S3D_PLUGIN_MANAGER* m_Plugins;
|
||||
@@ -167,7 +167,7 @@ public:
|
||||
*/
|
||||
SCENEGRAPH* Load( const wxString& aModelFile );
|
||||
|
||||
FILENAME_RESOLVER* GetResolver( void );
|
||||
S3D_FILENAME_RESOLVER* GetResolver( void );
|
||||
|
||||
/**
|
||||
* Function GetFileFilters
|
||||
|
||||
@@ -40,12 +40,6 @@ CACHE_WRAPPER::~CACHE_WRAPPER()
|
||||
}
|
||||
|
||||
|
||||
FILENAME_RESOLVER* PROJECT::Get3DFilenameResolver()
|
||||
{
|
||||
return Get3DCacheManager()->GetResolver();
|
||||
}
|
||||
|
||||
|
||||
S3D_CACHE* PROJECT::Get3DCacheManager( bool updateProjDir )
|
||||
{
|
||||
wxCriticalSectionLocker lock( lock3D_wrapper );
|
||||
|
||||
@@ -30,8 +30,6 @@
|
||||
class CACHE_WRAPPER : public S3D_CACHE, public PROJECT::_ELEM
|
||||
{
|
||||
public:
|
||||
KICAD_T Type() override { return CACHE_WRAPPER_T; }
|
||||
|
||||
CACHE_WRAPPER();
|
||||
virtual ~CACHE_WRAPPER();
|
||||
};
|
||||
|
||||
@@ -22,6 +22,7 @@
|
||||
*/
|
||||
|
||||
#include <sstream>
|
||||
#include <cstring>
|
||||
#include <fstream>
|
||||
#include <sstream>
|
||||
#include <wx/filename.h>
|
||||
@@ -31,11 +32,11 @@
|
||||
#include <trace_helpers.h>
|
||||
|
||||
#include "common.h"
|
||||
#include "filename_resolver.h"
|
||||
#include "3d_filename_resolver.h"
|
||||
|
||||
// configuration file version
|
||||
#define CFGFILE_VERSION 1
|
||||
#define RESOLVER_CONFIG wxT( "3Dresolver.cfg" )
|
||||
#define S3D_RESOLVER_CONFIG wxT( "3Dresolver.cfg" )
|
||||
|
||||
// flag bits used to track different one-off messages to users
|
||||
#define ERRFLG_ALIAS (1)
|
||||
@@ -44,19 +45,19 @@
|
||||
|
||||
#define MASK_3D_RESOLVER "3D_RESOLVER"
|
||||
|
||||
static wxCriticalSection lock_resolver;
|
||||
static wxCriticalSection lock3D_resolver;
|
||||
|
||||
static bool getHollerith( const std::string& aString, size_t& aIndex, wxString& aResult );
|
||||
|
||||
|
||||
FILENAME_RESOLVER::FILENAME_RESOLVER()
|
||||
S3D_FILENAME_RESOLVER::S3D_FILENAME_RESOLVER()
|
||||
{
|
||||
m_errflags = 0;
|
||||
m_pgm = NULL;
|
||||
}
|
||||
|
||||
|
||||
bool FILENAME_RESOLVER::Set3DConfigDir( const wxString& aConfigDir )
|
||||
bool S3D_FILENAME_RESOLVER::Set3DConfigDir( const wxString& aConfigDir )
|
||||
{
|
||||
if( aConfigDir.empty() )
|
||||
return false;
|
||||
@@ -70,7 +71,7 @@ bool FILENAME_RESOLVER::Set3DConfigDir( const wxString& aConfigDir )
|
||||
|
||||
cfgdir.Normalize();
|
||||
|
||||
if( !cfgdir.DirExists() )
|
||||
if( false == cfgdir.DirExists() )
|
||||
return false;
|
||||
|
||||
m_ConfigDir = cfgdir.GetPath();
|
||||
@@ -80,7 +81,7 @@ bool FILENAME_RESOLVER::Set3DConfigDir( const wxString& aConfigDir )
|
||||
}
|
||||
|
||||
|
||||
bool FILENAME_RESOLVER::SetProjectDir( const wxString& aProjDir, bool* flgChanged )
|
||||
bool S3D_FILENAME_RESOLVER::SetProjectDir( const wxString& aProjDir, bool* flgChanged )
|
||||
{
|
||||
if( aProjDir.empty() )
|
||||
return false;
|
||||
@@ -94,7 +95,7 @@ bool FILENAME_RESOLVER::SetProjectDir( const wxString& aProjDir, bool* flgChange
|
||||
|
||||
projdir.Normalize();
|
||||
|
||||
if( !projdir.DirExists() )
|
||||
if( false == projdir.DirExists() )
|
||||
return false;
|
||||
|
||||
m_curProjDir = projdir.GetPath();
|
||||
@@ -104,7 +105,7 @@ bool FILENAME_RESOLVER::SetProjectDir( const wxString& aProjDir, bool* flgChange
|
||||
|
||||
if( m_Paths.empty() )
|
||||
{
|
||||
SEARCH_PATH al;
|
||||
S3D_ALIAS al;
|
||||
al.m_alias = "${KIPRJMOD}";
|
||||
al.m_pathvar = "${KIPRJMOD}";
|
||||
al.m_pathexp = m_curProjDir;
|
||||
@@ -144,26 +145,28 @@ bool FILENAME_RESOLVER::SetProjectDir( const wxString& aProjDir, bool* flgChange
|
||||
}
|
||||
|
||||
|
||||
wxString FILENAME_RESOLVER::GetProjectDir()
|
||||
wxString S3D_FILENAME_RESOLVER::GetProjectDir( void )
|
||||
{
|
||||
return m_curProjDir;
|
||||
}
|
||||
|
||||
|
||||
void FILENAME_RESOLVER::SetProgramBase( PGM_BASE* aBase )
|
||||
void S3D_FILENAME_RESOLVER::SetProgramBase( PGM_BASE* aBase )
|
||||
{
|
||||
m_pgm = aBase;
|
||||
|
||||
if( !m_pgm || m_Paths.empty() )
|
||||
if( NULL == m_pgm || m_Paths.empty() )
|
||||
return;
|
||||
|
||||
// recreate the path list
|
||||
m_Paths.clear();
|
||||
createPathList();
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
bool FILENAME_RESOLVER::createPathList()
|
||||
bool S3D_FILENAME_RESOLVER::createPathList( void )
|
||||
{
|
||||
if( !m_Paths.empty() )
|
||||
return true;
|
||||
@@ -174,7 +177,7 @@ bool FILENAME_RESOLVER::createPathList()
|
||||
// we cannot set a sensible default so we use an empty string.
|
||||
// the user may change this later with a call to SetProjectDir()
|
||||
|
||||
SEARCH_PATH lpath;
|
||||
S3D_ALIAS lpath;
|
||||
lpath.m_alias = "${KIPRJMOD}";
|
||||
lpath.m_pathvar = "${KIPRJMOD}";
|
||||
lpath.m_pathexp = m_curProjDir;
|
||||
@@ -218,8 +221,8 @@ bool FILENAME_RESOLVER::createPathList()
|
||||
|
||||
#ifdef DEBUG
|
||||
wxLogTrace( MASK_3D_RESOLVER, " * [3D model] search paths:\n" );
|
||||
std::list< SEARCH_PATH >::const_iterator sPL = m_Paths.begin();
|
||||
std::list< SEARCH_PATH >::const_iterator ePL = m_Paths.end();
|
||||
std::list< S3D_ALIAS >::const_iterator sPL = m_Paths.begin();
|
||||
std::list< S3D_ALIAS >::const_iterator ePL = m_Paths.end();
|
||||
|
||||
while( sPL != ePL )
|
||||
{
|
||||
@@ -233,7 +236,7 @@ bool FILENAME_RESOLVER::createPathList()
|
||||
}
|
||||
|
||||
|
||||
bool FILENAME_RESOLVER::UpdatePathList( std::vector< SEARCH_PATH >& aPathList )
|
||||
bool S3D_FILENAME_RESOLVER::UpdatePathList( std::vector< S3D_ALIAS >& aPathList )
|
||||
{
|
||||
wxUniChar envMarker( '$' );
|
||||
|
||||
@@ -249,9 +252,9 @@ bool FILENAME_RESOLVER::UpdatePathList( std::vector< SEARCH_PATH >& aPathList )
|
||||
}
|
||||
|
||||
|
||||
wxString FILENAME_RESOLVER::ResolvePath( const wxString& aFileName )
|
||||
wxString S3D_FILENAME_RESOLVER::ResolvePath( const wxString& aFileName )
|
||||
{
|
||||
wxCriticalSectionLocker lock( lock_resolver );
|
||||
wxCriticalSectionLocker lock( lock3D_resolver );
|
||||
|
||||
if( aFileName.empty() )
|
||||
return wxEmptyString;
|
||||
@@ -326,8 +329,8 @@ wxString FILENAME_RESOLVER::ResolvePath( const wxString& aFileName )
|
||||
// a. an aliased shortened name or
|
||||
// b. cannot be determined
|
||||
|
||||
std::list< SEARCH_PATH >::const_iterator sPL = m_Paths.begin();
|
||||
std::list< SEARCH_PATH >::const_iterator ePL = m_Paths.end();
|
||||
std::list< S3D_ALIAS >::const_iterator sPL = m_Paths.begin();
|
||||
std::list< S3D_ALIAS >::const_iterator ePL = m_Paths.end();
|
||||
|
||||
// check the path relative to the current project directory;
|
||||
// note: this is not necessarily the same as the current working
|
||||
@@ -435,14 +438,14 @@ wxString FILENAME_RESOLVER::ResolvePath( const wxString& aFileName )
|
||||
}
|
||||
|
||||
|
||||
bool FILENAME_RESOLVER::addPath( const SEARCH_PATH& aPath )
|
||||
bool S3D_FILENAME_RESOLVER::addPath( const S3D_ALIAS& aPath )
|
||||
{
|
||||
if( aPath.m_alias.empty() || aPath.m_pathvar.empty() )
|
||||
return false;
|
||||
|
||||
wxCriticalSectionLocker lock( lock_resolver );
|
||||
wxCriticalSectionLocker lock( lock3D_resolver );
|
||||
|
||||
SEARCH_PATH tpath = aPath;
|
||||
S3D_ALIAS tpath = aPath;
|
||||
|
||||
#ifdef _WIN32
|
||||
while( tpath.m_pathvar.EndsWith( wxT( "\\" ) ) )
|
||||
@@ -489,8 +492,8 @@ bool FILENAME_RESOLVER::addPath( const SEARCH_PATH& aPath )
|
||||
}
|
||||
|
||||
wxString pname = path.GetPath();
|
||||
std::list< SEARCH_PATH >::iterator sPL = m_Paths.begin();
|
||||
std::list< SEARCH_PATH >::iterator ePL = m_Paths.end();
|
||||
std::list< S3D_ALIAS >::iterator sPL = m_Paths.begin();
|
||||
std::list< S3D_ALIAS >::iterator ePL = m_Paths.end();
|
||||
|
||||
while( sPL != ePL )
|
||||
{
|
||||
@@ -517,7 +520,7 @@ bool FILENAME_RESOLVER::addPath( const SEARCH_PATH& aPath )
|
||||
}
|
||||
|
||||
|
||||
bool FILENAME_RESOLVER::readPathList()
|
||||
bool S3D_FILENAME_RESOLVER::readPathList( void )
|
||||
{
|
||||
if( m_ConfigDir.empty() )
|
||||
{
|
||||
@@ -529,7 +532,7 @@ bool FILENAME_RESOLVER::readPathList()
|
||||
return false;
|
||||
}
|
||||
|
||||
wxFileName cfgpath( m_ConfigDir, RESOLVER_CONFIG );
|
||||
wxFileName cfgpath( m_ConfigDir, S3D_RESOLVER_CONFIG );
|
||||
cfgpath.Normalize();
|
||||
wxString cfgname = cfgpath.GetFullPath();
|
||||
|
||||
@@ -562,7 +565,7 @@ bool FILENAME_RESOLVER::readPathList()
|
||||
}
|
||||
|
||||
int lineno = 0;
|
||||
SEARCH_PATH al;
|
||||
S3D_ALIAS al;
|
||||
size_t idx;
|
||||
int vnum = 0; // version number
|
||||
|
||||
@@ -616,11 +619,14 @@ bool FILENAME_RESOLVER::readPathList()
|
||||
if( vnum < CFGFILE_VERSION )
|
||||
writePathList();
|
||||
|
||||
return( m_Paths.size() != nitems );
|
||||
if( m_Paths.size() != nitems )
|
||||
return true;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
bool FILENAME_RESOLVER::writePathList()
|
||||
bool S3D_FILENAME_RESOLVER::writePathList( void )
|
||||
{
|
||||
if( m_ConfigDir.empty() )
|
||||
{
|
||||
@@ -635,13 +641,13 @@ bool FILENAME_RESOLVER::writePathList()
|
||||
}
|
||||
|
||||
// skip all ${ENV_VAR} alias names
|
||||
std::list< SEARCH_PATH >::const_iterator sPL = m_Paths.begin();
|
||||
std::list< SEARCH_PATH >::const_iterator ePL = m_Paths.end();
|
||||
std::list< S3D_ALIAS >::const_iterator sPL = m_Paths.begin();
|
||||
std::list< S3D_ALIAS >::const_iterator ePL = m_Paths.end();
|
||||
|
||||
while( sPL != ePL && ( sPL->m_alias.StartsWith( "${" ) || sPL->m_alias.StartsWith( "$(" ) ) )
|
||||
++sPL;
|
||||
|
||||
wxFileName cfgpath( m_ConfigDir, RESOLVER_CONFIG );
|
||||
wxFileName cfgpath( m_ConfigDir, S3D_RESOLVER_CONFIG );
|
||||
wxString cfgname = cfgpath.GetFullPath();
|
||||
std::ofstream cfgFile;
|
||||
|
||||
@@ -688,7 +694,7 @@ bool FILENAME_RESOLVER::writePathList()
|
||||
}
|
||||
|
||||
|
||||
void FILENAME_RESOLVER::checkEnvVarPath( const wxString& aPath )
|
||||
void S3D_FILENAME_RESOLVER::checkEnvVarPath( const wxString& aPath )
|
||||
{
|
||||
bool useParen = false;
|
||||
|
||||
@@ -725,7 +731,7 @@ void FILENAME_RESOLVER::checkEnvVarPath( const wxString& aPath )
|
||||
++sPL;
|
||||
}
|
||||
|
||||
SEARCH_PATH lpath;
|
||||
S3D_ALIAS lpath;
|
||||
lpath.m_alias = envar;
|
||||
lpath.m_pathvar = lpath.m_alias;
|
||||
wxFileName tmpFN;
|
||||
@@ -750,19 +756,20 @@ void FILENAME_RESOLVER::checkEnvVarPath( const wxString& aPath )
|
||||
return;
|
||||
|
||||
m_Paths.insert( sPL, lpath );
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
wxString FILENAME_RESOLVER::ShortenPath( const wxString& aFullPathName )
|
||||
wxString S3D_FILENAME_RESOLVER::ShortenPath( const wxString& aFullPathName )
|
||||
{
|
||||
wxString fname = aFullPathName;
|
||||
|
||||
if( m_Paths.empty() )
|
||||
createPathList();
|
||||
|
||||
wxCriticalSectionLocker lock( lock_resolver );
|
||||
std::list< SEARCH_PATH >::const_iterator sL = m_Paths.begin();
|
||||
std::list< SEARCH_PATH >::const_iterator eL = m_Paths.end();
|
||||
wxCriticalSectionLocker lock( lock3D_resolver );
|
||||
std::list< S3D_ALIAS >::const_iterator sL = m_Paths.begin();
|
||||
std::list< S3D_ALIAS >::const_iterator eL = m_Paths.end();
|
||||
size_t idx;
|
||||
|
||||
while( sL != eL )
|
||||
@@ -800,7 +807,7 @@ wxString FILENAME_RESOLVER::ShortenPath( const wxString& aFullPathName )
|
||||
|
||||
idx = fname.find( fps );
|
||||
|
||||
if( idx == 0 )
|
||||
if( std::string::npos != idx && 0 == idx )
|
||||
{
|
||||
fname = fname.substr( fps.size() );
|
||||
|
||||
@@ -844,13 +851,13 @@ wxString FILENAME_RESOLVER::ShortenPath( const wxString& aFullPathName )
|
||||
|
||||
|
||||
|
||||
const std::list< SEARCH_PATH >* FILENAME_RESOLVER::GetPaths()
|
||||
const std::list< S3D_ALIAS >* S3D_FILENAME_RESOLVER::GetPaths( void )
|
||||
{
|
||||
return &m_Paths;
|
||||
}
|
||||
|
||||
|
||||
bool FILENAME_RESOLVER::SplitAlias( const wxString& aFileName,
|
||||
bool S3D_FILENAME_RESOLVER::SplitAlias( const wxString& aFileName,
|
||||
wxString& anAlias, wxString& aRelPath )
|
||||
{
|
||||
anAlias.clear();
|
||||
@@ -969,7 +976,7 @@ static bool getHollerith( const std::string& aString, size_t& aIndex, wxString&
|
||||
}
|
||||
|
||||
|
||||
bool FILENAME_RESOLVER::ValidateFileName( const wxString& aFileName, bool& hasAlias )
|
||||
bool S3D_FILENAME_RESOLVER::ValidateFileName( const wxString& aFileName, bool& hasAlias )
|
||||
{
|
||||
// Rules:
|
||||
// 1. The generic form of an aliased 3D relative path is:
|
||||
@@ -1027,7 +1034,7 @@ bool FILENAME_RESOLVER::ValidateFileName( const wxString& aFileName, bool& hasAl
|
||||
}
|
||||
|
||||
|
||||
bool FILENAME_RESOLVER::GetKicadPaths( std::list< wxString >& paths )
|
||||
bool S3D_FILENAME_RESOLVER::GetKicadPaths( std::list< wxString >& paths )
|
||||
{
|
||||
paths.clear();
|
||||
|
||||
@@ -22,7 +22,7 @@
|
||||
*/
|
||||
|
||||
/**
|
||||
* @file filename_resolver.h
|
||||
* @file 3d_filename_resolver.h
|
||||
* provides an extensible class to resolve 3D model paths. Initially
|
||||
* the legacy behavior will be implemented and an incomplete path
|
||||
* would be checked against the project directory or the KISYS3DMOD
|
||||
@@ -30,17 +30,18 @@
|
||||
* paths may be specified.
|
||||
*/
|
||||
|
||||
#ifndef FILENAME_RESOLVER_H
|
||||
#define FILENAME_RESOLVER_H
|
||||
#ifndef FILENAME_RESOLVER_3D_H
|
||||
#define FILENAME_RESOLVER_3D_H
|
||||
|
||||
#include <list>
|
||||
#include <map>
|
||||
#include <vector>
|
||||
#include <wx/string.h>
|
||||
#include "str_rsort.h"
|
||||
|
||||
class PGM_BASE;
|
||||
|
||||
struct SEARCH_PATH
|
||||
struct S3D_ALIAS
|
||||
{
|
||||
wxString m_alias; // alias to the base path
|
||||
wxString m_pathvar; // base path as stored in the config file
|
||||
@@ -48,11 +49,11 @@ struct SEARCH_PATH
|
||||
wxString m_description; // description of the aliased path
|
||||
};
|
||||
|
||||
class FILENAME_RESOLVER
|
||||
class S3D_FILENAME_RESOLVER
|
||||
{
|
||||
private:
|
||||
wxString m_ConfigDir; // 3D configuration directory
|
||||
std::list< SEARCH_PATH > m_Paths; // list of base paths to search from
|
||||
std::list< S3D_ALIAS > m_Paths; // list of base paths to search from
|
||||
int m_errflags;
|
||||
PGM_BASE* m_pgm;
|
||||
wxString m_curProjDir;
|
||||
@@ -75,7 +76,7 @@ private:
|
||||
* @param aPath is the alias set to be checked and added
|
||||
* @return true if aPath is valid
|
||||
*/
|
||||
bool addPath( const SEARCH_PATH& aPath );
|
||||
bool addPath( const S3D_ALIAS& aPath );
|
||||
|
||||
/**
|
||||
* Function readPathList
|
||||
@@ -104,7 +105,7 @@ private:
|
||||
void checkEnvVarPath( const wxString& aPath );
|
||||
|
||||
public:
|
||||
FILENAME_RESOLVER();
|
||||
S3D_FILENAME_RESOLVER();
|
||||
|
||||
/**
|
||||
* Function Set3DConfigDir
|
||||
@@ -142,7 +143,7 @@ public:
|
||||
* clears the current path list and substitutes the given path
|
||||
* list, updating the path configuration file on success.
|
||||
*/
|
||||
bool UpdatePathList( std::vector< SEARCH_PATH >& aPathList );
|
||||
bool UpdatePathList( std::vector< S3D_ALIAS >& aPathList );
|
||||
|
||||
/**
|
||||
* Function ResolvePath
|
||||
@@ -174,7 +175,7 @@ public:
|
||||
*
|
||||
* @return pointer to the internal path list
|
||||
*/
|
||||
const std::list< SEARCH_PATH >* GetPaths( void );
|
||||
const std::list< S3D_ALIAS >* GetPaths( void );
|
||||
|
||||
/**
|
||||
* Function SplitAlias
|
||||
@@ -200,4 +201,4 @@ public:
|
||||
bool GetKicadPaths( std::list< wxString >& paths );
|
||||
};
|
||||
|
||||
#endif // FILENAME_RESOLVER_H
|
||||
#endif // FILENAME_RESOLVER_3D_H
|
||||
@@ -149,10 +149,14 @@ void S3D_PLUGIN_MANAGER::loadPlugins( void )
|
||||
#endif
|
||||
|
||||
#ifndef _WIN32
|
||||
// PLUGINDIR = CMAKE_INSTALL_FULL_LIBDIR path is the absolute path
|
||||
// corresponding to the install path used for constructing KICAD_USER_PLUGIN
|
||||
// multiarch friendly determination of the plugin directory: the executable dir
|
||||
// is first determined via wxStandardPaths::Get().GetExecutablePath() and then
|
||||
// the CMAKE_INSTALL_LIBDIR path is appended relative to the executable dir.
|
||||
|
||||
wxString tfname = wxString::FromUTF8Unchecked( PLUGINDIR );
|
||||
fn.Assign( wxStandardPaths::Get().GetExecutablePath() );
|
||||
fn.RemoveLastDir();
|
||||
wxString tfname = fn.GetPathWithSep();
|
||||
tfname.Append( wxString::FromUTF8Unchecked( PLUGINDIR ) );
|
||||
fn.Assign( tfname, "");
|
||||
fn.AppendDir( "kicad" );
|
||||
#else
|
||||
@@ -486,7 +490,7 @@ SCENEGRAPH* S3D_PLUGIN_MANAGER::Load3DModel( const wxString& aFileName, std::str
|
||||
wxFileName raw( aFileName );
|
||||
wxString ext = raw.GetExt();
|
||||
|
||||
#ifdef _WIN32
|
||||
#ifdef WIN32
|
||||
// note: plugins only have a lowercase filter within Windows; including an uppercase
|
||||
// filter will result in duplicate file entries and should be avoided.
|
||||
ext.LowerCase();
|
||||
|
||||
@@ -27,7 +27,7 @@
|
||||
#include "3d_cache.h"
|
||||
#include "plugins/3dapi/ifsg_api.h"
|
||||
#include "3d_cache_dialogs.h"
|
||||
#include "dialog_configure_paths.h"
|
||||
#include "dlg_3d_pathconfig.h"
|
||||
#include "dlg_select_3dmodel.h"
|
||||
|
||||
|
||||
@@ -51,9 +51,16 @@ bool S3D::Select3DModel( wxWindow* aParent, S3D_CACHE* aCache,
|
||||
}
|
||||
|
||||
|
||||
bool S3D::Configure3DPaths( wxWindow* aParent, FILENAME_RESOLVER* aResolver )
|
||||
bool S3D::Configure3DPaths( wxWindow* aParent, S3D_FILENAME_RESOLVER* aResolver )
|
||||
{
|
||||
DIALOG_CONFIGURE_PATHS dlg( aParent, aResolver );
|
||||
DLG_3D_PATH_CONFIG* dp = new DLG_3D_PATH_CONFIG( aParent, aResolver );
|
||||
|
||||
return( dlg.ShowModal() == wxID_OK );
|
||||
if( wxID_OK == dp->ShowModal() )
|
||||
{
|
||||
delete dp;
|
||||
return true;
|
||||
}
|
||||
|
||||
delete dp;
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -27,14 +27,14 @@
|
||||
#include <wx/window.h>
|
||||
|
||||
class S3D_CACHE;
|
||||
class FILENAME_RESOLVER;
|
||||
class S3D_FILENAME_RESOLVER;
|
||||
|
||||
namespace S3D
|
||||
{
|
||||
bool Select3DModel( wxWindow* aParent, S3D_CACHE* aCache,
|
||||
wxString& prevModelSelectDir, int& prevModelWildcard, MODULE_3D_SETTINGS* aModel );
|
||||
|
||||
bool Configure3DPaths( wxWindow* aParent, FILENAME_RESOLVER* aResolver );
|
||||
bool Configure3DPaths( wxWindow* aParent, S3D_FILENAME_RESOLVER* aResolver );
|
||||
}
|
||||
|
||||
#endif // CACHE_DIALOGS_3D_H
|
||||
|
||||
@@ -0,0 +1,383 @@
|
||||
/*
|
||||
* This program source code file is part of KiCad, a free EDA CAD application.
|
||||
*
|
||||
* Copyright (C) 2016 Cirilo Bernardo <cirilo.bernardo@gmail.com>
|
||||
*
|
||||
* 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 <wx/msgdlg.h>
|
||||
#include <pgm_base.h>
|
||||
#include <html_messagebox.h>
|
||||
#include "3d_cache/dialogs/dlg_3d_pathconfig.h"
|
||||
#include "3d_cache/3d_filename_resolver.h"
|
||||
|
||||
DLG_3D_PATH_CONFIG::DLG_3D_PATH_CONFIG( wxWindow* aParent, S3D_FILENAME_RESOLVER* aResolver ) :
|
||||
DLG_3D_PATH_CONFIG_BASE( aParent ), m_resolver( aResolver )
|
||||
{
|
||||
initDialog();
|
||||
|
||||
GetSizer()->SetSizeHints( this );
|
||||
Centre();
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
void DLG_3D_PATH_CONFIG::initDialog()
|
||||
{
|
||||
m_Aliases->EnableEditing( true );
|
||||
|
||||
// Gives a min width to each column, when the user drags a column
|
||||
m_Aliases->SetColMinimalWidth( 0, 80 );
|
||||
m_Aliases->SetColMinimalWidth( 1, 300 );
|
||||
m_Aliases->SetColMinimalWidth( 2, 120 );
|
||||
m_Aliases->SetColMinimalAcceptableWidth( 80 );
|
||||
|
||||
// Set column sizes to this min value
|
||||
m_Aliases->SetColSize( 0, 80 );
|
||||
m_Aliases->SetColSize( 1, 300 );
|
||||
m_Aliases->SetColSize( 2, 120 );
|
||||
|
||||
m_EnvVars->SetColMinimalWidth( 0, 80 );
|
||||
m_EnvVars->SetColMinimalWidth( 1, 300 );
|
||||
m_EnvVars->SetColMinimalAcceptableWidth( 80 );
|
||||
m_EnvVars->SetColSize( 0, 80 );
|
||||
m_EnvVars->SetColSize( 1, 300 );
|
||||
|
||||
if( m_resolver )
|
||||
{
|
||||
updateEnvVars();
|
||||
|
||||
// prohibit these characters in the alias names: []{}()%~<>"='`;:.,&?/\|$
|
||||
m_aliasValidator.SetStyle( wxFILTER_EXCLUDE_CHAR_LIST );
|
||||
m_aliasValidator.SetCharExcludes( wxT( "{}[]()%~<>\"='`;:.,&?/\\|$" ) );
|
||||
|
||||
const std::list< S3D_ALIAS >* rpaths = m_resolver->GetPaths();
|
||||
std::list< S3D_ALIAS >::const_iterator rI = rpaths->begin();
|
||||
std::list< S3D_ALIAS >::const_iterator rE = rpaths->end();
|
||||
size_t listsize = rpaths->size();
|
||||
size_t listidx = 0;
|
||||
|
||||
while( rI != rE && ( (*rI).m_alias.StartsWith( "${" ) || (*rI).m_alias.StartsWith( "$(" ) ) )
|
||||
{
|
||||
++listidx;
|
||||
++rI;
|
||||
}
|
||||
|
||||
if( listidx < listsize )
|
||||
m_curdir = (*rI).m_pathexp;
|
||||
else
|
||||
return;
|
||||
|
||||
listsize = listsize - listidx - m_Aliases->GetNumberRows();
|
||||
|
||||
// note: if the list allocation fails we have bigger problems
|
||||
// and there is no point in trying to notify the user here
|
||||
if( listsize > 0 && !m_Aliases->InsertRows( 0, listsize ) )
|
||||
return;
|
||||
|
||||
int nitems = 0;
|
||||
wxGridCellTextEditor* pEdAlias;
|
||||
|
||||
while( rI != rE )
|
||||
{
|
||||
m_Aliases->SetCellValue( nitems, 0, rI->m_alias );
|
||||
|
||||
if( 0 == nitems )
|
||||
{
|
||||
m_Aliases->SetCellEditor( nitems, 0, new wxGridCellTextEditor );
|
||||
pEdAlias = (wxGridCellTextEditor*) m_Aliases->GetCellEditor( nitems, 0 );
|
||||
pEdAlias->SetValidator( m_aliasValidator );
|
||||
pEdAlias->DecRef();
|
||||
}
|
||||
else
|
||||
{
|
||||
pEdAlias->IncRef();
|
||||
m_Aliases->SetCellEditor( nitems, 0, pEdAlias );
|
||||
}
|
||||
|
||||
m_Aliases->SetCellValue( nitems, 1, rI->m_pathvar );
|
||||
m_Aliases->SetCellValue( nitems++, 2, rI->m_description );
|
||||
|
||||
// TODO: implement a wxGridCellEditor which invokes a wxDirDialog
|
||||
|
||||
++rI;
|
||||
}
|
||||
|
||||
m_Aliases->AutoSize();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
bool DLG_3D_PATH_CONFIG::TransferDataFromWindow()
|
||||
{
|
||||
if( NULL == m_resolver )
|
||||
{
|
||||
wxMessageBox( _( "[BUG] No valid resolver; data will not be updated" ),
|
||||
_( "Update 3D search path list" ) );
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
std::vector<S3D_ALIAS> alist;
|
||||
S3D_ALIAS alias;
|
||||
|
||||
int ni = m_Aliases->GetNumberRows();
|
||||
|
||||
if( ni <= 0 )
|
||||
{
|
||||
// note: UI usability: we should ask a user if they're sure they
|
||||
// want to clear the entire path list
|
||||
m_resolver->UpdatePathList( alist );
|
||||
return true;
|
||||
}
|
||||
|
||||
for( int i = 0; i < ni; ++i )
|
||||
{
|
||||
alias.m_alias = m_Aliases->GetCellValue( i, 0 );
|
||||
alias.m_pathvar = m_Aliases->GetCellValue( i, 1 );
|
||||
alias.m_description = m_Aliases->GetCellValue( i, 2 );
|
||||
|
||||
if( !alias.m_alias.empty() && !alias.m_pathvar.empty() )
|
||||
alist.push_back( alias );
|
||||
|
||||
}
|
||||
|
||||
return m_resolver->UpdatePathList( alist );
|
||||
}
|
||||
|
||||
|
||||
void DLG_3D_PATH_CONFIG::OnAddAlias( wxCommandEvent& event )
|
||||
{
|
||||
int ni = m_Aliases->GetNumberRows();
|
||||
|
||||
if( m_Aliases->InsertRows( ni, 1 ) )
|
||||
{
|
||||
wxGridCellTextEditor* pEdAlias;
|
||||
pEdAlias = (wxGridCellTextEditor*) m_Aliases->GetCellEditor( 0, 0 );
|
||||
m_Aliases->SetCellEditor( ni, 0, pEdAlias );
|
||||
m_Aliases->SelectRow( ni, false );
|
||||
m_Aliases->AutoSize();
|
||||
Fit();
|
||||
|
||||
// TODO: set the editors on any newly created rows
|
||||
}
|
||||
|
||||
event.Skip();
|
||||
}
|
||||
|
||||
|
||||
void DLG_3D_PATH_CONFIG::OnDelAlias( wxCommandEvent& event )
|
||||
{
|
||||
wxArrayInt sel = m_Aliases->GetSelectedRows();
|
||||
|
||||
if( sel.empty() )
|
||||
{
|
||||
wxMessageBox( _( "No entry selected" ), _( "Delete alias entry" ) );
|
||||
return;
|
||||
}
|
||||
|
||||
if( sel.size() > 1 )
|
||||
{
|
||||
wxMessageBox( _( "Multiple entries selected; please\nselect only one entry" ),
|
||||
_( "Delete alias entry" ) );
|
||||
return;
|
||||
}
|
||||
|
||||
if( m_Aliases->GetNumberRows() > 1 )
|
||||
{
|
||||
int ni = sel.front();
|
||||
m_Aliases->DeleteRows( ni, 1 );
|
||||
|
||||
if( ni >= m_Aliases->GetNumberRows() )
|
||||
ni = m_Aliases->GetNumberRows() - 1;
|
||||
|
||||
m_Aliases->SelectRow( ni, false );
|
||||
m_Aliases->AutoSize();
|
||||
Fit();
|
||||
}
|
||||
else
|
||||
{
|
||||
m_Aliases->SetCellValue( 0, 0, wxEmptyString );
|
||||
m_Aliases->SetCellValue( 0, 1, wxEmptyString );
|
||||
m_Aliases->SetCellValue( 0, 2, wxEmptyString );
|
||||
}
|
||||
|
||||
event.Skip();
|
||||
}
|
||||
|
||||
|
||||
void DLG_3D_PATH_CONFIG::OnAliasMoveUp( wxCommandEvent& event )
|
||||
{
|
||||
wxArrayInt sel = m_Aliases->GetSelectedRows();
|
||||
|
||||
if( sel.empty() )
|
||||
{
|
||||
wxMessageBox( _( "No entry selected" ), _( "Move alias up" ) );
|
||||
return;
|
||||
}
|
||||
|
||||
if( sel.size() > 1 )
|
||||
{
|
||||
wxMessageBox( _( "Multiple entries selected; please\nselect only one entry" ),
|
||||
_( "Move alias up" ) );
|
||||
return;
|
||||
}
|
||||
|
||||
int ci = sel.front();
|
||||
|
||||
if( ci > 0 )
|
||||
{
|
||||
S3D_ALIAS al0;
|
||||
al0.m_alias = m_Aliases->GetCellValue( ci, 0 );
|
||||
al0.m_pathvar = m_Aliases->GetCellValue( ci, 1 );
|
||||
al0.m_description = m_Aliases->GetCellValue( ci, 2 );
|
||||
|
||||
int ni = ci - 1;
|
||||
m_Aliases->SetCellValue( ci, 0, m_Aliases->GetCellValue( ni, 0 ) );
|
||||
m_Aliases->SetCellValue( ci, 1, m_Aliases->GetCellValue( ni, 1 ) );
|
||||
m_Aliases->SetCellValue( ci, 2, m_Aliases->GetCellValue( ni, 2 ) );
|
||||
|
||||
m_Aliases->SetCellValue( ni, 0, al0.m_alias );
|
||||
m_Aliases->SetCellValue( ni, 1, al0.m_pathvar );
|
||||
m_Aliases->SetCellValue( ni, 2, al0.m_description );
|
||||
m_Aliases->SelectRow( ni, false );
|
||||
}
|
||||
|
||||
event.Skip();
|
||||
}
|
||||
|
||||
|
||||
void DLG_3D_PATH_CONFIG::OnAliasMoveDown( wxCommandEvent& event )
|
||||
{
|
||||
wxArrayInt sel = m_Aliases->GetSelectedRows();
|
||||
|
||||
if( sel.empty() )
|
||||
{
|
||||
wxMessageBox( _( "No entry selected" ), _( "Move alias down" ) );
|
||||
return;
|
||||
}
|
||||
|
||||
if( sel.size() > 1 )
|
||||
{
|
||||
wxMessageBox( _( "Multiple entries selected; please\nselect only one entry" ),
|
||||
_( "Move alias down" ) );
|
||||
return;
|
||||
}
|
||||
|
||||
int ni = m_Aliases->GetNumberRows() - 1;
|
||||
int ci = sel.front();
|
||||
|
||||
if( ci < ni )
|
||||
{
|
||||
S3D_ALIAS al0;
|
||||
al0.m_alias = m_Aliases->GetCellValue( ci, 0 );
|
||||
al0.m_pathvar = m_Aliases->GetCellValue( ci, 1 );
|
||||
al0.m_description = m_Aliases->GetCellValue( ci, 2 );
|
||||
|
||||
ni = ci + 1;
|
||||
m_Aliases->SetCellValue( ci, 0, m_Aliases->GetCellValue( ni, 0 ) );
|
||||
m_Aliases->SetCellValue( ci, 1, m_Aliases->GetCellValue( ni, 1 ) );
|
||||
m_Aliases->SetCellValue( ci, 2, m_Aliases->GetCellValue( ni, 2 ) );
|
||||
|
||||
m_Aliases->SetCellValue( ni, 0, al0.m_alias );
|
||||
m_Aliases->SetCellValue( ni, 1, al0.m_pathvar );
|
||||
m_Aliases->SetCellValue( ni, 2, al0.m_description );
|
||||
m_Aliases->SelectRow( ni, false );
|
||||
}
|
||||
|
||||
event.Skip();
|
||||
}
|
||||
|
||||
|
||||
void DLG_3D_PATH_CONFIG::OnConfigEnvVar( wxCommandEvent& event )
|
||||
{
|
||||
Pgm().ConfigurePaths( this );
|
||||
updateEnvVars();
|
||||
event.Skip();
|
||||
}
|
||||
|
||||
|
||||
void DLG_3D_PATH_CONFIG::updateEnvVars( void )
|
||||
{
|
||||
if( !m_resolver )
|
||||
return;
|
||||
|
||||
std::list< wxString > epaths;
|
||||
|
||||
m_resolver->GetKicadPaths( epaths );
|
||||
size_t nitems = epaths.size();
|
||||
size_t nrows = m_EnvVars->GetNumberRows();
|
||||
bool resize = nrows != nitems; // true after adding/removing env vars
|
||||
|
||||
if( nrows > nitems )
|
||||
{
|
||||
size_t ni = nrows - nitems;
|
||||
m_EnvVars->DeleteRows( 0, ni );
|
||||
}
|
||||
else if( nrows < nitems )
|
||||
{
|
||||
size_t ni = nitems - nrows;
|
||||
m_EnvVars->InsertRows( 0, ni );
|
||||
}
|
||||
|
||||
int j = 0;
|
||||
|
||||
for( const auto& i : epaths )
|
||||
{
|
||||
wxString val = ExpandEnvVarSubstitutions( i );
|
||||
m_EnvVars->SetCellValue( j, 0, i );
|
||||
m_EnvVars->SetCellValue( j, 1, val );
|
||||
m_EnvVars->SetReadOnly( j, 0, true );
|
||||
m_EnvVars->SetReadOnly( j, 1, true );
|
||||
wxGridCellAttr* ap = m_EnvVars->GetOrCreateCellAttr( j, 0 );
|
||||
ap->SetReadOnly( true );
|
||||
ap->SetBackgroundColour( *wxLIGHT_GREY );
|
||||
m_EnvVars->SetRowAttr( j, ap );
|
||||
++j;
|
||||
}
|
||||
|
||||
m_EnvVars->AutoSize();
|
||||
|
||||
// Resizing the full dialog is sometimes needed for a clean display
|
||||
// i.e. when adding/removing Kicad environment variables
|
||||
if( resize )
|
||||
GetSizer()->SetSizeHints( this );
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
void DLG_3D_PATH_CONFIG::OnHelp( wxCommandEvent& event )
|
||||
{
|
||||
wxString msg = _( "Enter the name and path for each 3D alias variable.<br>KiCad "
|
||||
"environment variables and their values are shown for "
|
||||
"reference only and cannot be edited." );
|
||||
msg << "<br><br><b>";
|
||||
msg << _( "Alias names may not contain any of the characters " );
|
||||
msg << "{}[]()%~<>\"='`;:.,&?/\\|$";
|
||||
msg << "</b>";
|
||||
|
||||
HTML_MESSAGE_BOX dlg( GetParent(), _( "Environment Variable Help" ) );
|
||||
dlg.AddHTML_Text( msg );
|
||||
dlg.ShowModal();
|
||||
|
||||
event.Skip();
|
||||
}
|
||||
+23
-15
@@ -1,7 +1,7 @@
|
||||
/*
|
||||
* This program source code file is part of KiCad, a free EDA CAD application.
|
||||
*
|
||||
* Copyright (C) 2018 KiCad Developers, see AUTHORS.txt for contributors.
|
||||
* Copyright (C) 2016 Cirilo Bernardo <cirilo.bernardo@gmail.com>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
@@ -21,29 +21,37 @@
|
||||
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
|
||||
*/
|
||||
|
||||
#ifndef DIALOG_FP_BROWSER_DISPLAY_OPTIONS_H
|
||||
#define DIALOG_FP_BROWSER_DISPLAY_OPTIONS_H
|
||||
|
||||
#include <dialog_fp_browser_display_options_base.h>
|
||||
#ifndef DLG_3D_PATHCONFIG_H
|
||||
#define DLG_3D_PATHCONFIG_H
|
||||
|
||||
#include <wx/valtext.h>
|
||||
#include "dlg_3d_pathconfig_base.h"
|
||||
|
||||
class FOOTPRINT_VIEWER_FRAME;
|
||||
class S3D_FILENAME_RESOLVER;
|
||||
|
||||
|
||||
class DIALOG_FP_BROWSER_DISPLAY_OPTIONS : public DIALOG_FP_BROWSER_DISPLAY_OPTIONS_BASE
|
||||
class DLG_3D_PATH_CONFIG : public DLG_3D_PATH_CONFIG_BASE
|
||||
{
|
||||
private:
|
||||
FOOTPRINT_VIEWER_FRAME* m_frame;
|
||||
S3D_FILENAME_RESOLVER* m_resolver;
|
||||
wxString m_curdir;
|
||||
wxTextValidator m_aliasValidator;
|
||||
|
||||
void initDialog();
|
||||
|
||||
void OnAddAlias( wxCommandEvent& event ) override;
|
||||
void OnDelAlias( wxCommandEvent& event ) override;
|
||||
void OnAliasMoveUp( wxCommandEvent& event ) override;
|
||||
void OnAliasMoveDown( wxCommandEvent& event ) override;
|
||||
void OnConfigEnvVar( wxCommandEvent& event ) override;
|
||||
void OnHelp( wxCommandEvent& event ) override;
|
||||
|
||||
public:
|
||||
DIALOG_FP_BROWSER_DISPLAY_OPTIONS( FOOTPRINT_VIEWER_FRAME* aParent );
|
||||
~DIALOG_FP_BROWSER_DISPLAY_OPTIONS();
|
||||
DLG_3D_PATH_CONFIG( wxWindow* aParent, S3D_FILENAME_RESOLVER* aResolver );
|
||||
bool TransferDataFromWindow() override;
|
||||
|
||||
private:
|
||||
void initDialog();
|
||||
void UpdateObjectSettings();
|
||||
void OnApplyClick( wxCommandEvent& event ) override;
|
||||
bool TransferDataFromWindow() override;
|
||||
void updateEnvVars( void );
|
||||
};
|
||||
|
||||
#endif // DIALOG_FP_BROWSER_DISPLAY_OPTIONS_H
|
||||
#endif // DLG_3D_PATHCONFIG_H
|
||||
@@ -0,0 +1,162 @@
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
// C++ code generated with wxFormBuilder (version Nov 22 2017)
|
||||
// http://www.wxformbuilder.org/
|
||||
//
|
||||
// PLEASE DO *NOT* EDIT THIS FILE!
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#include "dlg_3d_pathconfig_base.h"
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
|
||||
DLG_3D_PATH_CONFIG_BASE::DLG_3D_PATH_CONFIG_BASE( wxWindow* parent, wxWindowID id, const wxString& title, const wxPoint& pos, const wxSize& size, long style ) : DIALOG_SHIM( parent, id, title, pos, size, style )
|
||||
{
|
||||
this->SetSizeHints( wxSize( -1,-1 ), wxDefaultSize );
|
||||
|
||||
wxBoxSizer* bSizerMain;
|
||||
bSizerMain = new wxBoxSizer( wxVERTICAL );
|
||||
|
||||
wxBoxSizer* bSizer5;
|
||||
bSizer5 = new wxBoxSizer( wxVERTICAL );
|
||||
|
||||
m_EnvVars = new wxGrid( this, wxID_ANY, wxDefaultPosition, wxDefaultSize, 0 );
|
||||
|
||||
// Grid
|
||||
m_EnvVars->CreateGrid( 1, 2 );
|
||||
m_EnvVars->EnableEditing( true );
|
||||
m_EnvVars->EnableGridLines( true );
|
||||
m_EnvVars->EnableDragGridSize( false );
|
||||
m_EnvVars->SetMargins( 0, 0 );
|
||||
|
||||
// Columns
|
||||
m_EnvVars->SetColSize( 0, 150 );
|
||||
m_EnvVars->SetColSize( 1, 300 );
|
||||
m_EnvVars->EnableDragColMove( false );
|
||||
m_EnvVars->EnableDragColSize( true );
|
||||
m_EnvVars->SetColLabelSize( 30 );
|
||||
m_EnvVars->SetColLabelValue( 0, _("Name") );
|
||||
m_EnvVars->SetColLabelValue( 1, _("Path") );
|
||||
m_EnvVars->SetColLabelAlignment( wxALIGN_CENTRE, wxALIGN_CENTRE );
|
||||
|
||||
// Rows
|
||||
m_EnvVars->EnableDragRowSize( true );
|
||||
m_EnvVars->SetRowLabelSize( 80 );
|
||||
m_EnvVars->SetRowLabelAlignment( wxALIGN_CENTRE, wxALIGN_CENTRE );
|
||||
|
||||
// Label Appearance
|
||||
|
||||
// Cell Defaults
|
||||
m_EnvVars->SetDefaultCellAlignment( wxALIGN_LEFT, wxALIGN_TOP );
|
||||
m_EnvVars->SetMinSize( wxSize( 250,100 ) );
|
||||
|
||||
bSizer5->Add( m_EnvVars, 1, wxALL|wxEXPAND, 5 );
|
||||
|
||||
m_btnEnvCfg = new wxButton( this, wxID_ANY, _("Configure Environment Variables"), wxDefaultPosition, wxDefaultSize, 0 );
|
||||
bSizer5->Add( m_btnEnvCfg, 0, wxALIGN_CENTER|wxALL, 5 );
|
||||
|
||||
|
||||
bSizerMain->Add( bSizer5, 0, wxEXPAND, 5 );
|
||||
|
||||
m_staticline2 = new wxStaticLine( this, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxLI_HORIZONTAL );
|
||||
bSizerMain->Add( m_staticline2, 0, wxEXPAND | wxALL, 5 );
|
||||
|
||||
wxBoxSizer* bSizerGrid;
|
||||
bSizerGrid = new wxBoxSizer( wxHORIZONTAL );
|
||||
|
||||
m_Aliases = new wxGrid( this, wxID_ANY, wxDefaultPosition, wxDefaultSize, 0 );
|
||||
|
||||
// Grid
|
||||
m_Aliases->CreateGrid( 1, 3 );
|
||||
m_Aliases->EnableEditing( true );
|
||||
m_Aliases->EnableGridLines( true );
|
||||
m_Aliases->EnableDragGridSize( false );
|
||||
m_Aliases->SetMargins( 0, 0 );
|
||||
|
||||
// Columns
|
||||
m_Aliases->SetColSize( 0, 80 );
|
||||
m_Aliases->SetColSize( 1, 300 );
|
||||
m_Aliases->SetColSize( 2, 120 );
|
||||
m_Aliases->EnableDragColMove( false );
|
||||
m_Aliases->EnableDragColSize( true );
|
||||
m_Aliases->SetColLabelSize( 30 );
|
||||
m_Aliases->SetColLabelValue( 0, _("Alias") );
|
||||
m_Aliases->SetColLabelValue( 1, _("Path") );
|
||||
m_Aliases->SetColLabelValue( 2, _("Description") );
|
||||
m_Aliases->SetColLabelAlignment( wxALIGN_CENTRE, wxALIGN_CENTRE );
|
||||
|
||||
// Rows
|
||||
m_Aliases->AutoSizeRows();
|
||||
m_Aliases->EnableDragRowSize( false );
|
||||
m_Aliases->SetRowLabelSize( 80 );
|
||||
m_Aliases->SetRowLabelAlignment( wxALIGN_CENTRE, wxALIGN_CENTRE );
|
||||
|
||||
// Label Appearance
|
||||
|
||||
// Cell Defaults
|
||||
m_Aliases->SetDefaultCellAlignment( wxALIGN_LEFT, wxALIGN_TOP );
|
||||
m_Aliases->SetMinSize( wxSize( -1,150 ) );
|
||||
|
||||
bSizerGrid->Add( m_Aliases, 1, wxALL|wxEXPAND, 5 );
|
||||
|
||||
|
||||
bSizerMain->Add( bSizerGrid, 1, wxEXPAND, 5 );
|
||||
|
||||
wxBoxSizer* bSizerButtons;
|
||||
bSizerButtons = new wxBoxSizer( wxHORIZONTAL );
|
||||
|
||||
m_btnAddAlias = new wxButton( this, wxID_ANY, _("Add Alias"), wxDefaultPosition, wxDefaultSize, 0 );
|
||||
bSizerButtons->Add( m_btnAddAlias, 0, wxALL, 5 );
|
||||
|
||||
m_btnDelAlias = new wxButton( this, wxID_ANY, _("Remove Alias"), wxDefaultPosition, wxDefaultSize, 0 );
|
||||
bSizerButtons->Add( m_btnDelAlias, 0, wxALL, 5 );
|
||||
|
||||
m_btnMoveUp = new wxButton( this, wxID_ANY, _("Move Up"), wxDefaultPosition, wxDefaultSize, 0 );
|
||||
bSizerButtons->Add( m_btnMoveUp, 0, wxALL, 5 );
|
||||
|
||||
m_btnMoveDown = new wxButton( this, wxID_ANY, _("Move Down"), wxDefaultPosition, wxDefaultSize, 0 );
|
||||
bSizerButtons->Add( m_btnMoveDown, 0, wxALL, 5 );
|
||||
|
||||
|
||||
bSizerMain->Add( bSizerButtons, 0, wxALIGN_CENTER_HORIZONTAL, 5 );
|
||||
|
||||
m_staticline1 = new wxStaticLine( this, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxLI_HORIZONTAL );
|
||||
bSizerMain->Add( m_staticline1, 0, wxEXPAND | wxALL, 5 );
|
||||
|
||||
m_sdbSizer2 = new wxStdDialogButtonSizer();
|
||||
m_sdbSizer2OK = new wxButton( this, wxID_OK );
|
||||
m_sdbSizer2->AddButton( m_sdbSizer2OK );
|
||||
m_sdbSizer2Cancel = new wxButton( this, wxID_CANCEL );
|
||||
m_sdbSizer2->AddButton( m_sdbSizer2Cancel );
|
||||
m_sdbSizer2Help = new wxButton( this, wxID_HELP );
|
||||
m_sdbSizer2->AddButton( m_sdbSizer2Help );
|
||||
m_sdbSizer2->Realize();
|
||||
|
||||
bSizerMain->Add( m_sdbSizer2, 0, wxALL|wxEXPAND, 5 );
|
||||
|
||||
|
||||
this->SetSizer( bSizerMain );
|
||||
this->Layout();
|
||||
bSizerMain->Fit( this );
|
||||
|
||||
this->Centre( wxBOTH );
|
||||
|
||||
// Connect Events
|
||||
m_btnEnvCfg->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( DLG_3D_PATH_CONFIG_BASE::OnConfigEnvVar ), NULL, this );
|
||||
m_btnAddAlias->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( DLG_3D_PATH_CONFIG_BASE::OnAddAlias ), NULL, this );
|
||||
m_btnDelAlias->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( DLG_3D_PATH_CONFIG_BASE::OnDelAlias ), NULL, this );
|
||||
m_btnMoveUp->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( DLG_3D_PATH_CONFIG_BASE::OnAliasMoveUp ), NULL, this );
|
||||
m_btnMoveDown->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( DLG_3D_PATH_CONFIG_BASE::OnAliasMoveDown ), NULL, this );
|
||||
m_sdbSizer2Help->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( DLG_3D_PATH_CONFIG_BASE::OnHelp ), NULL, this );
|
||||
}
|
||||
|
||||
DLG_3D_PATH_CONFIG_BASE::~DLG_3D_PATH_CONFIG_BASE()
|
||||
{
|
||||
// Disconnect Events
|
||||
m_btnEnvCfg->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( DLG_3D_PATH_CONFIG_BASE::OnConfigEnvVar ), NULL, this );
|
||||
m_btnAddAlias->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( DLG_3D_PATH_CONFIG_BASE::OnAddAlias ), NULL, this );
|
||||
m_btnDelAlias->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( DLG_3D_PATH_CONFIG_BASE::OnDelAlias ), NULL, this );
|
||||
m_btnMoveUp->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( DLG_3D_PATH_CONFIG_BASE::OnAliasMoveUp ), NULL, this );
|
||||
m_btnMoveDown->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( DLG_3D_PATH_CONFIG_BASE::OnAliasMoveDown ), NULL, this );
|
||||
m_sdbSizer2Help->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( DLG_3D_PATH_CONFIG_BASE::OnHelp ), NULL, this );
|
||||
|
||||
}
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,67 @@
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
// C++ code generated with wxFormBuilder (version Nov 22 2017)
|
||||
// http://www.wxformbuilder.org/
|
||||
//
|
||||
// PLEASE DO *NOT* EDIT THIS FILE!
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#ifndef __DLG_3D_PATHCONFIG_BASE_H__
|
||||
#define __DLG_3D_PATHCONFIG_BASE_H__
|
||||
|
||||
#include <wx/artprov.h>
|
||||
#include <wx/xrc/xmlres.h>
|
||||
#include <wx/intl.h>
|
||||
#include "dialog_shim.h"
|
||||
#include <wx/colour.h>
|
||||
#include <wx/settings.h>
|
||||
#include <wx/string.h>
|
||||
#include <wx/font.h>
|
||||
#include <wx/grid.h>
|
||||
#include <wx/gdicmn.h>
|
||||
#include <wx/button.h>
|
||||
#include <wx/sizer.h>
|
||||
#include <wx/statline.h>
|
||||
#include <wx/dialog.h>
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
/// Class DLG_3D_PATH_CONFIG_BASE
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
class DLG_3D_PATH_CONFIG_BASE : public DIALOG_SHIM
|
||||
{
|
||||
private:
|
||||
|
||||
protected:
|
||||
wxGrid* m_EnvVars;
|
||||
wxButton* m_btnEnvCfg;
|
||||
wxStaticLine* m_staticline2;
|
||||
wxGrid* m_Aliases;
|
||||
wxButton* m_btnAddAlias;
|
||||
wxButton* m_btnDelAlias;
|
||||
wxButton* m_btnMoveUp;
|
||||
wxButton* m_btnMoveDown;
|
||||
wxStaticLine* m_staticline1;
|
||||
wxStdDialogButtonSizer* m_sdbSizer2;
|
||||
wxButton* m_sdbSizer2OK;
|
||||
wxButton* m_sdbSizer2Cancel;
|
||||
wxButton* m_sdbSizer2Help;
|
||||
|
||||
// Virtual event handlers, overide them in your derived class
|
||||
virtual void OnConfigEnvVar( wxCommandEvent& event ) { event.Skip(); }
|
||||
virtual void OnAddAlias( wxCommandEvent& event ) { event.Skip(); }
|
||||
virtual void OnDelAlias( wxCommandEvent& event ) { event.Skip(); }
|
||||
virtual void OnAliasMoveUp( wxCommandEvent& event ) { event.Skip(); }
|
||||
virtual void OnAliasMoveDown( wxCommandEvent& event ) { event.Skip(); }
|
||||
virtual void OnHelp( wxCommandEvent& event ) { event.Skip(); }
|
||||
|
||||
|
||||
public:
|
||||
|
||||
DLG_3D_PATH_CONFIG_BASE( wxWindow* parent, wxWindowID id = wxID_ANY, const wxString& title = _("3D Search Path Configuration"), const wxPoint& pos = wxDefaultPosition, const wxSize& size = wxSize( -1,-1 ), long style = wxDEFAULT_DIALOG_STYLE|wxRESIZE_BORDER );
|
||||
~DLG_3D_PATH_CONFIG_BASE();
|
||||
|
||||
};
|
||||
|
||||
#endif //__DLG_3D_PATHCONFIG_BASE_H__
|
||||
@@ -75,7 +75,7 @@ DLG_SELECT_3DMODEL::DLG_SELECT_3DMODEL( wxWindow* aParent, S3D_CACHE* aCacheMana
|
||||
|
||||
m_FileTree = new wxGenericDirCtrl( this, ID_FILE_TREE, prevModelSelectDir, wxDefaultPosition,
|
||||
wxSize( 300,100 ), wxDIRCTRL_3D_INTERNAL | wxDIRCTRL_EDIT_LABELS
|
||||
| wxDIRCTRL_SELECT_FIRST | wxDIRCTRL_SHOW_FILTERS | wxBORDER_SIMPLE, wxEmptyString, 0 );
|
||||
| wxDIRCTRL_SELECT_FIRST | wxDIRCTRL_SHOW_FILTERS|wxSUNKEN_BORDER, wxEmptyString, 0 );
|
||||
|
||||
|
||||
m_FileTree->ShowHidden( false );
|
||||
@@ -111,7 +111,7 @@ DLG_SELECT_3DMODEL::DLG_SELECT_3DMODEL( wxWindow* aParent, S3D_CACHE* aCacheMana
|
||||
if( !filter.empty() )
|
||||
m_FileTree->SetFilter( filter );
|
||||
else
|
||||
m_FileTree->SetFilter( wxFileSelectorDefaultWildcardStr );
|
||||
m_FileTree->SetFilter( wxT( "*.*" ) );
|
||||
|
||||
if( prevModelWildcard >= 0 && prevModelWildcard < (int)fl->size() )
|
||||
m_FileTree->SetFilterIndex( prevModelWildcard );
|
||||
@@ -123,7 +123,7 @@ DLG_SELECT_3DMODEL::DLG_SELECT_3DMODEL( wxWindow* aParent, S3D_CACHE* aCacheMana
|
||||
}
|
||||
else
|
||||
{
|
||||
m_FileTree->SetFilter( wxFileSelectorDefaultWildcardStr );
|
||||
m_FileTree->SetFilter( wxT( "*.*" ) );
|
||||
prevModelWildcard = 0;
|
||||
m_FileTree->SetFilterIndex( 0 );
|
||||
}
|
||||
@@ -221,7 +221,7 @@ void DLG_SELECT_3DMODEL::OnFileActivated( wxTreeEvent& event )
|
||||
|
||||
void DLG_SELECT_3DMODEL::SetRootDir( wxCommandEvent& event )
|
||||
{
|
||||
if( m_FileTree && dirChoices->GetSelection() > 0 )
|
||||
if( m_FileTree )
|
||||
m_FileTree->SetPath( dirChoices->GetString( dirChoices->GetSelection() ) );
|
||||
|
||||
return;
|
||||
@@ -240,9 +240,9 @@ void DLG_SELECT_3DMODEL::updateDirChoiceList( void )
|
||||
if( NULL == m_FileTree || NULL == m_resolver || NULL == dirChoices )
|
||||
return;
|
||||
|
||||
std::list< SEARCH_PATH > const* md = m_resolver->GetPaths();
|
||||
std::list< SEARCH_PATH >::const_iterator sL = md->begin();
|
||||
std::list< SEARCH_PATH >::const_iterator eL = md->end();
|
||||
std::list< S3D_ALIAS > const* md = m_resolver->GetPaths();
|
||||
std::list< S3D_ALIAS >::const_iterator sL = md->begin();
|
||||
std::list< S3D_ALIAS >::const_iterator eL = md->end();
|
||||
std::set< wxString > cl;
|
||||
wxString prjDir;
|
||||
|
||||
@@ -263,31 +263,21 @@ void DLG_SELECT_3DMODEL::updateDirChoiceList( void )
|
||||
|
||||
if( !cl.empty() )
|
||||
{
|
||||
unsigned int choice = 0;
|
||||
dirChoices->Clear();
|
||||
dirChoices->Append( "" ); //Insert a blank string at the beginning to allow selection
|
||||
|
||||
if( !prjDir.empty() )
|
||||
{
|
||||
dirChoices->Append( prjDir );
|
||||
|
||||
if( prjDir == m_FileTree->GetPath() )
|
||||
choice = 1;
|
||||
}
|
||||
|
||||
std::set< wxString >::const_iterator sI = cl.begin();
|
||||
std::set< wxString >::const_iterator eI = cl.end();
|
||||
|
||||
while( sI != eI )
|
||||
{
|
||||
if( *sI == m_FileTree->GetPath() )
|
||||
choice = dirChoices->GetCount();
|
||||
|
||||
dirChoices->Append( *sI );
|
||||
++sI;
|
||||
}
|
||||
|
||||
dirChoices->Select( choice );
|
||||
dirChoices->Select( 0 );
|
||||
}
|
||||
|
||||
return;
|
||||
|
||||
@@ -43,7 +43,7 @@
|
||||
|
||||
class MODULE_3D_SETTINGS;
|
||||
class S3D_CACHE;
|
||||
class FILENAME_RESOLVER;
|
||||
class S3D_FILENAME_RESOLVER;
|
||||
class C3D_MODEL_VIEWER;
|
||||
|
||||
class DLG_SELECT_3DMODEL : public DIALOG_SHIM
|
||||
@@ -51,7 +51,7 @@ class DLG_SELECT_3DMODEL : public DIALOG_SHIM
|
||||
private:
|
||||
MODULE_3D_SETTINGS* m_model; // data for the selected model
|
||||
S3D_CACHE* m_cache; // cache manager
|
||||
FILENAME_RESOLVER* m_resolver; // 3D filename resolver
|
||||
S3D_FILENAME_RESOLVER* m_resolver; // 3D filename resolver
|
||||
|
||||
wxString& m_previousDir;
|
||||
int& m_previousFilterIndex;
|
||||
|
||||
@@ -1,310 +1,353 @@
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
// C++ code generated with wxFormBuilder (version Jun 5 2018)
|
||||
// http://www.wxformbuilder.org/
|
||||
//
|
||||
// PLEASE DO *NOT* EDIT THIS FILE!
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#include "panel_prev_3d_base.h"
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
|
||||
PANEL_PREV_3D_BASE::PANEL_PREV_3D_BASE( wxWindow* parent, wxWindowID id, const wxPoint& pos, const wxSize& size, long style ) : wxPanel( parent, id, pos, size, style )
|
||||
{
|
||||
wxBoxSizer* bSizermain;
|
||||
bSizermain = new wxBoxSizer( wxHORIZONTAL );
|
||||
|
||||
wxBoxSizer* bSizerLeft;
|
||||
bSizerLeft = new wxBoxSizer( wxVERTICAL );
|
||||
|
||||
wxStaticBoxSizer* sbSizerScale;
|
||||
sbSizerScale = new wxStaticBoxSizer( new wxStaticBox( this, wxID_ANY, _("Scale") ), wxVERTICAL );
|
||||
|
||||
wxFlexGridSizer* fgSizerScale;
|
||||
fgSizerScale = new wxFlexGridSizer( 0, 3, 0, 0 );
|
||||
fgSizerScale->SetFlexibleDirection( wxBOTH );
|
||||
fgSizerScale->SetNonFlexibleGrowMode( wxFLEX_GROWMODE_SPECIFIED );
|
||||
|
||||
m_staticText1 = new wxStaticText( sbSizerScale->GetStaticBox(), wxID_ANY, _("X:"), wxDefaultPosition, wxDefaultSize, 0 );
|
||||
m_staticText1->Wrap( -1 );
|
||||
fgSizerScale->Add( m_staticText1, 0, wxALIGN_CENTER_VERTICAL|wxLEFT, 5 );
|
||||
|
||||
xscale = new wxTextCtrl( sbSizerScale->GetStaticBox(), wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, 0 );
|
||||
fgSizerScale->Add( xscale, 0, wxALIGN_CENTER_VERTICAL|wxLEFT, 5 );
|
||||
|
||||
m_spinXscale = new wxSpinButton( sbSizerScale->GetStaticBox(), wxID_ANY, wxDefaultPosition, wxDefaultSize, wxSP_ARROW_KEYS|wxSP_VERTICAL );
|
||||
fgSizerScale->Add( m_spinXscale, 0, wxALIGN_CENTER_VERTICAL, 5 );
|
||||
|
||||
m_staticText2 = new wxStaticText( sbSizerScale->GetStaticBox(), wxID_ANY, _("Y:"), wxDefaultPosition, wxDefaultSize, 0 );
|
||||
m_staticText2->Wrap( -1 );
|
||||
fgSizerScale->Add( m_staticText2, 0, wxALIGN_CENTER_VERTICAL|wxLEFT, 5 );
|
||||
|
||||
yscale = new wxTextCtrl( sbSizerScale->GetStaticBox(), wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, 0 );
|
||||
fgSizerScale->Add( yscale, 0, wxALIGN_CENTER_VERTICAL|wxLEFT, 5 );
|
||||
|
||||
m_spinYscale = new wxSpinButton( sbSizerScale->GetStaticBox(), wxID_ANY, wxDefaultPosition, wxDefaultSize, wxSP_ARROW_KEYS|wxSP_VERTICAL );
|
||||
fgSizerScale->Add( m_spinYscale, 0, wxALIGN_CENTER_VERTICAL, 5 );
|
||||
|
||||
m_staticText3 = new wxStaticText( sbSizerScale->GetStaticBox(), wxID_ANY, _("Z:"), wxDefaultPosition, wxDefaultSize, 0 );
|
||||
m_staticText3->Wrap( -1 );
|
||||
fgSizerScale->Add( m_staticText3, 0, wxALIGN_CENTER_VERTICAL|wxBOTTOM|wxLEFT, 5 );
|
||||
|
||||
zscale = new wxTextCtrl( sbSizerScale->GetStaticBox(), wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, 0 );
|
||||
fgSizerScale->Add( zscale, 0, wxALIGN_CENTER_VERTICAL|wxBOTTOM|wxLEFT, 5 );
|
||||
|
||||
m_spinZscale = new wxSpinButton( sbSizerScale->GetStaticBox(), wxID_ANY, wxDefaultPosition, wxDefaultSize, wxSP_ARROW_KEYS|wxSP_VERTICAL );
|
||||
fgSizerScale->Add( m_spinZscale, 0, wxALIGN_CENTER_VERTICAL|wxBOTTOM, 5 );
|
||||
|
||||
|
||||
sbSizerScale->Add( fgSizerScale, 0, wxEXPAND|wxRIGHT|wxLEFT, 10 );
|
||||
|
||||
|
||||
bSizerLeft->Add( sbSizerScale, 0, wxEXPAND|wxTOP|wxRIGHT|wxLEFT, 5 );
|
||||
|
||||
wxStaticBoxSizer* sbSizerRotation;
|
||||
sbSizerRotation = new wxStaticBoxSizer( new wxStaticBox( this, wxID_ANY, _("Rotation") ), wxVERTICAL );
|
||||
|
||||
wxFlexGridSizer* fgSizerRotate;
|
||||
fgSizerRotate = new wxFlexGridSizer( 0, 3, 0, 0 );
|
||||
fgSizerRotate->SetFlexibleDirection( wxBOTH );
|
||||
fgSizerRotate->SetNonFlexibleGrowMode( wxFLEX_GROWMODE_SPECIFIED );
|
||||
|
||||
m_staticText11 = new wxStaticText( sbSizerRotation->GetStaticBox(), wxID_ANY, _("X:"), wxDefaultPosition, wxDefaultSize, 0 );
|
||||
m_staticText11->Wrap( -1 );
|
||||
fgSizerRotate->Add( m_staticText11, 0, wxALIGN_CENTER_VERTICAL|wxLEFT, 5 );
|
||||
|
||||
xrot = new wxTextCtrl( sbSizerRotation->GetStaticBox(), wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, 0 );
|
||||
fgSizerRotate->Add( xrot, 0, wxALIGN_CENTER_VERTICAL|wxLEFT, 5 );
|
||||
|
||||
m_spinXrot = new wxSpinButton( sbSizerRotation->GetStaticBox(), wxID_ANY, wxDefaultPosition, wxDefaultSize, wxSP_ARROW_KEYS|wxSP_VERTICAL );
|
||||
fgSizerRotate->Add( m_spinXrot, 0, wxALIGN_CENTER_VERTICAL, 5 );
|
||||
|
||||
m_staticText21 = new wxStaticText( sbSizerRotation->GetStaticBox(), wxID_ANY, _("Y:"), wxDefaultPosition, wxDefaultSize, 0 );
|
||||
m_staticText21->Wrap( -1 );
|
||||
fgSizerRotate->Add( m_staticText21, 0, wxALIGN_CENTER_VERTICAL|wxLEFT, 5 );
|
||||
|
||||
yrot = new wxTextCtrl( sbSizerRotation->GetStaticBox(), wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, 0 );
|
||||
fgSizerRotate->Add( yrot, 0, wxALIGN_CENTER_VERTICAL|wxLEFT, 5 );
|
||||
|
||||
m_spinYrot = new wxSpinButton( sbSizerRotation->GetStaticBox(), wxID_ANY, wxDefaultPosition, wxDefaultSize, wxSP_ARROW_KEYS|wxSP_VERTICAL );
|
||||
fgSizerRotate->Add( m_spinYrot, 0, wxALIGN_CENTER_VERTICAL, 5 );
|
||||
|
||||
m_staticText31 = new wxStaticText( sbSizerRotation->GetStaticBox(), wxID_ANY, _("Z:"), wxDefaultPosition, wxDefaultSize, 0 );
|
||||
m_staticText31->Wrap( -1 );
|
||||
fgSizerRotate->Add( m_staticText31, 0, wxALIGN_CENTER_VERTICAL|wxBOTTOM|wxLEFT, 5 );
|
||||
|
||||
zrot = new wxTextCtrl( sbSizerRotation->GetStaticBox(), wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, 0 );
|
||||
fgSizerRotate->Add( zrot, 0, wxALIGN_CENTER_VERTICAL|wxBOTTOM|wxLEFT, 5 );
|
||||
|
||||
m_spinZrot = new wxSpinButton( sbSizerRotation->GetStaticBox(), wxID_ANY, wxDefaultPosition, wxDefaultSize, wxSP_ARROW_KEYS|wxSP_VERTICAL );
|
||||
fgSizerRotate->Add( m_spinZrot, 0, wxALIGN_CENTER_VERTICAL|wxBOTTOM, 5 );
|
||||
|
||||
|
||||
sbSizerRotation->Add( fgSizerRotate, 0, wxEXPAND|wxRIGHT|wxLEFT, 10 );
|
||||
|
||||
|
||||
bSizerLeft->Add( sbSizerRotation, 0, wxEXPAND|wxTOP|wxRIGHT|wxLEFT, 5 );
|
||||
|
||||
wxStaticBoxSizer* sbSizerOffset;
|
||||
sbSizerOffset = new wxStaticBoxSizer( new wxStaticBox( this, wxID_ANY, _("Offset") ), wxVERTICAL );
|
||||
|
||||
wxFlexGridSizer* fgSizerOffset;
|
||||
fgSizerOffset = new wxFlexGridSizer( 0, 3, 0, 0 );
|
||||
fgSizerOffset->SetFlexibleDirection( wxBOTH );
|
||||
fgSizerOffset->SetNonFlexibleGrowMode( wxFLEX_GROWMODE_SPECIFIED );
|
||||
|
||||
m_staticText12 = new wxStaticText( sbSizerOffset->GetStaticBox(), wxID_ANY, _("X:"), wxDefaultPosition, wxDefaultSize, 0 );
|
||||
m_staticText12->Wrap( -1 );
|
||||
fgSizerOffset->Add( m_staticText12, 0, wxALIGN_CENTER_VERTICAL|wxLEFT, 5 );
|
||||
|
||||
xoff = new wxTextCtrl( sbSizerOffset->GetStaticBox(), wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, 0 );
|
||||
fgSizerOffset->Add( xoff, 0, wxALIGN_CENTER_VERTICAL|wxLEFT, 5 );
|
||||
|
||||
m_spinXoffset = new wxSpinButton( sbSizerOffset->GetStaticBox(), wxID_ANY, wxDefaultPosition, wxDefaultSize, wxSP_ARROW_KEYS|wxSP_VERTICAL );
|
||||
fgSizerOffset->Add( m_spinXoffset, 0, wxALIGN_CENTER_VERTICAL, 5 );
|
||||
|
||||
m_staticText22 = new wxStaticText( sbSizerOffset->GetStaticBox(), wxID_ANY, _("Y:"), wxDefaultPosition, wxDefaultSize, 0 );
|
||||
m_staticText22->Wrap( -1 );
|
||||
fgSizerOffset->Add( m_staticText22, 0, wxALIGN_CENTER_VERTICAL|wxLEFT, 5 );
|
||||
|
||||
yoff = new wxTextCtrl( sbSizerOffset->GetStaticBox(), wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, 0 );
|
||||
fgSizerOffset->Add( yoff, 0, wxALIGN_CENTER_VERTICAL|wxLEFT, 5 );
|
||||
|
||||
m_spinYoffset = new wxSpinButton( sbSizerOffset->GetStaticBox(), wxID_ANY, wxDefaultPosition, wxDefaultSize, wxSP_ARROW_KEYS|wxSP_VERTICAL );
|
||||
fgSizerOffset->Add( m_spinYoffset, 0, wxALIGN_CENTER_VERTICAL, 5 );
|
||||
|
||||
m_staticText32 = new wxStaticText( sbSizerOffset->GetStaticBox(), wxID_ANY, _("Z:"), wxDefaultPosition, wxDefaultSize, 0 );
|
||||
m_staticText32->Wrap( -1 );
|
||||
fgSizerOffset->Add( m_staticText32, 0, wxALIGN_CENTER_VERTICAL|wxBOTTOM|wxLEFT, 5 );
|
||||
|
||||
zoff = new wxTextCtrl( sbSizerOffset->GetStaticBox(), wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, 0 );
|
||||
fgSizerOffset->Add( zoff, 0, wxALIGN_CENTER_VERTICAL|wxBOTTOM|wxLEFT, 5 );
|
||||
|
||||
m_spinZoffset = new wxSpinButton( sbSizerOffset->GetStaticBox(), wxID_ANY, wxDefaultPosition, wxDefaultSize, wxSP_ARROW_KEYS|wxSP_VERTICAL );
|
||||
fgSizerOffset->Add( m_spinZoffset, 0, wxALIGN_CENTER_VERTICAL|wxBOTTOM, 5 );
|
||||
|
||||
|
||||
sbSizerOffset->Add( fgSizerOffset, 0, wxEXPAND|wxLEFT|wxRIGHT, 10 );
|
||||
|
||||
|
||||
bSizerLeft->Add( sbSizerOffset, 0, wxEXPAND|wxALL, 5 );
|
||||
|
||||
|
||||
bSizermain->Add( bSizerLeft, 0, 0, 5 );
|
||||
|
||||
wxBoxSizer* bSizerRight;
|
||||
bSizerRight = new wxBoxSizer( wxVERTICAL );
|
||||
|
||||
wxStaticText* staticPreviewLabel;
|
||||
staticPreviewLabel = new wxStaticText( this, wxID_ANY, _("Preview"), wxDefaultPosition, wxDefaultSize, 0 );
|
||||
staticPreviewLabel->Wrap( -1 );
|
||||
staticPreviewLabel->SetFont( wxFont( 11, wxFONTFAMILY_DEFAULT, wxFONTSTYLE_NORMAL, wxFONTWEIGHT_NORMAL, false, wxEmptyString ) );
|
||||
|
||||
bSizerRight->Add( staticPreviewLabel, 0, wxLEFT, 15 );
|
||||
|
||||
m_SizerPanelView = new wxBoxSizer( wxVERTICAL );
|
||||
|
||||
|
||||
bSizerRight->Add( m_SizerPanelView, 1, wxEXPAND|wxBOTTOM, 8 );
|
||||
|
||||
|
||||
bSizermain->Add( bSizerRight, 1, wxEXPAND|wxTOP|wxRIGHT|wxLEFT, 4 );
|
||||
|
||||
wxBoxSizer* bSizer3DButtons;
|
||||
bSizer3DButtons = new wxBoxSizer( wxVERTICAL );
|
||||
|
||||
|
||||
bSizer3DButtons->Add( 0, 0, 0, wxEXPAND|wxTOP, 4 );
|
||||
|
||||
m_bpvISO = new wxBitmapButton( this, wxID_ANY, wxNullBitmap, wxDefaultPosition, wxSize( 40,40 ), wxBU_AUTODRAW );
|
||||
m_bpvISO->SetToolTip( _("Change to isometric perspective") );
|
||||
|
||||
bSizer3DButtons->Add( m_bpvISO, 0, wxTOP|wxBOTTOM, 5 );
|
||||
|
||||
m_bpvLeft = new wxBitmapButton( this, wxID_ANY, wxNullBitmap, wxDefaultPosition, wxSize( 40,40 ), wxBU_AUTODRAW );
|
||||
bSizer3DButtons->Add( m_bpvLeft, 0, 0, 5 );
|
||||
|
||||
m_bpvRight = new wxBitmapButton( this, wxID_ANY, wxNullBitmap, wxDefaultPosition, wxSize( 40,40 ), wxBU_AUTODRAW );
|
||||
bSizer3DButtons->Add( m_bpvRight, 0, 0, 5 );
|
||||
|
||||
m_bpvFront = new wxBitmapButton( this, wxID_ANY, wxNullBitmap, wxDefaultPosition, wxSize( 40,40 ), wxBU_AUTODRAW );
|
||||
bSizer3DButtons->Add( m_bpvFront, 0, 0, 5 );
|
||||
|
||||
m_bpvBack = new wxBitmapButton( this, wxID_ANY, wxNullBitmap, wxDefaultPosition, wxSize( 40,40 ), wxBU_AUTODRAW );
|
||||
bSizer3DButtons->Add( m_bpvBack, 0, 0, 5 );
|
||||
|
||||
m_bpvTop = new wxBitmapButton( this, wxID_ANY, wxNullBitmap, wxDefaultPosition, wxSize( 40,40 ), wxBU_AUTODRAW );
|
||||
bSizer3DButtons->Add( m_bpvTop, 0, 0, 5 );
|
||||
|
||||
m_bpvBottom = new wxBitmapButton( this, wxID_ANY, wxNullBitmap, wxDefaultPosition, wxSize( 40,40 ), wxBU_AUTODRAW );
|
||||
bSizer3DButtons->Add( m_bpvBottom, 0, 0, 5 );
|
||||
|
||||
m_bpUpdate = new wxBitmapButton( this, wxID_ANY, wxNullBitmap, wxDefaultPosition, wxSize( 40,40 ), wxBU_AUTODRAW );
|
||||
m_bpUpdate->SetToolTip( _("Reload board and 3D models") );
|
||||
|
||||
bSizer3DButtons->Add( m_bpUpdate, 0, wxTOP, 5 );
|
||||
|
||||
|
||||
bSizermain->Add( bSizer3DButtons, 0, wxALL|wxEXPAND, 5 );
|
||||
|
||||
|
||||
this->SetSizer( bSizermain );
|
||||
this->Layout();
|
||||
bSizermain->Fit( this );
|
||||
|
||||
// Connect Events
|
||||
xscale->Connect( wxEVT_MOUSEWHEEL, wxMouseEventHandler( PANEL_PREV_3D_BASE::onMouseWheelScale ), NULL, this );
|
||||
xscale->Connect( wxEVT_COMMAND_TEXT_UPDATED, wxCommandEventHandler( PANEL_PREV_3D_BASE::updateOrientation ), NULL, this );
|
||||
m_spinXscale->Connect( wxEVT_SCROLL_LINEDOWN, wxSpinEventHandler( PANEL_PREV_3D_BASE::onDecrementScale ), NULL, this );
|
||||
m_spinXscale->Connect( wxEVT_SCROLL_LINEUP, wxSpinEventHandler( PANEL_PREV_3D_BASE::onIncrementScale ), NULL, this );
|
||||
yscale->Connect( wxEVT_MOUSEWHEEL, wxMouseEventHandler( PANEL_PREV_3D_BASE::onMouseWheelScale ), NULL, this );
|
||||
yscale->Connect( wxEVT_COMMAND_TEXT_UPDATED, wxCommandEventHandler( PANEL_PREV_3D_BASE::updateOrientation ), NULL, this );
|
||||
m_spinYscale->Connect( wxEVT_SCROLL_LINEDOWN, wxSpinEventHandler( PANEL_PREV_3D_BASE::onDecrementScale ), NULL, this );
|
||||
m_spinYscale->Connect( wxEVT_SCROLL_LINEUP, wxSpinEventHandler( PANEL_PREV_3D_BASE::onIncrementScale ), NULL, this );
|
||||
zscale->Connect( wxEVT_MOUSEWHEEL, wxMouseEventHandler( PANEL_PREV_3D_BASE::onMouseWheelScale ), NULL, this );
|
||||
zscale->Connect( wxEVT_COMMAND_TEXT_UPDATED, wxCommandEventHandler( PANEL_PREV_3D_BASE::updateOrientation ), NULL, this );
|
||||
m_spinZscale->Connect( wxEVT_SCROLL_LINEDOWN, wxSpinEventHandler( PANEL_PREV_3D_BASE::onDecrementScale ), NULL, this );
|
||||
m_spinZscale->Connect( wxEVT_SCROLL_LINEUP, wxSpinEventHandler( PANEL_PREV_3D_BASE::onIncrementScale ), NULL, this );
|
||||
xrot->Connect( wxEVT_MOUSEWHEEL, wxMouseEventHandler( PANEL_PREV_3D_BASE::onMouseWheelRot ), NULL, this );
|
||||
xrot->Connect( wxEVT_COMMAND_TEXT_UPDATED, wxCommandEventHandler( PANEL_PREV_3D_BASE::updateOrientation ), NULL, this );
|
||||
m_spinXrot->Connect( wxEVT_SCROLL_LINEDOWN, wxSpinEventHandler( PANEL_PREV_3D_BASE::onDecrementRot ), NULL, this );
|
||||
m_spinXrot->Connect( wxEVT_SCROLL_LINEUP, wxSpinEventHandler( PANEL_PREV_3D_BASE::onIncrementRot ), NULL, this );
|
||||
yrot->Connect( wxEVT_MOUSEWHEEL, wxMouseEventHandler( PANEL_PREV_3D_BASE::onMouseWheelRot ), NULL, this );
|
||||
yrot->Connect( wxEVT_COMMAND_TEXT_UPDATED, wxCommandEventHandler( PANEL_PREV_3D_BASE::updateOrientation ), NULL, this );
|
||||
m_spinYrot->Connect( wxEVT_SCROLL_LINEDOWN, wxSpinEventHandler( PANEL_PREV_3D_BASE::onDecrementRot ), NULL, this );
|
||||
m_spinYrot->Connect( wxEVT_SCROLL_LINEUP, wxSpinEventHandler( PANEL_PREV_3D_BASE::onIncrementRot ), NULL, this );
|
||||
zrot->Connect( wxEVT_MOUSEWHEEL, wxMouseEventHandler( PANEL_PREV_3D_BASE::onMouseWheelRot ), NULL, this );
|
||||
zrot->Connect( wxEVT_COMMAND_TEXT_UPDATED, wxCommandEventHandler( PANEL_PREV_3D_BASE::updateOrientation ), NULL, this );
|
||||
m_spinZrot->Connect( wxEVT_SCROLL_LINEDOWN, wxSpinEventHandler( PANEL_PREV_3D_BASE::onDecrementRot ), NULL, this );
|
||||
m_spinZrot->Connect( wxEVT_SCROLL_LINEUP, wxSpinEventHandler( PANEL_PREV_3D_BASE::onIncrementRot ), NULL, this );
|
||||
xoff->Connect( wxEVT_MOUSEWHEEL, wxMouseEventHandler( PANEL_PREV_3D_BASE::onMouseWheelOffset ), NULL, this );
|
||||
xoff->Connect( wxEVT_COMMAND_TEXT_UPDATED, wxCommandEventHandler( PANEL_PREV_3D_BASE::updateOrientation ), NULL, this );
|
||||
m_spinXoffset->Connect( wxEVT_SCROLL_LINEDOWN, wxSpinEventHandler( PANEL_PREV_3D_BASE::onDecrementOffset ), NULL, this );
|
||||
m_spinXoffset->Connect( wxEVT_SCROLL_LINEUP, wxSpinEventHandler( PANEL_PREV_3D_BASE::onIncrementOffset ), NULL, this );
|
||||
yoff->Connect( wxEVT_MOUSEWHEEL, wxMouseEventHandler( PANEL_PREV_3D_BASE::onMouseWheelOffset ), NULL, this );
|
||||
yoff->Connect( wxEVT_COMMAND_TEXT_UPDATED, wxCommandEventHandler( PANEL_PREV_3D_BASE::updateOrientation ), NULL, this );
|
||||
m_spinYoffset->Connect( wxEVT_SCROLL_LINEDOWN, wxSpinEventHandler( PANEL_PREV_3D_BASE::onDecrementOffset ), NULL, this );
|
||||
m_spinYoffset->Connect( wxEVT_SCROLL_LINEUP, wxSpinEventHandler( PANEL_PREV_3D_BASE::onIncrementOffset ), NULL, this );
|
||||
zoff->Connect( wxEVT_MOUSEWHEEL, wxMouseEventHandler( PANEL_PREV_3D_BASE::onMouseWheelOffset ), NULL, this );
|
||||
zoff->Connect( wxEVT_COMMAND_TEXT_UPDATED, wxCommandEventHandler( PANEL_PREV_3D_BASE::updateOrientation ), NULL, this );
|
||||
m_spinZoffset->Connect( wxEVT_SCROLL_LINEDOWN, wxSpinEventHandler( PANEL_PREV_3D_BASE::onDecrementOffset ), NULL, this );
|
||||
m_spinZoffset->Connect( wxEVT_SCROLL_LINEUP, wxSpinEventHandler( PANEL_PREV_3D_BASE::onIncrementOffset ), NULL, this );
|
||||
m_bpvISO->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( PANEL_PREV_3D_BASE::View3DISO ), NULL, this );
|
||||
m_bpvLeft->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( PANEL_PREV_3D_BASE::View3DLeft ), NULL, this );
|
||||
m_bpvRight->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( PANEL_PREV_3D_BASE::View3DRight ), NULL, this );
|
||||
m_bpvFront->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( PANEL_PREV_3D_BASE::View3DFront ), NULL, this );
|
||||
m_bpvBack->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( PANEL_PREV_3D_BASE::View3DBack ), NULL, this );
|
||||
m_bpvTop->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( PANEL_PREV_3D_BASE::View3DTop ), NULL, this );
|
||||
m_bpvBottom->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( PANEL_PREV_3D_BASE::View3DBottom ), NULL, this );
|
||||
m_bpUpdate->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( PANEL_PREV_3D_BASE::View3DUpdate ), NULL, this );
|
||||
}
|
||||
|
||||
PANEL_PREV_3D_BASE::~PANEL_PREV_3D_BASE()
|
||||
{
|
||||
// Disconnect Events
|
||||
xscale->Disconnect( wxEVT_MOUSEWHEEL, wxMouseEventHandler( PANEL_PREV_3D_BASE::onMouseWheelScale ), NULL, this );
|
||||
xscale->Disconnect( wxEVT_COMMAND_TEXT_UPDATED, wxCommandEventHandler( PANEL_PREV_3D_BASE::updateOrientation ), NULL, this );
|
||||
m_spinXscale->Disconnect( wxEVT_SCROLL_LINEDOWN, wxSpinEventHandler( PANEL_PREV_3D_BASE::onDecrementScale ), NULL, this );
|
||||
m_spinXscale->Disconnect( wxEVT_SCROLL_LINEUP, wxSpinEventHandler( PANEL_PREV_3D_BASE::onIncrementScale ), NULL, this );
|
||||
yscale->Disconnect( wxEVT_MOUSEWHEEL, wxMouseEventHandler( PANEL_PREV_3D_BASE::onMouseWheelScale ), NULL, this );
|
||||
yscale->Disconnect( wxEVT_COMMAND_TEXT_UPDATED, wxCommandEventHandler( PANEL_PREV_3D_BASE::updateOrientation ), NULL, this );
|
||||
m_spinYscale->Disconnect( wxEVT_SCROLL_LINEDOWN, wxSpinEventHandler( PANEL_PREV_3D_BASE::onDecrementScale ), NULL, this );
|
||||
m_spinYscale->Disconnect( wxEVT_SCROLL_LINEUP, wxSpinEventHandler( PANEL_PREV_3D_BASE::onIncrementScale ), NULL, this );
|
||||
zscale->Disconnect( wxEVT_MOUSEWHEEL, wxMouseEventHandler( PANEL_PREV_3D_BASE::onMouseWheelScale ), NULL, this );
|
||||
zscale->Disconnect( wxEVT_COMMAND_TEXT_UPDATED, wxCommandEventHandler( PANEL_PREV_3D_BASE::updateOrientation ), NULL, this );
|
||||
m_spinZscale->Disconnect( wxEVT_SCROLL_LINEDOWN, wxSpinEventHandler( PANEL_PREV_3D_BASE::onDecrementScale ), NULL, this );
|
||||
m_spinZscale->Disconnect( wxEVT_SCROLL_LINEUP, wxSpinEventHandler( PANEL_PREV_3D_BASE::onIncrementScale ), NULL, this );
|
||||
xrot->Disconnect( wxEVT_MOUSEWHEEL, wxMouseEventHandler( PANEL_PREV_3D_BASE::onMouseWheelRot ), NULL, this );
|
||||
xrot->Disconnect( wxEVT_COMMAND_TEXT_UPDATED, wxCommandEventHandler( PANEL_PREV_3D_BASE::updateOrientation ), NULL, this );
|
||||
m_spinXrot->Disconnect( wxEVT_SCROLL_LINEDOWN, wxSpinEventHandler( PANEL_PREV_3D_BASE::onDecrementRot ), NULL, this );
|
||||
m_spinXrot->Disconnect( wxEVT_SCROLL_LINEUP, wxSpinEventHandler( PANEL_PREV_3D_BASE::onIncrementRot ), NULL, this );
|
||||
yrot->Disconnect( wxEVT_MOUSEWHEEL, wxMouseEventHandler( PANEL_PREV_3D_BASE::onMouseWheelRot ), NULL, this );
|
||||
yrot->Disconnect( wxEVT_COMMAND_TEXT_UPDATED, wxCommandEventHandler( PANEL_PREV_3D_BASE::updateOrientation ), NULL, this );
|
||||
m_spinYrot->Disconnect( wxEVT_SCROLL_LINEDOWN, wxSpinEventHandler( PANEL_PREV_3D_BASE::onDecrementRot ), NULL, this );
|
||||
m_spinYrot->Disconnect( wxEVT_SCROLL_LINEUP, wxSpinEventHandler( PANEL_PREV_3D_BASE::onIncrementRot ), NULL, this );
|
||||
zrot->Disconnect( wxEVT_MOUSEWHEEL, wxMouseEventHandler( PANEL_PREV_3D_BASE::onMouseWheelRot ), NULL, this );
|
||||
zrot->Disconnect( wxEVT_COMMAND_TEXT_UPDATED, wxCommandEventHandler( PANEL_PREV_3D_BASE::updateOrientation ), NULL, this );
|
||||
m_spinZrot->Disconnect( wxEVT_SCROLL_LINEDOWN, wxSpinEventHandler( PANEL_PREV_3D_BASE::onDecrementRot ), NULL, this );
|
||||
m_spinZrot->Disconnect( wxEVT_SCROLL_LINEUP, wxSpinEventHandler( PANEL_PREV_3D_BASE::onIncrementRot ), NULL, this );
|
||||
xoff->Disconnect( wxEVT_MOUSEWHEEL, wxMouseEventHandler( PANEL_PREV_3D_BASE::onMouseWheelOffset ), NULL, this );
|
||||
xoff->Disconnect( wxEVT_COMMAND_TEXT_UPDATED, wxCommandEventHandler( PANEL_PREV_3D_BASE::updateOrientation ), NULL, this );
|
||||
m_spinXoffset->Disconnect( wxEVT_SCROLL_LINEDOWN, wxSpinEventHandler( PANEL_PREV_3D_BASE::onDecrementOffset ), NULL, this );
|
||||
m_spinXoffset->Disconnect( wxEVT_SCROLL_LINEUP, wxSpinEventHandler( PANEL_PREV_3D_BASE::onIncrementOffset ), NULL, this );
|
||||
yoff->Disconnect( wxEVT_MOUSEWHEEL, wxMouseEventHandler( PANEL_PREV_3D_BASE::onMouseWheelOffset ), NULL, this );
|
||||
yoff->Disconnect( wxEVT_COMMAND_TEXT_UPDATED, wxCommandEventHandler( PANEL_PREV_3D_BASE::updateOrientation ), NULL, this );
|
||||
m_spinYoffset->Disconnect( wxEVT_SCROLL_LINEDOWN, wxSpinEventHandler( PANEL_PREV_3D_BASE::onDecrementOffset ), NULL, this );
|
||||
m_spinYoffset->Disconnect( wxEVT_SCROLL_LINEUP, wxSpinEventHandler( PANEL_PREV_3D_BASE::onIncrementOffset ), NULL, this );
|
||||
zoff->Disconnect( wxEVT_MOUSEWHEEL, wxMouseEventHandler( PANEL_PREV_3D_BASE::onMouseWheelOffset ), NULL, this );
|
||||
zoff->Disconnect( wxEVT_COMMAND_TEXT_UPDATED, wxCommandEventHandler( PANEL_PREV_3D_BASE::updateOrientation ), NULL, this );
|
||||
m_spinZoffset->Disconnect( wxEVT_SCROLL_LINEDOWN, wxSpinEventHandler( PANEL_PREV_3D_BASE::onDecrementOffset ), NULL, this );
|
||||
m_spinZoffset->Disconnect( wxEVT_SCROLL_LINEUP, wxSpinEventHandler( PANEL_PREV_3D_BASE::onIncrementOffset ), NULL, this );
|
||||
m_bpvISO->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( PANEL_PREV_3D_BASE::View3DISO ), NULL, this );
|
||||
m_bpvLeft->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( PANEL_PREV_3D_BASE::View3DLeft ), NULL, this );
|
||||
m_bpvRight->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( PANEL_PREV_3D_BASE::View3DRight ), NULL, this );
|
||||
m_bpvFront->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( PANEL_PREV_3D_BASE::View3DFront ), NULL, this );
|
||||
m_bpvBack->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( PANEL_PREV_3D_BASE::View3DBack ), NULL, this );
|
||||
m_bpvTop->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( PANEL_PREV_3D_BASE::View3DTop ), NULL, this );
|
||||
m_bpvBottom->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( PANEL_PREV_3D_BASE::View3DBottom ), NULL, this );
|
||||
m_bpUpdate->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( PANEL_PREV_3D_BASE::View3DUpdate ), NULL, this );
|
||||
|
||||
}
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
// C++ code generated with wxFormBuilder (version Jan 12 2018)
|
||||
// http://www.wxformbuilder.org/
|
||||
//
|
||||
// PLEASE DO *NOT* EDIT THIS FILE!
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#include "panel_prev_3d_base.h"
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
|
||||
PANEL_PREV_3D_BASE::PANEL_PREV_3D_BASE( wxWindow* parent, wxWindowID id, const wxPoint& pos, const wxSize& size, long style ) : wxPanel( parent, id, pos, size, style )
|
||||
{
|
||||
wxBoxSizer* bSizermain;
|
||||
bSizermain = new wxBoxSizer( wxHORIZONTAL );
|
||||
|
||||
wxBoxSizer* bSizerLeft;
|
||||
bSizerLeft = new wxBoxSizer( wxVERTICAL );
|
||||
|
||||
wxBoxSizer* bSizerScale;
|
||||
bSizerScale = new wxBoxSizer( wxVERTICAL );
|
||||
|
||||
m_staticTextScale = new wxStaticText( this, wxID_ANY, _("Scale"), wxDefaultPosition, wxDefaultSize, 0 );
|
||||
m_staticTextScale->Wrap( -1 );
|
||||
bSizerScale->Add( m_staticTextScale, 0, wxTOP|wxRIGHT|wxLEFT, 5 );
|
||||
|
||||
wxFlexGridSizer* fgSizerScale;
|
||||
fgSizerScale = new wxFlexGridSizer( 0, 3, 0, 0 );
|
||||
fgSizerScale->SetFlexibleDirection( wxBOTH );
|
||||
fgSizerScale->SetNonFlexibleGrowMode( wxFLEX_GROWMODE_SPECIFIED );
|
||||
|
||||
m_staticText1 = new wxStaticText( this, wxID_ANY, _("X:"), wxDefaultPosition, wxDefaultSize, 0 );
|
||||
m_staticText1->Wrap( -1 );
|
||||
fgSizerScale->Add( m_staticText1, 0, wxALIGN_CENTER_VERTICAL|wxLEFT, 5 );
|
||||
|
||||
xscale = new wxTextCtrl( this, wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, 0 );
|
||||
fgSizerScale->Add( xscale, 0, wxALIGN_CENTER_VERTICAL|wxLEFT, 5 );
|
||||
|
||||
m_spinXscale = new wxSpinButton( this, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxSP_ARROW_KEYS|wxSP_VERTICAL );
|
||||
fgSizerScale->Add( m_spinXscale, 0, wxALIGN_CENTER_VERTICAL, 5 );
|
||||
|
||||
m_staticText2 = new wxStaticText( this, wxID_ANY, _("Y:"), wxDefaultPosition, wxDefaultSize, 0 );
|
||||
m_staticText2->Wrap( -1 );
|
||||
fgSizerScale->Add( m_staticText2, 0, wxALIGN_CENTER_VERTICAL|wxLEFT, 5 );
|
||||
|
||||
yscale = new wxTextCtrl( this, wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, 0 );
|
||||
fgSizerScale->Add( yscale, 0, wxALIGN_CENTER_VERTICAL|wxBOTTOM|wxLEFT|wxTOP, 5 );
|
||||
|
||||
m_spinYscale = new wxSpinButton( this, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxSP_ARROW_KEYS|wxSP_VERTICAL );
|
||||
fgSizerScale->Add( m_spinYscale, 0, wxALIGN_CENTER_VERTICAL, 5 );
|
||||
|
||||
m_staticText3 = new wxStaticText( this, wxID_ANY, _("Z:"), wxDefaultPosition, wxDefaultSize, 0 );
|
||||
m_staticText3->Wrap( -1 );
|
||||
fgSizerScale->Add( m_staticText3, 0, wxALIGN_CENTER_VERTICAL|wxLEFT, 5 );
|
||||
|
||||
zscale = new wxTextCtrl( this, wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, 0 );
|
||||
fgSizerScale->Add( zscale, 0, wxALIGN_CENTER_VERTICAL|wxBOTTOM|wxLEFT, 5 );
|
||||
|
||||
m_spinZscale = new wxSpinButton( this, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxSP_ARROW_KEYS|wxSP_VERTICAL );
|
||||
fgSizerScale->Add( m_spinZscale, 0, wxALIGN_CENTER_VERTICAL|wxBOTTOM, 5 );
|
||||
|
||||
|
||||
bSizerScale->Add( fgSizerScale, 0, wxEXPAND|wxRIGHT|wxLEFT, 10 );
|
||||
|
||||
|
||||
bSizerLeft->Add( bSizerScale, 0, wxEXPAND, 5 );
|
||||
|
||||
wxBoxSizer* bSizerRotation;
|
||||
bSizerRotation = new wxBoxSizer( wxVERTICAL );
|
||||
|
||||
m_staticTextRot = new wxStaticText( this, wxID_ANY, _("Rotation (degrees)"), wxDefaultPosition, wxDefaultSize, 0 );
|
||||
m_staticTextRot->Wrap( -1 );
|
||||
bSizerRotation->Add( m_staticTextRot, 0, wxTOP|wxRIGHT|wxLEFT, 5 );
|
||||
|
||||
wxFlexGridSizer* fgSizerRotate;
|
||||
fgSizerRotate = new wxFlexGridSizer( 0, 3, 0, 0 );
|
||||
fgSizerRotate->SetFlexibleDirection( wxBOTH );
|
||||
fgSizerRotate->SetNonFlexibleGrowMode( wxFLEX_GROWMODE_SPECIFIED );
|
||||
|
||||
m_staticText11 = new wxStaticText( this, wxID_ANY, _("X:"), wxDefaultPosition, wxDefaultSize, 0 );
|
||||
m_staticText11->Wrap( -1 );
|
||||
fgSizerRotate->Add( m_staticText11, 0, wxALIGN_CENTER_VERTICAL|wxLEFT, 5 );
|
||||
|
||||
xrot = new wxTextCtrl( this, wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, 0 );
|
||||
#ifdef __WXGTK__
|
||||
if ( !xrot->HasFlag( wxTE_MULTILINE ) )
|
||||
{
|
||||
xrot->SetMaxLength( 9 );
|
||||
}
|
||||
#else
|
||||
xrot->SetMaxLength( 9 );
|
||||
#endif
|
||||
fgSizerRotate->Add( xrot, 0, wxALIGN_CENTER_VERTICAL|wxLEFT, 5 );
|
||||
|
||||
m_spinXrot = new wxSpinButton( this, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxSP_ARROW_KEYS|wxSP_VERTICAL );
|
||||
fgSizerRotate->Add( m_spinXrot, 0, wxALIGN_CENTER_VERTICAL, 5 );
|
||||
|
||||
m_staticText21 = new wxStaticText( this, wxID_ANY, _("Y:"), wxDefaultPosition, wxDefaultSize, 0 );
|
||||
m_staticText21->Wrap( -1 );
|
||||
fgSizerRotate->Add( m_staticText21, 0, wxALIGN_CENTER_VERTICAL|wxLEFT, 5 );
|
||||
|
||||
yrot = new wxTextCtrl( this, wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, 0 );
|
||||
#ifdef __WXGTK__
|
||||
if ( !yrot->HasFlag( wxTE_MULTILINE ) )
|
||||
{
|
||||
yrot->SetMaxLength( 9 );
|
||||
}
|
||||
#else
|
||||
yrot->SetMaxLength( 9 );
|
||||
#endif
|
||||
fgSizerRotate->Add( yrot, 0, wxALIGN_CENTER_VERTICAL|wxBOTTOM|wxLEFT|wxTOP, 5 );
|
||||
|
||||
m_spinYrot = new wxSpinButton( this, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxSP_ARROW_KEYS|wxSP_VERTICAL );
|
||||
fgSizerRotate->Add( m_spinYrot, 0, wxALIGN_CENTER_VERTICAL, 5 );
|
||||
|
||||
m_staticText31 = new wxStaticText( this, wxID_ANY, _("Z:"), wxDefaultPosition, wxDefaultSize, 0 );
|
||||
m_staticText31->Wrap( -1 );
|
||||
fgSizerRotate->Add( m_staticText31, 0, wxALIGN_CENTER_VERTICAL|wxLEFT, 5 );
|
||||
|
||||
zrot = new wxTextCtrl( this, wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, 0 );
|
||||
#ifdef __WXGTK__
|
||||
if ( !zrot->HasFlag( wxTE_MULTILINE ) )
|
||||
{
|
||||
zrot->SetMaxLength( 9 );
|
||||
}
|
||||
#else
|
||||
zrot->SetMaxLength( 9 );
|
||||
#endif
|
||||
fgSizerRotate->Add( zrot, 0, wxALIGN_CENTER_VERTICAL|wxBOTTOM|wxLEFT, 5 );
|
||||
|
||||
m_spinZrot = new wxSpinButton( this, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxSP_ARROW_KEYS|wxSP_VERTICAL );
|
||||
fgSizerRotate->Add( m_spinZrot, 0, wxALIGN_CENTER_VERTICAL|wxBOTTOM, 5 );
|
||||
|
||||
|
||||
bSizerRotation->Add( fgSizerRotate, 0, wxEXPAND|wxRIGHT|wxLEFT, 10 );
|
||||
|
||||
|
||||
bSizerLeft->Add( bSizerRotation, 0, wxEXPAND, 5 );
|
||||
|
||||
wxBoxSizer* bSizerOffset;
|
||||
bSizerOffset = new wxBoxSizer( wxVERTICAL );
|
||||
|
||||
m_staticTextOffset = new wxStaticText( this, wxID_ANY, _("Offset"), wxDefaultPosition, wxDefaultSize, 0 );
|
||||
m_staticTextOffset->Wrap( -1 );
|
||||
bSizerOffset->Add( m_staticTextOffset, 0, wxTOP|wxRIGHT|wxLEFT, 5 );
|
||||
|
||||
wxFlexGridSizer* fgSizerOffset;
|
||||
fgSizerOffset = new wxFlexGridSizer( 0, 3, 0, 0 );
|
||||
fgSizerOffset->SetFlexibleDirection( wxBOTH );
|
||||
fgSizerOffset->SetNonFlexibleGrowMode( wxFLEX_GROWMODE_SPECIFIED );
|
||||
|
||||
m_staticText12 = new wxStaticText( this, wxID_ANY, _("X:"), wxDefaultPosition, wxDefaultSize, 0 );
|
||||
m_staticText12->Wrap( -1 );
|
||||
fgSizerOffset->Add( m_staticText12, 0, wxALIGN_CENTER_VERTICAL|wxLEFT, 5 );
|
||||
|
||||
xoff = new wxTextCtrl( this, wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, 0 );
|
||||
fgSizerOffset->Add( xoff, 0, wxALIGN_CENTER_VERTICAL|wxLEFT, 5 );
|
||||
|
||||
m_spinXoffset = new wxSpinButton( this, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxSP_ARROW_KEYS|wxSP_VERTICAL );
|
||||
fgSizerOffset->Add( m_spinXoffset, 0, wxALIGN_CENTER_VERTICAL, 5 );
|
||||
|
||||
m_staticText22 = new wxStaticText( this, wxID_ANY, _("Y:"), wxDefaultPosition, wxDefaultSize, 0 );
|
||||
m_staticText22->Wrap( -1 );
|
||||
fgSizerOffset->Add( m_staticText22, 0, wxALIGN_CENTER_VERTICAL|wxLEFT, 5 );
|
||||
|
||||
yoff = new wxTextCtrl( this, wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, 0 );
|
||||
fgSizerOffset->Add( yoff, 0, wxALIGN_CENTER_VERTICAL|wxLEFT|wxTOP, 5 );
|
||||
|
||||
m_spinYoffset = new wxSpinButton( this, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxSP_ARROW_KEYS|wxSP_VERTICAL );
|
||||
fgSizerOffset->Add( m_spinYoffset, 0, wxALIGN_CENTER_VERTICAL, 5 );
|
||||
|
||||
m_staticText32 = new wxStaticText( this, wxID_ANY, _("Z:"), wxDefaultPosition, wxDefaultSize, 0 );
|
||||
m_staticText32->Wrap( -1 );
|
||||
fgSizerOffset->Add( m_staticText32, 0, wxALIGN_CENTER_VERTICAL|wxLEFT, 5 );
|
||||
|
||||
zoff = new wxTextCtrl( this, wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, 0 );
|
||||
fgSizerOffset->Add( zoff, 0, wxALIGN_CENTER_VERTICAL|wxLEFT, 5 );
|
||||
|
||||
m_spinZoffset = new wxSpinButton( this, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxSP_ARROW_KEYS|wxSP_VERTICAL );
|
||||
fgSizerOffset->Add( m_spinZoffset, 0, wxALIGN_CENTER_VERTICAL, 5 );
|
||||
|
||||
|
||||
bSizerOffset->Add( fgSizerOffset, 0, wxEXPAND|wxLEFT|wxRIGHT, 10 );
|
||||
|
||||
|
||||
bSizerLeft->Add( bSizerOffset, 1, wxEXPAND, 5 );
|
||||
|
||||
|
||||
bSizermain->Add( bSizerLeft, 0, wxEXPAND, 5 );
|
||||
|
||||
wxBoxSizer* bSizerRight;
|
||||
bSizerRight = new wxBoxSizer( wxVERTICAL );
|
||||
|
||||
m_SizerPanelView = new wxBoxSizer( wxVERTICAL );
|
||||
|
||||
|
||||
bSizerRight->Add( m_SizerPanelView, 1, wxEXPAND, 5 );
|
||||
|
||||
wxBoxSizer* bSizer3DButtons;
|
||||
bSizer3DButtons = new wxBoxSizer( wxHORIZONTAL );
|
||||
|
||||
|
||||
bSizer3DButtons->Add( 0, 0, 1, wxEXPAND, 5 );
|
||||
|
||||
m_fgSizerButtons = new wxFlexGridSizer( 0, 4, 0, 0 );
|
||||
m_fgSizerButtons->AddGrowableCol( 0 );
|
||||
m_fgSizerButtons->AddGrowableCol( 1 );
|
||||
m_fgSizerButtons->AddGrowableCol( 2 );
|
||||
m_fgSizerButtons->AddGrowableCol( 3 );
|
||||
m_fgSizerButtons->SetFlexibleDirection( wxBOTH );
|
||||
m_fgSizerButtons->SetNonFlexibleGrowMode( wxFLEX_GROWMODE_SPECIFIED );
|
||||
|
||||
m_bpvISO = new wxBitmapButton( this, wxID_ANY, wxNullBitmap, wxDefaultPosition, wxDefaultSize, wxBU_AUTODRAW );
|
||||
m_bpvISO->SetToolTip( _("Change to isometric perspective") );
|
||||
|
||||
m_fgSizerButtons->Add( m_bpvISO, 0, wxALL|wxEXPAND, 5 );
|
||||
|
||||
m_bpvLeft = new wxBitmapButton( this, wxID_ANY, wxNullBitmap, wxDefaultPosition, wxDefaultSize, wxBU_AUTODRAW );
|
||||
m_fgSizerButtons->Add( m_bpvLeft, 0, wxALL|wxEXPAND, 5 );
|
||||
|
||||
m_bpvFront = new wxBitmapButton( this, wxID_ANY, wxNullBitmap, wxDefaultPosition, wxDefaultSize, wxBU_AUTODRAW );
|
||||
m_fgSizerButtons->Add( m_bpvFront, 0, wxALL|wxEXPAND, 5 );
|
||||
|
||||
m_bpvTop = new wxBitmapButton( this, wxID_ANY, wxNullBitmap, wxDefaultPosition, wxDefaultSize, wxBU_AUTODRAW );
|
||||
m_fgSizerButtons->Add( m_bpvTop, 0, wxALL|wxEXPAND, 5 );
|
||||
|
||||
m_bpUpdate = new wxBitmapButton( this, wxID_ANY, wxNullBitmap, wxDefaultPosition, wxDefaultSize, wxBU_AUTODRAW );
|
||||
m_bpUpdate->SetToolTip( _("Reload board and 3D models") );
|
||||
|
||||
m_fgSizerButtons->Add( m_bpUpdate, 0, wxALL|wxEXPAND, 5 );
|
||||
|
||||
m_bpvRight = new wxBitmapButton( this, wxID_ANY, wxNullBitmap, wxDefaultPosition, wxDefaultSize, wxBU_AUTODRAW );
|
||||
m_fgSizerButtons->Add( m_bpvRight, 0, wxALL|wxEXPAND, 5 );
|
||||
|
||||
m_bpvBack = new wxBitmapButton( this, wxID_ANY, wxNullBitmap, wxDefaultPosition, wxDefaultSize, wxBU_AUTODRAW );
|
||||
m_fgSizerButtons->Add( m_bpvBack, 0, wxALL|wxEXPAND, 5 );
|
||||
|
||||
m_bpvBottom = new wxBitmapButton( this, wxID_ANY, wxNullBitmap, wxDefaultPosition, wxDefaultSize, wxBU_AUTODRAW );
|
||||
m_fgSizerButtons->Add( m_bpvBottom, 0, wxALL|wxEXPAND, 5 );
|
||||
|
||||
|
||||
bSizer3DButtons->Add( m_fgSizerButtons, 6, wxEXPAND, 5 );
|
||||
|
||||
|
||||
bSizer3DButtons->Add( 0, 0, 1, wxEXPAND, 5 );
|
||||
|
||||
|
||||
bSizerRight->Add( bSizer3DButtons, 0, wxALL|wxEXPAND, 5 );
|
||||
|
||||
|
||||
bSizermain->Add( bSizerRight, 1, wxEXPAND, 5 );
|
||||
|
||||
|
||||
this->SetSizer( bSizermain );
|
||||
this->Layout();
|
||||
bSizermain->Fit( this );
|
||||
|
||||
// Connect Events
|
||||
xscale->Connect( wxEVT_MOUSEWHEEL, wxMouseEventHandler( PANEL_PREV_3D_BASE::onMouseWheelScale ), NULL, this );
|
||||
xscale->Connect( wxEVT_COMMAND_TEXT_UPDATED, wxCommandEventHandler( PANEL_PREV_3D_BASE::updateOrientation ), NULL, this );
|
||||
m_spinXscale->Connect( wxEVT_SCROLL_LINEDOWN, wxSpinEventHandler( PANEL_PREV_3D_BASE::onDecrementScale ), NULL, this );
|
||||
m_spinXscale->Connect( wxEVT_SCROLL_LINEUP, wxSpinEventHandler( PANEL_PREV_3D_BASE::onIncrementScale ), NULL, this );
|
||||
yscale->Connect( wxEVT_MOUSEWHEEL, wxMouseEventHandler( PANEL_PREV_3D_BASE::onMouseWheelScale ), NULL, this );
|
||||
yscale->Connect( wxEVT_COMMAND_TEXT_UPDATED, wxCommandEventHandler( PANEL_PREV_3D_BASE::updateOrientation ), NULL, this );
|
||||
m_spinYscale->Connect( wxEVT_SCROLL_LINEDOWN, wxSpinEventHandler( PANEL_PREV_3D_BASE::onDecrementScale ), NULL, this );
|
||||
m_spinYscale->Connect( wxEVT_SCROLL_LINEUP, wxSpinEventHandler( PANEL_PREV_3D_BASE::onIncrementScale ), NULL, this );
|
||||
zscale->Connect( wxEVT_MOUSEWHEEL, wxMouseEventHandler( PANEL_PREV_3D_BASE::onMouseWheelScale ), NULL, this );
|
||||
zscale->Connect( wxEVT_COMMAND_TEXT_UPDATED, wxCommandEventHandler( PANEL_PREV_3D_BASE::updateOrientation ), NULL, this );
|
||||
m_spinZscale->Connect( wxEVT_SCROLL_LINEDOWN, wxSpinEventHandler( PANEL_PREV_3D_BASE::onDecrementScale ), NULL, this );
|
||||
m_spinZscale->Connect( wxEVT_SCROLL_LINEUP, wxSpinEventHandler( PANEL_PREV_3D_BASE::onIncrementScale ), NULL, this );
|
||||
xrot->Connect( wxEVT_MOUSEWHEEL, wxMouseEventHandler( PANEL_PREV_3D_BASE::onMouseWheelRot ), NULL, this );
|
||||
xrot->Connect( wxEVT_COMMAND_TEXT_UPDATED, wxCommandEventHandler( PANEL_PREV_3D_BASE::updateOrientation ), NULL, this );
|
||||
m_spinXrot->Connect( wxEVT_SCROLL_LINEDOWN, wxSpinEventHandler( PANEL_PREV_3D_BASE::onDecrementRot ), NULL, this );
|
||||
m_spinXrot->Connect( wxEVT_SCROLL_LINEUP, wxSpinEventHandler( PANEL_PREV_3D_BASE::onIncrementRot ), NULL, this );
|
||||
yrot->Connect( wxEVT_MOUSEWHEEL, wxMouseEventHandler( PANEL_PREV_3D_BASE::onMouseWheelRot ), NULL, this );
|
||||
yrot->Connect( wxEVT_COMMAND_TEXT_UPDATED, wxCommandEventHandler( PANEL_PREV_3D_BASE::updateOrientation ), NULL, this );
|
||||
m_spinYrot->Connect( wxEVT_SCROLL_LINEDOWN, wxSpinEventHandler( PANEL_PREV_3D_BASE::onDecrementRot ), NULL, this );
|
||||
m_spinYrot->Connect( wxEVT_SCROLL_LINEUP, wxSpinEventHandler( PANEL_PREV_3D_BASE::onIncrementRot ), NULL, this );
|
||||
zrot->Connect( wxEVT_MOUSEWHEEL, wxMouseEventHandler( PANEL_PREV_3D_BASE::onMouseWheelRot ), NULL, this );
|
||||
zrot->Connect( wxEVT_COMMAND_TEXT_UPDATED, wxCommandEventHandler( PANEL_PREV_3D_BASE::updateOrientation ), NULL, this );
|
||||
m_spinZrot->Connect( wxEVT_SCROLL_LINEDOWN, wxSpinEventHandler( PANEL_PREV_3D_BASE::onDecrementRot ), NULL, this );
|
||||
m_spinZrot->Connect( wxEVT_SCROLL_LINEUP, wxSpinEventHandler( PANEL_PREV_3D_BASE::onIncrementRot ), NULL, this );
|
||||
xoff->Connect( wxEVT_MOUSEWHEEL, wxMouseEventHandler( PANEL_PREV_3D_BASE::onMouseWheelOffset ), NULL, this );
|
||||
xoff->Connect( wxEVT_COMMAND_TEXT_UPDATED, wxCommandEventHandler( PANEL_PREV_3D_BASE::updateOrientation ), NULL, this );
|
||||
m_spinXoffset->Connect( wxEVT_SCROLL_LINEDOWN, wxSpinEventHandler( PANEL_PREV_3D_BASE::onDecrementOffset ), NULL, this );
|
||||
m_spinXoffset->Connect( wxEVT_SCROLL_LINEUP, wxSpinEventHandler( PANEL_PREV_3D_BASE::onIncrementOffset ), NULL, this );
|
||||
yoff->Connect( wxEVT_MOUSEWHEEL, wxMouseEventHandler( PANEL_PREV_3D_BASE::onMouseWheelOffset ), NULL, this );
|
||||
yoff->Connect( wxEVT_COMMAND_TEXT_UPDATED, wxCommandEventHandler( PANEL_PREV_3D_BASE::updateOrientation ), NULL, this );
|
||||
m_spinYoffset->Connect( wxEVT_SCROLL_LINEDOWN, wxSpinEventHandler( PANEL_PREV_3D_BASE::onDecrementOffset ), NULL, this );
|
||||
m_spinYoffset->Connect( wxEVT_SCROLL_LINEUP, wxSpinEventHandler( PANEL_PREV_3D_BASE::onIncrementOffset ), NULL, this );
|
||||
zoff->Connect( wxEVT_MOUSEWHEEL, wxMouseEventHandler( PANEL_PREV_3D_BASE::onMouseWheelOffset ), NULL, this );
|
||||
zoff->Connect( wxEVT_COMMAND_TEXT_UPDATED, wxCommandEventHandler( PANEL_PREV_3D_BASE::updateOrientation ), NULL, this );
|
||||
m_spinZoffset->Connect( wxEVT_SCROLL_LINEDOWN, wxSpinEventHandler( PANEL_PREV_3D_BASE::onDecrementOffset ), NULL, this );
|
||||
m_spinZoffset->Connect( wxEVT_SCROLL_LINEUP, wxSpinEventHandler( PANEL_PREV_3D_BASE::onIncrementOffset ), NULL, this );
|
||||
m_bpvISO->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( PANEL_PREV_3D_BASE::View3DISO ), NULL, this );
|
||||
m_bpvLeft->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( PANEL_PREV_3D_BASE::View3DLeft ), NULL, this );
|
||||
m_bpvFront->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( PANEL_PREV_3D_BASE::View3DFront ), NULL, this );
|
||||
m_bpvTop->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( PANEL_PREV_3D_BASE::View3DTop ), NULL, this );
|
||||
m_bpUpdate->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( PANEL_PREV_3D_BASE::View3DUpdate ), NULL, this );
|
||||
m_bpvRight->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( PANEL_PREV_3D_BASE::View3DRight ), NULL, this );
|
||||
m_bpvBack->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( PANEL_PREV_3D_BASE::View3DBack ), NULL, this );
|
||||
m_bpvBottom->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( PANEL_PREV_3D_BASE::View3DBottom ), NULL, this );
|
||||
}
|
||||
|
||||
PANEL_PREV_3D_BASE::~PANEL_PREV_3D_BASE()
|
||||
{
|
||||
// Disconnect Events
|
||||
xscale->Disconnect( wxEVT_MOUSEWHEEL, wxMouseEventHandler( PANEL_PREV_3D_BASE::onMouseWheelScale ), NULL, this );
|
||||
xscale->Disconnect( wxEVT_COMMAND_TEXT_UPDATED, wxCommandEventHandler( PANEL_PREV_3D_BASE::updateOrientation ), NULL, this );
|
||||
m_spinXscale->Disconnect( wxEVT_SCROLL_LINEDOWN, wxSpinEventHandler( PANEL_PREV_3D_BASE::onDecrementScale ), NULL, this );
|
||||
m_spinXscale->Disconnect( wxEVT_SCROLL_LINEUP, wxSpinEventHandler( PANEL_PREV_3D_BASE::onIncrementScale ), NULL, this );
|
||||
yscale->Disconnect( wxEVT_MOUSEWHEEL, wxMouseEventHandler( PANEL_PREV_3D_BASE::onMouseWheelScale ), NULL, this );
|
||||
yscale->Disconnect( wxEVT_COMMAND_TEXT_UPDATED, wxCommandEventHandler( PANEL_PREV_3D_BASE::updateOrientation ), NULL, this );
|
||||
m_spinYscale->Disconnect( wxEVT_SCROLL_LINEDOWN, wxSpinEventHandler( PANEL_PREV_3D_BASE::onDecrementScale ), NULL, this );
|
||||
m_spinYscale->Disconnect( wxEVT_SCROLL_LINEUP, wxSpinEventHandler( PANEL_PREV_3D_BASE::onIncrementScale ), NULL, this );
|
||||
zscale->Disconnect( wxEVT_MOUSEWHEEL, wxMouseEventHandler( PANEL_PREV_3D_BASE::onMouseWheelScale ), NULL, this );
|
||||
zscale->Disconnect( wxEVT_COMMAND_TEXT_UPDATED, wxCommandEventHandler( PANEL_PREV_3D_BASE::updateOrientation ), NULL, this );
|
||||
m_spinZscale->Disconnect( wxEVT_SCROLL_LINEDOWN, wxSpinEventHandler( PANEL_PREV_3D_BASE::onDecrementScale ), NULL, this );
|
||||
m_spinZscale->Disconnect( wxEVT_SCROLL_LINEUP, wxSpinEventHandler( PANEL_PREV_3D_BASE::onIncrementScale ), NULL, this );
|
||||
xrot->Disconnect( wxEVT_MOUSEWHEEL, wxMouseEventHandler( PANEL_PREV_3D_BASE::onMouseWheelRot ), NULL, this );
|
||||
xrot->Disconnect( wxEVT_COMMAND_TEXT_UPDATED, wxCommandEventHandler( PANEL_PREV_3D_BASE::updateOrientation ), NULL, this );
|
||||
m_spinXrot->Disconnect( wxEVT_SCROLL_LINEDOWN, wxSpinEventHandler( PANEL_PREV_3D_BASE::onDecrementRot ), NULL, this );
|
||||
m_spinXrot->Disconnect( wxEVT_SCROLL_LINEUP, wxSpinEventHandler( PANEL_PREV_3D_BASE::onIncrementRot ), NULL, this );
|
||||
yrot->Disconnect( wxEVT_MOUSEWHEEL, wxMouseEventHandler( PANEL_PREV_3D_BASE::onMouseWheelRot ), NULL, this );
|
||||
yrot->Disconnect( wxEVT_COMMAND_TEXT_UPDATED, wxCommandEventHandler( PANEL_PREV_3D_BASE::updateOrientation ), NULL, this );
|
||||
m_spinYrot->Disconnect( wxEVT_SCROLL_LINEDOWN, wxSpinEventHandler( PANEL_PREV_3D_BASE::onDecrementRot ), NULL, this );
|
||||
m_spinYrot->Disconnect( wxEVT_SCROLL_LINEUP, wxSpinEventHandler( PANEL_PREV_3D_BASE::onIncrementRot ), NULL, this );
|
||||
zrot->Disconnect( wxEVT_MOUSEWHEEL, wxMouseEventHandler( PANEL_PREV_3D_BASE::onMouseWheelRot ), NULL, this );
|
||||
zrot->Disconnect( wxEVT_COMMAND_TEXT_UPDATED, wxCommandEventHandler( PANEL_PREV_3D_BASE::updateOrientation ), NULL, this );
|
||||
m_spinZrot->Disconnect( wxEVT_SCROLL_LINEDOWN, wxSpinEventHandler( PANEL_PREV_3D_BASE::onDecrementRot ), NULL, this );
|
||||
m_spinZrot->Disconnect( wxEVT_SCROLL_LINEUP, wxSpinEventHandler( PANEL_PREV_3D_BASE::onIncrementRot ), NULL, this );
|
||||
xoff->Disconnect( wxEVT_MOUSEWHEEL, wxMouseEventHandler( PANEL_PREV_3D_BASE::onMouseWheelOffset ), NULL, this );
|
||||
xoff->Disconnect( wxEVT_COMMAND_TEXT_UPDATED, wxCommandEventHandler( PANEL_PREV_3D_BASE::updateOrientation ), NULL, this );
|
||||
m_spinXoffset->Disconnect( wxEVT_SCROLL_LINEDOWN, wxSpinEventHandler( PANEL_PREV_3D_BASE::onDecrementOffset ), NULL, this );
|
||||
m_spinXoffset->Disconnect( wxEVT_SCROLL_LINEUP, wxSpinEventHandler( PANEL_PREV_3D_BASE::onIncrementOffset ), NULL, this );
|
||||
yoff->Disconnect( wxEVT_MOUSEWHEEL, wxMouseEventHandler( PANEL_PREV_3D_BASE::onMouseWheelOffset ), NULL, this );
|
||||
yoff->Disconnect( wxEVT_COMMAND_TEXT_UPDATED, wxCommandEventHandler( PANEL_PREV_3D_BASE::updateOrientation ), NULL, this );
|
||||
m_spinYoffset->Disconnect( wxEVT_SCROLL_LINEDOWN, wxSpinEventHandler( PANEL_PREV_3D_BASE::onDecrementOffset ), NULL, this );
|
||||
m_spinYoffset->Disconnect( wxEVT_SCROLL_LINEUP, wxSpinEventHandler( PANEL_PREV_3D_BASE::onIncrementOffset ), NULL, this );
|
||||
zoff->Disconnect( wxEVT_MOUSEWHEEL, wxMouseEventHandler( PANEL_PREV_3D_BASE::onMouseWheelOffset ), NULL, this );
|
||||
zoff->Disconnect( wxEVT_COMMAND_TEXT_UPDATED, wxCommandEventHandler( PANEL_PREV_3D_BASE::updateOrientation ), NULL, this );
|
||||
m_spinZoffset->Disconnect( wxEVT_SCROLL_LINEDOWN, wxSpinEventHandler( PANEL_PREV_3D_BASE::onDecrementOffset ), NULL, this );
|
||||
m_spinZoffset->Disconnect( wxEVT_SCROLL_LINEUP, wxSpinEventHandler( PANEL_PREV_3D_BASE::onIncrementOffset ), NULL, this );
|
||||
m_bpvISO->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( PANEL_PREV_3D_BASE::View3DISO ), NULL, this );
|
||||
m_bpvLeft->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( PANEL_PREV_3D_BASE::View3DLeft ), NULL, this );
|
||||
m_bpvFront->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( PANEL_PREV_3D_BASE::View3DFront ), NULL, this );
|
||||
m_bpvTop->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( PANEL_PREV_3D_BASE::View3DTop ), NULL, this );
|
||||
m_bpUpdate->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( PANEL_PREV_3D_BASE::View3DUpdate ), NULL, this );
|
||||
m_bpvRight->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( PANEL_PREV_3D_BASE::View3DRight ), NULL, this );
|
||||
m_bpvBack->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( PANEL_PREV_3D_BASE::View3DBack ), NULL, this );
|
||||
m_bpvBottom->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( PANEL_PREV_3D_BASE::View3DBottom ), NULL, this );
|
||||
|
||||
}
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,107 +1,110 @@
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
// C++ code generated with wxFormBuilder (version Jun 5 2018)
|
||||
// http://www.wxformbuilder.org/
|
||||
//
|
||||
// PLEASE DO *NOT* EDIT THIS FILE!
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#ifndef __PANEL_PREV_3D_BASE_H__
|
||||
#define __PANEL_PREV_3D_BASE_H__
|
||||
|
||||
#include <wx/artprov.h>
|
||||
#include <wx/xrc/xmlres.h>
|
||||
#include <wx/intl.h>
|
||||
#include <wx/string.h>
|
||||
#include <wx/stattext.h>
|
||||
#include <wx/gdicmn.h>
|
||||
#include <wx/font.h>
|
||||
#include <wx/colour.h>
|
||||
#include <wx/settings.h>
|
||||
#include <wx/textctrl.h>
|
||||
#include <wx/spinbutt.h>
|
||||
#include <wx/sizer.h>
|
||||
#include <wx/statbox.h>
|
||||
#include <wx/bitmap.h>
|
||||
#include <wx/image.h>
|
||||
#include <wx/icon.h>
|
||||
#include <wx/bmpbuttn.h>
|
||||
#include <wx/button.h>
|
||||
#include <wx/panel.h>
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
/// Class PANEL_PREV_3D_BASE
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
class PANEL_PREV_3D_BASE : public wxPanel
|
||||
{
|
||||
private:
|
||||
|
||||
protected:
|
||||
wxStaticText* m_staticText1;
|
||||
wxTextCtrl* xscale;
|
||||
wxSpinButton* m_spinXscale;
|
||||
wxStaticText* m_staticText2;
|
||||
wxTextCtrl* yscale;
|
||||
wxSpinButton* m_spinYscale;
|
||||
wxStaticText* m_staticText3;
|
||||
wxTextCtrl* zscale;
|
||||
wxSpinButton* m_spinZscale;
|
||||
wxStaticText* m_staticText11;
|
||||
wxTextCtrl* xrot;
|
||||
wxSpinButton* m_spinXrot;
|
||||
wxStaticText* m_staticText21;
|
||||
wxTextCtrl* yrot;
|
||||
wxSpinButton* m_spinYrot;
|
||||
wxStaticText* m_staticText31;
|
||||
wxTextCtrl* zrot;
|
||||
wxSpinButton* m_spinZrot;
|
||||
wxStaticText* m_staticText12;
|
||||
wxTextCtrl* xoff;
|
||||
wxSpinButton* m_spinXoffset;
|
||||
wxStaticText* m_staticText22;
|
||||
wxSpinButton* m_spinYoffset;
|
||||
wxStaticText* m_staticText32;
|
||||
wxTextCtrl* zoff;
|
||||
wxSpinButton* m_spinZoffset;
|
||||
wxBoxSizer* m_SizerPanelView;
|
||||
wxBitmapButton* m_bpvISO;
|
||||
wxBitmapButton* m_bpvLeft;
|
||||
wxBitmapButton* m_bpvRight;
|
||||
wxBitmapButton* m_bpvFront;
|
||||
wxBitmapButton* m_bpvBack;
|
||||
wxBitmapButton* m_bpvTop;
|
||||
wxBitmapButton* m_bpvBottom;
|
||||
wxBitmapButton* m_bpUpdate;
|
||||
|
||||
// Virtual event handlers, overide them in your derived class
|
||||
virtual void onMouseWheelScale( wxMouseEvent& event ) { event.Skip(); }
|
||||
virtual void updateOrientation( wxCommandEvent& event ) { event.Skip(); }
|
||||
virtual void onDecrementScale( wxSpinEvent& event ) { event.Skip(); }
|
||||
virtual void onIncrementScale( wxSpinEvent& event ) { event.Skip(); }
|
||||
virtual void onMouseWheelRot( wxMouseEvent& event ) { event.Skip(); }
|
||||
virtual void onDecrementRot( wxSpinEvent& event ) { event.Skip(); }
|
||||
virtual void onIncrementRot( wxSpinEvent& event ) { event.Skip(); }
|
||||
virtual void onMouseWheelOffset( wxMouseEvent& event ) { event.Skip(); }
|
||||
virtual void onDecrementOffset( wxSpinEvent& event ) { event.Skip(); }
|
||||
virtual void onIncrementOffset( wxSpinEvent& event ) { event.Skip(); }
|
||||
virtual void View3DISO( wxCommandEvent& event ) { event.Skip(); }
|
||||
virtual void View3DLeft( wxCommandEvent& event ) { event.Skip(); }
|
||||
virtual void View3DRight( wxCommandEvent& event ) { event.Skip(); }
|
||||
virtual void View3DFront( wxCommandEvent& event ) { event.Skip(); }
|
||||
virtual void View3DBack( wxCommandEvent& event ) { event.Skip(); }
|
||||
virtual void View3DTop( wxCommandEvent& event ) { event.Skip(); }
|
||||
virtual void View3DBottom( wxCommandEvent& event ) { event.Skip(); }
|
||||
virtual void View3DUpdate( wxCommandEvent& event ) { event.Skip(); }
|
||||
|
||||
|
||||
public:
|
||||
wxTextCtrl* yoff;
|
||||
|
||||
PANEL_PREV_3D_BASE( wxWindow* parent, wxWindowID id = wxID_ANY, const wxPoint& pos = wxDefaultPosition, const wxSize& size = wxSize( -1,-1 ), long style = wxTAB_TRAVERSAL );
|
||||
~PANEL_PREV_3D_BASE();
|
||||
|
||||
};
|
||||
|
||||
#endif //__PANEL_PREV_3D_BASE_H__
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
// C++ code generated with wxFormBuilder (version Jan 12 2018)
|
||||
// http://www.wxformbuilder.org/
|
||||
//
|
||||
// PLEASE DO *NOT* EDIT THIS FILE!
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#ifndef __PANEL_PREV_3D_BASE_H__
|
||||
#define __PANEL_PREV_3D_BASE_H__
|
||||
|
||||
#include <wx/artprov.h>
|
||||
#include <wx/xrc/xmlres.h>
|
||||
#include <wx/intl.h>
|
||||
#include <wx/string.h>
|
||||
#include <wx/stattext.h>
|
||||
#include <wx/gdicmn.h>
|
||||
#include <wx/font.h>
|
||||
#include <wx/colour.h>
|
||||
#include <wx/settings.h>
|
||||
#include <wx/textctrl.h>
|
||||
#include <wx/spinbutt.h>
|
||||
#include <wx/sizer.h>
|
||||
#include <wx/bitmap.h>
|
||||
#include <wx/image.h>
|
||||
#include <wx/icon.h>
|
||||
#include <wx/bmpbuttn.h>
|
||||
#include <wx/button.h>
|
||||
#include <wx/panel.h>
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
/// Class PANEL_PREV_3D_BASE
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
class PANEL_PREV_3D_BASE : public wxPanel
|
||||
{
|
||||
private:
|
||||
|
||||
protected:
|
||||
wxStaticText* m_staticTextScale;
|
||||
wxStaticText* m_staticText1;
|
||||
wxTextCtrl* xscale;
|
||||
wxSpinButton* m_spinXscale;
|
||||
wxStaticText* m_staticText2;
|
||||
wxTextCtrl* yscale;
|
||||
wxSpinButton* m_spinYscale;
|
||||
wxStaticText* m_staticText3;
|
||||
wxTextCtrl* zscale;
|
||||
wxSpinButton* m_spinZscale;
|
||||
wxStaticText* m_staticTextRot;
|
||||
wxStaticText* m_staticText11;
|
||||
wxTextCtrl* xrot;
|
||||
wxSpinButton* m_spinXrot;
|
||||
wxStaticText* m_staticText21;
|
||||
wxTextCtrl* yrot;
|
||||
wxSpinButton* m_spinYrot;
|
||||
wxStaticText* m_staticText31;
|
||||
wxTextCtrl* zrot;
|
||||
wxSpinButton* m_spinZrot;
|
||||
wxStaticText* m_staticTextOffset;
|
||||
wxStaticText* m_staticText12;
|
||||
wxTextCtrl* xoff;
|
||||
wxSpinButton* m_spinXoffset;
|
||||
wxStaticText* m_staticText22;
|
||||
wxSpinButton* m_spinYoffset;
|
||||
wxStaticText* m_staticText32;
|
||||
wxTextCtrl* zoff;
|
||||
wxSpinButton* m_spinZoffset;
|
||||
wxBoxSizer* m_SizerPanelView;
|
||||
wxFlexGridSizer* m_fgSizerButtons;
|
||||
wxBitmapButton* m_bpvISO;
|
||||
wxBitmapButton* m_bpvLeft;
|
||||
wxBitmapButton* m_bpvFront;
|
||||
wxBitmapButton* m_bpvTop;
|
||||
wxBitmapButton* m_bpUpdate;
|
||||
wxBitmapButton* m_bpvRight;
|
||||
wxBitmapButton* m_bpvBack;
|
||||
wxBitmapButton* m_bpvBottom;
|
||||
|
||||
// Virtual event handlers, overide them in your derived class
|
||||
virtual void onMouseWheelScale( wxMouseEvent& event ) { event.Skip(); }
|
||||
virtual void updateOrientation( wxCommandEvent& event ) { event.Skip(); }
|
||||
virtual void onDecrementScale( wxSpinEvent& event ) { event.Skip(); }
|
||||
virtual void onIncrementScale( wxSpinEvent& event ) { event.Skip(); }
|
||||
virtual void onMouseWheelRot( wxMouseEvent& event ) { event.Skip(); }
|
||||
virtual void onDecrementRot( wxSpinEvent& event ) { event.Skip(); }
|
||||
virtual void onIncrementRot( wxSpinEvent& event ) { event.Skip(); }
|
||||
virtual void onMouseWheelOffset( wxMouseEvent& event ) { event.Skip(); }
|
||||
virtual void onDecrementOffset( wxSpinEvent& event ) { event.Skip(); }
|
||||
virtual void onIncrementOffset( wxSpinEvent& event ) { event.Skip(); }
|
||||
virtual void View3DISO( wxCommandEvent& event ) { event.Skip(); }
|
||||
virtual void View3DLeft( wxCommandEvent& event ) { event.Skip(); }
|
||||
virtual void View3DFront( wxCommandEvent& event ) { event.Skip(); }
|
||||
virtual void View3DTop( wxCommandEvent& event ) { event.Skip(); }
|
||||
virtual void View3DUpdate( wxCommandEvent& event ) { event.Skip(); }
|
||||
virtual void View3DRight( wxCommandEvent& event ) { event.Skip(); }
|
||||
virtual void View3DBack( wxCommandEvent& event ) { event.Skip(); }
|
||||
virtual void View3DBottom( wxCommandEvent& event ) { event.Skip(); }
|
||||
|
||||
|
||||
public:
|
||||
wxTextCtrl* yoff;
|
||||
|
||||
PANEL_PREV_3D_BASE( wxWindow* parent, wxWindowID id = wxID_ANY, const wxPoint& pos = wxDefaultPosition, const wxSize& size = wxSize( -1,-1 ), long style = wxTAB_TRAVERSAL );
|
||||
~PANEL_PREV_3D_BASE();
|
||||
|
||||
};
|
||||
|
||||
#endif //__PANEL_PREV_3D_BASE_H__
|
||||
|
||||
@@ -24,49 +24,73 @@
|
||||
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
|
||||
*/
|
||||
|
||||
#include "panel_prev_model.h"
|
||||
/**
|
||||
* @file panel_prev_model.cpp
|
||||
*/
|
||||
|
||||
#include <3d_canvas/eda_3d_canvas.h>
|
||||
#include <common_ogl/cogl_att_list.h>
|
||||
#include <class_board.h>
|
||||
#include <base_units.h>
|
||||
#include <cstdlib>
|
||||
#include <limits.h>
|
||||
#include <bitmaps.h>
|
||||
#include <dpi_scaling.h>
|
||||
#include <pgm_base.h>
|
||||
#include <project.h>
|
||||
|
||||
#include <wx/valnum.h>
|
||||
#include <wx/tglbtn.h>
|
||||
|
||||
#include "project.h"
|
||||
#include "panel_prev_model.h"
|
||||
#include <class_board.h>
|
||||
|
||||
|
||||
PANEL_PREV_3D::PANEL_PREV_3D( wxWindow* aParent, PCB_BASE_FRAME* aFrame, MODULE* aModule,
|
||||
std::vector<MODULE_3D_SETTINGS> *aParentModelList ) :
|
||||
PANEL_PREV_3D::PANEL_PREV_3D( wxWindow* aParent, S3D_CACHE* aCacheManager,
|
||||
MODULE* aModuleCopy,
|
||||
COLORS_DESIGN_SETTINGS *aColors,
|
||||
std::vector<MODULE_3D_SETTINGS> *aParentInfoList ) :
|
||||
PANEL_PREV_3D_BASE( aParent, wxID_ANY )
|
||||
{
|
||||
m_userUnits = aFrame->GetUserUnits();
|
||||
|
||||
initPanel();
|
||||
|
||||
// Initialize the color settings to draw the board and the footprint
|
||||
m_dummyBoard->SetGeneralSettings( &aFrame->Settings() );
|
||||
if( aColors )
|
||||
m_dummyBoard->SetColorsSettings( aColors );
|
||||
else
|
||||
{
|
||||
static COLORS_DESIGN_SETTINGS defaultColors( FRAME_PCB_DISPLAY3D );
|
||||
m_dummyBoard->SetColorsSettings( &defaultColors );
|
||||
}
|
||||
|
||||
m_parentModelList = aParentModelList;
|
||||
if( NULL != aCacheManager )
|
||||
m_resolver = aCacheManager->GetResolver();
|
||||
|
||||
m_dummyModule = new MODULE( *aModule );
|
||||
m_dummyBoard->Add( m_dummyModule );
|
||||
m_parentInfoList = aParentInfoList;
|
||||
|
||||
m_dummyBoard->Add( (MODULE*)aModuleCopy );
|
||||
m_copyModule = aModuleCopy;
|
||||
|
||||
// Set 3d viewer configuration for preview
|
||||
m_settings3Dviewer = new CINFO3D_VISU();
|
||||
|
||||
// Create the 3D canvas
|
||||
m_previewPane = new EDA_3D_CANVAS( this, COGL_ATT_LIST::GetAttributesList( true ),
|
||||
m_dummyBoard, *m_settings3Dviewer,
|
||||
aFrame->Prj().Get3DCacheManager() );
|
||||
m_previewPane = new EDA_3D_CANVAS( this,
|
||||
COGL_ATT_LIST::GetAttributesList( true ),
|
||||
m_dummyBoard,
|
||||
*m_settings3Dviewer,
|
||||
aCacheManager );
|
||||
|
||||
loadCommonSettings();
|
||||
m_SizerPanelView->Add( m_previewPane, 1, wxEXPAND );
|
||||
|
||||
m_SizerPanelView->Add( m_previewPane, 1, wxEXPAND, 5 );
|
||||
m_previewPane->Connect( wxEVT_ENTER_WINDOW,
|
||||
wxMouseEventHandler( PANEL_PREV_3D::onEnterPreviewCanvas ),
|
||||
NULL, this );
|
||||
}
|
||||
|
||||
|
||||
PANEL_PREV_3D::~PANEL_PREV_3D()
|
||||
{
|
||||
m_previewPane->Disconnect( wxEVT_ENTER_WINDOW,
|
||||
wxMouseEventHandler( PANEL_PREV_3D::onEnterPreviewCanvas ),
|
||||
NULL, this );
|
||||
|
||||
delete m_settings3Dviewer;
|
||||
delete m_dummyBoard;
|
||||
delete m_previewPane;
|
||||
@@ -75,8 +99,10 @@ PANEL_PREV_3D::~PANEL_PREV_3D()
|
||||
|
||||
void PANEL_PREV_3D::initPanel()
|
||||
{
|
||||
m_resolver = NULL;
|
||||
currentModelFile.clear();
|
||||
m_dummyBoard = new BOARD();
|
||||
m_selected = -1;
|
||||
m_currentSelectedIdx = -1;
|
||||
|
||||
// Set the bitmap of 3D view buttons:
|
||||
m_bpvTop->SetBitmap( KiBitmap( axis3d_top_xpm ) );
|
||||
@@ -100,143 +126,324 @@ void PANEL_PREV_3D::initPanel()
|
||||
m_spinXoffset,m_spinYoffset, m_spinZoffset
|
||||
};
|
||||
|
||||
for( wxSpinButton* button : spinButtonList )
|
||||
button->SetRange(INT_MIN, INT_MAX );
|
||||
}
|
||||
|
||||
|
||||
void PANEL_PREV_3D::loadCommonSettings()
|
||||
{
|
||||
wxCHECK_RET( m_previewPane, "Cannot load settings to null canvas" );
|
||||
|
||||
wxConfigBase& cmnCfg = *Pgm().CommonSettings();
|
||||
|
||||
for( int ii = 0; ii < 9; ii++ )
|
||||
{
|
||||
const DPI_SCALING dpi{ &cmnCfg, this };
|
||||
m_previewPane->SetScaleFactor( dpi.GetScaleFactor() );
|
||||
spinButtonList[ii]->SetRange( INT_MIN, INT_MAX );
|
||||
}
|
||||
|
||||
wxString units;
|
||||
|
||||
switch( g_UserUnit )
|
||||
{
|
||||
bool option;
|
||||
cmnCfg.Read( ENBL_MOUSEWHEEL_PAN_KEY, &option, false );
|
||||
m_settings3Dviewer->SetFlag( FL_MOUSEWHEEL_PANNING, option );
|
||||
case INCHES:
|
||||
units = _( "inches" );
|
||||
break;
|
||||
case MILLIMETRES:
|
||||
units = _( "mm" );
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
if( !units.IsEmpty() )
|
||||
{
|
||||
units = wxString::Format( _( "Offset (%s)" ), units );
|
||||
m_staticTextOffset->SetLabel( units );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* @brief rotationFromString
|
||||
* @brief checkRotation
|
||||
* Ensure -MAX_ROTATION <= rotation <= MAX_ROTATION
|
||||
* aRotation will be normalized between -MAX_ROTATION and MAX_ROTATION
|
||||
* @param aRotation: in out parameter
|
||||
*/
|
||||
static double rotationFromString( const wxString& aValue )
|
||||
static void checkRotation( double& aRotation )
|
||||
{
|
||||
double rotation = DoubleValueFromString( DEGREES, aValue ) / 10.0;
|
||||
|
||||
if( rotation > MAX_ROTATION )
|
||||
if( aRotation > MAX_ROTATION )
|
||||
{
|
||||
int n = rotation / MAX_ROTATION;
|
||||
rotation -= MAX_ROTATION * n;
|
||||
int n = aRotation / MAX_ROTATION;
|
||||
aRotation -= MAX_ROTATION * n;
|
||||
}
|
||||
else if( rotation < -MAX_ROTATION )
|
||||
else if( aRotation < -MAX_ROTATION )
|
||||
{
|
||||
int n = -rotation / MAX_ROTATION;
|
||||
rotation += MAX_ROTATION * n;
|
||||
int n = -aRotation / MAX_ROTATION;
|
||||
aRotation += MAX_ROTATION * n;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static bool validateFloatTextCtrl( wxTextCtrl* aTextCtrl )
|
||||
{
|
||||
if( aTextCtrl == NULL )
|
||||
return false;
|
||||
|
||||
if( aTextCtrl->GetLineLength(0) == 0 ) // This will skip the got and event with empty field
|
||||
return false;
|
||||
|
||||
if( aTextCtrl->GetLineLength(0) == 1 )
|
||||
{
|
||||
if( (aTextCtrl->GetLineText(0).compare( "." ) == 0) ||
|
||||
(aTextCtrl->GetLineText(0).compare( "," ) == 0) )
|
||||
return false;
|
||||
}
|
||||
|
||||
return rotation;
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
wxString PANEL_PREV_3D::formatScaleValue( double aValue )
|
||||
static void incrementTextCtrl( wxTextCtrl* aTextCtrl, double aInc, double aMinval, double aMaxval )
|
||||
{
|
||||
return wxString::Format( "%.4f", aValue );
|
||||
if( !validateFloatTextCtrl( aTextCtrl ) )
|
||||
return;
|
||||
|
||||
double curr_value = 0;
|
||||
|
||||
aTextCtrl->GetValue().ToDouble( &curr_value );
|
||||
curr_value += aInc;
|
||||
|
||||
if( curr_value > aMaxval )
|
||||
curr_value = aMaxval;
|
||||
|
||||
if( curr_value < aMinval )
|
||||
curr_value = aMinval;
|
||||
|
||||
aTextCtrl->SetValue( wxString::Format( "%.4f", curr_value ) );
|
||||
}
|
||||
|
||||
|
||||
wxString PANEL_PREV_3D::formatRotationValue( double aValue )
|
||||
void PANEL_PREV_3D::SetModelDataIdx( int idx, bool aReloadPreviewModule )
|
||||
{
|
||||
return wxString::Format( "%.2f %s", aValue, GetAbbreviatedUnitsLabel( DEGREES ) );
|
||||
}
|
||||
wxASSERT( m_parentInfoList != NULL );
|
||||
|
||||
|
||||
wxString PANEL_PREV_3D::formatOffsetValue( double aValue )
|
||||
{
|
||||
// Convert from internal units (mm) to user units
|
||||
if( m_userUnits == INCHES )
|
||||
aValue /= 25.4f;
|
||||
|
||||
return wxString::Format( "%.4f %s", aValue, GetAbbreviatedUnitsLabel( m_userUnits ) );
|
||||
}
|
||||
|
||||
|
||||
void PANEL_PREV_3D::SetSelectedModel( int idx )
|
||||
{
|
||||
if( m_parentModelList && idx >= 0 && idx < (int) m_parentModelList->size() )
|
||||
if( m_parentInfoList && (idx >= 0) )
|
||||
{
|
||||
m_selected = idx;
|
||||
const MODULE_3D_SETTINGS& modelInfo = m_parentModelList->at( (unsigned) m_selected );
|
||||
wxASSERT( (unsigned int)idx < (*m_parentInfoList).size() );
|
||||
|
||||
// Use ChangeValue() instead of SetValue(). It's not the user making the change, so we
|
||||
// don't want to generate wxEVT_GRID_CELL_CHANGED events.
|
||||
if( (unsigned int)idx < (*m_parentInfoList).size() )
|
||||
{
|
||||
m_currentSelectedIdx = -1; // In case that we receive events on the
|
||||
// next updates, it will set first an
|
||||
// invalid selection
|
||||
|
||||
xscale->ChangeValue( formatScaleValue( modelInfo.m_Scale.x ) );
|
||||
yscale->ChangeValue( formatScaleValue( modelInfo.m_Scale.y ) );
|
||||
zscale->ChangeValue( formatScaleValue( modelInfo.m_Scale.z ) );
|
||||
const MODULE_3D_SETTINGS *aModel = (const MODULE_3D_SETTINGS *)&((*m_parentInfoList)[idx]);
|
||||
|
||||
xrot->ChangeValue( formatRotationValue( modelInfo.m_Rotation.x ) );
|
||||
yrot->ChangeValue( formatRotationValue( modelInfo.m_Rotation.y ) );
|
||||
zrot->ChangeValue( formatRotationValue( modelInfo.m_Rotation.z ) );
|
||||
xscale->SetValue( wxString::Format( "%.4f", aModel->m_Scale.x ) );
|
||||
yscale->SetValue( wxString::Format( "%.4f", aModel->m_Scale.y ) );
|
||||
zscale->SetValue( wxString::Format( "%.4f", aModel->m_Scale.z ) );
|
||||
|
||||
xoff->ChangeValue( formatOffsetValue( modelInfo.m_Offset.x ) );
|
||||
yoff->ChangeValue( formatOffsetValue( modelInfo.m_Offset.y ) );
|
||||
zoff->ChangeValue( formatOffsetValue( modelInfo.m_Offset.z ) );
|
||||
xrot->SetValue( wxString::Format( "%.2f", aModel->m_Rotation.x ) );
|
||||
yrot->SetValue( wxString::Format( "%.2f", aModel->m_Rotation.y ) );
|
||||
zrot->SetValue( wxString::Format( "%.2f", aModel->m_Rotation.z ) );
|
||||
|
||||
// Convert from internal units (mm) to user units
|
||||
|
||||
double scaler = 1;
|
||||
|
||||
switch( g_UserUnit )
|
||||
{
|
||||
case MILLIMETRES:
|
||||
scaler = 1.0f;
|
||||
break;
|
||||
case INCHES:
|
||||
scaler = 25.4f;
|
||||
break;
|
||||
default:
|
||||
wxASSERT( 0 );
|
||||
}
|
||||
|
||||
xoff->SetValue( wxString::Format( "%.4f", aModel->m_Offset.x / scaler ) );
|
||||
yoff->SetValue( wxString::Format( "%.4f", aModel->m_Offset.y / scaler ) );
|
||||
zoff->SetValue( wxString::Format( "%.4f", aModel->m_Offset.z / scaler ) );
|
||||
|
||||
UpdateModelName( aModel->m_Filename );
|
||||
|
||||
if( aReloadPreviewModule && m_previewPane )
|
||||
{
|
||||
updateListOnModelCopy();
|
||||
|
||||
m_previewPane->ReloadRequest();
|
||||
m_previewPane->Request_refresh();
|
||||
}
|
||||
|
||||
m_currentSelectedIdx = idx;
|
||||
}
|
||||
}
|
||||
|
||||
if( m_previewPane )
|
||||
{
|
||||
m_previewPane->SetFocus();
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
void PANEL_PREV_3D::ResetModelData( bool aReloadPreviewModule )
|
||||
{
|
||||
m_currentSelectedIdx = -1;
|
||||
|
||||
xscale->SetValue( wxString::FromDouble( 1.0 ) );
|
||||
yscale->SetValue( wxString::FromDouble( 1.0 ) );
|
||||
zscale->SetValue( wxString::FromDouble( 1.0 ) );
|
||||
|
||||
xrot->SetValue( wxString::FromDouble( 0.0 ) );
|
||||
yrot->SetValue( wxString::FromDouble( 0.0 ) );
|
||||
zrot->SetValue( wxString::FromDouble( 0.0 ) );
|
||||
|
||||
xoff->SetValue( wxString::FromDouble( 0.0 ) );
|
||||
yoff->SetValue( wxString::FromDouble( 0.0 ) );
|
||||
zoff->SetValue( wxString::FromDouble( 0.0 ) );
|
||||
|
||||
// This will update the model on the preview board with the current list of 3d shapes
|
||||
if( aReloadPreviewModule )
|
||||
{
|
||||
updateListOnModelCopy();
|
||||
|
||||
if( m_previewPane )
|
||||
{
|
||||
m_previewPane->ReloadRequest();
|
||||
m_previewPane->Request_refresh();
|
||||
}
|
||||
}
|
||||
|
||||
if( m_previewPane )
|
||||
m_previewPane->SetFocus();
|
||||
}
|
||||
|
||||
|
||||
void PANEL_PREV_3D::UpdateModelName( wxString const& aModelName )
|
||||
{
|
||||
bool newModel = false;
|
||||
|
||||
m_modelInfo.m_Filename = aModelName;
|
||||
|
||||
// if the model name is a directory simply clear the current model
|
||||
if( aModelName.empty() || wxFileName::DirExists( aModelName ) )
|
||||
{
|
||||
currentModelFile.clear();
|
||||
m_modelInfo.m_Filename.clear();
|
||||
}
|
||||
else
|
||||
{
|
||||
m_selected = -1;
|
||||
wxString newModelFile;
|
||||
|
||||
xscale->ChangeValue( wxEmptyString );
|
||||
yscale->ChangeValue( wxEmptyString );
|
||||
zscale->ChangeValue( wxEmptyString );
|
||||
if( m_resolver )
|
||||
newModelFile = m_resolver->ResolvePath( aModelName );
|
||||
|
||||
xrot->ChangeValue( wxEmptyString );
|
||||
yrot->ChangeValue( wxEmptyString );
|
||||
zrot->ChangeValue( wxEmptyString );
|
||||
if( !newModelFile.empty() && newModelFile.Cmp( currentModelFile ) )
|
||||
newModel = true;
|
||||
|
||||
xoff->ChangeValue( wxEmptyString );
|
||||
yoff->ChangeValue( wxEmptyString );
|
||||
zoff->ChangeValue( wxEmptyString );
|
||||
currentModelFile = newModelFile;
|
||||
}
|
||||
|
||||
if( currentModelFile.empty() || newModel )
|
||||
{
|
||||
updateListOnModelCopy();
|
||||
|
||||
if( m_previewPane )
|
||||
{
|
||||
m_previewPane->ReloadRequest();
|
||||
m_previewPane->Refresh();
|
||||
}
|
||||
|
||||
if( currentModelFile.empty() )
|
||||
return;
|
||||
}
|
||||
else
|
||||
{
|
||||
if( m_previewPane )
|
||||
m_previewPane->Refresh();
|
||||
}
|
||||
|
||||
if( m_previewPane )
|
||||
m_previewPane->SetFocus();
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
void PANEL_PREV_3D::updateOrientation( wxCommandEvent &event )
|
||||
{
|
||||
if( m_parentModelList && m_selected >= 0 && m_selected < (int) m_parentModelList->size() )
|
||||
wxTextCtrl *textCtrl = (wxTextCtrl *)event.GetEventObject();
|
||||
|
||||
if( textCtrl == NULL )
|
||||
return;
|
||||
|
||||
if( textCtrl->GetLineLength(0) == 0 ) // This will skip the got and event with empty field
|
||||
return;
|
||||
|
||||
if( textCtrl->GetLineLength(0) == 1 )
|
||||
if( (textCtrl->GetLineText(0).compare( "." ) == 0) ||
|
||||
(textCtrl->GetLineText(0).compare( "," ) == 0) )
|
||||
return;
|
||||
|
||||
SGPOINT scale;
|
||||
SGPOINT rotation;
|
||||
SGPOINT offset;
|
||||
|
||||
getOrientationVars( scale, rotation, offset );
|
||||
|
||||
m_modelInfo.m_Scale.x = scale.x;
|
||||
m_modelInfo.m_Scale.y = scale.y;
|
||||
m_modelInfo.m_Scale.z = scale.z;
|
||||
m_modelInfo.m_Offset.x = offset.x;
|
||||
m_modelInfo.m_Offset.y = offset.y;
|
||||
m_modelInfo.m_Offset.z = offset.z;
|
||||
m_modelInfo.m_Rotation.x = rotation.x;
|
||||
m_modelInfo.m_Rotation.y = rotation.y;
|
||||
m_modelInfo.m_Rotation.z = rotation.z;
|
||||
|
||||
if( m_currentSelectedIdx >= 0 )
|
||||
{
|
||||
// Write settings back to the parent
|
||||
MODULE_3D_SETTINGS* modelInfo = &m_parentModelList->at( (unsigned) m_selected );
|
||||
// This will update the parent list with the new data
|
||||
(*m_parentInfoList)[m_currentSelectedIdx] = m_modelInfo;
|
||||
|
||||
modelInfo->m_Scale.x = DoubleValueFromString( UNSCALED_UNITS, xscale->GetValue() );
|
||||
modelInfo->m_Scale.y = DoubleValueFromString( UNSCALED_UNITS, yscale->GetValue() );
|
||||
modelInfo->m_Scale.z = DoubleValueFromString( UNSCALED_UNITS, zscale->GetValue() );
|
||||
// It will update the copy model in the preview board
|
||||
updateListOnModelCopy();
|
||||
|
||||
modelInfo->m_Rotation.x = rotationFromString( xrot->GetValue() );
|
||||
modelInfo->m_Rotation.y = rotationFromString( yrot->GetValue() );
|
||||
modelInfo->m_Rotation.z = rotationFromString( zrot->GetValue() );
|
||||
|
||||
modelInfo->m_Offset.x = DoubleValueFromString( m_userUnits, xoff->GetValue() ) / IU_PER_MM;
|
||||
modelInfo->m_Offset.y = DoubleValueFromString( m_userUnits, yoff->GetValue() ) / IU_PER_MM;
|
||||
modelInfo->m_Offset.z = DoubleValueFromString( m_userUnits, zoff->GetValue() ) / IU_PER_MM;
|
||||
|
||||
// Update the dummy module for the preview
|
||||
UpdateDummyModule( false );
|
||||
// Since the OpenGL render does not need to be reloaded to update the
|
||||
// shapes position, we just request to redraw again the canvas
|
||||
if( m_previewPane )
|
||||
m_previewPane->Refresh();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void PANEL_PREV_3D::doIncrementScale( wxSpinEvent& event, double aSign )
|
||||
void PANEL_PREV_3D::onIncrementRot( wxSpinEvent& event )
|
||||
{
|
||||
wxSpinButton* spinCtrl = (wxSpinButton*) event.GetEventObject();
|
||||
|
||||
wxTextCtrl * textCtrl = xrot;
|
||||
|
||||
if( spinCtrl == m_spinYrot )
|
||||
textCtrl = yrot;
|
||||
else if( spinCtrl == m_spinZrot )
|
||||
textCtrl = zrot;
|
||||
|
||||
incrementTextCtrl( textCtrl, ROTATION_INCREMENT, -MAX_ROTATION, MAX_ROTATION );
|
||||
}
|
||||
|
||||
|
||||
void PANEL_PREV_3D::onDecrementRot( wxSpinEvent& event )
|
||||
{
|
||||
wxSpinButton* spinCtrl = (wxSpinButton*) event.GetEventObject();
|
||||
|
||||
wxTextCtrl * textCtrl = xrot;
|
||||
|
||||
if( spinCtrl == m_spinYrot )
|
||||
textCtrl = yrot;
|
||||
else if( spinCtrl == m_spinZrot )
|
||||
textCtrl = zrot;
|
||||
|
||||
incrementTextCtrl( textCtrl, -ROTATION_INCREMENT, -MAX_ROTATION, MAX_ROTATION );
|
||||
}
|
||||
|
||||
|
||||
void PANEL_PREV_3D::onIncrementScale( wxSpinEvent& event )
|
||||
{
|
||||
wxSpinButton* spinCtrl = (wxSpinButton*) event.GetEventObject();
|
||||
|
||||
@@ -247,37 +454,26 @@ void PANEL_PREV_3D::doIncrementScale( wxSpinEvent& event, double aSign )
|
||||
else if( spinCtrl == m_spinZscale )
|
||||
textCtrl = zscale;
|
||||
|
||||
double curr_value = DoubleValueFromString( UNSCALED_UNITS, textCtrl->GetValue() );
|
||||
|
||||
curr_value += ( SCALE_INCREMENT * aSign );
|
||||
curr_value = std::max( 1/MAX_SCALE, curr_value );
|
||||
curr_value = std::min( curr_value, MAX_SCALE );
|
||||
|
||||
textCtrl->SetValue( formatScaleValue( curr_value ) );
|
||||
incrementTextCtrl( textCtrl, SCALE_INCREMENT, 1/MAX_SCALE, MAX_SCALE );
|
||||
}
|
||||
|
||||
|
||||
void PANEL_PREV_3D::doIncrementRotation( wxSpinEvent& aEvent, double aSign )
|
||||
void PANEL_PREV_3D::onDecrementScale( wxSpinEvent& event )
|
||||
{
|
||||
wxSpinButton* spinCtrl = (wxSpinButton*) aEvent.GetEventObject();
|
||||
wxTextCtrl* textCtrl = xrot;
|
||||
wxSpinButton* spinCtrl = (wxSpinButton*) event.GetEventObject();
|
||||
|
||||
if( spinCtrl == m_spinYrot )
|
||||
textCtrl = yrot;
|
||||
else if( spinCtrl == m_spinZrot )
|
||||
textCtrl = zrot;
|
||||
wxTextCtrl * textCtrl = xscale;
|
||||
|
||||
double curr_value = DoubleValueFromString( DEGREES, textCtrl->GetValue() ) / 10.0;
|
||||
if( spinCtrl == m_spinYscale )
|
||||
textCtrl = yscale;
|
||||
else if( spinCtrl == m_spinZscale )
|
||||
textCtrl = zscale;
|
||||
|
||||
curr_value += ( ROTATION_INCREMENT * aSign );
|
||||
curr_value = std::max( -MAX_ROTATION, curr_value );
|
||||
curr_value = std::min( curr_value, MAX_ROTATION );
|
||||
|
||||
textCtrl->SetValue( formatRotationValue( curr_value ) );
|
||||
incrementTextCtrl( textCtrl, -SCALE_INCREMENT, 1/MAX_SCALE, MAX_SCALE );
|
||||
}
|
||||
|
||||
|
||||
void PANEL_PREV_3D::doIncrementOffset( wxSpinEvent& event, double aSign )
|
||||
void PANEL_PREV_3D::onIncrementOffset( wxSpinEvent& event )
|
||||
{
|
||||
wxSpinButton* spinCtrl = (wxSpinButton*) event.GetEventObject();
|
||||
|
||||
@@ -290,16 +486,30 @@ void PANEL_PREV_3D::doIncrementOffset( wxSpinEvent& event, double aSign )
|
||||
|
||||
double step = OFFSET_INCREMENT_MM;
|
||||
|
||||
if( m_userUnits == INCHES )
|
||||
if( g_UserUnit == INCHES )
|
||||
step = OFFSET_INCREMENT_MIL/1000.0;
|
||||
|
||||
double curr_value = DoubleValueFromString( m_userUnits, textCtrl->GetValue() ) / IU_PER_MM;
|
||||
incrementTextCtrl( textCtrl, step, -MAX_OFFSET, MAX_OFFSET );
|
||||
}
|
||||
|
||||
curr_value += ( step * aSign );
|
||||
curr_value = std::max( -MAX_OFFSET, curr_value );
|
||||
curr_value = std::min( curr_value, MAX_OFFSET );
|
||||
|
||||
textCtrl->SetValue( formatOffsetValue( curr_value ) );
|
||||
void PANEL_PREV_3D::onDecrementOffset( wxSpinEvent& event )
|
||||
{
|
||||
wxSpinButton* spinCtrl = (wxSpinButton*) event.GetEventObject();
|
||||
|
||||
wxTextCtrl * textCtrl = xoff;
|
||||
|
||||
if( spinCtrl == m_spinYoffset )
|
||||
textCtrl = yoff;
|
||||
else if( spinCtrl == m_spinZoffset )
|
||||
textCtrl = zoff;
|
||||
|
||||
double step = OFFSET_INCREMENT_MM;
|
||||
|
||||
if( g_UserUnit == INCHES )
|
||||
step = OFFSET_INCREMENT_MIL/1000.0;
|
||||
|
||||
incrementTextCtrl( textCtrl, -step, -MAX_OFFSET, MAX_OFFSET );
|
||||
}
|
||||
|
||||
|
||||
@@ -315,13 +525,7 @@ void PANEL_PREV_3D::onMouseWheelScale( wxMouseEvent& event )
|
||||
if( event.GetWheelRotation() >= 0 )
|
||||
step = -step;
|
||||
|
||||
double curr_value = DoubleValueFromString( UNSCALED_UNITS, textCtrl->GetValue() );
|
||||
|
||||
curr_value += step;
|
||||
curr_value = std::max( 1/MAX_SCALE, curr_value );
|
||||
curr_value = std::min( curr_value, MAX_SCALE );
|
||||
|
||||
textCtrl->SetValue( formatScaleValue( curr_value ) );
|
||||
incrementTextCtrl( textCtrl, step, 1/MAX_SCALE, MAX_SCALE );
|
||||
}
|
||||
|
||||
|
||||
@@ -329,6 +533,8 @@ void PANEL_PREV_3D::onMouseWheelRot( wxMouseEvent& event )
|
||||
{
|
||||
wxTextCtrl* textCtrl = (wxTextCtrl*) event.GetEventObject();
|
||||
|
||||
wxKeyboardState kbdState;
|
||||
|
||||
double step = ROTATION_INCREMENT_WHEEL;
|
||||
|
||||
if( event.ShiftDown( ) )
|
||||
@@ -337,13 +543,7 @@ void PANEL_PREV_3D::onMouseWheelRot( wxMouseEvent& event )
|
||||
if( event.GetWheelRotation() >= 0 )
|
||||
step = -step;
|
||||
|
||||
double curr_value = DoubleValueFromString( DEGREES, textCtrl->GetValue() ) / 10.0;
|
||||
|
||||
curr_value += step;
|
||||
curr_value = std::max( -MAX_ROTATION, curr_value );
|
||||
curr_value = std::min( curr_value, MAX_ROTATION );
|
||||
|
||||
textCtrl->SetValue( formatRotationValue( curr_value ) );
|
||||
incrementTextCtrl( textCtrl, step, -MAX_ROTATION, MAX_ROTATION );
|
||||
}
|
||||
|
||||
|
||||
@@ -356,7 +556,7 @@ void PANEL_PREV_3D::onMouseWheelOffset( wxMouseEvent& event )
|
||||
if( event.ShiftDown( ) )
|
||||
step = OFFSET_INCREMENT_MM_FINE;
|
||||
|
||||
if( m_userUnits == INCHES )
|
||||
if( g_UserUnit == INCHES )
|
||||
{
|
||||
step = OFFSET_INCREMENT_MIL/1000.0;
|
||||
if( event.ShiftDown( ) )
|
||||
@@ -366,31 +566,128 @@ void PANEL_PREV_3D::onMouseWheelOffset( wxMouseEvent& event )
|
||||
if( event.GetWheelRotation() >= 0 )
|
||||
step = -step;
|
||||
|
||||
double curr_value = DoubleValueFromString( m_userUnits, textCtrl->GetValue() ) / IU_PER_MM;
|
||||
|
||||
curr_value += step;
|
||||
curr_value = std::max( -MAX_OFFSET, curr_value );
|
||||
curr_value = std::min( curr_value, MAX_OFFSET );
|
||||
|
||||
textCtrl->SetValue( formatOffsetValue( curr_value ) );
|
||||
incrementTextCtrl( textCtrl, step, -MAX_OFFSET, MAX_OFFSET );
|
||||
}
|
||||
|
||||
|
||||
void PANEL_PREV_3D::UpdateDummyModule( bool aReloadRequired )
|
||||
void PANEL_PREV_3D::getOrientationVars( SGPOINT& aScale, SGPOINT& aRotation, SGPOINT& aOffset )
|
||||
{
|
||||
m_dummyModule->Models().clear();
|
||||
|
||||
for( size_t i = 0; i < m_parentModelList->size(); ++i )
|
||||
if( NULL == xscale || NULL == yscale || NULL == zscale
|
||||
|| NULL == xrot || NULL == yrot || NULL == zrot
|
||||
|| NULL == xoff || NULL == yoff || NULL == zoff )
|
||||
{
|
||||
if( m_parentModelList->at( i ).m_Preview )
|
||||
return;
|
||||
}
|
||||
|
||||
xscale->GetValue().ToDouble( &aScale.x );
|
||||
yscale->GetValue().ToDouble( &aScale.y );
|
||||
zscale->GetValue().ToDouble( &aScale.z );
|
||||
|
||||
xrot->GetValue().ToDouble( &aRotation.x );
|
||||
yrot->GetValue().ToDouble( &aRotation.y );
|
||||
zrot->GetValue().ToDouble( &aRotation.z );
|
||||
|
||||
checkRotation( aRotation.x );
|
||||
checkRotation( aRotation.y );
|
||||
checkRotation( aRotation.z );
|
||||
|
||||
xoff->GetValue().ToDouble( &aOffset.x );
|
||||
yoff->GetValue().ToDouble( &aOffset.y );
|
||||
zoff->GetValue().ToDouble( &aOffset.z );
|
||||
|
||||
// Convert from user units to internal units (mm)
|
||||
|
||||
double scaler = 1.0f;
|
||||
|
||||
switch( g_UserUnit )
|
||||
{
|
||||
case MILLIMETRES:
|
||||
scaler = 1.0f;
|
||||
break;
|
||||
case INCHES:
|
||||
scaler = 25.4f;
|
||||
break;
|
||||
default:
|
||||
wxASSERT( 0 );
|
||||
}
|
||||
|
||||
aOffset.x *= scaler;
|
||||
aOffset.y *= scaler;
|
||||
aOffset.z *= scaler;
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
bool PANEL_PREV_3D::ValidateWithMessage( wxString& aErrorMessage )
|
||||
{
|
||||
bool invalidScale = false;
|
||||
|
||||
for( unsigned int idx = 0; idx < m_parentInfoList->size(); ++idx )
|
||||
{
|
||||
wxString msg;
|
||||
bool addError = false;
|
||||
MODULE_3D_SETTINGS& s3dshape = (*m_parentInfoList)[idx];
|
||||
|
||||
SGPOINT scale;
|
||||
scale.x = s3dshape.m_Scale.x;
|
||||
scale.y = s3dshape.m_Scale.y;
|
||||
scale.z = s3dshape.m_Scale.z;
|
||||
|
||||
if( 1/MAX_SCALE > scale.x || MAX_SCALE < scale.x )
|
||||
{
|
||||
m_dummyModule->Models().insert( m_dummyModule->Models().end(),
|
||||
m_parentModelList->at( i ) );
|
||||
invalidScale = true;
|
||||
addError = true;
|
||||
msg += _( "Invalid X scale" );
|
||||
}
|
||||
|
||||
if( 1/MAX_SCALE > scale.y || MAX_SCALE < scale.y )
|
||||
{
|
||||
invalidScale = true;
|
||||
addError = true;
|
||||
|
||||
if( !msg.IsEmpty() )
|
||||
msg += "\n";
|
||||
|
||||
msg += _( "Invalid Y scale" );
|
||||
}
|
||||
|
||||
if( 1/MAX_SCALE > scale.z || MAX_SCALE < scale.z )
|
||||
{
|
||||
invalidScale = true;
|
||||
addError = true;
|
||||
|
||||
if( !msg.IsEmpty() )
|
||||
msg += "\n";
|
||||
|
||||
msg += _( "Invalid Z scale" );
|
||||
}
|
||||
|
||||
if( addError )
|
||||
{
|
||||
msg.Prepend( s3dshape.m_Filename + "\n" );
|
||||
|
||||
if( !aErrorMessage.IsEmpty() )
|
||||
aErrorMessage += "\n\n";
|
||||
|
||||
aErrorMessage += msg;
|
||||
}
|
||||
}
|
||||
|
||||
if( aReloadRequired )
|
||||
m_previewPane->ReloadRequest();
|
||||
if( !aErrorMessage.IsEmpty() )
|
||||
{
|
||||
aErrorMessage += "\n\n";
|
||||
aErrorMessage += wxString::Format( "Min value = %.4f and max value = %.4f",
|
||||
1/MAX_SCALE, MAX_SCALE );
|
||||
}
|
||||
|
||||
m_previewPane->Request_refresh();
|
||||
return invalidScale == false;
|
||||
}
|
||||
|
||||
|
||||
void PANEL_PREV_3D::updateListOnModelCopy()
|
||||
{
|
||||
auto draw3D = &m_copyModule->Models();
|
||||
draw3D->clear();
|
||||
draw3D->insert( draw3D->end(), m_parentInfoList->begin(), m_parentInfoList->end() );
|
||||
}
|
||||
|
||||
@@ -47,23 +47,23 @@
|
||||
#define MAX_ROTATION 180.0
|
||||
#define MAX_OFFSET 1000.0
|
||||
|
||||
#define SCALE_INCREMENT_FINE 0.02
|
||||
#define SCALE_INCREMENT 0.1
|
||||
#define SCALE_INCREMENT_FINE 0.02
|
||||
#define SCALE_INCREMENT 0.1
|
||||
|
||||
#define ROTATION_INCREMENT 90 // in degrees, for spin button command
|
||||
#define ROTATION_INCREMENT_WHEEL 90 // in degrees, for mouse wheel command
|
||||
#define ROTATION_INCREMENT 5 // in degrees, for spin button command
|
||||
#define ROTATION_INCREMENT_WHEEL 15 // in degrees, for mouse wheel command
|
||||
#define ROTATION_INCREMENT_WHEEL_FINE 1 // in degrees, for mouse wheel command
|
||||
|
||||
#define OFFSET_INCREMENT_MM 0.5
|
||||
#define OFFSET_INCREMENT_MM_FINE 0.1
|
||||
#define OFFSET_INCREMENT_MM 0.5
|
||||
#define OFFSET_INCREMENT_MM_FINE 0.1
|
||||
|
||||
#define OFFSET_INCREMENT_MIL 25.0
|
||||
#define OFFSET_INCREMENT_MIL_FINE 5.0
|
||||
#define OFFSET_INCREMENT_MIL 25.0
|
||||
#define OFFSET_INCREMENT_MIL_FINE 5.0
|
||||
|
||||
|
||||
// Declared classes to create pointers
|
||||
class S3D_CACHE;
|
||||
class FILENAME_RESOLVER;
|
||||
class S3D_FILENAME_RESOLVER;
|
||||
class BOARD;
|
||||
class CINFO3D_VISU;
|
||||
class MODULE;
|
||||
@@ -72,32 +72,42 @@ class COLORS_DESIGN_SETTINGS;
|
||||
class PANEL_PREV_3D: public PANEL_PREV_3D_BASE
|
||||
{
|
||||
public:
|
||||
PANEL_PREV_3D( wxWindow* aParent, PCB_BASE_FRAME* aFrame, MODULE* aModule,
|
||||
std::vector<MODULE_3D_SETTINGS> *aParentModelList );
|
||||
PANEL_PREV_3D( wxWindow* aParent, S3D_CACHE* aCacheManager,
|
||||
MODULE* aModuleCopy,
|
||||
COLORS_DESIGN_SETTINGS *aColors,
|
||||
std::vector<MODULE_3D_SETTINGS> *aParentInfoList = NULL );
|
||||
|
||||
~PANEL_PREV_3D();
|
||||
|
||||
private:
|
||||
EDA_3D_CANVAS* m_previewPane;
|
||||
CINFO3D_VISU* m_settings3Dviewer;
|
||||
wxString currentModelFile; ///< Used to check if the model file was changed
|
||||
S3D_FILENAME_RESOLVER *m_resolver; ///< Used to get the full path name
|
||||
|
||||
BOARD* m_dummyBoard;
|
||||
MODULE* m_dummyModule;
|
||||
/// The 3D canvas
|
||||
EDA_3D_CANVAS *m_previewPane;
|
||||
|
||||
std::vector<MODULE_3D_SETTINGS>* m_parentModelList;
|
||||
int m_selected; /// Index into m_parentInfoList
|
||||
/// A dummy board used to store the copy moduled
|
||||
BOARD *m_dummyBoard;
|
||||
|
||||
EDA_UNITS_T m_userUnits;
|
||||
/// The settings that will be used for this 3D viewer canvas
|
||||
CINFO3D_VISU *m_settings3Dviewer;
|
||||
|
||||
/// A pointer to a new copy of the original module
|
||||
MODULE *m_copyModule;
|
||||
|
||||
/// A pointer to the parent MODULE_3D_SETTINGS list that we will use to copy to the preview module
|
||||
std::vector<MODULE_3D_SETTINGS> *m_parentInfoList;
|
||||
|
||||
/// The current selected index of the MODULE_3D_SETTINGS list
|
||||
int m_currentSelectedIdx;
|
||||
|
||||
/// Current MODULE_3D_SETTINGS that is being edited
|
||||
MODULE_3D_SETTINGS m_modelInfo;
|
||||
|
||||
// Methods of the class
|
||||
private:
|
||||
void initPanel();
|
||||
|
||||
/**
|
||||
* Load 3D relevant settings from the user configuration
|
||||
*/
|
||||
void loadCommonSettings();
|
||||
|
||||
/**
|
||||
* @brief updateOrientation - it will receive the events from editing the fields
|
||||
* @param event
|
||||
@@ -108,38 +118,32 @@ private:
|
||||
void onMouseWheelRot( wxMouseEvent& event ) override;
|
||||
void onMouseWheelOffset( wxMouseEvent& event ) override;
|
||||
|
||||
void onIncrementRot( wxSpinEvent& event ) override
|
||||
{
|
||||
doIncrementRotation( event, 1.0 );
|
||||
}
|
||||
void onDecrementRot( wxSpinEvent& event ) override
|
||||
{
|
||||
doIncrementRotation( event, -1.0 );
|
||||
}
|
||||
void onIncrementScale( wxSpinEvent& event ) override
|
||||
{
|
||||
doIncrementScale( event, 1.0 );
|
||||
}
|
||||
void onDecrementScale( wxSpinEvent& event ) override
|
||||
{
|
||||
doIncrementScale( event, -1.0 );
|
||||
}
|
||||
void onIncrementOffset( wxSpinEvent& event ) override
|
||||
{
|
||||
doIncrementOffset( event, 1.0 );
|
||||
}
|
||||
void onDecrementOffset( wxSpinEvent& event ) override
|
||||
{
|
||||
doIncrementOffset( event, -1.0 );
|
||||
}
|
||||
void onIncrementRot( wxSpinEvent& event ) override;
|
||||
void onDecrementRot( wxSpinEvent& event ) override;
|
||||
void onIncrementScale( wxSpinEvent& event ) override;
|
||||
void onDecrementScale( wxSpinEvent& event ) override;
|
||||
void onIncrementOffset( wxSpinEvent& event ) override;
|
||||
void onDecrementOffset( wxSpinEvent& event ) override;
|
||||
|
||||
void doIncrementScale( wxSpinEvent& aEvent, double aSign );
|
||||
void doIncrementRotation( wxSpinEvent& aEvent, double aSign );
|
||||
void doIncrementOffset( wxSpinEvent& aEvent, double aSign );
|
||||
/**
|
||||
* @brief getOrientationVars - gets the transformation from entries and validate it
|
||||
* @param aScale: output scale var
|
||||
* @param aRotation: output rotation var
|
||||
* @param aOffset: output offset var
|
||||
*/
|
||||
void getOrientationVars( SGPOINT& aScale, SGPOINT& aRotation, SGPOINT& aOffset );
|
||||
|
||||
wxString formatScaleValue( double aValue );
|
||||
wxString formatRotationValue( double aValue );
|
||||
wxString formatOffsetValue( double aValue );
|
||||
/**
|
||||
* @brief updateListOnModelCopy - copy the current shape list to the copy of module that is on
|
||||
* the preview dummy board
|
||||
*/
|
||||
void updateListOnModelCopy();
|
||||
|
||||
|
||||
void onEnterPreviewCanvas( wxMouseEvent& event )
|
||||
{
|
||||
m_previewPane->SetFocus();
|
||||
}
|
||||
|
||||
void View3DISO( wxCommandEvent& event ) override
|
||||
{
|
||||
@@ -185,16 +189,33 @@ private:
|
||||
|
||||
public:
|
||||
/**
|
||||
* @brief SetModelDataIdx - Sets the currently selected index in the model list so that
|
||||
* the scale/rotation/offset controls can be updated.
|
||||
* @brief SetModelDataIdx - This will set the index of the INFO list that was set on the parent.
|
||||
* So we will update our values to edit based on the index on that list.
|
||||
* @param idx - The index that was selected
|
||||
* @param aReloadPreviewModule: if need to update the preview module
|
||||
*/
|
||||
void SetSelectedModel( int idx );
|
||||
void SetModelDataIdx( int idx, bool aReloadPreviewModule = false );
|
||||
|
||||
/**
|
||||
* @brief UpdateModelInfoList - copy shapes from the current shape list which are flagged
|
||||
* for preview to the copy of module that is on the preview dummy board
|
||||
* @brief ResetModelData - Clear the values and reload the preview board
|
||||
* @param aReloadPreviewModule: if need to update the preview module
|
||||
*/
|
||||
void UpdateDummyModule( bool aRelaodRequired = true );
|
||||
void ResetModelData( bool aReloadPreviewModule = false );
|
||||
|
||||
void UpdateModelName( wxString const& aModel );
|
||||
|
||||
/**
|
||||
* @brief verify X,Y and Z scale factors are acceptable (> 0.001 and < 1000.0)
|
||||
* @return false if one (or more) value is not acceptable.
|
||||
* @param aErrorMessage is a wxString to store error messages, if any
|
||||
*/
|
||||
bool ValidateWithMessage( wxString& aErrorMessage );
|
||||
|
||||
bool Validate() override
|
||||
{
|
||||
wxString temp;
|
||||
return ValidateWithMessage(temp);
|
||||
}
|
||||
};
|
||||
|
||||
#endif // PANEL_PREV_MODEL_H
|
||||
|
||||
@@ -358,19 +358,22 @@ bool S3D::GetMatIndex( MATLIST& aList, SGNODE* aNode, int& aIndex )
|
||||
|
||||
void S3D::INIT_SMATERIAL( SMATERIAL& aMaterial )
|
||||
{
|
||||
aMaterial = {};
|
||||
memset( &aMaterial, 0, sizeof( aMaterial ) );
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
void S3D::INIT_SMESH( SMESH& aMesh )
|
||||
{
|
||||
aMesh = {};
|
||||
memset( &aMesh, 0, sizeof( aMesh ) );
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
void S3D::INIT_S3DMODEL( S3DMODEL& aModel )
|
||||
{
|
||||
aModel = {};
|
||||
memset( &aModel, 0, sizeof( aModel ) );
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -0,0 +1,87 @@
|
||||
/*
|
||||
* This program source code file is part of KiCad, a free EDA CAD application.
|
||||
*
|
||||
* Copyright (C) 2015 Cirilo Bernardo <cirilo.bernardo@gmail.com>
|
||||
*
|
||||
* 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 str_rsort.h
|
||||
* provides a wxString sorting functino which works from the
|
||||
* end of the string towards the beginning
|
||||
*/
|
||||
|
||||
#ifndef STR_RSORT_H
|
||||
#define STR_RSORT_H
|
||||
|
||||
#include <wx/string.h>
|
||||
|
||||
namespace S3D
|
||||
{
|
||||
|
||||
struct rsort_wxString
|
||||
{
|
||||
bool operator() (const wxString& strA, const wxString& strB ) const
|
||||
{
|
||||
// sort a wxString using the reverse character order; for 3d model
|
||||
// filenames this will typically be a much faster operation than
|
||||
// a normal alphabetic sort
|
||||
wxString::const_reverse_iterator sA = strA.rbegin();
|
||||
wxString::const_reverse_iterator eA = strA.rend();
|
||||
|
||||
wxString::const_reverse_iterator sB = strB.rbegin();
|
||||
wxString::const_reverse_iterator eB = strB.rend();
|
||||
|
||||
if( strA.empty() )
|
||||
{
|
||||
if( strB.empty() )
|
||||
return false;
|
||||
|
||||
// note: this rule implies that a null string is first in the sort order
|
||||
return true;
|
||||
}
|
||||
|
||||
if( strB.empty() )
|
||||
return false;
|
||||
|
||||
while( sA != eA && sB != eB )
|
||||
{
|
||||
if( (*sA) == (*sB) )
|
||||
{
|
||||
++sA;
|
||||
++sB;
|
||||
continue;
|
||||
}
|
||||
|
||||
if( (*sA) < (*sB) )
|
||||
return true;
|
||||
else
|
||||
return false;
|
||||
}
|
||||
|
||||
if( sB == eB )
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
};
|
||||
|
||||
} // end NAMESPACE
|
||||
|
||||
#endif // STR_RSORT_H
|
||||
@@ -65,7 +65,8 @@ CINFO3D_VISU::CINFO3D_VISU() :
|
||||
m_boardSize = wxSize();
|
||||
m_boardCenter = SFVEC3F( 0.0f );
|
||||
|
||||
m_boardBoundingBox.Reset();
|
||||
m_boardBoudingBox.Reset();
|
||||
m_board2dBBox3DU.Reset();
|
||||
|
||||
m_layers_container2D.clear();
|
||||
m_layers_holes2D.clear();
|
||||
@@ -255,8 +256,7 @@ unsigned int CINFO3D_VISU::GetNrSegmentsCircle( int aDiameterBIU ) const
|
||||
{
|
||||
wxASSERT( aDiameterBIU > 0 );
|
||||
|
||||
// Require at least 3 segments for a circle
|
||||
return std::max( GetArcToSegmentCount( aDiameterBIU / 2, ARC_HIGH_DEF, 360.0 ), 3 );
|
||||
return GetArcToSegmentCount( aDiameterBIU / 2, ARC_HIGH_DEF, 360.0 );
|
||||
}
|
||||
|
||||
|
||||
@@ -415,7 +415,7 @@ void CINFO3D_VISU::InitSettings( REPORTER *aStatusTextReporter )
|
||||
boardMin.z = m_layerZcoordTop[B_Adhes];
|
||||
boardMax.z = m_layerZcoordTop[F_Adhes];
|
||||
|
||||
m_boardBoundingBox = CBBOX( boardMin, boardMax );
|
||||
m_boardBoudingBox = CBBOX( boardMin, boardMax );
|
||||
|
||||
#ifdef PRINT_STATISTICS_3D_VIEWER
|
||||
unsigned stats_startCreateBoardPolyTime = GetRunningMicroSecs();
|
||||
@@ -461,6 +461,11 @@ void CINFO3D_VISU::createBoardPolygon()
|
||||
errmsg.append( _( "Cannot determine the board outline." ) );
|
||||
wxLogMessage( errmsg );
|
||||
}
|
||||
|
||||
// Be sure the polygon is strictly simple to avoid issues.
|
||||
m_board_poly.Simplify( SHAPE_POLY_SET::PM_STRICTLY_SIMPLE );
|
||||
|
||||
Polygon_Calc_BBox_3DU( m_board_poly, m_board2dBBox3DU, m_biuTo3Dunits );
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -144,7 +144,7 @@ class CINFO3D_VISU
|
||||
* @brief GetBBox3DU - Get the bbox of the pcb board
|
||||
* @return the board bbox in 3d units
|
||||
*/
|
||||
const CBBOX &GetBBox3DU() const { return m_boardBoundingBox; }
|
||||
const CBBOX &GetBBox3DU() const { return m_boardBoudingBox; }
|
||||
|
||||
/**
|
||||
* @brief GetEpoxyThickness3DU - Get the current epoxy thickness
|
||||
@@ -425,6 +425,10 @@ class CINFO3D_VISU
|
||||
// Helper functions to create the board
|
||||
COBJECT2D *createNewTrack( const TRACK* aTrack , int aClearanceValue ) const;
|
||||
|
||||
void createNewPad( const D_PAD* aPad,
|
||||
CGENERICCONTAINER2D *aDstContainer,
|
||||
wxSize aInflateValue ) const;
|
||||
|
||||
void createNewPadWithClearance( const D_PAD *aPad,
|
||||
CGENERICCONTAINER2D *aDstContainer,
|
||||
wxSize aClearanceValue ) const;
|
||||
@@ -478,7 +482,7 @@ class CINFO3D_VISU
|
||||
SHAPE_POLY_SET &aCornerBuffer,
|
||||
int aWidth) const;
|
||||
|
||||
void transformPadsShapesWithClearanceToPolygon( const PADS &aPads,
|
||||
void transformPadsShapesWithClearanceToPolygon( const DLIST<D_PAD> &aPads,
|
||||
PCB_LAYER_ID aLayer,
|
||||
SHAPE_POLY_SET &aCornerBuffer,
|
||||
int aInflateValue,
|
||||
@@ -490,10 +494,12 @@ class CINFO3D_VISU
|
||||
|
||||
void buildPadShapePolygon( const D_PAD *aPad,
|
||||
SHAPE_POLY_SET &aCornerBuffer,
|
||||
wxSize aInflateValue ) const;
|
||||
wxSize aInflateValue,
|
||||
int aSegmentsPerCircle,
|
||||
double aCorrectionFactor ) const;
|
||||
|
||||
|
||||
public:
|
||||
public:
|
||||
SFVEC3D m_BgColorBot; ///< background bottom color
|
||||
SFVEC3D m_BgColorTop; ///< background top color
|
||||
SFVEC3D m_BoardBodyColor; ///< in realistic mode: FR4 board color
|
||||
@@ -503,7 +509,7 @@ public:
|
||||
SFVEC3D m_CopperColor; ///< in realistic mode: copper color
|
||||
|
||||
|
||||
private:
|
||||
private:
|
||||
|
||||
/// Current board
|
||||
BOARD *m_board;
|
||||
@@ -541,8 +547,11 @@ private:
|
||||
|
||||
// Pcb board bounding boxes
|
||||
|
||||
/// 3d bounding box of the pcb board in 3d units
|
||||
CBBOX m_boardBoundingBox;
|
||||
/// 3d bouding box of the pcb board in 3d units
|
||||
CBBOX m_boardBoudingBox;
|
||||
|
||||
/// 2d bouding box of the pcb board in 3d units
|
||||
CBBOX2D m_board2dBBox3DU;
|
||||
|
||||
/// It contains polygon contours for each layer
|
||||
MAP_POLY m_layers_poly;
|
||||
|
||||
@@ -50,7 +50,7 @@
|
||||
#include <class_text_mod.h>
|
||||
#include <convert_basic_shapes_to_polygon.h>
|
||||
#include <trigo.h>
|
||||
#include <gr_text.h>
|
||||
#include <draw_graphic_text.h>
|
||||
#include <utility>
|
||||
#include <vector>
|
||||
|
||||
@@ -62,11 +62,13 @@
|
||||
static int s_textWidth;
|
||||
static CGENERICCONTAINER2D *s_dstcontainer = NULL;
|
||||
static float s_biuTo3Dunits;
|
||||
static const CBBOX2D *s_boardBBox3DU = NULL;
|
||||
static const BOARD_ITEM *s_boardItem = NULL;
|
||||
|
||||
// This is a call back function, used by GRText to draw the 3D text shape:
|
||||
// This is a call back function, used by DrawGraphicText to draw the 3D text shape:
|
||||
void addTextSegmToContainer( int x0, int y0, int xf, int yf, void* aData )
|
||||
{
|
||||
wxASSERT( s_boardBBox3DU != NULL );
|
||||
wxASSERT( s_dstcontainer != NULL );
|
||||
|
||||
const SFVEC2F start3DU( x0 * s_biuTo3Dunits, -y0 * s_biuTo3Dunits );
|
||||
@@ -74,7 +76,7 @@ void addTextSegmToContainer( int x0, int y0, int xf, int yf, void* aData )
|
||||
|
||||
if( Is_segment_a_circle( start3DU, end3DU ) )
|
||||
s_dstcontainer->Add( new CFILLEDCIRCLE2D( start3DU,
|
||||
( s_textWidth / 2 ) * s_biuTo3Dunits,
|
||||
s_textWidth * s_biuTo3Dunits,
|
||||
*s_boardItem) );
|
||||
else
|
||||
s_dstcontainer->Add( new CROUNDSEGMENT2D( start3DU,
|
||||
@@ -87,46 +89,52 @@ void addTextSegmToContainer( int x0, int y0, int xf, int yf, void* aData )
|
||||
// Based on
|
||||
// void TEXTE_PCB::TransformShapeWithClearanceToPolygonSet
|
||||
// board_items_to_polygon_shape_transform.cpp
|
||||
void CINFO3D_VISU::AddShapeWithClearanceToContainer( const TEXTE_PCB* aText,
|
||||
void CINFO3D_VISU::AddShapeWithClearanceToContainer( const TEXTE_PCB* aTextPCB,
|
||||
CGENERICCONTAINER2D *aDstContainer,
|
||||
PCB_LAYER_ID aLayerId,
|
||||
int aClearanceValue )
|
||||
{
|
||||
wxSize size = aText->GetTextSize();
|
||||
wxSize size = aTextPCB->GetTextSize();
|
||||
|
||||
if( aText->IsMirrored() )
|
||||
if( aTextPCB->IsMirrored() )
|
||||
size.x = -size.x;
|
||||
|
||||
s_boardItem = (const BOARD_ITEM *) &aText;
|
||||
s_boardItem = (const BOARD_ITEM *)&aTextPCB;
|
||||
s_dstcontainer = aDstContainer;
|
||||
s_textWidth = aText->GetThickness() + ( 2 * aClearanceValue );
|
||||
s_textWidth = aTextPCB->GetThickness() + ( 2 * aClearanceValue );
|
||||
s_biuTo3Dunits = m_biuTo3Dunits;
|
||||
s_boardBBox3DU = &m_board2dBBox3DU;
|
||||
|
||||
// not actually used, but needed by GRText
|
||||
// not actually used, but needed by DrawGraphicText
|
||||
const COLOR4D dummy_color = COLOR4D::BLACK;
|
||||
|
||||
if( aText->IsMultilineAllowed() )
|
||||
if( aTextPCB->IsMultilineAllowed() )
|
||||
{
|
||||
wxArrayString strings_list;
|
||||
wxStringSplit( aText->GetShownText(), strings_list, '\n' );
|
||||
wxStringSplit( aTextPCB->GetShownText(), strings_list, '\n' );
|
||||
std::vector<wxPoint> positions;
|
||||
positions.reserve( strings_list.Count() );
|
||||
aText->GetPositionsOfLinesOfMultilineText( positions, strings_list.Count() );
|
||||
aTextPCB->GetPositionsOfLinesOfMultilineText( positions,
|
||||
strings_list.Count() );
|
||||
|
||||
for( unsigned ii = 0; ii < strings_list.Count(); ++ii )
|
||||
{
|
||||
wxString txt = strings_list.Item( ii );
|
||||
|
||||
GRText( NULL, positions[ii], dummy_color, txt, aText->GetTextAngle(), size,
|
||||
aText->GetHorizJustify(), aText->GetVertJustify(), aText->GetThickness(),
|
||||
aText->IsItalic(), true, addTextSegmToContainer );
|
||||
DrawGraphicText( NULL, NULL, positions[ii], dummy_color,
|
||||
txt, aTextPCB->GetTextAngle(), size,
|
||||
aTextPCB->GetHorizJustify(), aTextPCB->GetVertJustify(),
|
||||
aTextPCB->GetThickness(), aTextPCB->IsItalic(),
|
||||
true, addTextSegmToContainer );
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
GRText( NULL, aText->GetTextPos(), dummy_color, aText->GetShownText(),
|
||||
aText->GetTextAngle(), size, aText->GetHorizJustify(), aText->GetVertJustify(),
|
||||
aText->GetThickness(), aText->IsItalic(), true, addTextSegmToContainer );
|
||||
DrawGraphicText( NULL, NULL, aTextPCB->GetTextPos(), dummy_color,
|
||||
aTextPCB->GetShownText(), aTextPCB->GetTextAngle(), size,
|
||||
aTextPCB->GetHorizJustify(), aTextPCB->GetVertJustify(),
|
||||
aTextPCB->GetThickness(), aTextPCB->IsItalic(),
|
||||
true, addTextSegmToContainer );
|
||||
}
|
||||
}
|
||||
|
||||
@@ -176,7 +184,9 @@ void CINFO3D_VISU::AddGraphicsShapesWithClearanceToContainer( const MODULE* aMod
|
||||
std::vector<TEXTE_MODULE *> texts; // List of TEXTE_MODULE to convert
|
||||
EDGE_MODULE* outline;
|
||||
|
||||
for( auto item : aModule->GraphicalItems() )
|
||||
for( EDA_ITEM* item = aModule->GraphicalItemsList();
|
||||
item != NULL;
|
||||
item = item->Next() )
|
||||
{
|
||||
switch( item->Type() )
|
||||
{
|
||||
@@ -218,18 +228,22 @@ void CINFO3D_VISU::AddGraphicsShapesWithClearanceToContainer( const MODULE* aMod
|
||||
s_boardItem = (const BOARD_ITEM *)&aModule->Value();
|
||||
s_dstcontainer = aDstContainer;
|
||||
s_biuTo3Dunits = m_biuTo3Dunits;
|
||||
s_boardBBox3DU = &m_board2dBBox3DU;
|
||||
|
||||
for( TEXTE_MODULE* text : texts )
|
||||
for( unsigned ii = 0; ii < texts.size(); ++ii )
|
||||
{
|
||||
s_textWidth = text->GetThickness() + ( 2 * aInflateValue );
|
||||
wxSize size = text->GetTextSize();
|
||||
TEXTE_MODULE *textmod = texts[ii];
|
||||
s_textWidth = textmod->GetThickness() + ( 2 * aInflateValue );
|
||||
wxSize size = textmod->GetTextSize();
|
||||
|
||||
if( text->IsMirrored() )
|
||||
if( textmod->IsMirrored() )
|
||||
size.x = -size.x;
|
||||
|
||||
GRText( NULL, text->GetTextPos(), BLACK, text->GetShownText(), text->GetDrawRotation(),
|
||||
size, text->GetHorizJustify(), text->GetVertJustify(), text->GetThickness(),
|
||||
text->IsItalic(), true, addTextSegmToContainer );
|
||||
DrawGraphicText( NULL, NULL, textmod->GetTextPos(), BLACK,
|
||||
textmod->GetShownText(), textmod->GetDrawRotation(), size,
|
||||
textmod->GetHorizJustify(), textmod->GetVertJustify(),
|
||||
textmod->GetThickness(), textmod->IsItalic(),
|
||||
true, addTextSegmToContainer );
|
||||
}
|
||||
}
|
||||
|
||||
@@ -477,25 +491,6 @@ void CINFO3D_VISU::createNewPadWithClearance( const D_PAD* aPad,
|
||||
}
|
||||
break;
|
||||
|
||||
case PAD_SHAPE_CHAMFERED_RECT:
|
||||
{
|
||||
wxSize shapesize( aPad->GetSize() );
|
||||
shapesize.x += aClearanceValue.x * 2;
|
||||
shapesize.y += aClearanceValue.y * 2;
|
||||
|
||||
SHAPE_POLY_SET polyList; // Will contain the pad outlines in board coordinates
|
||||
|
||||
int corner_radius = aPad->GetRoundRectCornerRadius( shapesize );
|
||||
TransformRoundChamferedRectToPolygon( polyList, PadShapePos, shapesize, aPad->GetOrientation(),
|
||||
corner_radius, aPad->GetChamferRectRatio(),
|
||||
aPad->GetChamferPositions(), ARC_HIGH_DEF );
|
||||
|
||||
// Add the PAD polygon
|
||||
Convert_shape_line_polygon_to_triangles( polyList, *aDstContainer, m_biuTo3Dunits, *aPad );
|
||||
|
||||
}
|
||||
break;
|
||||
|
||||
case PAD_SHAPE_CUSTOM:
|
||||
{
|
||||
SHAPE_POLY_SET polyList; // Will contain the pad outlines in board coordinates
|
||||
@@ -568,15 +563,59 @@ COBJECT2D *CINFO3D_VISU::createNewPadDrill( const D_PAD* aPad, int aInflateValue
|
||||
}
|
||||
|
||||
|
||||
// This function pretends to be like the
|
||||
// void D_PAD::BuildPadShapePolygon(
|
||||
// board_items_to_polygon_shape_transform.cpp
|
||||
void CINFO3D_VISU::createNewPad( const D_PAD* aPad,
|
||||
CGENERICCONTAINER2D *aDstContainer,
|
||||
wxSize aInflateValue ) const
|
||||
{
|
||||
switch( aPad->GetShape() )
|
||||
{
|
||||
case PAD_SHAPE_CIRCLE:
|
||||
case PAD_SHAPE_OVAL:
|
||||
case PAD_SHAPE_ROUNDRECT:
|
||||
case PAD_SHAPE_CUSTOM:
|
||||
createNewPadWithClearance( aPad, aDstContainer, aInflateValue );
|
||||
break;
|
||||
|
||||
case PAD_SHAPE_TRAPEZOID:
|
||||
case PAD_SHAPE_RECT:
|
||||
wxPoint corners[4];
|
||||
aPad->BuildPadPolygon( corners, aInflateValue, aPad->GetOrientation() );
|
||||
|
||||
// Note: for pad having a shape offset,
|
||||
// the pad position is NOT the shape position
|
||||
for( unsigned int ii = 0; ii < 4; ++ii )
|
||||
corners[ii] += aPad->ShapePos(); // Shift origin to position
|
||||
|
||||
aDstContainer->Add( new CPOLYGON4PTS2D(
|
||||
SFVEC2F( corners[0].x * m_biuTo3Dunits,
|
||||
-corners[0].y * m_biuTo3Dunits ),
|
||||
SFVEC2F( corners[1].x * m_biuTo3Dunits,
|
||||
-corners[1].y * m_biuTo3Dunits ),
|
||||
SFVEC2F( corners[2].x * m_biuTo3Dunits,
|
||||
-corners[2].y * m_biuTo3Dunits ),
|
||||
SFVEC2F( corners[3].x * m_biuTo3Dunits,
|
||||
-corners[3].y * m_biuTo3Dunits ),
|
||||
*aPad ) );
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void CINFO3D_VISU::AddPadsShapesWithClearanceToContainer( const MODULE* aModule,
|
||||
CGENERICCONTAINER2D *aDstContainer,
|
||||
PCB_LAYER_ID aLayerId,
|
||||
int aInflateValue,
|
||||
bool aSkipNPTHPadsWihNoCopper )
|
||||
{
|
||||
const D_PAD* pad = aModule->PadsList();
|
||||
|
||||
wxSize margin;
|
||||
|
||||
for( auto pad : aModule->Pads() )
|
||||
for( ; pad != NULL; pad = pad->Next() )
|
||||
{
|
||||
if( !pad->IsOnLayer( aLayerId ) )
|
||||
continue;
|
||||
@@ -625,7 +664,7 @@ void CINFO3D_VISU::AddPadsShapesWithClearanceToContainer( const MODULE* aModule,
|
||||
break;
|
||||
}
|
||||
|
||||
createNewPadWithClearance( pad, aDstContainer, margin );
|
||||
createNewPad( pad, aDstContainer, margin );
|
||||
}
|
||||
}
|
||||
|
||||
@@ -724,13 +763,13 @@ void CINFO3D_VISU::AddShapeWithClearanceToContainer( const DRAWSEGMENT* aDrawSeg
|
||||
const SFVEC2F center3DU( aDrawSegment->GetCenter().x * m_biuTo3Dunits,
|
||||
-aDrawSegment->GetCenter().y * m_biuTo3Dunits );
|
||||
|
||||
float inner_radius = ( aDrawSegment->GetRadius() - linewidth / 2 ) * m_biuTo3Dunits;
|
||||
float outer_radius = ( aDrawSegment->GetRadius() + linewidth / 2 ) * m_biuTo3Dunits;
|
||||
const float inner_radius = (aDrawSegment->GetRadius() - linewidth / 2) * m_biuTo3Dunits;
|
||||
const float outter_radius = (aDrawSegment->GetRadius() + linewidth / 2) * m_biuTo3Dunits;
|
||||
|
||||
if( inner_radius < 0 )
|
||||
inner_radius = 0;
|
||||
|
||||
aDstContainer->Add( new CRING2D( center3DU, inner_radius, outer_radius, *aDrawSegment ) );
|
||||
aDstContainer->Add( new CRING2D( center3DU,
|
||||
inner_radius,
|
||||
outter_radius,
|
||||
*aDrawSegment ) );
|
||||
}
|
||||
break;
|
||||
|
||||
@@ -773,12 +812,14 @@ void CINFO3D_VISU::AddShapeWithClearanceToContainer( const DRAWSEGMENT* aDrawSeg
|
||||
}
|
||||
break;
|
||||
|
||||
case S_CURVE:
|
||||
case S_POLYGON:
|
||||
{
|
||||
const int segcountforcircle = 16;
|
||||
const double correctionFactor = GetCircleCorrectionFactor( segcountforcircle );
|
||||
SHAPE_POLY_SET polyList;
|
||||
|
||||
aDrawSegment->TransformShapeWithClearanceToPolygon( polyList, aClearanceValue );
|
||||
aDrawSegment->TransformShapeWithClearanceToPolygon( polyList, aClearanceValue,
|
||||
segcountforcircle, correctionFactor );
|
||||
|
||||
polyList.Simplify( SHAPE_POLY_SET::PM_FAST );
|
||||
|
||||
@@ -790,6 +831,9 @@ void CINFO3D_VISU::AddShapeWithClearanceToContainer( const DRAWSEGMENT* aDrawSeg
|
||||
}
|
||||
break;
|
||||
|
||||
case S_CURVE: // Bezier curve (not yet in use in KiCad)
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
@@ -807,16 +851,13 @@ void CINFO3D_VISU::AddSolidAreasShapesToContainer( const ZONE_CONTAINER* aZoneCo
|
||||
SHAPE_POLY_SET polyList = SHAPE_POLY_SET( aZoneContainer->GetFilledPolysList(), true );
|
||||
|
||||
// This convert the poly in outline and holes
|
||||
Convert_shape_line_polygon_to_triangles( polyList, *aDstContainer, m_biuTo3Dunits,
|
||||
Convert_shape_line_polygon_to_triangles( polyList,
|
||||
*aDstContainer,
|
||||
m_biuTo3Dunits,
|
||||
*aZoneContainer );
|
||||
|
||||
// add filled areas outlines, which are drawn with thick lines segments
|
||||
// but only if filled polygons outlines have thickness
|
||||
if( !aZoneContainer->GetFilledPolysUseThickness() )
|
||||
return;
|
||||
|
||||
float line_thickness = aZoneContainer->GetMinThickness() * m_biuTo3Dunits;
|
||||
|
||||
// /////////////////////////////////////////////////////////////////////////
|
||||
for( int i = 0; i < polyList.OutlineCount(); ++i )
|
||||
{
|
||||
// Add outline
|
||||
@@ -832,15 +873,17 @@ void CINFO3D_VISU::AddSolidAreasShapesToContainer( const ZONE_CONTAINER* aZoneCo
|
||||
|
||||
if( Is_segment_a_circle( start3DU, end3DU ) )
|
||||
{
|
||||
float radius = line_thickness/2;
|
||||
float radius = (aZoneContainer->GetMinThickness() / 2) * m_biuTo3Dunits;
|
||||
|
||||
if( radius > 0.0 ) // degenerated circles crash 3D viewer
|
||||
aDstContainer->Add( new CFILLEDCIRCLE2D( start3DU, radius,
|
||||
aDstContainer->Add( new CFILLEDCIRCLE2D( start3DU, radius ,
|
||||
*aZoneContainer ) );
|
||||
}
|
||||
else
|
||||
{
|
||||
aDstContainer->Add( new CROUNDSEGMENT2D( start3DU, end3DU, line_thickness,
|
||||
aDstContainer->Add( new CROUNDSEGMENT2D( start3DU, end3DU,
|
||||
aZoneContainer->GetMinThickness() *
|
||||
m_biuTo3Dunits,
|
||||
*aZoneContainer ) );
|
||||
}
|
||||
}
|
||||
@@ -860,7 +903,7 @@ void CINFO3D_VISU::AddSolidAreasShapesToContainer( const ZONE_CONTAINER* aZoneCo
|
||||
|
||||
if( Is_segment_a_circle( start3DU, end3DU ) )
|
||||
{
|
||||
float radius = line_thickness/2;
|
||||
float radius = (aZoneContainer->GetMinThickness() / 2) * m_biuTo3Dunits;
|
||||
|
||||
if( radius > 0.0 ) // degenerated circles crash 3D viewer
|
||||
aDstContainer->Add(
|
||||
@@ -870,7 +913,9 @@ void CINFO3D_VISU::AddSolidAreasShapesToContainer( const ZONE_CONTAINER* aZoneCo
|
||||
else
|
||||
{
|
||||
aDstContainer->Add(
|
||||
new CROUNDSEGMENT2D( start3DU, end3DU, line_thickness,
|
||||
new CROUNDSEGMENT2D( start3DU, end3DU,
|
||||
aZoneContainer->GetMinThickness() *
|
||||
m_biuTo3Dunits,
|
||||
*aZoneContainer ) );
|
||||
}
|
||||
}
|
||||
@@ -890,17 +935,28 @@ void CINFO3D_VISU::buildPadShapeThickOutlineAsSegments( const D_PAD* aPad,
|
||||
-aPad->ShapePos().y * m_biuTo3Dunits );
|
||||
|
||||
const int radius = aPad->GetSize().x / 2;
|
||||
const float inner_radius = ( radius - aWidth / 2 ) * m_biuTo3Dunits;
|
||||
const float outer_radius = ( radius + aWidth / 2 ) * m_biuTo3Dunits;
|
||||
const float inner_radius = (radius - aWidth / 2) * m_biuTo3Dunits;
|
||||
const float outter_radius = (radius + aWidth / 2) * m_biuTo3Dunits;
|
||||
|
||||
aDstContainer->Add( new CRING2D( center3DU, inner_radius, outer_radius, *aPad ) );
|
||||
aDstContainer->Add( new CRING2D( center3DU,
|
||||
inner_radius,
|
||||
outter_radius,
|
||||
*aPad ) );
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
// For other shapes, draw polygon outlines
|
||||
SHAPE_POLY_SET corners;
|
||||
aPad->BuildPadShapePolygon( corners, wxSize( 0, 0 ) );
|
||||
|
||||
const int segcountforcircle = GetNrSegmentsCircle( glm::min( aPad->GetSize().x,
|
||||
aPad->GetSize().y) );
|
||||
|
||||
const double correctionFactor = GetCircleCorrectionFactor( segcountforcircle );
|
||||
|
||||
aPad->BuildPadShapePolygon( corners, wxSize( 0, 0 ),
|
||||
// This two factors are only expected to be used if render an oval
|
||||
segcountforcircle, correctionFactor );
|
||||
|
||||
|
||||
// Add outlines as thick segments in polygon buffer
|
||||
@@ -917,13 +973,15 @@ void CINFO3D_VISU::buildPadShapeThickOutlineAsSegments( const D_PAD* aPad,
|
||||
|
||||
if( Is_segment_a_circle( start3DU, end3DU ) )
|
||||
{
|
||||
aDstContainer->Add(
|
||||
new CFILLEDCIRCLE2D( start3DU, ( aWidth / 2 ) * m_biuTo3Dunits, *aPad ) );
|
||||
aDstContainer->Add( new CFILLEDCIRCLE2D( start3DU,
|
||||
(aWidth / 2) * m_biuTo3Dunits,
|
||||
*aPad ) );
|
||||
}
|
||||
else
|
||||
{
|
||||
aDstContainer->Add(
|
||||
new CROUNDSEGMENT2D( start3DU, end3DU, aWidth * m_biuTo3Dunits, *aPad ) );
|
||||
aDstContainer->Add( new CROUNDSEGMENT2D( start3DU, end3DU,
|
||||
aWidth * m_biuTo3Dunits,
|
||||
*aPad ) );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -140,6 +140,17 @@ void CINFO3D_VISU::destroyLayers()
|
||||
|
||||
void CINFO3D_VISU::createLayers( REPORTER *aStatusTextReporter )
|
||||
{
|
||||
// Number of segments to draw a circle using segments (used on countour zones
|
||||
// and text copper elements )
|
||||
const int segcountforcircle = 12;
|
||||
const double correctionFactor = GetCircleCorrectionFactor( segcountforcircle );
|
||||
|
||||
// segments to draw a circle to build texts. Is is used only to build
|
||||
// the shape of each segment of the stroke font, therefore no need to have
|
||||
// many segments per circle.
|
||||
const int segcountInStrokeFont = 12;
|
||||
const double correctionFactorStroke = GetCircleCorrectionFactor( segcountInStrokeFont );
|
||||
|
||||
destroyLayers();
|
||||
|
||||
// Build Copper layers
|
||||
@@ -166,9 +177,9 @@ void CINFO3D_VISU::createLayers( REPORTER *aStatusTextReporter )
|
||||
// /////////////////////////////////////////////////////////////////////////
|
||||
std::vector< const TRACK *> trackList;
|
||||
trackList.clear();
|
||||
trackList.reserve( m_board->Tracks().size() );
|
||||
trackList.reserve( m_board->m_Track.GetCount() );
|
||||
|
||||
for( auto track : m_board->Tracks() )
|
||||
for( const TRACK* track = m_board->m_Track; track; track = track->Next() )
|
||||
{
|
||||
if( !Is3DLayerEnabled( track->GetLayer() ) ) // Skip non enabled layers
|
||||
continue;
|
||||
@@ -208,10 +219,10 @@ void CINFO3D_VISU::createLayers( REPORTER *aStatusTextReporter )
|
||||
layer_id.clear();
|
||||
layer_id.reserve( m_copperLayersCount );
|
||||
|
||||
for( unsigned i = 0; i < arrayDim( cu_seq ); ++i )
|
||||
for( unsigned i = 0; i < DIM( cu_seq ); ++i )
|
||||
cu_seq[i] = ToLAYER_ID( B_Cu - i );
|
||||
|
||||
for( LSEQ cu = cu_set.Seq( cu_seq, arrayDim( cu_seq ) ); cu; ++cu )
|
||||
for( LSEQ cu = cu_set.Seq( cu_seq, DIM( cu_seq ) ); cu; ++cu )
|
||||
{
|
||||
const PCB_LAYER_ID curr_layer_id = *cu;
|
||||
|
||||
@@ -382,7 +393,7 @@ void CINFO3D_VISU::createLayers( REPORTER *aStatusTextReporter )
|
||||
// Add VIA hole contourns
|
||||
// /////////////////////////////////////////////////////////
|
||||
|
||||
// Add outer holes of VIAs
|
||||
// Add outter holes of VIAs
|
||||
SHAPE_POLY_SET *layerOuterHolesPoly = NULL;
|
||||
SHAPE_POLY_SET *layerInnerHolesPoly = NULL;
|
||||
|
||||
@@ -414,11 +425,15 @@ void CINFO3D_VISU::createLayers( REPORTER *aStatusTextReporter )
|
||||
const int holediameter = via->GetDrillValue();
|
||||
const int hole_outer_radius = (holediameter / 2) + GetCopperThicknessBIU();
|
||||
|
||||
TransformCircleToPolygon( *layerOuterHolesPoly, via->GetStart(),
|
||||
hole_outer_radius, ARC_HIGH_DEF );
|
||||
TransformCircleToPolygon( *layerOuterHolesPoly,
|
||||
via->GetStart(),
|
||||
hole_outer_radius,
|
||||
GetNrSegmentsCircle( hole_outer_radius * 2 ) );
|
||||
|
||||
TransformCircleToPolygon( *layerInnerHolesPoly, via->GetStart(),
|
||||
holediameter / 2, ARC_HIGH_DEF );
|
||||
TransformCircleToPolygon( *layerInnerHolesPoly,
|
||||
via->GetStart(),
|
||||
holediameter / 2,
|
||||
GetNrSegmentsCircle( holediameter ) );
|
||||
}
|
||||
else if( lIdx == 0 ) // it only adds once the THT holes
|
||||
{
|
||||
@@ -427,16 +442,22 @@ void CINFO3D_VISU::createLayers( REPORTER *aStatusTextReporter )
|
||||
|
||||
// Add through hole contourns
|
||||
// /////////////////////////////////////////////////////////
|
||||
TransformCircleToPolygon( m_through_outer_holes_poly, via->GetStart(),
|
||||
hole_outer_radius, ARC_HIGH_DEF );
|
||||
TransformCircleToPolygon( m_through_outer_holes_poly,
|
||||
via->GetStart(),
|
||||
hole_outer_radius,
|
||||
GetNrSegmentsCircle( hole_outer_radius * 2 ) );
|
||||
|
||||
TransformCircleToPolygon( m_through_inner_holes_poly, via->GetStart(),
|
||||
holediameter / 2, ARC_HIGH_DEF );
|
||||
TransformCircleToPolygon( m_through_inner_holes_poly,
|
||||
via->GetStart(),
|
||||
holediameter / 2,
|
||||
GetNrSegmentsCircle( holediameter ) );
|
||||
|
||||
// Add samething for vias only
|
||||
|
||||
TransformCircleToPolygon( m_through_outer_holes_vias_poly, via->GetStart(),
|
||||
hole_outer_radius, ARC_HIGH_DEF );
|
||||
TransformCircleToPolygon( m_through_outer_holes_vias_poly,
|
||||
via->GetStart(),
|
||||
hole_outer_radius,
|
||||
GetNrSegmentsCircle( hole_outer_radius * 2 ) );
|
||||
|
||||
//TransformCircleToPolygon( m_through_inner_holes_vias_poly,
|
||||
// via->GetStart(),
|
||||
@@ -476,7 +497,13 @@ void CINFO3D_VISU::createLayers( REPORTER *aStatusTextReporter )
|
||||
continue;
|
||||
|
||||
// Add the track contour
|
||||
track->TransformShapeWithClearanceToPolygon( *layerPoly, 0 );
|
||||
int nrSegments = GetNrSegmentsCircle( track->GetWidth() );
|
||||
|
||||
track->TransformShapeWithClearanceToPolygon(
|
||||
*layerPoly,
|
||||
0,
|
||||
nrSegments,
|
||||
GetCircleCorrectionFactor( nrSegments ) );
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -488,9 +515,11 @@ void CINFO3D_VISU::createLayers( REPORTER *aStatusTextReporter )
|
||||
|
||||
// Add holes of modules
|
||||
// /////////////////////////////////////////////////////////////////////////
|
||||
for( auto module : m_board->Modules() )
|
||||
for( const MODULE* module = m_board->m_Modules; module; module = module->Next() )
|
||||
{
|
||||
for( auto pad : module->Pads() )
|
||||
const D_PAD* pad = module->PadsList();
|
||||
|
||||
for( ; pad; pad = pad->Next() )
|
||||
{
|
||||
const wxSize padHole = pad->GetDrillSize();
|
||||
|
||||
@@ -520,9 +549,11 @@ void CINFO3D_VISU::createLayers( REPORTER *aStatusTextReporter )
|
||||
|
||||
// Add contours of the pad holes (pads can be Circle or Segment holes)
|
||||
// /////////////////////////////////////////////////////////////////////////
|
||||
for( auto module : m_board->Modules() )
|
||||
for( const MODULE* module = m_board->m_Modules; module; module = module->Next() )
|
||||
{
|
||||
for( auto pad : module->Pads() )
|
||||
const D_PAD* pad = module->PadsList();
|
||||
|
||||
for( ; pad; pad = pad->Next() )
|
||||
{
|
||||
const wxSize padHole = pad->GetDrillSize();
|
||||
|
||||
@@ -532,16 +563,28 @@ void CINFO3D_VISU::createLayers( REPORTER *aStatusTextReporter )
|
||||
// The hole in the body is inflated by copper thickness.
|
||||
const int inflate = GetCopperThicknessBIU();
|
||||
|
||||
// we use the hole diameter to calculate the seg count.
|
||||
// for round holes, padHole.x == padHole.y
|
||||
// for oblong holes, the diameter is the smaller of (padHole.x, padHole.y)
|
||||
const int diam = std::min( padHole.x, padHole.y );
|
||||
|
||||
|
||||
if( pad->GetAttribute () != PAD_ATTRIB_HOLE_NOT_PLATED )
|
||||
{
|
||||
pad->BuildPadDrillShapePolygon( m_through_outer_holes_poly, inflate );
|
||||
pad->BuildPadDrillShapePolygon( m_through_outer_holes_poly,
|
||||
inflate,
|
||||
GetNrSegmentsCircle( diam ) );
|
||||
|
||||
pad->BuildPadDrillShapePolygon( m_through_inner_holes_poly, 0 );
|
||||
pad->BuildPadDrillShapePolygon( m_through_inner_holes_poly,
|
||||
0,
|
||||
GetNrSegmentsCircle( diam ) );
|
||||
}
|
||||
else
|
||||
{
|
||||
// If not plated, no copper.
|
||||
pad->BuildPadDrillShapePolygon( m_through_outer_holes_poly_NPTH, inflate );
|
||||
pad->BuildPadDrillShapePolygon( m_through_outer_holes_poly_NPTH,
|
||||
inflate,
|
||||
GetNrSegmentsCircle( diam ) );
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -562,7 +605,7 @@ void CINFO3D_VISU::createLayers( REPORTER *aStatusTextReporter )
|
||||
CBVHCONTAINER2D *layerContainer = m_layers_container2D[curr_layer_id];
|
||||
|
||||
// ADD PADS
|
||||
for( auto module : m_board->Modules() )
|
||||
for( const MODULE* module = m_board->m_Modules; module; module = module->Next() )
|
||||
{
|
||||
// Note: NPTH pads are not drawn on copper layers when the pad
|
||||
// has same shape as its hole
|
||||
@@ -599,22 +642,25 @@ void CINFO3D_VISU::createLayers( REPORTER *aStatusTextReporter )
|
||||
SHAPE_POLY_SET *layerPoly = m_layers_poly[curr_layer_id];
|
||||
|
||||
// ADD PADS
|
||||
for( auto module : m_board->Modules() )
|
||||
for( const MODULE* module = m_board->m_Modules; module; module = module->Next() )
|
||||
{
|
||||
// Construct polys
|
||||
// /////////////////////////////////////////////////////////////
|
||||
|
||||
// Note: NPTH pads are not drawn on copper layers when the pad
|
||||
// has same shape as its hole
|
||||
transformPadsShapesWithClearanceToPolygon( module->Pads(),
|
||||
transformPadsShapesWithClearanceToPolygon( module->PadsList(),
|
||||
curr_layer_id,
|
||||
*layerPoly,
|
||||
0,
|
||||
true );
|
||||
|
||||
// Micro-wave modules may have items on copper layers
|
||||
module->TransformGraphicTextWithClearanceToPolygonSet(
|
||||
curr_layer_id, *layerPoly, 0 );
|
||||
module->TransformGraphicTextWithClearanceToPolygonSet( curr_layer_id,
|
||||
*layerPoly,
|
||||
0,
|
||||
segcountforcircle,
|
||||
correctionFactor );
|
||||
|
||||
transformGraphicModuleEdgeToPolygonSet( module, curr_layer_id, *layerPoly );
|
||||
}
|
||||
@@ -644,7 +690,7 @@ void CINFO3D_VISU::createLayers( REPORTER *aStatusTextReporter )
|
||||
|
||||
switch( item->Type() )
|
||||
{
|
||||
case PCB_LINE_T:
|
||||
case PCB_LINE_T: // should not exist on copper layers
|
||||
{
|
||||
AddShapeWithClearanceToContainer( (DRAWSEGMENT*)item,
|
||||
layerContainer,
|
||||
@@ -702,18 +748,32 @@ void CINFO3D_VISU::createLayers( REPORTER *aStatusTextReporter )
|
||||
|
||||
switch( item->Type() )
|
||||
{
|
||||
case PCB_LINE_T:
|
||||
( (DRAWSEGMENT*) item )->TransformShapeWithClearanceToPolygon( *layerPoly, 0 );
|
||||
break;
|
||||
case PCB_LINE_T: // should not exist on copper layers
|
||||
{
|
||||
const int nrSegments =
|
||||
GetNrSegmentsCircle( item->GetBoundingBox().GetSizeMax() );
|
||||
|
||||
( (DRAWSEGMENT*) item )->TransformShapeWithClearanceToPolygon(
|
||||
*layerPoly,
|
||||
0,
|
||||
nrSegments,
|
||||
GetCircleCorrectionFactor( nrSegments ) );
|
||||
}
|
||||
break;
|
||||
|
||||
case PCB_TEXT_T:
|
||||
( (TEXTE_PCB*) item )->TransformShapeWithClearanceToPolygonSet( *layerPoly, 0 );
|
||||
break;
|
||||
( (TEXTE_PCB*) item )->TransformShapeWithClearanceToPolygonSet(
|
||||
*layerPoly,
|
||||
0,
|
||||
segcountforcircle,
|
||||
correctionFactor );
|
||||
break;
|
||||
|
||||
default:
|
||||
wxLogTrace( m_logTrace, wxT( "createLayers: item type: %d not implemented" ),
|
||||
item->Type() );
|
||||
break;
|
||||
wxLogTrace( m_logTrace,
|
||||
wxT( "createLayers: item type: %d not implemented" ),
|
||||
item->Type() );
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -786,7 +846,7 @@ void CINFO3D_VISU::createLayers( REPORTER *aStatusTextReporter )
|
||||
auto layerContainer = m_layers_poly.find( zone->GetLayer() );
|
||||
|
||||
if( layerContainer != m_layers_poly.end() )
|
||||
zone->TransformSolidAreasShapesToPolygonSet( *layerContainer->second );
|
||||
zone->TransformSolidAreasShapesToPolygonSet( *layerContainer->second, segcountforcircle, correctionFactor );
|
||||
}
|
||||
}
|
||||
|
||||
@@ -913,7 +973,7 @@ void CINFO3D_VISU::createLayers( REPORTER *aStatusTextReporter )
|
||||
|
||||
// User layers are not drawn here, only technical layers
|
||||
|
||||
for( LSEQ seq = LSET::AllNonCuMask().Seq( teckLayerList, arrayDim( teckLayerList ) );
|
||||
for( LSEQ seq = LSET::AllNonCuMask().Seq( teckLayerList, DIM( teckLayerList ) );
|
||||
seq;
|
||||
++seq )
|
||||
{
|
||||
@@ -974,11 +1034,22 @@ void CINFO3D_VISU::createLayers( REPORTER *aStatusTextReporter )
|
||||
switch( item->Type() )
|
||||
{
|
||||
case PCB_LINE_T:
|
||||
( (DRAWSEGMENT*) item )->TransformShapeWithClearanceToPolygon( *layerPoly, 0 );
|
||||
{
|
||||
const unsigned int nr_segments =
|
||||
GetNrSegmentsCircle( item->GetBoundingBox().GetSizeMax() );
|
||||
|
||||
((DRAWSEGMENT*) item)->TransformShapeWithClearanceToPolygon( *layerPoly,
|
||||
0,
|
||||
nr_segments,
|
||||
0.0 );
|
||||
}
|
||||
break;
|
||||
|
||||
case PCB_TEXT_T:
|
||||
( (TEXTE_PCB*) item )->TransformShapeWithClearanceToPolygonSet( *layerPoly, 0 );
|
||||
((TEXTE_PCB*) item)->TransformShapeWithClearanceToPolygonSet( *layerPoly,
|
||||
0,
|
||||
segcountInStrokeFont,
|
||||
1.0 );
|
||||
break;
|
||||
|
||||
default:
|
||||
@@ -989,39 +1060,49 @@ void CINFO3D_VISU::createLayers( REPORTER *aStatusTextReporter )
|
||||
|
||||
// Add modules tech layers - objects
|
||||
// /////////////////////////////////////////////////////////////////////
|
||||
for( auto module : m_board->Modules() )
|
||||
for( MODULE* module = m_board->m_Modules; module; module = module->Next() )
|
||||
{
|
||||
if( (curr_layer_id == F_SilkS) || (curr_layer_id == B_SilkS) )
|
||||
{
|
||||
D_PAD* pad = module->PadsList();
|
||||
int linewidth = g_DrawDefaultLineThickness;
|
||||
|
||||
for( auto pad : module->Pads() )
|
||||
for( ; pad; pad = pad->Next() )
|
||||
{
|
||||
if( !pad->IsOnLayer( curr_layer_id ) )
|
||||
continue;
|
||||
|
||||
buildPadShapeThickOutlineAsSegments( pad, layerContainer, linewidth );
|
||||
buildPadShapeThickOutlineAsSegments( pad,
|
||||
layerContainer,
|
||||
linewidth );
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
AddPadsShapesWithClearanceToContainer(
|
||||
module, layerContainer, curr_layer_id, 0, false );
|
||||
AddPadsShapesWithClearanceToContainer( module,
|
||||
layerContainer,
|
||||
curr_layer_id,
|
||||
0,
|
||||
false );
|
||||
}
|
||||
|
||||
AddGraphicsShapesWithClearanceToContainer( module, layerContainer, curr_layer_id, 0 );
|
||||
AddGraphicsShapesWithClearanceToContainer( module,
|
||||
layerContainer,
|
||||
curr_layer_id,
|
||||
0 );
|
||||
}
|
||||
|
||||
|
||||
// Add modules tech layers - contours
|
||||
// /////////////////////////////////////////////////////////////////////
|
||||
for( auto module : m_board->Modules() )
|
||||
for( MODULE* module = m_board->m_Modules; module; module = module->Next() )
|
||||
{
|
||||
if( (curr_layer_id == F_SilkS) || (curr_layer_id == B_SilkS) )
|
||||
{
|
||||
D_PAD* pad = module->PadsList();
|
||||
const int linewidth = g_DrawDefaultLineThickness;
|
||||
|
||||
for( auto pad : module->Pads() )
|
||||
for( ; pad; pad = pad->Next() )
|
||||
{
|
||||
if( !pad->IsOnLayer( curr_layer_id ) )
|
||||
continue;
|
||||
@@ -1031,12 +1112,20 @@ void CINFO3D_VISU::createLayers( REPORTER *aStatusTextReporter )
|
||||
}
|
||||
else
|
||||
{
|
||||
transformPadsShapesWithClearanceToPolygon(
|
||||
module->Pads(), curr_layer_id, *layerPoly, 0, false );
|
||||
transformPadsShapesWithClearanceToPolygon( module->PadsList(),
|
||||
curr_layer_id,
|
||||
*layerPoly,
|
||||
0,
|
||||
false );
|
||||
}
|
||||
|
||||
// On tech layers, use a poor circle approximation, only for texts (stroke font)
|
||||
module->TransformGraphicTextWithClearanceToPolygonSet( curr_layer_id, *layerPoly, 0 );
|
||||
module->TransformGraphicTextWithClearanceToPolygonSet( curr_layer_id,
|
||||
*layerPoly,
|
||||
0,
|
||||
segcountInStrokeFont,
|
||||
correctionFactorStroke,
|
||||
segcountInStrokeFont );
|
||||
|
||||
// Add the remaining things with dynamic seg count for circles
|
||||
transformGraphicModuleEdgeToPolygonSet( module, curr_layer_id, *layerPoly );
|
||||
@@ -1066,7 +1155,10 @@ void CINFO3D_VISU::createLayers( REPORTER *aStatusTextReporter )
|
||||
if( !zone->IsOnLayer( curr_layer_id ) )
|
||||
continue;
|
||||
|
||||
zone->TransformSolidAreasShapesToPolygonSet( *layerPoly );
|
||||
zone->TransformSolidAreasShapesToPolygonSet( *layerPoly,
|
||||
// Use the same segcount as stroke font
|
||||
segcountInStrokeFont,
|
||||
correctionFactorStroke );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -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-2019 KiCad Developers, see AUTHORS.txt for contributors.
|
||||
* Copyright (C) 1992-2016 KiCad Developers, see AUTHORS.txt for contributors.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
@@ -40,7 +40,9 @@
|
||||
// but it adds the rect/trapezoid shapes with a different winding
|
||||
void CINFO3D_VISU::buildPadShapePolygon( const D_PAD* aPad,
|
||||
SHAPE_POLY_SET& aCornerBuffer,
|
||||
wxSize aInflateValue ) const
|
||||
wxSize aInflateValue,
|
||||
int aSegmentsPerCircle,
|
||||
double aCorrectionFactor ) const
|
||||
{
|
||||
wxPoint corners[4];
|
||||
wxPoint PadShapePos = aPad->ShapePos(); /* Note: for pad having a shape offset,
|
||||
@@ -50,7 +52,6 @@ void CINFO3D_VISU::buildPadShapePolygon( const D_PAD* aPad,
|
||||
case PAD_SHAPE_CIRCLE:
|
||||
case PAD_SHAPE_OVAL:
|
||||
case PAD_SHAPE_ROUNDRECT:
|
||||
case PAD_SHAPE_CHAMFERED_RECT:
|
||||
{
|
||||
// We are using TransformShapeWithClearanceToPolygon to build the shape.
|
||||
// Currently, this method uses only the same inflate value for X and Y dirs.
|
||||
@@ -61,7 +62,8 @@ void CINFO3D_VISU::buildPadShapePolygon( const D_PAD* aPad,
|
||||
D_PAD dummy( *aPad );
|
||||
wxSize new_size = aPad->GetSize() + aInflateValue + aInflateValue;
|
||||
dummy.SetSize( new_size );
|
||||
dummy.TransformShapeWithClearanceToPolygon( aCornerBuffer, 0 );
|
||||
dummy.TransformShapeWithClearanceToPolygon( aCornerBuffer, 0,
|
||||
aSegmentsPerCircle, aCorrectionFactor );
|
||||
}
|
||||
break;
|
||||
|
||||
@@ -87,17 +89,8 @@ void CINFO3D_VISU::buildPadShapePolygon( const D_PAD* aPad,
|
||||
case PAD_SHAPE_CUSTOM:
|
||||
{
|
||||
SHAPE_POLY_SET polyList; // Will contain the pad outlines in board coordinates
|
||||
auto inflate_val = std::max( aInflateValue.x, aInflateValue.y );
|
||||
|
||||
polyList.Append( aPad->GetCustomShapeAsPolygon() );
|
||||
aPad->CustomShapeAsPolygonToBoardPosition( &polyList, aPad->ShapePos(), aPad->GetOrientation() );
|
||||
|
||||
if( inflate_val > 0 )
|
||||
{
|
||||
int numSegs = GetNrSegmentsCircle( inflate_val );
|
||||
polyList.Inflate( inflate_val, numSegs );
|
||||
}
|
||||
|
||||
aCornerBuffer.Append( polyList );
|
||||
}
|
||||
break;
|
||||
@@ -111,8 +104,11 @@ void CINFO3D_VISU::buildPadShapeThickOutlineAsPolygon( const D_PAD* aPad,
|
||||
{
|
||||
if( aPad->GetShape() == PAD_SHAPE_CIRCLE ) // Draw a ring
|
||||
{
|
||||
unsigned int nr_sides_per_circle = GetNrSegmentsCircle( ( aPad->GetSize().x / 2 +
|
||||
aWidth / 2 ) * 2 );
|
||||
|
||||
TransformRingToPolygon( aCornerBuffer, aPad->ShapePos(),
|
||||
aPad->GetSize().x / 2, ARC_HIGH_DEF, aWidth );
|
||||
aPad->GetSize().x / 2, nr_sides_per_circle, aWidth );
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -120,7 +116,11 @@ void CINFO3D_VISU::buildPadShapeThickOutlineAsPolygon( const D_PAD* aPad,
|
||||
// For other shapes, draw polygon outlines
|
||||
SHAPE_POLY_SET corners;
|
||||
|
||||
buildPadShapePolygon( aPad, corners, wxSize( 0, 0 ) );
|
||||
unsigned int nr_sides_per_circle = GetNrSegmentsCircle( glm::min( aPad->GetSize().x,
|
||||
aPad->GetSize().y) );
|
||||
buildPadShapePolygon( aPad, corners, wxSize( 0, 0 ),
|
||||
nr_sides_per_circle,
|
||||
GetCircleCorrectionFactor( nr_sides_per_circle ) );
|
||||
|
||||
// Add outlines as thick segments in polygon buffer
|
||||
|
||||
@@ -131,21 +131,26 @@ void CINFO3D_VISU::buildPadShapeThickOutlineAsPolygon( const D_PAD* aPad,
|
||||
const VECTOR2I& a = path.CPoint( ii );
|
||||
const VECTOR2I& b = path.CPoint( ii + 1 );
|
||||
|
||||
TransformRoundedEndsSegmentToPolygon( aCornerBuffer, wxPoint( a.x, a.y ),
|
||||
wxPoint( b.x, b.y ), ARC_HIGH_DEF, aWidth );
|
||||
TransformRoundedEndsSegmentToPolygon( aCornerBuffer,
|
||||
wxPoint( a.x, a.y ),
|
||||
wxPoint( b.x, b.y ),
|
||||
nr_sides_per_circle,
|
||||
aWidth );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// Based on the same function name in board_items_to_polyshape_transform.cpp
|
||||
// It was implemented here to allow dynamic segments count per pad shape
|
||||
void CINFO3D_VISU::transformPadsShapesWithClearanceToPolygon( const PADS& aPads, PCB_LAYER_ID aLayer,
|
||||
void CINFO3D_VISU::transformPadsShapesWithClearanceToPolygon( const DLIST<D_PAD>& aPads, PCB_LAYER_ID aLayer,
|
||||
SHAPE_POLY_SET& aCornerBuffer,
|
||||
int aInflateValue,
|
||||
bool aSkipNPTHPadsWihNoCopper ) const
|
||||
{
|
||||
const D_PAD* pad = aPads;
|
||||
|
||||
wxSize margin;
|
||||
for( auto pad : aPads )
|
||||
for( ; pad != NULL; pad = pad->Next() )
|
||||
{
|
||||
if( !pad->IsOnLayer(aLayer) )
|
||||
continue;
|
||||
@@ -194,7 +199,11 @@ void CINFO3D_VISU::transformPadsShapesWithClearanceToPolygon( const PADS& aPads,
|
||||
break;
|
||||
}
|
||||
|
||||
buildPadShapePolygon( pad, aCornerBuffer, margin );
|
||||
unsigned int aCircleToSegmentsCount = GetNrSegmentsCircle( pad->GetSize().x );
|
||||
double aCorrectionFactor = GetCircleCorrectionFactor( aCircleToSegmentsCount );
|
||||
|
||||
buildPadShapePolygon( pad, aCornerBuffer, margin,
|
||||
aCircleToSegmentsCount, aCorrectionFactor );
|
||||
}
|
||||
}
|
||||
|
||||
@@ -202,7 +211,9 @@ void CINFO3D_VISU::transformGraphicModuleEdgeToPolygonSet( const MODULE *aModule
|
||||
PCB_LAYER_ID aLayer,
|
||||
SHAPE_POLY_SET& aCornerBuffer ) const
|
||||
{
|
||||
for( auto item : aModule->GraphicalItems() )
|
||||
for( const EDA_ITEM* item = aModule->GraphicalItemsList();
|
||||
item != NULL;
|
||||
item = item->Next() )
|
||||
{
|
||||
switch( item->Type() )
|
||||
{
|
||||
@@ -213,7 +224,15 @@ void CINFO3D_VISU::transformGraphicModuleEdgeToPolygonSet( const MODULE *aModule
|
||||
if( outline->GetLayer() != aLayer )
|
||||
break;
|
||||
|
||||
outline->TransformShapeWithClearanceToPolygon( aCornerBuffer, 0 );
|
||||
unsigned int aCircleToSegmentsCount =
|
||||
GetNrSegmentsCircle( outline->GetBoundingBox().GetSizeMax() );
|
||||
|
||||
double aCorrectionFactor = GetCircleCorrectionFactor( aCircleToSegmentsCount );
|
||||
|
||||
outline->TransformShapeWithClearanceToPolygon( aCornerBuffer,
|
||||
0,
|
||||
aCircleToSegmentsCount,
|
||||
aCorrectionFactor );
|
||||
}
|
||||
break;
|
||||
|
||||
|
||||
@@ -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-2019 KiCad Developers, see AUTHORS.txt for contributors.
|
||||
* Copyright (C) 1992-2017 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,7 +28,6 @@
|
||||
*/
|
||||
|
||||
#include <GL/glew.h> // Must be included first
|
||||
#include <wx/tokenzr.h>
|
||||
|
||||
#include "../common_ogl/openGL_includes.h"
|
||||
#include "../common_ogl/ogl_utils.h"
|
||||
@@ -45,15 +44,14 @@
|
||||
#include <hotkeys_basic.h>
|
||||
#include <menus_helpers.h>
|
||||
|
||||
#include <widgets/wx_busy_indicator.h>
|
||||
extern struct EDA_HOTKEY_CONFIG g_3DViewer_Hokeys_Descr[];
|
||||
|
||||
|
||||
/**
|
||||
* Flag to enable 3D canvas debug tracing.
|
||||
*
|
||||
* Use "KI_TRACE_EDA_3D_CANVAS" to enable.
|
||||
*
|
||||
* @ingroup trace_env_vars
|
||||
* 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_3D_CANVAS". See the wxWidgets documentation on wxLogTrace for
|
||||
* more information.
|
||||
*/
|
||||
const wxChar * EDA_3D_CANVAS::m_logTrace = wxT( "KI_TRACE_EDA_3D_CANVAS" );
|
||||
|
||||
@@ -66,16 +64,16 @@ BEGIN_EVENT_TABLE( EDA_3D_CANVAS, wxGLCanvas )
|
||||
EVT_CHAR_HOOK( EDA_3D_CANVAS::OnCharHook )
|
||||
|
||||
// mouse events
|
||||
EVT_LEFT_DOWN( EDA_3D_CANVAS::OnLeftDown )
|
||||
EVT_LEFT_UP( EDA_3D_CANVAS::OnLeftUp )
|
||||
EVT_MIDDLE_UP( EDA_3D_CANVAS::OnMiddleUp )
|
||||
EVT_LEFT_DOWN( EDA_3D_CANVAS::OnLeftDown )
|
||||
EVT_LEFT_UP( EDA_3D_CANVAS::OnLeftUp )
|
||||
EVT_MIDDLE_UP( EDA_3D_CANVAS::OnMiddleUp )
|
||||
EVT_MIDDLE_DOWN( EDA_3D_CANVAS::OnMiddleDown)
|
||||
EVT_RIGHT_DOWN( EDA_3D_CANVAS::OnRightClick )
|
||||
EVT_MOUSEWHEEL( EDA_3D_CANVAS::OnMouseWheel )
|
||||
EVT_MOTION( EDA_3D_CANVAS::OnMouseMove )
|
||||
EVT_RIGHT_DOWN( EDA_3D_CANVAS::OnRightClick )
|
||||
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 )
|
||||
EVT_MAGNIFY( EDA_3D_CANVAS::OnMagnify )
|
||||
#endif
|
||||
|
||||
// other events
|
||||
@@ -92,6 +90,7 @@ EDA_3D_CANVAS::EDA_3D_CANVAS( wxWindow *aParent,
|
||||
const int *aAttribList,
|
||||
BOARD *aBoard,
|
||||
CINFO3D_VISU &aSettings , S3D_CACHE *a3DCachePointer ) :
|
||||
|
||||
HIDPI_GL_CANVAS( aParent,
|
||||
wxID_ANY,
|
||||
aAttribList,
|
||||
@@ -102,8 +101,9 @@ EDA_3D_CANVAS::EDA_3D_CANVAS( wxWindow *aParent,
|
||||
m_settings( aSettings )
|
||||
{
|
||||
// Run test cases in debug mode, once.
|
||||
//DBG( Run_3d_viewer_test_cases() );
|
||||
|
||||
wxLogTrace( m_logTrace, "EDA_3D_CANVAS::EDA_3D_CANVAS" );
|
||||
wxLogTrace( m_logTrace, wxT( "EDA_3D_CANVAS::EDA_3D_CANVAS" ) );
|
||||
|
||||
m_editing_timeout_timer.SetOwner( this );
|
||||
Connect( m_editing_timeout_timer.GetId(),
|
||||
@@ -130,7 +130,6 @@ EDA_3D_CANVAS::EDA_3D_CANVAS( wxWindow *aParent,
|
||||
m_is_opengl_initialized = false;
|
||||
|
||||
m_render_raytracing_was_requested = false;
|
||||
m_opengl_supports_raytracing = false;
|
||||
|
||||
m_parentStatusBar = NULL;
|
||||
m_glRC = NULL;
|
||||
@@ -143,11 +142,6 @@ EDA_3D_CANVAS::EDA_3D_CANVAS( wxWindow *aParent,
|
||||
wxASSERT( m_3d_render_raytracing != NULL );
|
||||
wxASSERT( m_3d_render_ogl_legacy != NULL );
|
||||
|
||||
auto busy_indicator_factory = []() { return std::make_unique<WX_BUSY_INDICATOR>(); };
|
||||
|
||||
m_3d_render_raytracing->SetBusyIndicatorFactory( busy_indicator_factory );
|
||||
m_3d_render_ogl_legacy->SetBusyIndicatorFactory( busy_indicator_factory );
|
||||
|
||||
RenderEngineChanged();
|
||||
|
||||
wxASSERT( aBoard != NULL );
|
||||
@@ -160,7 +154,7 @@ EDA_3D_CANVAS::EDA_3D_CANVAS( wxWindow *aParent,
|
||||
|
||||
EDA_3D_CANVAS::~EDA_3D_CANVAS()
|
||||
{
|
||||
wxLogTrace( m_logTrace, "EDA_3D_CANVAS::~EDA_3D_CANVAS" );
|
||||
wxLogTrace( m_logTrace, wxT( "EDA_3D_CANVAS::~EDA_3D_CANVAS" ) );
|
||||
|
||||
releaseOpenGL();
|
||||
}
|
||||
@@ -178,7 +172,7 @@ void EDA_3D_CANVAS::releaseOpenGL()
|
||||
delete m_3d_render_ogl_legacy;
|
||||
m_3d_render_ogl_legacy = NULL;
|
||||
|
||||
// This is just a copy of a pointer, can safely be set to NULL
|
||||
// This is just a copy of a pointer, can safelly be set to NULL
|
||||
m_3d_render = NULL;
|
||||
|
||||
GL_CONTEXT_MANAGER::Get().UnlockCtx( m_glRC );
|
||||
@@ -195,16 +189,14 @@ void EDA_3D_CANVAS::OnCloseWindow( wxCloseEvent &event )
|
||||
event.Skip();
|
||||
}
|
||||
|
||||
|
||||
void EDA_3D_CANVAS::OnResize( wxSizeEvent &event )
|
||||
{
|
||||
this->Request_refresh();
|
||||
}
|
||||
|
||||
|
||||
bool EDA_3D_CANVAS::initializeOpenGL()
|
||||
{
|
||||
wxLogTrace( m_logTrace, "EDA_3D_CANVAS::initializeOpenGL" );
|
||||
wxLogTrace( m_logTrace, wxT( "EDA_3D_CANVAS::initializeOpenGL" ) );
|
||||
|
||||
const GLenum err = glewInit();
|
||||
|
||||
@@ -218,53 +210,11 @@ bool EDA_3D_CANVAS::initializeOpenGL()
|
||||
}
|
||||
else
|
||||
{
|
||||
wxLogTrace( m_logTrace, "EDA_3D_CANVAS::initializeOpenGL Using GLEW version %s",
|
||||
wxLogTrace( m_logTrace,
|
||||
wxString( wxT( "EDA_3D_CANVAS::initializeOpenGL Using GLEW " ) ) +
|
||||
FROM_UTF8( (char*) glewGetString( GLEW_VERSION ) ) );
|
||||
}
|
||||
|
||||
wxString version = FROM_UTF8( (char *) glGetString( GL_VERSION ) );
|
||||
|
||||
wxLogTrace( m_logTrace, "EDA_3D_CANVAS::%s OpenGL version string %s.",
|
||||
__WXFUNCTION__, version );
|
||||
|
||||
// Extract OpenGL version from string. This method is used because prior to OpenGL 2,
|
||||
// getting the OpenGL major and minor version as integers didn't exist.
|
||||
wxString tmp;
|
||||
|
||||
wxStringTokenizer tokenizer( version );
|
||||
|
||||
m_opengl_supports_raytracing = true;
|
||||
|
||||
if( tokenizer.HasMoreTokens() )
|
||||
{
|
||||
long major = 0;
|
||||
long minor = 0;
|
||||
|
||||
tmp = tokenizer.GetNextToken();
|
||||
|
||||
tokenizer.SetString( tmp, wxString( "." ) );
|
||||
|
||||
if( tokenizer.HasMoreTokens() )
|
||||
tokenizer.GetNextToken().ToLong( &major );
|
||||
|
||||
if( tokenizer.HasMoreTokens() )
|
||||
tokenizer.GetNextToken().ToLong( &minor );
|
||||
|
||||
if( major < 2 || ( (major == 2 ) && (minor < 1) ) )
|
||||
{
|
||||
wxLogTrace( m_logTrace, "EDA_3D_CANVAS::%s OpenGL ray tracing not supported.",
|
||||
__WXFUNCTION__ );
|
||||
|
||||
if( GetParent() )
|
||||
{
|
||||
wxCommandEvent evt( wxEVT_MENU, ID_DISABLE_RAY_TRACING );
|
||||
GetParent()->ProcessWindowEvent( evt );
|
||||
}
|
||||
|
||||
m_opengl_supports_raytracing = false;
|
||||
}
|
||||
}
|
||||
|
||||
m_is_opengl_initialized = true;
|
||||
|
||||
return true;
|
||||
@@ -310,11 +260,14 @@ void EDA_3D_CANVAS::DisplayStatus()
|
||||
{
|
||||
wxString msg;
|
||||
|
||||
msg.Printf( "dx %3.2f", m_settings.CameraGet().GetCameraPos().x );
|
||||
msg.Printf( wxT( "dx %3.2f" ), m_settings.CameraGet().GetCameraPos().x );
|
||||
m_parentStatusBar->SetStatusText( msg, 1 );
|
||||
|
||||
msg.Printf( "dy %3.2f", m_settings.CameraGet().GetCameraPos().y );
|
||||
msg.Printf( wxT( "dy %3.2f" ), m_settings.CameraGet().GetCameraPos().y );
|
||||
m_parentStatusBar->SetStatusText( msg, 2 );
|
||||
|
||||
//msg.Printf( _( "Zoom: %3.1f" ), 50 * m_settings.CameraGet().ZoomGet() );
|
||||
//m_parentStatusBar->SetStatusText( msg, 3 );
|
||||
}
|
||||
}
|
||||
|
||||
@@ -329,7 +282,7 @@ void EDA_3D_CANVAS::OnPaint( wxPaintEvent &event )
|
||||
// SwapBuffer requires the window to be shown before calling
|
||||
if( !IsShownOnScreen() )
|
||||
{
|
||||
wxLogTrace( m_logTrace, "EDA_3D_CANVAS::OnPaint !IsShown" );
|
||||
wxLogTrace( m_logTrace, wxT( "EDA_3D_CANVAS::OnPaint !IsShown" ) );
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -337,7 +290,7 @@ void EDA_3D_CANVAS::OnPaint( wxPaintEvent &event )
|
||||
// ensure this parent is still alive. When it is closed before the viewer
|
||||
// frame, a paint event can be generated after the parent is closed,
|
||||
// therefore with invalid board.
|
||||
// This is dependent of the platform.
|
||||
// This is dependant of the platform.
|
||||
// Especially on OSX, but also on Windows, it frequently happens
|
||||
if( !GetParent()->GetParent()->IsShown() )
|
||||
return; // The parent board editor frame is no more alive
|
||||
@@ -348,6 +301,7 @@ void EDA_3D_CANVAS::OnPaint( wxPaintEvent &event )
|
||||
//WX_STRING_REPORTER errorReporter( &err_messages );
|
||||
STATUS_TEXT_REPORTER activityReporter( m_parentStatusBar, 0 );
|
||||
|
||||
|
||||
unsigned strtime = GetRunningMicroSecs();
|
||||
|
||||
// "Makes the OpenGL state that is represented by the OpenGL rendering
|
||||
@@ -366,10 +320,11 @@ void EDA_3D_CANVAS::OnPaint( wxPaintEvent &event )
|
||||
// multiple canvases: If we updated the viewport in the wxSizeEvent
|
||||
// handler, changing the size of one canvas causes a viewport setting that
|
||||
// is wrong when next another canvas is repainted.
|
||||
wxSize clientSize = GetNativePixelSize();
|
||||
wxSize clientSize = GetClientSize();
|
||||
|
||||
const bool windows_size_changed = m_settings.CameraGet().SetCurWindowSize( clientSize );
|
||||
|
||||
|
||||
// Initialize openGL if need
|
||||
// /////////////////////////////////////////////////////////////////////////
|
||||
if( !m_is_opengl_initialized )
|
||||
@@ -382,15 +337,8 @@ void EDA_3D_CANVAS::OnPaint( wxPaintEvent &event )
|
||||
}
|
||||
}
|
||||
|
||||
// Don't attend to ray trace if OpenGL doesn't support it.
|
||||
if( !m_opengl_supports_raytracing )
|
||||
{
|
||||
m_3d_render = m_3d_render_ogl_legacy;
|
||||
m_render_raytracing_was_requested = false;
|
||||
m_settings.RenderEngineSet( RENDER_ENGINE_OPENGL_LEGACY );
|
||||
}
|
||||
|
||||
// Check if a raytacing was requested and need to switch to raytracing mode
|
||||
// Check if a raytacing was requented and need to switch to raytracing mode
|
||||
if( m_settings.RenderEngineGet() == RENDER_ENGINE_OPENGL_LEGACY )
|
||||
{
|
||||
const bool was_camera_changed = m_settings.CameraGet().ParametersChanged();
|
||||
@@ -408,6 +356,7 @@ void EDA_3D_CANVAS::OnPaint( wxPaintEvent &event )
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
float curtime_delta_s = 0.0f;
|
||||
|
||||
if( m_camera_is_moving )
|
||||
@@ -431,6 +380,7 @@ void EDA_3D_CANVAS::OnPaint( wxPaintEvent &event )
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// It will return true if the render request a new redraw
|
||||
bool requested_redraw = false;
|
||||
|
||||
@@ -459,7 +409,7 @@ void EDA_3D_CANVAS::OnPaint( wxPaintEvent &event )
|
||||
{
|
||||
if( m_mouse_was_moved || m_camera_is_moving )
|
||||
{
|
||||
// Calculation time in milliseconds
|
||||
// Calculation time in miliseconds
|
||||
const double calculation_time = (double)( GetRunningMicroSecs() - strtime) / 1e3;
|
||||
|
||||
activityReporter.Report( wxString::Format( _( "Render time %.0f ms ( %.1f fps)" ),
|
||||
@@ -483,7 +433,7 @@ void EDA_3D_CANVAS::OnPaint( wxPaintEvent &event )
|
||||
|
||||
void EDA_3D_CANVAS::OnEraseBackground( wxEraseEvent &event )
|
||||
{
|
||||
wxLogTrace( m_logTrace, "EDA_3D_CANVAS::OnEraseBackground" );
|
||||
wxLogTrace( m_logTrace, wxT( "EDA_3D_CANVAS::OnEraseBackground" ) );
|
||||
// Do nothing, to avoid flashing.
|
||||
}
|
||||
|
||||
@@ -492,7 +442,7 @@ void EDA_3D_CANVAS::OnMouseWheel( wxMouseEvent &event )
|
||||
{
|
||||
bool mouseActivity = false;
|
||||
|
||||
wxLogTrace( m_logTrace, "EDA_3D_CANVAS::OnMouseWheel" );
|
||||
wxLogTrace( m_logTrace, wxT( "EDA_3D_CANVAS::OnMouseWheel" ) );
|
||||
|
||||
if( m_camera_is_moving )
|
||||
return;
|
||||
@@ -558,8 +508,6 @@ void EDA_3D_CANVAS::OnMouseWheel( wxMouseEvent &event )
|
||||
#if wxCHECK_VERSION( 3, 1, 0 ) || defined( USE_OSX_MAGNIFY_EVENT )
|
||||
void EDA_3D_CANVAS::OnMagnify( wxMouseEvent& event )
|
||||
{
|
||||
SetFocus();
|
||||
|
||||
if( m_camera_is_moving )
|
||||
return;
|
||||
|
||||
@@ -583,7 +531,7 @@ void EDA_3D_CANVAS::OnMouseMove( wxMouseEvent &event )
|
||||
if( m_camera_is_moving )
|
||||
return;
|
||||
|
||||
m_settings.CameraGet().SetCurWindowSize( GetNativePixelSize() );
|
||||
m_settings.CameraGet().SetCurWindowSize( GetClientSize() );
|
||||
|
||||
if( event.Dragging() )
|
||||
{
|
||||
@@ -607,7 +555,6 @@ void EDA_3D_CANVAS::OnMouseMove( wxMouseEvent &event )
|
||||
|
||||
void EDA_3D_CANVAS::OnLeftDown( wxMouseEvent &event )
|
||||
{
|
||||
SetFocus();
|
||||
stop_editingTimeOut_Timer();
|
||||
}
|
||||
|
||||
@@ -627,7 +574,6 @@ void EDA_3D_CANVAS::OnLeftUp( wxMouseEvent &event )
|
||||
|
||||
void EDA_3D_CANVAS::OnMiddleDown( wxMouseEvent &event )
|
||||
{
|
||||
SetFocus();
|
||||
stop_editingTimeOut_Timer();
|
||||
}
|
||||
|
||||
@@ -651,51 +597,86 @@ void EDA_3D_CANVAS::OnMiddleUp( wxMouseEvent &event )
|
||||
|
||||
void EDA_3D_CANVAS::OnRightClick( wxMouseEvent &event )
|
||||
{
|
||||
wxLogTrace( m_logTrace, "EDA_3D_CANVAS::OnRightClick" );
|
||||
|
||||
SetFocus();
|
||||
wxLogTrace( m_logTrace, wxT( "EDA_3D_CANVAS::OnRightClick" ) );
|
||||
|
||||
if( m_camera_is_moving )
|
||||
return;
|
||||
|
||||
wxPoint pos;
|
||||
wxMenu PopUpMenu;
|
||||
wxString msg;
|
||||
|
||||
pos.x = event.GetX();
|
||||
pos.y = event.GetY();
|
||||
|
||||
msg = AddHotkeyName( _( "Zoom +" ), g_3DViewer_Hokeys_Descr,
|
||||
ID_POPUP_ZOOMIN );
|
||||
AddMenuItem( &PopUpMenu, ID_POPUP_ZOOMIN,
|
||||
_( "Zoom +\tF1" ), KiBitmap( zoom_in_xpm ) );
|
||||
msg, KiBitmap( zoom_in_xpm ) );
|
||||
|
||||
|
||||
msg = AddHotkeyName( _( "Zoom -" ), g_3DViewer_Hokeys_Descr,
|
||||
ID_POPUP_ZOOMOUT );
|
||||
AddMenuItem( &PopUpMenu, ID_POPUP_ZOOMOUT,
|
||||
_( "Zoom -\tF2" ), KiBitmap( zoom_out_xpm ) );
|
||||
msg, KiBitmap( zoom_out_xpm ) );
|
||||
|
||||
PopUpMenu.AppendSeparator();
|
||||
|
||||
msg = AddHotkeyName( _( "Top View" ), g_3DViewer_Hokeys_Descr,
|
||||
ID_POPUP_VIEW_ZPOS );
|
||||
AddMenuItem( &PopUpMenu, ID_POPUP_VIEW_ZPOS,
|
||||
_( "Top View\tZ" ), KiBitmap( axis3d_top_xpm ) );
|
||||
msg, KiBitmap( axis3d_top_xpm ) );
|
||||
|
||||
msg = AddHotkeyName( _( "Bottom View" ), g_3DViewer_Hokeys_Descr,
|
||||
ID_POPUP_VIEW_ZNEG );
|
||||
AddMenuItem( &PopUpMenu, ID_POPUP_VIEW_ZNEG,
|
||||
_( "Bottom View\tShift+Z" ), KiBitmap( axis3d_bottom_xpm ) );
|
||||
msg, KiBitmap( axis3d_bottom_xpm ) );
|
||||
|
||||
PopUpMenu.AppendSeparator();
|
||||
|
||||
msg = AddHotkeyName( _( "Right View" ), g_3DViewer_Hokeys_Descr,
|
||||
ID_POPUP_VIEW_XPOS );
|
||||
AddMenuItem( &PopUpMenu, ID_POPUP_VIEW_XPOS,
|
||||
_( "Right View\tX" ), KiBitmap( axis3d_right_xpm ) );
|
||||
msg, KiBitmap( axis3d_right_xpm ) );
|
||||
|
||||
msg = AddHotkeyName( _( "Left View" ), g_3DViewer_Hokeys_Descr,
|
||||
ID_POPUP_VIEW_XNEG );
|
||||
AddMenuItem( &PopUpMenu, ID_POPUP_VIEW_XNEG,
|
||||
_( "Left View\tShift+X" ), KiBitmap( axis3d_left_xpm ) );
|
||||
msg, KiBitmap( axis3d_left_xpm ) );
|
||||
|
||||
PopUpMenu.AppendSeparator();
|
||||
|
||||
msg = AddHotkeyName( _( "Front View" ), g_3DViewer_Hokeys_Descr,
|
||||
ID_POPUP_VIEW_YPOS );
|
||||
AddMenuItem( &PopUpMenu, ID_POPUP_VIEW_YPOS,
|
||||
_( "Front View\tY" ), KiBitmap( axis3d_front_xpm ) );
|
||||
msg, KiBitmap( axis3d_front_xpm ) );
|
||||
|
||||
msg = AddHotkeyName( _( "Back View" ), g_3DViewer_Hokeys_Descr,
|
||||
ID_POPUP_VIEW_YNEG );
|
||||
AddMenuItem( &PopUpMenu, ID_POPUP_VIEW_YNEG,
|
||||
_( "Back View\tShift+Y" ), KiBitmap( axis3d_back_xpm ) );
|
||||
msg, KiBitmap( axis3d_back_xpm ) );
|
||||
|
||||
PopUpMenu.AppendSeparator();
|
||||
|
||||
msg = AddHotkeyName( _( "Move Left <-" ), g_3DViewer_Hokeys_Descr,
|
||||
ID_POPUP_MOVE3D_LEFT );
|
||||
AddMenuItem( &PopUpMenu, ID_POPUP_MOVE3D_LEFT,
|
||||
_( "Move Left <-\tLeft" ), KiBitmap( left_xpm ) );
|
||||
msg, KiBitmap( left_xpm ) );
|
||||
|
||||
msg = AddHotkeyName( _( "Move Right ->" ), g_3DViewer_Hokeys_Descr,
|
||||
ID_POPUP_MOVE3D_RIGHT );
|
||||
AddMenuItem( &PopUpMenu, ID_POPUP_MOVE3D_RIGHT,
|
||||
_( "Move Right ->\tRight" ), KiBitmap( right_xpm ) );
|
||||
msg, KiBitmap( right_xpm ) );
|
||||
|
||||
msg = AddHotkeyName( _( "Move Up ^" ), g_3DViewer_Hokeys_Descr,
|
||||
ID_POPUP_MOVE3D_UP );
|
||||
AddMenuItem( &PopUpMenu, ID_POPUP_MOVE3D_UP,
|
||||
_( "Move Up ^\tUp" ), KiBitmap( up_xpm ) );
|
||||
msg, KiBitmap( up_xpm ) );
|
||||
|
||||
msg = AddHotkeyName( _( "Move Down" ), g_3DViewer_Hokeys_Descr,
|
||||
ID_POPUP_MOVE3D_DOWN );
|
||||
AddMenuItem( &PopUpMenu, ID_POPUP_MOVE3D_DOWN,
|
||||
_( "Move Down\tDown" ), KiBitmap( down_xpm ) );
|
||||
msg, KiBitmap( down_xpm ) );
|
||||
|
||||
PopupMenu( &PopUpMenu, pos );
|
||||
}
|
||||
@@ -705,7 +686,7 @@ void EDA_3D_CANVAS::OnPopUpMenu( wxCommandEvent &event )
|
||||
{
|
||||
int id = event.GetId();
|
||||
|
||||
wxLogTrace( m_logTrace, "EDA_3D_CANVAS::OnPopUpMenu id:%d", id );
|
||||
wxLogTrace( m_logTrace, wxT( "EDA_3D_CANVAS::OnPopUpMenu id:%d" ), id );
|
||||
|
||||
int key = 0;
|
||||
|
||||
@@ -769,14 +750,14 @@ void EDA_3D_CANVAS::OnPopUpMenu( wxCommandEvent &event )
|
||||
|
||||
void EDA_3D_CANVAS::OnCharHook( wxKeyEvent &event )
|
||||
{
|
||||
//wxLogTrace( m_logTrace, "EDA_3D_CANVAS::OnCharHook" );
|
||||
//wxLogTrace( m_logTrace, wxT( "EDA_3D_CANVAS::OnCharHook" ) );
|
||||
event.Skip();
|
||||
}
|
||||
|
||||
|
||||
void EDA_3D_CANVAS::OnKeyEvent( wxKeyEvent& event )
|
||||
{
|
||||
//wxLogTrace( m_logTrace, "EDA_3D_CANVAS::OnKeyEvent" );
|
||||
//wxLogTrace( m_logTrace, wxT( "EDA_3D_CANVAS::OnKeyEvent" ) );
|
||||
int localkey = event.GetKeyCode();
|
||||
|
||||
// Use only upper char values in comparisons
|
||||
|
||||
@@ -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-2019 KiCad Developers, see AUTHORS.txt for contributors.
|
||||
* Copyright (C) 1992-2016 KiCad Developers, see AUTHORS.txt for contributors.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
@@ -47,6 +47,7 @@
|
||||
|
||||
|
||||
/**
|
||||
* Class EDA_3D_CANVAS
|
||||
* Implement a canvas based on a wxGLCanvas
|
||||
*/
|
||||
class EDA_3D_CANVAS : public HIDPI_GL_CANVAS
|
||||
@@ -124,11 +125,7 @@ class EDA_3D_CANVAS : public HIDPI_GL_CANVAS
|
||||
|
||||
void OnKeyEvent( wxKeyEvent& event );
|
||||
|
||||
bool SupportsRayTracing() const { return m_opengl_supports_raytracing; }
|
||||
|
||||
bool IsOpenGLInitialized() const { return m_is_opengl_initialized; }
|
||||
|
||||
private:
|
||||
private:
|
||||
|
||||
void OnPaint( wxPaintEvent &event );
|
||||
|
||||
@@ -273,8 +270,6 @@ private:
|
||||
/// Flags that the user requested the current view to be render with raytracing
|
||||
bool m_render_raytracing_was_requested;
|
||||
|
||||
bool m_opengl_supports_raytracing;
|
||||
|
||||
/**
|
||||
* Trace mask used to enable or disable the trace output of this class.
|
||||
* The debug output can be turned on by setting the WXTRACE environment variable to
|
||||
|
||||
@@ -1 +1 @@
|
||||
#define PLUGINDIR "@CMAKE_INSTALL_FULL_LIBDIR@"
|
||||
#define PLUGINDIR "@CMAKE_INSTALL_LIBDIR@"
|
||||
|
||||
@@ -501,7 +501,11 @@ void C3D_RENDER_OGL_LEGACY::reload( REPORTER *aStatusTextReporter )
|
||||
get_layer_z_pos( layer_id, layer_z_top, layer_z_bot );
|
||||
|
||||
m_ogl_disp_lists_layers_holes_outer[layer_id] = generate_holes_display_list(
|
||||
container->GetList(), *poly, layer_z_top, layer_z_bot, false );
|
||||
container->GetList(),
|
||||
*poly,
|
||||
layer_z_top,
|
||||
layer_z_bot,
|
||||
false );
|
||||
}
|
||||
|
||||
for( MAP_POLY::const_iterator ii = innerMapHoles.begin();
|
||||
@@ -515,7 +519,11 @@ void C3D_RENDER_OGL_LEGACY::reload( REPORTER *aStatusTextReporter )
|
||||
get_layer_z_pos( layer_id, layer_z_top, layer_z_bot );
|
||||
|
||||
m_ogl_disp_lists_layers_holes_inner[layer_id] = generate_holes_display_list(
|
||||
container->GetList(), *poly, layer_z_top, layer_z_bot, false );
|
||||
container->GetList(),
|
||||
*poly,
|
||||
layer_z_top,
|
||||
layer_z_bot,
|
||||
false );
|
||||
}
|
||||
}
|
||||
|
||||
@@ -523,6 +531,7 @@ void C3D_RENDER_OGL_LEGACY::reload( REPORTER *aStatusTextReporter )
|
||||
generate_3D_Vias_and_Pads();
|
||||
|
||||
// Add layers maps
|
||||
// /////////////////////////////////////////////////////////////////////////
|
||||
|
||||
if( aStatusTextReporter )
|
||||
aStatusTextReporter->Report( _( "Load OpenGL: layers" ) );
|
||||
@@ -563,33 +572,38 @@ void C3D_RENDER_OGL_LEGACY::reload( REPORTER *aStatusTextReporter )
|
||||
|
||||
switch( object2d_A->GetObjectType() )
|
||||
{
|
||||
case OBJ2D_FILLED_CIRCLE:
|
||||
add_object_to_triangle_layer( (const CFILLEDCIRCLE2D *)object2d_A,
|
||||
layerTriangles, layer_z_top, layer_z_bot );
|
||||
case OBJ2D_FILLED_CIRCLE:
|
||||
add_object_to_triangle_layer( (const CFILLEDCIRCLE2D *)object2d_A,
|
||||
layerTriangles,
|
||||
layer_z_top, layer_z_bot );
|
||||
break;
|
||||
|
||||
case OBJ2D_POLYGON4PT:
|
||||
add_object_to_triangle_layer( (const CPOLYGON4PTS2D *)object2d_A,
|
||||
layerTriangles, layer_z_top, layer_z_bot );
|
||||
case OBJ2D_POLYGON4PT:
|
||||
add_object_to_triangle_layer( (const CPOLYGON4PTS2D *)object2d_A,
|
||||
layerTriangles,
|
||||
layer_z_top, layer_z_bot );
|
||||
break;
|
||||
|
||||
case OBJ2D_RING:
|
||||
add_object_to_triangle_layer( (const CRING2D *)object2d_A,
|
||||
layerTriangles, layer_z_top, layer_z_bot );
|
||||
case OBJ2D_RING:
|
||||
add_object_to_triangle_layer( (const CRING2D *)object2d_A,
|
||||
layerTriangles,
|
||||
layer_z_top, layer_z_bot );
|
||||
break;
|
||||
|
||||
case OBJ2D_TRIANGLE:
|
||||
add_object_to_triangle_layer( (const CTRIANGLE2D *)object2d_A,
|
||||
layerTriangles, layer_z_top, layer_z_bot );
|
||||
case OBJ2D_TRIANGLE:
|
||||
add_object_to_triangle_layer( (const CTRIANGLE2D *)object2d_A,
|
||||
layerTriangles,
|
||||
layer_z_top, layer_z_bot );
|
||||
break;
|
||||
|
||||
case OBJ2D_ROUNDSEG:
|
||||
add_object_to_triangle_layer( (const CROUNDSEGMENT2D *) object2d_A,
|
||||
layerTriangles, layer_z_top, layer_z_bot );
|
||||
case OBJ2D_ROUNDSEG:
|
||||
add_object_to_triangle_layer( (const CROUNDSEGMENT2D *) object2d_A,
|
||||
layerTriangles,
|
||||
layer_z_top, layer_z_bot );
|
||||
break;
|
||||
|
||||
default:
|
||||
wxFAIL_MSG("C3D_RENDER_OGL_LEGACY: Object type is not implemented");
|
||||
default:
|
||||
wxFAIL_MSG("C3D_RENDER_OGL_LEGACY: Object type is not implemented");
|
||||
break;
|
||||
}
|
||||
}
|
||||
@@ -745,7 +759,9 @@ void C3D_RENDER_OGL_LEGACY::generate_3D_Vias_and_Pads()
|
||||
// /////////////////////////////////////////////////////////////////////////
|
||||
|
||||
// Insert vias holes (vertical cylinders)
|
||||
for( auto track : m_settings.GetBoard()->Tracks() )
|
||||
for( const TRACK* track = m_settings.GetBoard()->m_Track;
|
||||
track;
|
||||
track = track->Next() )
|
||||
{
|
||||
if( track->Type() == PCB_VIA_T )
|
||||
{
|
||||
@@ -798,9 +814,11 @@ void C3D_RENDER_OGL_LEGACY::generate_3D_Vias_and_Pads()
|
||||
tht_inner_holes_poly.RemoveAllContours();
|
||||
|
||||
// Insert pads holes (vertical cylinders)
|
||||
for( const auto module : m_settings.GetBoard()->Modules() )
|
||||
for( const MODULE* module = m_settings.GetBoard()->m_Modules;
|
||||
module;
|
||||
module = module->Next() )
|
||||
{
|
||||
for( auto pad : module->Pads() )
|
||||
for( const D_PAD* pad = module->PadsList(); pad; pad = pad->Next() )
|
||||
{
|
||||
if( pad->GetAttribute() != PAD_ATTRIB_HOLE_NOT_PLATED )
|
||||
{
|
||||
@@ -819,10 +837,13 @@ void C3D_RENDER_OGL_LEGACY::generate_3D_Vias_and_Pads()
|
||||
double correctionFactor = m_settings.GetCircleCorrectionFactor( nrSegments );
|
||||
int correction = radius * ( correctionFactor - 1 );
|
||||
|
||||
pad->BuildPadDrillShapePolygon(
|
||||
tht_outer_holes_poly, copperThickness + correction );
|
||||
pad->BuildPadDrillShapePolygon( tht_outer_holes_poly,
|
||||
copperThickness + correction,
|
||||
nrSegments );
|
||||
|
||||
pad->BuildPadDrillShapePolygon( tht_inner_holes_poly, correction );
|
||||
pad->BuildPadDrillShapePolygon( tht_inner_holes_poly,
|
||||
correction,
|
||||
nrSegments );
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -864,8 +885,12 @@ void C3D_RENDER_OGL_LEGACY::generate_3D_Vias_and_Pads()
|
||||
const SFVEC2F &v2 = tri->GetP2();
|
||||
const SFVEC2F &v3 = tri->GetP3();
|
||||
|
||||
add_triangle_top_bot( layerTriangles, v1, v2, v3,
|
||||
layer_z_top, layer_z_bot );
|
||||
add_triangle_top_bot( layerTriangles,
|
||||
v1,
|
||||
v2,
|
||||
v3,
|
||||
layer_z_top,
|
||||
layer_z_bot );
|
||||
}
|
||||
|
||||
wxASSERT( tht_outer_holes_poly.OutlineCount() > 0 );
|
||||
@@ -873,14 +898,16 @@ void C3D_RENDER_OGL_LEGACY::generate_3D_Vias_and_Pads()
|
||||
if( tht_outer_holes_poly.OutlineCount() > 0 )
|
||||
{
|
||||
layerTriangles->AddToMiddleContourns( tht_outer_holes_poly,
|
||||
layer_z_bot, layer_z_top,
|
||||
layer_z_bot,
|
||||
layer_z_top,
|
||||
m_settings.BiuTo3Dunits(),
|
||||
false );
|
||||
|
||||
m_ogl_disp_list_pads_holes = new CLAYERS_OGL_DISP_LISTS(
|
||||
*layerTriangles,
|
||||
m_ogl_circle_texture, // not need
|
||||
layer_z_top, layer_z_top );
|
||||
layer_z_top,
|
||||
layer_z_top );
|
||||
}
|
||||
|
||||
delete layerTriangles;
|
||||
@@ -903,7 +930,9 @@ void C3D_RENDER_OGL_LEGACY::load_3D_models( REPORTER *aStatusTextReporter )
|
||||
return;
|
||||
|
||||
// Go for all modules
|
||||
for( auto module : m_settings.GetBoard()->Modules() )
|
||||
for( const MODULE* module = m_settings.GetBoard()->m_Modules;
|
||||
module;
|
||||
module = module->Next() )
|
||||
{
|
||||
if( !module->Models().empty() )
|
||||
{
|
||||
|
||||
@@ -175,7 +175,8 @@ void C3D_RENDER_OGL_LEGACY::render_3D_arrows()
|
||||
|
||||
void C3D_RENDER_OGL_LEGACY::setupMaterials()
|
||||
{
|
||||
m_materials = {};
|
||||
|
||||
memset( &m_materials, 0, sizeof( m_materials ) );
|
||||
|
||||
if( m_settings.GetFlag( FL_USE_REALISTIC_MODE ) )
|
||||
{
|
||||
@@ -472,7 +473,7 @@ bool C3D_RENDER_OGL_LEGACY::Redraw( bool aIsMoving,
|
||||
|
||||
if( m_reloadRequested )
|
||||
{
|
||||
std::unique_ptr<BUSY_INDICATOR> busy = CreateBusyIndicator();
|
||||
wxBusyCursor dummy;
|
||||
|
||||
if( aStatusTextReporter )
|
||||
aStatusTextReporter->Report( _( "Loading..." ) );
|
||||
@@ -980,13 +981,18 @@ void C3D_RENDER_OGL_LEGACY::render_3D_models( bool aRenderTopOrBot,
|
||||
bool aRenderTransparentOnly )
|
||||
{
|
||||
// Go for all modules
|
||||
for( auto module : m_settings.GetBoard()->Modules() )
|
||||
if( m_settings.GetBoard()->m_Modules.GetCount() )
|
||||
{
|
||||
if( !module->Models().empty() )
|
||||
if( m_settings.ShouldModuleBeDisplayed( (MODULE_ATTR_T) module->GetAttributes() ) )
|
||||
if( ( aRenderTopOrBot && !module->IsFlipped() )
|
||||
|| ( !aRenderTopOrBot && module->IsFlipped() ) )
|
||||
render_3D_module( module, aRenderTransparentOnly );
|
||||
for( const MODULE* module = m_settings.GetBoard()->m_Modules;
|
||||
module;
|
||||
module = module->Next() )
|
||||
{
|
||||
if( !module->Models().empty() )
|
||||
if( m_settings.ShouldModuleBeDisplayed( (MODULE_ATTR_T)module->GetAttributes() ) )
|
||||
if( ( aRenderTopOrBot && !module->IsFlipped()) ||
|
||||
(!aRenderTopOrBot && module->IsFlipped()) )
|
||||
render_3D_module( module, aRenderTransparentOnly );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -150,7 +150,7 @@ void CLAYER_TRIANGLES::AddToMiddleContourns( const std::vector< SFVEC2F > &aCont
|
||||
float zTop,
|
||||
bool aInvertFaceDirection )
|
||||
{
|
||||
if( aContournPoints.size() >= 4 )
|
||||
if( aContournPoints.size() > 4 )
|
||||
{
|
||||
// Calculate normals of each segment of the contourn
|
||||
std::vector< SFVEC2F > contournNormals;
|
||||
@@ -164,6 +164,7 @@ void CLAYER_TRIANGLES::AddToMiddleContourns( const std::vector< SFVEC2F > &aCont
|
||||
{
|
||||
const SFVEC2F &v0 = aContournPoints[i + 0];
|
||||
const SFVEC2F &v1 = aContournPoints[i + 1];
|
||||
|
||||
const SFVEC2F n = glm::normalize( v1 - v0 );
|
||||
|
||||
contournNormals[i] = SFVEC2F( n.y,-n.x );
|
||||
@@ -175,6 +176,7 @@ void CLAYER_TRIANGLES::AddToMiddleContourns( const std::vector< SFVEC2F > &aCont
|
||||
{
|
||||
const SFVEC2F &v0 = aContournPoints[i + 0];
|
||||
const SFVEC2F &v1 = aContournPoints[i + 1];
|
||||
|
||||
const SFVEC2F n = glm::normalize( v1 - v0 );
|
||||
|
||||
contournNormals[i] = SFVEC2F( -n.y, n.x );
|
||||
@@ -304,20 +306,41 @@ void CLAYER_TRIANGLES::AddToMiddleContourns( const SHAPE_POLY_SET &aPolySet,
|
||||
m_layer_middle_contourns_quads->Reserve_More( nrContournPointsToReserve * 2,
|
||||
true );
|
||||
|
||||
for( int i = 0; i < aPolySet.OutlineCount(); i++ )
|
||||
std::atomic<int> nextItem( 0 );
|
||||
std::atomic<size_t> threadsFinished( 0 );
|
||||
|
||||
size_t parallelThreadCount = std::min<size_t>(
|
||||
std::max<size_t>( std::thread::hardware_concurrency(), 2 ),
|
||||
static_cast<size_t>( aPolySet.OutlineCount() ) );
|
||||
for( size_t ii = 0; ii < parallelThreadCount; ++ii )
|
||||
{
|
||||
// Add outline
|
||||
const SHAPE_LINE_CHAIN& pathOutline = aPolySet.COutline( i );
|
||||
|
||||
AddToMiddleContourns( pathOutline, zBot, zTop, aBiuTo3Du, aInvertFaceDirection );
|
||||
|
||||
// Add holes for this outline
|
||||
for( int h = 0; h < aPolySet.HoleCount( i ); ++h )
|
||||
std::thread t = std::thread( [&]()
|
||||
{
|
||||
const SHAPE_LINE_CHAIN &hole = aPolySet.CHole( i, h );
|
||||
AddToMiddleContourns( hole, zBot, zTop, aBiuTo3Du, aInvertFaceDirection );
|
||||
}
|
||||
for( int i = nextItem.fetch_add( 1 );
|
||||
i < aPolySet.OutlineCount();
|
||||
i = nextItem.fetch_add( 1 ) )
|
||||
{
|
||||
// Add outline
|
||||
const SHAPE_LINE_CHAIN& pathOutline = aPolySet.COutline( i );
|
||||
|
||||
AddToMiddleContourns( pathOutline, zBot, zTop, aBiuTo3Du, aInvertFaceDirection );
|
||||
|
||||
// Add holes for this outline
|
||||
for( int h = 0; h < aPolySet.HoleCount( i ); ++h )
|
||||
{
|
||||
const SHAPE_LINE_CHAIN &hole = aPolySet.CHole( i, h );
|
||||
AddToMiddleContourns( hole, zBot, zTop, aBiuTo3Du, aInvertFaceDirection );
|
||||
}
|
||||
}
|
||||
|
||||
threadsFinished++;
|
||||
} );
|
||||
|
||||
t.detach();
|
||||
}
|
||||
|
||||
while( threadsFinished < parallelThreadCount )
|
||||
std::this_thread::sleep_for( std::chrono::milliseconds( 10 ) );
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -1076,7 +1076,7 @@ void C3D_RENDER_RAYTRACING::insert3DPadHole( const D_PAD* aPad )
|
||||
width * m_settings.BiuTo3Dunits(),
|
||||
*aPad );
|
||||
|
||||
CROUNDSEGMENT2D *outerSeg = new CROUNDSEGMENT2D(
|
||||
CROUNDSEGMENT2D *outterSeg = new CROUNDSEGMENT2D(
|
||||
SFVEC2F( start.x * m_settings.BiuTo3Dunits(),
|
||||
-start.y * m_settings.BiuTo3Dunits() ),
|
||||
SFVEC2F( end.x * m_settings.BiuTo3Dunits(),
|
||||
@@ -1090,14 +1090,14 @@ void C3D_RENDER_RAYTRACING::insert3DPadHole( const D_PAD* aPad )
|
||||
std::vector<const COBJECT2D *> *object2d_B = new std::vector<const COBJECT2D *>();
|
||||
object2d_B->push_back( innerSeg );
|
||||
|
||||
CITEMLAYERCSG2D *itemCSG2d = new CITEMLAYERCSG2D( outerSeg,
|
||||
CITEMLAYERCSG2D *itemCSG2d = new CITEMLAYERCSG2D( outterSeg,
|
||||
object2d_B,
|
||||
CSGITEM_FULL,
|
||||
*aPad );
|
||||
|
||||
m_containerWithObjectsToDelete.Add( itemCSG2d );
|
||||
m_containerWithObjectsToDelete.Add( innerSeg );
|
||||
m_containerWithObjectsToDelete.Add( outerSeg );
|
||||
m_containerWithObjectsToDelete.Add( outterSeg );
|
||||
|
||||
object2d_A = itemCSG2d;
|
||||
}
|
||||
@@ -1171,7 +1171,9 @@ void C3D_RENDER_RAYTRACING::add_3D_vias_and_pads_to_container()
|
||||
// /////////////////////////////////////////////////////////////////////////
|
||||
|
||||
// Insert vias holes (vertical cylinders)
|
||||
for( auto track : m_settings.GetBoard()->Tracks() )
|
||||
for( const TRACK* track = m_settings.GetBoard()->m_Track;
|
||||
track;
|
||||
track = track->Next() )
|
||||
{
|
||||
if( track->Type() == PCB_VIA_T )
|
||||
{
|
||||
@@ -1181,9 +1183,11 @@ void C3D_RENDER_RAYTRACING::add_3D_vias_and_pads_to_container()
|
||||
}
|
||||
|
||||
// Insert pads holes (vertical cylinders)
|
||||
for( auto module : m_settings.GetBoard()->Modules() )
|
||||
for( const MODULE* module = m_settings.GetBoard()->m_Modules;
|
||||
module;
|
||||
module = module->Next() )
|
||||
{
|
||||
for( auto pad : module->Pads() )
|
||||
for( const D_PAD* pad = module->PadsList(); pad; pad = pad->Next() )
|
||||
if( pad->GetAttribute () != PAD_ATTRIB_HOLE_NOT_PLATED )
|
||||
{
|
||||
insert3DPadHole( pad );
|
||||
@@ -1195,7 +1199,9 @@ void C3D_RENDER_RAYTRACING::add_3D_vias_and_pads_to_container()
|
||||
void C3D_RENDER_RAYTRACING::load_3D_models()
|
||||
{
|
||||
// Go for all modules
|
||||
for( auto module : m_settings.GetBoard()->Modules() )
|
||||
for( const MODULE* module = m_settings.GetBoard()->m_Modules;
|
||||
module;
|
||||
module = module->Next() )
|
||||
{
|
||||
if( (!module->Models().empty() ) &&
|
||||
m_settings.ShouldModuleBeDisplayed( (MODULE_ATTR_T)module->GetAttributes() ) )
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
/*
|
||||
/*
|
||||
* This program source code file is part of KiCad, a free EDA CAD application.
|
||||
*
|
||||
* Copyright (C) 2015-2016 Mario Luzeiro <mrluzeiro@ua.pt>
|
||||
@@ -28,11 +28,10 @@
|
||||
*/
|
||||
|
||||
#include <GL/glew.h>
|
||||
#include <algorithm>
|
||||
#include <atomic>
|
||||
#include <chrono>
|
||||
#include <climits>
|
||||
#include <atomic>
|
||||
#include <thread>
|
||||
#include <chrono>
|
||||
|
||||
#include "c3d_render_raytracing.h"
|
||||
#include "mortoncodes.h"
|
||||
@@ -167,7 +166,7 @@ bool C3D_RENDER_RAYTRACING::Redraw( bool aIsMoving, REPORTER *aStatusTextReporte
|
||||
initialize_block_positions();
|
||||
}
|
||||
|
||||
std::unique_ptr<BUSY_INDICATOR> busy = CreateBusyIndicator();
|
||||
wxBusyCursor dummy;
|
||||
|
||||
// Reload board if it was requested
|
||||
// /////////////////////////////////////////////////////////////////////////
|
||||
@@ -2075,13 +2074,6 @@ bool C3D_RENDER_RAYTRACING::initializeOpenGL()
|
||||
}
|
||||
|
||||
|
||||
static float distance( const SFVEC2UI& a, const SFVEC2UI& b )
|
||||
{
|
||||
const float dx = (float) a.x - (float) b.x;
|
||||
const float dy = (float) a.y - (float) b.y;
|
||||
return hypotf( dx, dy );
|
||||
}
|
||||
|
||||
void C3D_RENDER_RAYTRACING::initialize_block_positions()
|
||||
{
|
||||
|
||||
@@ -2131,24 +2123,26 @@ void C3D_RENDER_RAYTRACING::initialize_block_positions()
|
||||
m_postshader_ssao.UpdateSize( m_realBufferSize );
|
||||
|
||||
|
||||
// Calc block positions for regular rendering. Choose an 'inside out'
|
||||
// style of rendering
|
||||
// Calc block positions
|
||||
// /////////////////////////////////////////////////////////////////////
|
||||
m_blockPositions.clear();
|
||||
const int blocks_x = m_realBufferSize.x / RAYPACKET_DIM;
|
||||
const int blocks_y = m_realBufferSize.y / RAYPACKET_DIM;
|
||||
m_blockPositions.reserve( blocks_x * blocks_y );
|
||||
m_blockPositions.reserve( (m_realBufferSize.x / RAYPACKET_DIM) *
|
||||
(m_realBufferSize.y / RAYPACKET_DIM) );
|
||||
|
||||
for( int x = 0; x < blocks_x; ++x )
|
||||
for( int y = 0; y < blocks_y; ++y )
|
||||
m_blockPositions.push_back( SFVEC2UI( x * RAYPACKET_DIM, y * RAYPACKET_DIM ) );
|
||||
i = 0;
|
||||
|
||||
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 ) {
|
||||
// Sort order: inside out.
|
||||
return distance( a, center ) < distance( b, center );
|
||||
} );
|
||||
while(1)
|
||||
{
|
||||
SFVEC2UI blockPos( DecodeMorton2X(i) * RAYPACKET_DIM,
|
||||
DecodeMorton2Y(i) * RAYPACKET_DIM );
|
||||
i++;
|
||||
|
||||
if( (blockPos.x >= m_realBufferSize.x) && (blockPos.y >= m_realBufferSize.y) )
|
||||
break;
|
||||
|
||||
if( (blockPos.x < m_realBufferSize.x) && (blockPos.y < m_realBufferSize.y) )
|
||||
m_blockPositions.push_back( blockPos );
|
||||
}
|
||||
|
||||
// Create m_shader buffer
|
||||
delete[] m_shaderBuffer;
|
||||
|
||||
@@ -109,9 +109,9 @@ public:
|
||||
float *aOutT,
|
||||
SFVEC2F *aNormalOut ) const = 0;
|
||||
|
||||
/**
|
||||
* Function IsBBoxInside
|
||||
* @brief Tests if the bounding is out, intersects or is complety inside
|
||||
/** Function IsBBoxInside
|
||||
* @brief Tests if the bouding is out, intersects or is complety inside
|
||||
* @param aBBox - The bounding box to test
|
||||
* @return INTERSECTION_RESULT
|
||||
*/
|
||||
virtual INTERSECTION_RESULT IsBBoxInside( const CBBOX2D &aBBox ) const = 0;
|
||||
|
||||
@@ -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-2018 KiCad Developers, see AUTHORS.txt for contributors.
|
||||
* Copyright (C) 1992-2016 KiCad Developers, see AUTHORS.txt for contributors.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
@@ -711,6 +711,60 @@ void Convert_path_polygon_to_polygon_blocks_and_dummy_blocks(
|
||||
}
|
||||
|
||||
|
||||
void Polygon_Calc_BBox_3DU( const SHAPE_POLY_SET &aPolysList,
|
||||
CBBOX2D &aOutBBox ,
|
||||
float aBiuTo3DunitsScale )
|
||||
{
|
||||
aOutBBox.Reset();
|
||||
|
||||
for( int idx = 0; idx < aPolysList.OutlineCount(); ++idx )
|
||||
{
|
||||
// Each polygon in aPolysList is a polygon with holes
|
||||
const SHAPE_POLY_SET::POLYGON& curr_polywithholes = aPolysList.CPolygon( idx );
|
||||
|
||||
for( unsigned ipoly = 0; ipoly < curr_polywithholes.size(); ++ipoly )
|
||||
{
|
||||
const SHAPE_LINE_CHAIN& path = curr_polywithholes[ipoly]; // a simple polygon
|
||||
|
||||
for( int jj = 0; jj < path.PointCount(); jj++ )
|
||||
{
|
||||
const VECTOR2I& a = path.CPoint( jj );
|
||||
|
||||
aOutBBox.Union( SFVEC2F( (float) a.x * aBiuTo3DunitsScale,
|
||||
(float)-a.y * aBiuTo3DunitsScale ) );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
aOutBBox.ScaleNextUp();
|
||||
}
|
||||
|
||||
|
||||
void Polygon_Convert( const KI_POLYGON &aPolygon,
|
||||
ClipperLib::Path &aOutPath,
|
||||
CBBOX2D &aOutBBox,
|
||||
float aBiuTo3DunitsScale )
|
||||
{
|
||||
aOutPath.resize( aPolygon.size() );
|
||||
aOutBBox.Reset();
|
||||
|
||||
for( unsigned i = 0; i < aPolygon.size(); i++ )
|
||||
{
|
||||
const KI_POLY_POINT point = *(aPolygon.begin() + i);
|
||||
|
||||
aOutPath[i] = ClipperLib::IntPoint( (ClipperLib::cInt)point.x(),
|
||||
(ClipperLib::cInt)point.y() );
|
||||
|
||||
aOutBBox.Union( SFVEC2F( (float) point.x() * aBiuTo3DunitsScale,
|
||||
(float)-point.y() * aBiuTo3DunitsScale ) );
|
||||
}
|
||||
|
||||
aOutBBox.ScaleNextUp();
|
||||
|
||||
ClipperLib::CleanPolygon( aOutPath );
|
||||
}
|
||||
|
||||
|
||||
#ifdef DEBUG
|
||||
static void polygon_Convert( const ClipperLib::Path &aPath,
|
||||
SEGMENTS &aOutSegment,
|
||||
@@ -751,7 +805,7 @@ void Polygon2d_TestModule()
|
||||
aPath[2] = ClipperLib::IntPoint( 2, 2 );
|
||||
aPath[3] = ClipperLib::IntPoint( -2, 2 );
|
||||
|
||||
// It must be an outer polygon
|
||||
// It must be an outter polygon
|
||||
wxASSERT( ClipperLib::Orientation( aPath ) );
|
||||
|
||||
polygon_Convert( aPath, aSegments, 1.0f );
|
||||
|
||||
@@ -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-2018 KiCad Developers, see AUTHORS.txt for contributors.
|
||||
* Copyright (C) 1992-2016 KiCad Developers, see AUTHORS.txt for contributors.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
@@ -33,6 +33,7 @@
|
||||
#include "cobject2d.h"
|
||||
#include "../accelerators/ccontainer2d.h"
|
||||
#include <geometry/shape_poly_set.h>
|
||||
#include <polygons_defs.h>
|
||||
#include <vector>
|
||||
|
||||
|
||||
@@ -86,7 +87,7 @@ typedef struct
|
||||
class CPOLYGONBLOCK2D : public COBJECT2D
|
||||
{
|
||||
private:
|
||||
/// This is the outer part of the polygon. This list is used to test a ray
|
||||
/// This is the outter part of the polygon. This list is used to test a ray
|
||||
/// intersection with the boundaries of this sub polygon.
|
||||
/// It contains also the interpolated normals that are passed from the main
|
||||
/// polygon.
|
||||
@@ -150,6 +151,15 @@ void Convert_path_polygon_to_polygon_blocks_and_dummy_blocks(
|
||||
float aDivFactor,
|
||||
const BOARD_ITEM &aBoardItem );
|
||||
|
||||
void Polygon_Calc_BBox_3DU( const SHAPE_POLY_SET &aPolysList,
|
||||
CBBOX2D &aOutBBox,
|
||||
float aBiuTo3DunitsScale );
|
||||
|
||||
void Polygon_Convert( const KI_POLYGON &aPolygon,
|
||||
ClipperLib::Path &aOutPath,
|
||||
CBBOX2D &aOutBBox,
|
||||
float aBiuTo3DunitsScale );
|
||||
|
||||
void Polygon2d_TestModule();
|
||||
|
||||
#endif // _CPOLYGON2D_H_
|
||||
|
||||
@@ -88,7 +88,7 @@ bool CPOLYGON4PTS2D::Intersects( const CBBOX2D &aBBox ) const
|
||||
if( !m_bbox.Intersects( aBBox ) )
|
||||
return false;
|
||||
|
||||
// Check if the bounding box complety have inside the small bounding box
|
||||
// Check if the bouding box complety have inside the small bouding box
|
||||
if( (aBBox.Max().x > m_bbox.Max().x) &&
|
||||
(aBBox.Max().y > m_bbox.Max().x) &&
|
||||
(aBBox.Min().x < m_bbox.Min().x) &&
|
||||
|
||||
@@ -87,15 +87,15 @@ bool CRING2D::Intersect( const RAYSEG2D &aSegRay,
|
||||
// dd*t^2 + (2*qd)*t + (qq-r^2) = 0
|
||||
|
||||
const float discriminantsqr = qd * qd - qq;
|
||||
const float discriminantsqr_outer = discriminantsqr + m_outer_radius_squared;
|
||||
const float discriminantsqr_outter = discriminantsqr + m_outer_radius_squared;
|
||||
|
||||
// If the discriminant is less than zero, there is no intersection
|
||||
if( discriminantsqr_outer < FLT_EPSILON )
|
||||
if( discriminantsqr_outter < FLT_EPSILON )
|
||||
return false;
|
||||
|
||||
// Otherwise check and make sure that the intersections occur on the ray (t
|
||||
// > 0) and return the closer one
|
||||
const float discriminant = sqrt( discriminantsqr_outer );
|
||||
const float discriminant = sqrt( discriminantsqr_outter );
|
||||
float t = (-qd - discriminant);
|
||||
|
||||
if( (t > FLT_EPSILON) && (t < aSegRay.m_Length) )
|
||||
|
||||
@@ -76,7 +76,7 @@ bool CROUNDSEGMENT2D::Intersects( const CBBOX2D &aBBox ) const
|
||||
return false;
|
||||
|
||||
if( (aBBox.Max().x > m_bbox.Max().x) &&
|
||||
(aBBox.Max().y > m_bbox.Max().y) &&
|
||||
(aBBox.Max().y > m_bbox.Max().x) &&
|
||||
(aBBox.Min().x < m_bbox.Min().x) &&
|
||||
(aBBox.Min().y < m_bbox.Min().y)
|
||||
)
|
||||
|
||||
@@ -85,7 +85,7 @@ public:
|
||||
bool IsPointInside( const SFVEC2F &aPoint ) const override;
|
||||
};
|
||||
|
||||
static const float s_min_dot = (FLT_EPSILON * 4.0f * FLT_EPSILON * 4.0f) ;
|
||||
static const float s_min_dot = (FLT_EPSILON * 4.0f) ;
|
||||
|
||||
/**
|
||||
* @brief Segment_is_a_circle - check if segment start and end is very close to each other
|
||||
|
||||
@@ -138,9 +138,9 @@ void Convert_shape_line_polygon_to_triangles( SHAPE_POLY_SET &aPolyList,
|
||||
aPolyList.CacheTriangulation();
|
||||
const double conver_d = (double)aBiuTo3DunitsScale;
|
||||
|
||||
for( unsigned int j = 0; j < aPolyList.TriangulatedPolyCount(); j++ )
|
||||
for( unsigned int i = 0; i < aPolyList.TriangulatedPolyCount(); i++ )
|
||||
{
|
||||
auto triPoly = aPolyList.TriangulatedPolygon( j );
|
||||
auto triPoly = aPolyList.TriangulatedPolygon( i );
|
||||
|
||||
for( size_t i = 0; i < triPoly->GetTriangleCount(); i++ )
|
||||
{
|
||||
|
||||
@@ -83,7 +83,7 @@ public:
|
||||
CROUNDSEG( const SFVEC2F &aStart,
|
||||
const SFVEC2F &aEnd,
|
||||
float aInnerRadius,
|
||||
float aOuterRadius,
|
||||
float aOutterRadius,
|
||||
float aZmin,
|
||||
float aZmax );
|
||||
|
||||
@@ -102,9 +102,9 @@ private:
|
||||
float m_inner_radius;
|
||||
float m_inner_radius_squared;
|
||||
float m_inner_inv_radius;
|
||||
float m_outer_radius;
|
||||
float m_outer_radius_squared;
|
||||
float m_outer_inv_radius;
|
||||
float m_outter_radius;
|
||||
float m_outter_radius_squared;
|
||||
float m_outter_inv_radius;
|
||||
float m_width;
|
||||
float m_seglen_over_two_squared;
|
||||
};
|
||||
|
||||
@@ -54,19 +54,3 @@ C3D_RENDER_BASE::~C3D_RENDER_BASE()
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
void C3D_RENDER_BASE::SetBusyIndicatorFactory( BUSY_INDICATOR::FACTORY aNewFactory )
|
||||
{
|
||||
m_busyIndicatorFactory = aNewFactory;
|
||||
}
|
||||
|
||||
|
||||
std::unique_ptr<BUSY_INDICATOR> C3D_RENDER_BASE::CreateBusyIndicator() const
|
||||
{
|
||||
std::unique_ptr<BUSY_INDICATOR> busy;
|
||||
|
||||
if( m_busyIndicatorFactory )
|
||||
busy = m_busyIndicatorFactory();
|
||||
|
||||
return busy;
|
||||
}
|
||||
|
||||
@@ -35,8 +35,6 @@
|
||||
#include "../3d_canvas/cinfo3d_visu.h"
|
||||
#include <reporter.h>
|
||||
|
||||
#include <widgets/busy_indicator.h>
|
||||
|
||||
/**
|
||||
* This is a base class to hold data and functions for render targets.
|
||||
*/
|
||||
@@ -88,22 +86,9 @@ public:
|
||||
*/
|
||||
virtual int GetWaitForEditingTimeOut() = 0;
|
||||
|
||||
/**
|
||||
* Set a new busy indicator factory.
|
||||
*
|
||||
* When set, this factory will be used to generate busy indicators when
|
||||
* suitable. If not set, no busy indicator will be used.
|
||||
*/
|
||||
void SetBusyIndicatorFactory( BUSY_INDICATOR::FACTORY aNewFactory );
|
||||
|
||||
// Attributes
|
||||
|
||||
protected:
|
||||
/**
|
||||
* Return a created busy indicator, if a factory has been set, else
|
||||
* a null pointer.
|
||||
*/
|
||||
std::unique_ptr<BUSY_INDICATOR> CreateBusyIndicator() const;
|
||||
|
||||
/// settings refrence in use for this render
|
||||
CINFO3D_VISU &m_settings;
|
||||
@@ -124,10 +109,6 @@ protected:
|
||||
* more information.
|
||||
*/
|
||||
static const wxChar *m_logTrace;
|
||||
|
||||
private:
|
||||
/// Factory that returns a suitable busy indicator for the context.
|
||||
BUSY_INDICATOR::FACTORY m_busyIndicatorFactory;
|
||||
};
|
||||
|
||||
#endif // C3D_RENDER_BASE_H
|
||||
|
||||
@@ -310,7 +310,7 @@ void CCAMERA::MakeRay( const SFVEC2I &aWindowPos,
|
||||
|
||||
case PROJECTION_ORTHO:
|
||||
aOutOrigin = up_plus_right * 0.5f + m_frustum.nc;
|
||||
aOutDirection = -m_dir + SFVEC3F( FLT_EPSILON );
|
||||
aOutDirection = -m_dir;
|
||||
break;
|
||||
}
|
||||
}
|
||||
@@ -341,7 +341,7 @@ void CCAMERA::MakeRay( const SFVEC2F &aWindowPos, SFVEC3F &aOutOrigin, SFVEC3F &
|
||||
|
||||
case PROJECTION_ORTHO:
|
||||
aOutOrigin = up_plus_right * 0.5f + m_frustum.nc;
|
||||
aOutDirection = -m_dir + SFVEC3F( FLT_EPSILON );
|
||||
aOutDirection = -m_dir;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,8 +1,10 @@
|
||||
/*
|
||||
* This program source code file is part of KiCad, a free EDA CAD application.
|
||||
*
|
||||
* Copyright (C) 2015 Jean-Pierre Charras, jp.charras at wanadoo.fr
|
||||
* Copyright (C) 1992-2017 KiCad Developers, see AUTHORS.txt for contributors.
|
||||
* 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@verizon.net>
|
||||
* Copyright (C) 1992-2016 KiCad Developers, see AUTHORS.txt for contributors.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
@@ -22,29 +24,22 @@
|
||||
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
|
||||
*/
|
||||
|
||||
#ifndef PAD_NAMING_H
|
||||
#define PAD_NAMING_H
|
||||
|
||||
#include <class_pad.h>
|
||||
|
||||
/**
|
||||
* The PAD_NAMING namespace contains helper functions for common operations
|
||||
* to do with naming of #D_PAD objects.
|
||||
* @file 3d_viewer.h
|
||||
* @brief Declaration of the eda_3d_viewer class
|
||||
*/
|
||||
namespace PAD_NAMING
|
||||
{
|
||||
|
||||
/**
|
||||
* Check if a pad should be named.
|
||||
*
|
||||
* For example, NPTH or paste apertures normally do not have names, as they
|
||||
* cannot be assigned to a netlist.
|
||||
*
|
||||
* @param aPad the pad to check
|
||||
* @return true if the pad gets a name
|
||||
*/
|
||||
bool PadCanHaveName( const D_PAD& aPad );
|
||||
#ifndef _3D_VIEWER_H_
|
||||
#define _3D_VIEWER_H_
|
||||
|
||||
} // namespace PAD_NAMING
|
||||
|
||||
#endif // PAD_NAMING_H
|
||||
/// A variable name whose value holds the path of 3D shape files.
|
||||
/// Currently an environment variable, eventually a project variable.
|
||||
#define KISYS3DMOD wxT( "KISYS3DMOD" )
|
||||
|
||||
/// All 3D files are expected to be stored in LIB3D_FOLDER, or one of
|
||||
/// its subdirectory.
|
||||
#define LIB3D_FOLDER wxT( "packages3d" )
|
||||
|
||||
|
||||
#endif // _3D_VIEWER_H_
|
||||
@@ -1,129 +0,0 @@
|
||||
/*
|
||||
* This program source code file is part of KiCad, a free EDA CAD application.
|
||||
*
|
||||
* Copyright (C) 2017 Jon Evans <jon@craftyjon.com>
|
||||
* Copyright (C) 2017-2019 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 <tool/tool_manager.h>
|
||||
#include <bitmaps.h>
|
||||
#include "3d_actions.h"
|
||||
|
||||
|
||||
// Actions, being statically-defined, require specialized I18N handling. We continue to
|
||||
// use the _() macro so that string harvesting by the I18N framework doesn't have to be
|
||||
// specialized, but we don't translate on initialization and instead do it in the getters.
|
||||
|
||||
#undef _
|
||||
#define _(s) s
|
||||
|
||||
|
||||
TOOL_ACTION EDA_3D_ACTIONS::pivotCenter( "3DViewer.Control.pivotCenter",
|
||||
AS_GLOBAL,
|
||||
' ', "",
|
||||
"Center pivot rotation (Middle mouse click)" );
|
||||
|
||||
TOOL_ACTION EDA_3D_ACTIONS::moveLeft( "3DViewer.Control.moveLeft",
|
||||
AS_GLOBAL,
|
||||
WXK_LEFT, "",
|
||||
"Move board Left" );
|
||||
|
||||
TOOL_ACTION EDA_3D_ACTIONS::moveRight( "3DViewer.Control.moveRight",
|
||||
AS_GLOBAL,
|
||||
WXK_RIGHT, "",
|
||||
"Move board Right" );
|
||||
|
||||
TOOL_ACTION EDA_3D_ACTIONS::moveUp( "3DViewer.Control.moveUp",
|
||||
AS_GLOBAL,
|
||||
WXK_UP, "",
|
||||
"Move board Up" );
|
||||
|
||||
TOOL_ACTION EDA_3D_ACTIONS::moveDown( "3DViewer.Control.moveDown",
|
||||
AS_GLOBAL,
|
||||
WXK_DOWN, "",
|
||||
"Move board Down" );
|
||||
|
||||
TOOL_ACTION EDA_3D_ACTIONS::homeView( "3DViewer.Control.homeView",
|
||||
AS_GLOBAL,
|
||||
WXK_HOME, "",
|
||||
"Home view" );
|
||||
|
||||
TOOL_ACTION EDA_3D_ACTIONS::resetView( "3DViewer.Control.resetView",
|
||||
AS_GLOBAL,
|
||||
'R', "",
|
||||
"Reset view" );
|
||||
|
||||
TOOL_ACTION EDA_3D_ACTIONS::viewFront( "3DViewer.Control.viewFront",
|
||||
AS_GLOBAL,
|
||||
'Y', "",
|
||||
"View Front" );
|
||||
|
||||
TOOL_ACTION EDA_3D_ACTIONS::viewBack( "3DViewer.Control.viewBack",
|
||||
AS_GLOBAL,
|
||||
MD_SHIFT + 'Y', "",
|
||||
"View Back" );
|
||||
|
||||
TOOL_ACTION EDA_3D_ACTIONS::viewLeft( "3DViewer.Control.viewLeft",
|
||||
AS_GLOBAL,
|
||||
MD_SHIFT + 'X', "",
|
||||
"View Left" );
|
||||
|
||||
TOOL_ACTION EDA_3D_ACTIONS::viewRight( "3DViewer.Control.viewRight",
|
||||
AS_GLOBAL,
|
||||
'X', "",
|
||||
"View Right" );
|
||||
|
||||
TOOL_ACTION EDA_3D_ACTIONS::viewTop( "3DViewer.Control.viewTop",
|
||||
AS_GLOBAL,
|
||||
'Z', "",
|
||||
"View Top" );
|
||||
|
||||
TOOL_ACTION EDA_3D_ACTIONS::viewBottom( "3DViewer.Control.viewBottom",
|
||||
AS_GLOBAL,
|
||||
MD_SHIFT + 'Z', "",
|
||||
"View Bottom" );
|
||||
|
||||
TOOL_ACTION EDA_3D_ACTIONS::rotate45axisZ( "3DViewer.Control.rotate45axisZ",
|
||||
AS_GLOBAL,
|
||||
WXK_TAB, "",
|
||||
"Rotate 45 degrees over Z axis" );
|
||||
|
||||
TOOL_ACTION EDA_3D_ACTIONS::zoomIn( "3DViewer.Control.zoomIn",
|
||||
AS_GLOBAL,
|
||||
WXK_F1, "",
|
||||
"Zoom in " );
|
||||
|
||||
TOOL_ACTION EDA_3D_ACTIONS::zoomOut( "3DViewer.Control.zoomOut",
|
||||
AS_GLOBAL,
|
||||
WXK_F2, "",
|
||||
"Zoom out" );
|
||||
|
||||
TOOL_ACTION EDA_3D_ACTIONS::attributesTHT( "3DViewer.Control.attributesTHT",
|
||||
AS_GLOBAL,
|
||||
'T', "",
|
||||
"Toggle 3D models with type Through Hole" );
|
||||
|
||||
TOOL_ACTION EDA_3D_ACTIONS::attributesSMD( "3DViewer.Control.attributesSMD",
|
||||
AS_GLOBAL,
|
||||
'S', "",
|
||||
"Toggle 3D models with type Surface Mount" );
|
||||
|
||||
TOOL_ACTION EDA_3D_ACTIONS::attributesVirtual( "3DViewer.Control.attributesVirtual",
|
||||
AS_GLOBAL,
|
||||
'V', "",
|
||||
"Toggle 3D models with type Virtual" );
|
||||
|
||||
|
||||
@@ -1,70 +0,0 @@
|
||||
/*
|
||||
* This program source code file is part of KiCad, a free EDA CAD application.
|
||||
*
|
||||
* Copyright (C) 2013-2016 CERN
|
||||
* Copyright (C) 2018 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
|
||||
* 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 EDA_3D_ACTIONS_H
|
||||
#define EDA_3D_ACTIONS_H
|
||||
|
||||
#include <tool/tool_action.h>
|
||||
#include <tool/actions.h>
|
||||
#include <core/optional.h>
|
||||
|
||||
class TOOL_EVENT;
|
||||
class TOOL_MANAGER;
|
||||
|
||||
/**
|
||||
* Class EDA_3D_ACTIONS
|
||||
*
|
||||
* Note: these aren't "real" actions; we just use them to see the hotkeys display.
|
||||
*/
|
||||
class EDA_3D_ACTIONS : public ACTIONS
|
||||
{
|
||||
public:
|
||||
static TOOL_ACTION pivotCenter;
|
||||
static TOOL_ACTION moveLeft;
|
||||
static TOOL_ACTION moveRight;
|
||||
static TOOL_ACTION moveUp;
|
||||
static TOOL_ACTION moveDown;
|
||||
static TOOL_ACTION homeView;
|
||||
static TOOL_ACTION resetView;
|
||||
|
||||
static TOOL_ACTION viewFront;
|
||||
static TOOL_ACTION viewBack;
|
||||
static TOOL_ACTION viewLeft;
|
||||
static TOOL_ACTION viewRight;
|
||||
static TOOL_ACTION viewTop;
|
||||
static TOOL_ACTION viewBottom;
|
||||
|
||||
static TOOL_ACTION rotate45axisZ;
|
||||
static TOOL_ACTION zoomIn;
|
||||
static TOOL_ACTION zoomOut;
|
||||
static TOOL_ACTION attributesTHT;
|
||||
static TOOL_ACTION attributesSMD;
|
||||
static TOOL_ACTION attributesVirtual;
|
||||
|
||||
///> @copydoc COMMON_ACTIONS::TranslateLegacyId()
|
||||
virtual OPT<TOOL_EVENT> TranslateLegacyId( int aId ) override { return OPT<TOOL_EVENT>(); }
|
||||
};
|
||||
|
||||
#endif
|
||||
+343
-262
@@ -4,7 +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) 1992-2019 KiCad Developers, see AUTHORS.txt for contributors.
|
||||
* Copyright (C) 1992-2018 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,319 +24,400 @@
|
||||
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
|
||||
*/
|
||||
|
||||
/**
|
||||
* @file 3d_menubar.cpp
|
||||
*/
|
||||
|
||||
#include <fctsys.h>
|
||||
#include <tool/conditional_menu.h>
|
||||
|
||||
#include <eda_3d_viewer.h>
|
||||
#include <3d_canvas/cinfo3d_visu.h>
|
||||
#include <menus_helpers.h>
|
||||
#include <3d_viewer_id.h>
|
||||
#include <3d_actions.h>
|
||||
#include <tool/tool_manager.h>
|
||||
#include <tool/common_control.h>
|
||||
#include "help_common_strings.h"
|
||||
|
||||
extern struct EDA_HOTKEY_CONFIG g_3DViewer_Hokeys_Descr[];
|
||||
|
||||
void EDA_3D_VIEWER::CreateMenuBar()
|
||||
{
|
||||
wxLogTrace( m_logTrace, "EDA_3D_VIEWER::CreateMenuBar" );
|
||||
wxLogTrace( m_logTrace, wxT( "EDA_3D_VIEWER::CreateMenuBar" ) );
|
||||
|
||||
COMMON_CONTROL* tool = m_toolManager->GetTool<COMMON_CONTROL>();
|
||||
wxMenuBar* menuBar = new wxMenuBar;
|
||||
wxMenu* fileMenu = new wxMenu;
|
||||
wxMenu* editMenu = new wxMenu;
|
||||
wxMenu* viewMenu = new wxMenu;
|
||||
wxMenu* prefsMenu = new wxMenu;
|
||||
wxMenu* helpMenu = new wxMenu;
|
||||
|
||||
menuBar->Append( fileMenu, _( "&File" ) );
|
||||
|
||||
AddMenuItem( fileMenu, ID_MENU_SCREENCOPY_PNG,
|
||||
_( "Export Current View as PNG..." ),
|
||||
KiBitmap( export_xpm ) );
|
||||
|
||||
AddMenuItem( fileMenu, ID_MENU_SCREENCOPY_JPEG,
|
||||
_( "Export Current View as JPEG..." ),
|
||||
KiBitmap( export_xpm ) );
|
||||
|
||||
fileMenu->AppendSeparator();
|
||||
AddMenuItem( fileMenu, wxID_EXIT,
|
||||
_( "&Exit" ),
|
||||
KiBitmap( exit_xpm ) );
|
||||
|
||||
menuBar->Append( editMenu, _( "&Edit" ) );
|
||||
|
||||
AddMenuItem( editMenu, ID_TOOL_SCREENCOPY_TOCLIBBOARD,
|
||||
_( "Copy 3D Image" ),
|
||||
KiBitmap( copy_xpm ) );
|
||||
|
||||
menuBar->Append( viewMenu, _( "&View" ) );
|
||||
|
||||
AddMenuItem( viewMenu, ID_ZOOM_IN,
|
||||
_( "Zoom &In" ), HELP_ZOOM_IN,
|
||||
KiBitmap( zoom_in_xpm ) );
|
||||
|
||||
AddMenuItem( viewMenu, ID_ZOOM_OUT,
|
||||
_( "Zoom &Out" ), HELP_ZOOM_OUT,
|
||||
KiBitmap( zoom_out_xpm ) );
|
||||
|
||||
AddMenuItem( viewMenu, ID_ZOOM_PAGE,
|
||||
_( "Zoom to &Fit" ), HELP_ZOOM_FIT,
|
||||
KiBitmap( zoom_fit_in_page_xpm ) );
|
||||
|
||||
AddMenuItem( viewMenu, ID_ZOOM_REDRAW,
|
||||
_( "&Redraw" ), HELP_ZOOM_REDRAW,
|
||||
KiBitmap( zoom_redraw_xpm ) );
|
||||
|
||||
viewMenu->AppendSeparator();
|
||||
|
||||
AddMenuItem( viewMenu, ID_ROTATE3D_X_NEG,
|
||||
_( "Rotate X Clockwise" ),
|
||||
KiBitmap( rotate_neg_x_xpm ) );
|
||||
|
||||
AddMenuItem( viewMenu, ID_ROTATE3D_X_POS,
|
||||
_( "Rotate X Counterclockwise" ),
|
||||
KiBitmap( rotate_pos_x_xpm ) );
|
||||
|
||||
viewMenu->AppendSeparator();
|
||||
|
||||
AddMenuItem( viewMenu, ID_ROTATE3D_Y_NEG,
|
||||
_( "Rotate Y Clockwise" ),
|
||||
KiBitmap( rotate_neg_y_xpm ) );
|
||||
|
||||
AddMenuItem( viewMenu, ID_ROTATE3D_Y_POS,
|
||||
_( "Rotate Y Counterclockwise" ),
|
||||
KiBitmap( rotate_pos_y_xpm ) );
|
||||
|
||||
viewMenu->AppendSeparator();
|
||||
|
||||
AddMenuItem( viewMenu, ID_ROTATE3D_Z_NEG,
|
||||
_( "Rotate Z Clockwise" ),
|
||||
KiBitmap( rotate_neg_z_xpm ) );
|
||||
|
||||
AddMenuItem( viewMenu, ID_ROTATE3D_Z_POS,
|
||||
_( "Rotate Z Counterclockwise" ),
|
||||
KiBitmap( rotate_pos_z_xpm ) );
|
||||
|
||||
viewMenu->AppendSeparator();
|
||||
|
||||
AddMenuItem( viewMenu, ID_MOVE3D_LEFT,
|
||||
_( "Move left" ),
|
||||
KiBitmap( left_xpm ) );
|
||||
|
||||
AddMenuItem( viewMenu, ID_MOVE3D_RIGHT,
|
||||
_( "Move right" ),
|
||||
KiBitmap( right_xpm ) );
|
||||
|
||||
AddMenuItem( viewMenu, ID_MOVE3D_UP,
|
||||
_( "Move up" ),
|
||||
KiBitmap( up_xpm ) );
|
||||
|
||||
AddMenuItem( viewMenu, ID_MOVE3D_DOWN,
|
||||
_( "Move down" ),
|
||||
KiBitmap( down_xpm ) );
|
||||
|
||||
menuBar->Append( prefsMenu, _( "&Preferences" ) );
|
||||
|
||||
AddMenuItem( prefsMenu, ID_MENU3D_MOUSEWHEEL_PANNING,
|
||||
_( "Use Touchpad to Pan" ),
|
||||
KiBitmap( tools_xpm ), wxITEM_CHECK );
|
||||
|
||||
prefsMenu->AppendSeparator();
|
||||
|
||||
AddMenuItem( prefsMenu, ID_TOOL_SET_VISIBLE_ITEMS,
|
||||
_( "Display Options" ),
|
||||
KiBitmap( read_setup_xpm ) );
|
||||
|
||||
wxMenu * renderEngineList = new wxMenu;
|
||||
AddMenuItem( prefsMenu, renderEngineList, ID_MENU3D_ENGINE,
|
||||
_( "Render Engine" ), KiBitmap( render_mode_xpm ) );
|
||||
|
||||
renderEngineList->AppendRadioItem( ID_MENU3D_ENGINE_OPENGL_LEGACY,
|
||||
_( "OpenGL" ),
|
||||
wxEmptyString );
|
||||
|
||||
renderEngineList->AppendRadioItem( ID_MENU3D_ENGINE_RAYTRACING,
|
||||
_( "Raytracing" ),
|
||||
wxEmptyString );
|
||||
|
||||
renderEngineList->Check( ID_MENU3D_ENGINE_OPENGL_LEGACY,
|
||||
m_settings.RenderEngineGet() == RENDER_ENGINE_OPENGL_LEGACY );
|
||||
|
||||
renderEngineList->Check( ID_MENU3D_ENGINE_RAYTRACING,
|
||||
m_settings.RenderEngineGet() == RENDER_ENGINE_RAYTRACING );
|
||||
|
||||
wxMenu * renderOptionsMenu = new wxMenu;
|
||||
AddMenuItem( prefsMenu, renderOptionsMenu, ID_MENU3D_FL,
|
||||
_( "Render Options" ), KiBitmap( options_3drender_xpm ) );
|
||||
|
||||
wxMenu * materialsList = new wxMenu;
|
||||
AddMenuItem( renderOptionsMenu, materialsList, ID_MENU3D_FL_RENDER_MATERIAL,
|
||||
_( "Material Properties" ), KiBitmap( color_materials_xpm ) );
|
||||
|
||||
materialsList->AppendRadioItem( ID_MENU3D_FL_RENDER_MATERIAL_MODE_NORMAL,
|
||||
_( "Use All Properties" ),
|
||||
_( "Use all material properties from each 3D model file" ) );
|
||||
|
||||
materialsList->AppendRadioItem( ID_MENU3D_FL_RENDER_MATERIAL_MODE_DIFFUSE_ONLY,
|
||||
_( "Use Diffuse Only" ),
|
||||
_( "Use only the diffuse color property from model 3D model file " ) );
|
||||
|
||||
materialsList->AppendRadioItem( ID_MENU3D_FL_RENDER_MATERIAL_MODE_CAD_MODE,
|
||||
_( "CAD Color Style" ),
|
||||
_( "Use a CAD color style based on the diffuse color of the material" ) );
|
||||
|
||||
// Add specific preferences for OpenGL
|
||||
// /////////////////////////////////////////////////////////////////////////
|
||||
wxMenu * renderOptionsMenu_OPENGL = new wxMenu;
|
||||
|
||||
AddMenuItem( renderOptionsMenu, renderOptionsMenu_OPENGL, ID_MENU3D_FL_OPENGL,
|
||||
_( "OpenGL Options" ), KiBitmap( tools_xpm ) );
|
||||
|
||||
AddMenuItem( renderOptionsMenu_OPENGL, ID_MENU3D_FL_OPENGL_RENDER_COPPER_THICKNESS,
|
||||
_( "Show Copper Thickness" ),
|
||||
_( "Shows the copper thickness on copper layers (slower loading)"),
|
||||
KiBitmap( use_3D_copper_thickness_xpm ), wxITEM_CHECK );
|
||||
|
||||
AddMenuItem( renderOptionsMenu_OPENGL, ID_MENU3D_FL_OPENGL_RENDER_SHOW_MODEL_BBOX,
|
||||
_( "Show Model Bounding Boxes" ),
|
||||
KiBitmap( ortho_xpm ), wxITEM_CHECK );
|
||||
|
||||
|
||||
//-- File menu -----------------------------------------------------------
|
||||
//
|
||||
CONDITIONAL_MENU* fileMenu = new CONDITIONAL_MENU( false, tool );
|
||||
// Add specific preferences for Raytracing
|
||||
// /////////////////////////////////////////////////////////////////////////
|
||||
wxMenu * renderOptionsMenu_RAYTRACING = new wxMenu;
|
||||
AddMenuItem( renderOptionsMenu, renderOptionsMenu_RAYTRACING, ID_MENU3D_FL_RAYTRACING,
|
||||
_( "Raytracing Options" ), KiBitmap( tools_xpm ) );
|
||||
|
||||
fileMenu->AddItem( ID_MENU_SCREENCOPY_PNG, _( "Export Current View as PNG..." ), "",
|
||||
export_xpm, SELECTION_CONDITIONS::ShowAlways );
|
||||
AddMenuItem( renderOptionsMenu_RAYTRACING, ID_MENU3D_FL_RAYTRACING_RENDER_SHADOWS,
|
||||
_( "Render Shadows" ),
|
||||
KiBitmap( green_xpm ), wxITEM_CHECK );
|
||||
|
||||
fileMenu->AddItem( ID_MENU_SCREENCOPY_JPEG, _( "Export Current View as JPEG..." ), "",
|
||||
export_xpm, SELECTION_CONDITIONS::ShowAlways );
|
||||
|
||||
fileMenu->AddSeparator();
|
||||
fileMenu->AddClose( _( "3D Viewer" ) );
|
||||
|
||||
fileMenu->Resolve();
|
||||
|
||||
//-- Edit menu -------------------------------------------------------
|
||||
//
|
||||
CONDITIONAL_MENU* editMenu = new CONDITIONAL_MENU( false, tool );
|
||||
|
||||
editMenu->AddItem( ID_TOOL_SCREENCOPY_TOCLIBBOARD, _( "Copy 3D Image" ), "",
|
||||
copy_xpm, SELECTION_CONDITIONS::ShowAlways );
|
||||
|
||||
editMenu->Resolve();
|
||||
|
||||
//-- View menu -------------------------------------------------------
|
||||
//
|
||||
CONDITIONAL_MENU* viewMenu = new CONDITIONAL_MENU( false, tool );
|
||||
|
||||
viewMenu->AddItem( ID_ZOOM_IN, _( "Zoom In\tF1" ), HELP_ZOOM_IN,
|
||||
zoom_in_xpm, SELECTION_CONDITIONS::ShowAlways );
|
||||
|
||||
viewMenu->AddItem( ID_ZOOM_OUT, _( "Zoom Out\tF2" ), HELP_ZOOM_OUT,
|
||||
zoom_out_xpm, SELECTION_CONDITIONS::ShowAlways );
|
||||
|
||||
viewMenu->AddItem( ID_ZOOM_PAGE, _( "Zoom to Fit" ), HELP_ZOOM_FIT,
|
||||
zoom_fit_in_page_xpm, SELECTION_CONDITIONS::ShowAlways );
|
||||
|
||||
viewMenu->AddItem( ID_ZOOM_REDRAW, _( "Redraw\tR" ), HELP_ZOOM_REDRAW,
|
||||
zoom_redraw_xpm, SELECTION_CONDITIONS::ShowAlways );
|
||||
|
||||
viewMenu->AddSeparator();
|
||||
viewMenu->AddItem( ID_ROTATE3D_X_NEG, _( "Rotate X Clockwise\tShift+X" ), "",
|
||||
rotate_neg_x_xpm, SELECTION_CONDITIONS::ShowAlways );
|
||||
|
||||
viewMenu->AddItem( ID_ROTATE3D_X_POS, _( "Rotate X Counterclockwise\tX" ), "",
|
||||
rotate_pos_x_xpm, SELECTION_CONDITIONS::ShowAlways );
|
||||
|
||||
viewMenu->AddSeparator();
|
||||
viewMenu->AddItem( ID_ROTATE3D_Y_NEG, _( "Rotate Y Clockwise\tShift+Y" ), "",
|
||||
rotate_neg_y_xpm, SELECTION_CONDITIONS::ShowAlways );
|
||||
|
||||
viewMenu->AddItem( ID_ROTATE3D_Y_POS, _( "Rotate Y Counterclockwise\tY" ), "",
|
||||
rotate_pos_y_xpm, SELECTION_CONDITIONS::ShowAlways );
|
||||
|
||||
viewMenu->AddSeparator();
|
||||
viewMenu->AddItem( ID_ROTATE3D_Z_NEG, _( "Rotate Z Clockwise\tShift+Z" ), "",
|
||||
rotate_neg_z_xpm, SELECTION_CONDITIONS::ShowAlways );;
|
||||
|
||||
viewMenu->AddItem( ID_ROTATE3D_Z_POS, _( "Rotate Z Counterclockwise\tZ" ), "",
|
||||
rotate_pos_z_xpm, SELECTION_CONDITIONS::ShowAlways );
|
||||
|
||||
viewMenu->AddSeparator();
|
||||
viewMenu->AddItem( ID_MOVE3D_LEFT, _( "Move Left\tLeft" ), "",
|
||||
left_xpm, SELECTION_CONDITIONS::ShowAlways );
|
||||
|
||||
viewMenu->AddItem( ID_MOVE3D_RIGHT, _( "Move Right\tRight" ), "",
|
||||
right_xpm, SELECTION_CONDITIONS::ShowAlways );
|
||||
|
||||
viewMenu->AddItem( ID_MOVE3D_UP, _( "Move Up\tUp" ), "",
|
||||
up_xpm, SELECTION_CONDITIONS::ShowAlways );
|
||||
|
||||
viewMenu->AddItem( ID_MOVE3D_DOWN, _( "Move Down\tDown" ), "",
|
||||
down_xpm, SELECTION_CONDITIONS::ShowAlways );
|
||||
|
||||
viewMenu->Resolve();
|
||||
|
||||
//-- Preferences menu -----------------------------------------------
|
||||
//
|
||||
CONDITIONAL_MENU* prefsMenu = new CONDITIONAL_MENU( false, tool );
|
||||
|
||||
auto raytracingCondition = [ this ] ( const SELECTION& aSel ) {
|
||||
return m_settings.RenderEngineGet() != RENDER_ENGINE_OPENGL_LEGACY;
|
||||
};
|
||||
auto NormalModeCondition = [ this ] ( const SELECTION& aSel ) {
|
||||
return m_settings.MaterialModeGet() == MATERIAL_MODE_NORMAL;
|
||||
};
|
||||
auto DiffuseModeCondition = [ this ] ( const SELECTION& aSel ) {
|
||||
return m_settings.MaterialModeGet() == MATERIAL_MODE_DIFFUSE_ONLY;
|
||||
};
|
||||
auto CADModeCondition = [ this ] ( const SELECTION& aSel ) {
|
||||
return m_settings.MaterialModeGet() == MATERIAL_MODE_CAD_MODE;
|
||||
};
|
||||
auto copperThicknessCondition = [ this ] ( const SELECTION& aSel ) {
|
||||
return m_settings.GetFlag( FL_RENDER_OPENGL_COPPER_THICKNESS );
|
||||
};
|
||||
auto boundingBoxesCondition = [ this ] ( const SELECTION& aSel ) {
|
||||
return m_settings.GetFlag( FL_RENDER_OPENGL_SHOW_MODEL_BBOX );
|
||||
};
|
||||
auto renderShadowsCondition = [ this ] ( const SELECTION& aSel ) {
|
||||
return m_settings.GetFlag( FL_RENDER_RAYTRACING_SHADOWS );
|
||||
};
|
||||
auto proceduralTexturesCondition = [ this ] ( const SELECTION& aSel ) {
|
||||
return m_settings.GetFlag( FL_RENDER_RAYTRACING_PROCEDURAL_TEXTURES );
|
||||
};
|
||||
auto showFloorCondition = [ this ] ( const SELECTION& aSel ) {
|
||||
return m_settings.GetFlag( FL_RENDER_RAYTRACING_BACKFLOOR );
|
||||
};
|
||||
auto useRefractionsCondition = [ this ] ( const SELECTION& aSel ) {
|
||||
return m_settings.GetFlag( FL_RENDER_RAYTRACING_REFRACTIONS );
|
||||
};
|
||||
auto useReflectionsCondition = [ this ] ( const SELECTION& aSel ) {
|
||||
return m_settings.GetFlag( FL_RENDER_RAYTRACING_REFLECTIONS );
|
||||
};
|
||||
auto antiAliasingCondition = [ this ] ( const SELECTION& aSel ) {
|
||||
return m_settings.GetFlag( FL_RENDER_RAYTRACING_ANTI_ALIASING );
|
||||
};
|
||||
auto postProcessCondition = [ this ] ( const SELECTION& aSel ) {
|
||||
return m_settings.GetFlag( FL_RENDER_RAYTRACING_POST_PROCESSING );
|
||||
};
|
||||
auto showAxesCondition = [ this ] ( const SELECTION& aSel ) {
|
||||
return m_settings.GetFlag( FL_AXIS );
|
||||
};
|
||||
|
||||
prefsMenu->AddItem( ID_TOOL_SET_VISIBLE_ITEMS, _( "Display Options" ), "",
|
||||
read_setup_xpm, SELECTION_CONDITIONS::ShowAlways );
|
||||
|
||||
prefsMenu->AddCheckItem( ID_RENDER_CURRENT_VIEW, _( "Raytracing" ), "",
|
||||
tools_xpm, raytracingCondition );
|
||||
|
||||
// Render options submenu
|
||||
CONDITIONAL_MENU* optsSubmenu = new CONDITIONAL_MENU( false, tool );
|
||||
optsSubmenu->SetTitle( _( "Render Options" ) );
|
||||
optsSubmenu->SetIcon( options_3drender_xpm );
|
||||
|
||||
// Material properties submenu
|
||||
CONDITIONAL_MENU* propsSubmenu = new CONDITIONAL_MENU( false, tool );
|
||||
propsSubmenu->SetTitle( _( "Material Properties" ) );
|
||||
propsSubmenu->SetIcon( color_materials_xpm );
|
||||
|
||||
propsSubmenu->AddCheckItem( ID_MENU3D_FL_RENDER_MATERIAL_MODE_NORMAL,
|
||||
_( "Use All Properties" ),
|
||||
_( "Use all material properties from each 3D model file" ),
|
||||
nullptr, NormalModeCondition );
|
||||
|
||||
propsSubmenu->AddCheckItem( ID_MENU3D_FL_RENDER_MATERIAL_MODE_DIFFUSE_ONLY,
|
||||
_( "Use Diffuse Only" ),
|
||||
_( "Use only the diffuse color property from model 3D model file" ),
|
||||
nullptr, DiffuseModeCondition );
|
||||
|
||||
propsSubmenu->AddCheckItem( ID_MENU3D_FL_RENDER_MATERIAL_MODE_CAD_MODE,
|
||||
_( "CAD Color Style" ),
|
||||
_( "Use a CAD color style based on the diffuse color of the material" ),
|
||||
nullptr, CADModeCondition );
|
||||
|
||||
optsSubmenu->AddMenu( propsSubmenu, SELECTION_CONDITIONS::ShowAlways );
|
||||
|
||||
optsSubmenu->AddCheckItem( ID_MENU3D_FL_OPENGL_RENDER_COPPER_THICKNESS,
|
||||
_( "Show Copper Thickness" ),
|
||||
_( "Shows the copper thickness on copper layers (slower loading)" ),
|
||||
use_3D_copper_thickness_xpm, copperThicknessCondition );
|
||||
|
||||
optsSubmenu->AddCheckItem( ID_MENU3D_FL_OPENGL_RENDER_SHOW_MODEL_BBOX,
|
||||
_( "Show Model Bounding Boxes" ), "",
|
||||
ortho_xpm, boundingBoxesCondition );
|
||||
|
||||
// Raytracing submenu
|
||||
CONDITIONAL_MENU* raySubmenu = new CONDITIONAL_MENU( false, tool );
|
||||
raySubmenu->SetTitle( _( "Raytracing Options" ) );
|
||||
raySubmenu->SetIcon( tools_xpm );
|
||||
|
||||
raySubmenu->AddCheckItem( ID_MENU3D_FL_RAYTRACING_RENDER_SHADOWS,
|
||||
_( "Render Shadows" ), "",
|
||||
green_xpm, renderShadowsCondition );
|
||||
|
||||
raySubmenu->AddCheckItem( ID_MENU3D_FL_RAYTRACING_PROCEDURAL_TEXTURES,
|
||||
AddMenuItem( renderOptionsMenu_RAYTRACING, ID_MENU3D_FL_RAYTRACING_PROCEDURAL_TEXTURES,
|
||||
_( "Procedural Textures" ),
|
||||
_( "Apply procedural textures to materials (slow)"),
|
||||
green_xpm, proceduralTexturesCondition );
|
||||
KiBitmap( green_xpm ), wxITEM_CHECK );
|
||||
|
||||
raySubmenu->AddCheckItem( ID_MENU3D_FL_RAYTRACING_BACKFLOOR,
|
||||
AddMenuItem( renderOptionsMenu_RAYTRACING, ID_MENU3D_FL_RAYTRACING_BACKFLOOR,
|
||||
_( "Add Floor" ),
|
||||
_( "Adds a floor plane below the board (slow)"),
|
||||
green_xpm, showFloorCondition );
|
||||
KiBitmap( green_xpm ), wxITEM_CHECK );
|
||||
|
||||
raySubmenu->AddCheckItem( ID_MENU3D_FL_RAYTRACING_REFRACTIONS,
|
||||
AddMenuItem( renderOptionsMenu_RAYTRACING, ID_MENU3D_FL_RAYTRACING_REFRACTIONS,
|
||||
_( "Refractions" ),
|
||||
_( "Render materials with refractions properties on final render (slow)"),
|
||||
green_xpm, useRefractionsCondition );
|
||||
KiBitmap( green_xpm ), wxITEM_CHECK );
|
||||
|
||||
raySubmenu->AddCheckItem( ID_MENU3D_FL_RAYTRACING_REFLECTIONS,
|
||||
AddMenuItem( renderOptionsMenu_RAYTRACING, ID_MENU3D_FL_RAYTRACING_REFLECTIONS,
|
||||
_( "Reflections" ),
|
||||
_( "Render materials with reflections properties on final render (slow)"),
|
||||
green_xpm, useReflectionsCondition );
|
||||
KiBitmap( green_xpm ), wxITEM_CHECK );
|
||||
|
||||
raySubmenu->AddCheckItem( ID_MENU3D_FL_RAYTRACING_ANTI_ALIASING,
|
||||
AddMenuItem( renderOptionsMenu_RAYTRACING, ID_MENU3D_FL_RAYTRACING_ANTI_ALIASING,
|
||||
_( "Anti-aliasing" ),
|
||||
_( "Render with improved quality on final render (slow)"),
|
||||
green_xpm, antiAliasingCondition );
|
||||
KiBitmap( green_xpm ), wxITEM_CHECK );
|
||||
|
||||
raySubmenu->AddCheckItem( ID_MENU3D_FL_RAYTRACING_POST_PROCESSING,
|
||||
AddMenuItem( renderOptionsMenu_RAYTRACING, ID_MENU3D_FL_RAYTRACING_POST_PROCESSING,
|
||||
_( "Post-processing" ),
|
||||
_( "Apply Screen Space Ambient Occlusion and Global Illumination reflections on final render (slow)"),
|
||||
green_xpm, postProcessCondition );
|
||||
KiBitmap( green_xpm ), wxITEM_CHECK );
|
||||
|
||||
optsSubmenu->AddMenu( raySubmenu, SELECTION_CONDITIONS::ShowAlways );
|
||||
prefsMenu->AddMenu( optsSubmenu, SELECTION_CONDITIONS::ShowAlways );
|
||||
prefsMenu->AppendSeparator();
|
||||
|
||||
prefsMenu->AddSeparator();
|
||||
|
||||
// Color submenu
|
||||
CONDITIONAL_MENU* colorSubmenu = new CONDITIONAL_MENU( false, tool );
|
||||
colorSubmenu->SetTitle( _( "Choose Colors" ) );
|
||||
colorSubmenu->SetIcon( palette_xpm );
|
||||
// Colors, axis and grid elements
|
||||
// /////////////////////////////////////////////////////////////////////////
|
||||
|
||||
colorSubmenu->AddItem( ID_MENU3D_BGCOLOR_TOP, _( "Background Top Color..." ), "",
|
||||
setcolor_3d_bg_xpm, SELECTION_CONDITIONS::ShowAlways );
|
||||
// Add submenu set Colors
|
||||
wxMenu * setColorMenu = new wxMenu;
|
||||
AddMenuItem( prefsMenu, setColorMenu, ID_MENU3D_COLOR,
|
||||
_( "Choose Colors" ), KiBitmap( palette_xpm ) );
|
||||
|
||||
colorSubmenu->AddItem( ID_MENU3D_BGCOLOR_BOTTOM, _( "Background Bottom Color..." ), "",
|
||||
setcolor_3d_bg_xpm, SELECTION_CONDITIONS::ShowAlways );
|
||||
wxMenu * setBgColorMenu = new wxMenu;
|
||||
AddMenuItem( setColorMenu, setBgColorMenu, ID_MENU3D_BGCOLOR,
|
||||
_( "Background Color" ), KiBitmap( palette_xpm ) );
|
||||
|
||||
colorSubmenu->AddItem( ID_MENU3D_SILKSCREEN_COLOR, _( "Silkscreen Color..." ), "",
|
||||
setcolor_silkscreen_xpm, SELECTION_CONDITIONS::ShowAlways );
|
||||
AddMenuItem( setBgColorMenu, ID_MENU3D_BGCOLOR_TOP_SELECTION,
|
||||
_( "Background Top Color..." ), KiBitmap( setcolor_3d_bg_xpm ) );
|
||||
|
||||
colorSubmenu->AddItem( ID_MENU3D_SOLDERMASK_COLOR, _( "Solder Mask Color..." ), "",
|
||||
setcolor_soldermask_xpm, SELECTION_CONDITIONS::ShowAlways );
|
||||
AddMenuItem( setBgColorMenu, ID_MENU3D_BGCOLOR_BOTTOM_SELECTION,
|
||||
_( "Background Bottom Color..." ), KiBitmap( setcolor_3d_bg_xpm ) );
|
||||
|
||||
colorSubmenu->AddItem( ID_MENU3D_SOLDERPASTE_COLOR, _( "Solder Paste Color..." ), "",
|
||||
setcolor_solderpaste_xpm, SELECTION_CONDITIONS::ShowAlways );
|
||||
AddMenuItem( setColorMenu, ID_MENU3D_SILKSCREEN_COLOR_SELECTION,
|
||||
_( "Silkscreen Color..." ), KiBitmap( setcolor_silkscreen_xpm ) );
|
||||
|
||||
colorSubmenu->AddItem( ID_MENU3D_COPPER_COLOR, _( "Copper/Surface Finish Color..." ), "",
|
||||
setcolor_copper_xpm, SELECTION_CONDITIONS::ShowAlways );
|
||||
AddMenuItem( setColorMenu, ID_MENU3D_SOLDERMASK_COLOR_SELECTION,
|
||||
_( "Solder Mask Color..." ), KiBitmap( setcolor_soldermask_xpm ) );
|
||||
|
||||
colorSubmenu->AddItem( ID_MENU3D_PCB_BODY_COLOR, _( "Board Body Color..." ), "",
|
||||
setcolor_board_body_xpm, SELECTION_CONDITIONS::ShowAlways );
|
||||
AddMenuItem( setColorMenu, ID_MENU3D_SOLDERPASTE_COLOR_SELECTION,
|
||||
_( "Solder Paste Color..." ), KiBitmap( setcolor_solderpaste_xpm ) );
|
||||
|
||||
prefsMenu->AddMenu( colorSubmenu );
|
||||
AddMenuItem( setColorMenu, ID_MENU3D_COPPER_COLOR_SELECTION,
|
||||
_( "Copper/Surface Finish Color..." ), KiBitmap( setcolor_copper_xpm ) );
|
||||
|
||||
prefsMenu->AddCheckItem( ID_MENU3D_AXIS_ONOFF, _( "Show 3D &Axis" ), "",
|
||||
axis3d_front_xpm, showAxesCondition );
|
||||
AddMenuItem( setColorMenu, ID_MENU3D_PCB_BODY_COLOR_SELECTION,
|
||||
_( "Board Body Color..." ), KiBitmap( setcolor_board_body_xpm ) );
|
||||
|
||||
// Grid submenu
|
||||
CONDITIONAL_MENU* gridSubmenu = new CONDITIONAL_MENU( false, tool );
|
||||
gridSubmenu->SetTitle( _( "3D Grid" ) );
|
||||
gridSubmenu->SetIcon( grid_xpm );
|
||||
AddMenuItem( prefsMenu, ID_MENU3D_AXIS_ONOFF,
|
||||
_( "Show 3D &Axis" ), KiBitmap( axis3d_front_xpm ), wxITEM_CHECK );
|
||||
|
||||
auto noGridCondition = [ this ] ( const SELECTION& aSel ) {
|
||||
return m_settings.GridGet() == GRID3D_NONE;
|
||||
};
|
||||
auto grid10mmCondition = [ this ] ( const SELECTION& aSel ) {
|
||||
return m_settings.GridGet() == GRID3D_10MM;
|
||||
};
|
||||
auto grid5mmCondition = [ this ] ( const SELECTION& aSel ) {
|
||||
return m_settings.GridGet() == GRID3D_5MM;
|
||||
};
|
||||
auto grid2p5mmCondition = [ this ] ( const SELECTION& aSel ) {
|
||||
return m_settings.GridGet() == GRID3D_2P5MM;
|
||||
};
|
||||
auto grid_1mmCondition = [ this ] ( const SELECTION& aSel ) {
|
||||
return m_settings.GridGet() == GRID3D_1MM;
|
||||
};
|
||||
|
||||
gridSubmenu->AddCheckItem( ID_MENU3D_GRID_NOGRID, _( "No 3D Grid" ), "",
|
||||
nullptr, noGridCondition );
|
||||
gridSubmenu->AddCheckItem( ID_MENU3D_GRID_10_MM, _( "3D Grid 10mm" ), "",
|
||||
nullptr, grid10mmCondition );
|
||||
gridSubmenu->AddCheckItem( ID_MENU3D_GRID_5_MM, _( "3D Grid 5mm" ), "",
|
||||
nullptr, grid5mmCondition );
|
||||
gridSubmenu->AddCheckItem( ID_MENU3D_GRID_2P5_MM, _( "3D Grid 2.5mm" ), "",
|
||||
nullptr, grid2p5mmCondition );
|
||||
gridSubmenu->AddCheckItem( ID_MENU3D_GRID_1_MM, _( "3D Grid 1mm" ), "",
|
||||
nullptr, grid_1mmCondition );
|
||||
// Creates grid menu
|
||||
// /////////////////////////////////////////////////////////////////////////
|
||||
|
||||
prefsMenu->AddMenu( gridSubmenu, SELECTION_CONDITIONS::ShowAlways );
|
||||
wxMenu * gridlistMenu = new wxMenu;
|
||||
AddMenuItem( prefsMenu, gridlistMenu, ID_MENU3D_GRID,
|
||||
_( "3D Grid" ), KiBitmap( grid_xpm ) );
|
||||
gridlistMenu->AppendRadioItem( ID_MENU3D_GRID_NOGRID, _( "No 3D Grid" ), wxEmptyString );
|
||||
gridlistMenu->AppendRadioItem( ID_MENU3D_GRID_10_MM, _( "3D Grid 10 mm" ), wxEmptyString );
|
||||
gridlistMenu->AppendRadioItem( ID_MENU3D_GRID_5_MM, _( "3D Grid 5 mm" ), wxEmptyString );
|
||||
gridlistMenu->AppendRadioItem( ID_MENU3D_GRID_2P5_MM, _( "3D Grid 2.5 mm" ), wxEmptyString );
|
||||
gridlistMenu->AppendRadioItem( ID_MENU3D_GRID_1_MM, _( "3D Grid 1 mm" ), wxEmptyString );
|
||||
|
||||
prefsMenu->AddSeparator();
|
||||
prefsMenu->AddItem( ID_MENU3D_RESET_DEFAULTS, _( "Reset to Default Settings" ), "",
|
||||
tools_xpm, SELECTION_CONDITIONS::ShowAlways );
|
||||
// If the grid is on, check the corresponding menuitem showing the grid size
|
||||
if( m_settings.GridGet() != GRID3D_NONE )
|
||||
{
|
||||
gridlistMenu->Check( ID_MENU3D_GRID_10_MM, m_settings.GridGet() == GRID3D_10MM );
|
||||
gridlistMenu->Check( ID_MENU3D_GRID_5_MM, m_settings.GridGet() == GRID3D_5MM );
|
||||
gridlistMenu->Check( ID_MENU3D_GRID_2P5_MM, m_settings.GridGet() == GRID3D_2P5MM );
|
||||
gridlistMenu->Check( ID_MENU3D_GRID_1_MM, m_settings.GridGet() == GRID3D_1MM );
|
||||
}
|
||||
else
|
||||
gridlistMenu->Check( ID_MENU3D_GRID_NOGRID, true );
|
||||
|
||||
#ifdef __APPLE__ // Note: will get moved to Apple menu by wxWidgets
|
||||
prefsMenu->AddItem( wxID_PREFERENCES,
|
||||
_( "Preferences...\tCTRL+," ),
|
||||
_( "Show preferences for all open tools" ),
|
||||
preference_xpm, SELECTION_CONDITIONS::ShowAlways );
|
||||
#endif
|
||||
// Reset options
|
||||
// /////////////////////////////////////////////////////////////////////////
|
||||
prefsMenu->AppendSeparator();
|
||||
|
||||
prefsMenu->Resolve();
|
||||
AddMenuItem( prefsMenu, ID_MENU3D_RESET_DEFAULTS,
|
||||
_( "Reset to Default Settings" ),
|
||||
KiBitmap( tools_xpm ) );
|
||||
|
||||
//-- Menubar -------------------------------------------------------------
|
||||
//
|
||||
menuBar->Append( fileMenu, _( "&File" ) );
|
||||
menuBar->Append( editMenu, _( "&Edit" ) );
|
||||
menuBar->Append( viewMenu, _( "&View" ) );
|
||||
menuBar->Append( prefsMenu, _( "&Preferences" ) );
|
||||
AddStandardHelpMenu( menuBar );
|
||||
// Help menu
|
||||
// /////////////////////////////////////////////////////////////////////////
|
||||
menuBar->Append( helpMenu, _( "&Help" ) );
|
||||
|
||||
AddMenuItem( helpMenu, wxID_HELP,
|
||||
_( "Pcbnew &Manual" ),
|
||||
_( "Open Pcbnew Manual" ),
|
||||
KiBitmap( online_help_xpm ) );
|
||||
|
||||
AddMenuItem( helpMenu, wxID_INDEX,
|
||||
_( "&Getting Started in KiCad" ),
|
||||
_( "Open \"Getting Started in KiCad\" guide for beginners" ),
|
||||
KiBitmap( help_xpm ) );
|
||||
|
||||
wxString text = AddHotkeyName( _( "&List Hotkeys..." ), g_3DViewer_Hokeys_Descr, HK_HELP );
|
||||
AddMenuItem( helpMenu, ID_MENU3D_HELP_HOTKEY_SHOW_CURRENT_LIST,
|
||||
text,
|
||||
_( "Displays the current hotkeys list and corresponding commands" ),
|
||||
KiBitmap( hotkeys_xpm ) );
|
||||
|
||||
helpMenu->AppendSeparator();
|
||||
|
||||
AddMenuItem( helpMenu, ID_HELP_GET_INVOLVED,
|
||||
_( "Get &Involved" ),
|
||||
_( "Contribute to KiCad (opens a web browser)" ),
|
||||
KiBitmap( info_xpm ) );
|
||||
|
||||
helpMenu->AppendSeparator();
|
||||
|
||||
AddMenuItem( helpMenu, wxID_ABOUT,
|
||||
_( "&About KiCad" ),
|
||||
_( "Display KiCad About dialog" ),
|
||||
KiBitmap( about_xpm ) );
|
||||
|
||||
SetMenuBar( menuBar );
|
||||
SetMenuBarOptionsState();
|
||||
}
|
||||
|
||||
|
||||
void EDA_3D_VIEWER::SetMenuBarOptionsState()
|
||||
{
|
||||
wxLogTrace( m_logTrace, wxT( "EDA_3D_VIEWER::SetMenuBarOptionsState" ) );
|
||||
|
||||
wxMenuBar* menuBar = GetMenuBar();
|
||||
|
||||
if( menuBar == NULL )
|
||||
{
|
||||
wxLogTrace( m_logTrace, wxT( "EDA_3D_VIEWER::SetMenuBarOptionsState menuBar == NULL" ) );
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
wxMenuItem* item;
|
||||
// Set the state of toggle menus according to the current display options
|
||||
item = menuBar->FindItem( ID_MENU3D_MOUSEWHEEL_PANNING );
|
||||
item->Check( m_settings.GetFlag( FL_MOUSEWHEEL_PANNING ) );
|
||||
|
||||
|
||||
item = menuBar->FindItem( ID_MENU3D_ENGINE_OPENGL_LEGACY );
|
||||
item->Check( m_settings.RenderEngineGet() == RENDER_ENGINE_OPENGL_LEGACY );
|
||||
|
||||
item = menuBar->FindItem( ID_MENU3D_ENGINE_RAYTRACING );
|
||||
item->Check( m_settings.RenderEngineGet() == RENDER_ENGINE_RAYTRACING );
|
||||
|
||||
item = menuBar->FindItem( ID_MENU3D_FL_RENDER_MATERIAL_MODE_NORMAL );
|
||||
item->Check( m_settings.MaterialModeGet() == MATERIAL_MODE_NORMAL );
|
||||
|
||||
item = menuBar->FindItem( ID_MENU3D_FL_RENDER_MATERIAL_MODE_DIFFUSE_ONLY );
|
||||
item->Check( m_settings.MaterialModeGet() == MATERIAL_MODE_DIFFUSE_ONLY );
|
||||
|
||||
item = menuBar->FindItem( ID_MENU3D_FL_RENDER_MATERIAL_MODE_CAD_MODE );
|
||||
item->Check( m_settings.MaterialModeGet() == MATERIAL_MODE_CAD_MODE );
|
||||
|
||||
// OpenGL
|
||||
item = menuBar->FindItem( ID_MENU3D_FL_OPENGL_RENDER_COPPER_THICKNESS );
|
||||
item->Check( m_settings.GetFlag( FL_RENDER_OPENGL_COPPER_THICKNESS ) );
|
||||
|
||||
item = menuBar->FindItem( ID_MENU3D_FL_OPENGL_RENDER_SHOW_MODEL_BBOX );
|
||||
item->Check( m_settings.GetFlag( FL_RENDER_OPENGL_SHOW_MODEL_BBOX ) );
|
||||
|
||||
// Raytracing
|
||||
item = menuBar->FindItem( ID_MENU3D_FL_RAYTRACING_RENDER_SHADOWS );
|
||||
item->Check( m_settings.GetFlag( FL_RENDER_RAYTRACING_SHADOWS ) );
|
||||
|
||||
item = menuBar->FindItem( ID_MENU3D_FL_RAYTRACING_BACKFLOOR );
|
||||
item->Check( m_settings.GetFlag( FL_RENDER_RAYTRACING_BACKFLOOR ) );
|
||||
|
||||
item = menuBar->FindItem( ID_MENU3D_FL_RAYTRACING_REFRACTIONS );
|
||||
item->Check( m_settings.GetFlag( FL_RENDER_RAYTRACING_REFRACTIONS ) );
|
||||
|
||||
item = menuBar->FindItem( ID_MENU3D_FL_RAYTRACING_REFLECTIONS );
|
||||
item->Check( m_settings.GetFlag( FL_RENDER_RAYTRACING_REFLECTIONS ) );
|
||||
|
||||
item = menuBar->FindItem( ID_MENU3D_FL_RAYTRACING_POST_PROCESSING );
|
||||
item->Check( m_settings.GetFlag( FL_RENDER_RAYTRACING_POST_PROCESSING ) );
|
||||
|
||||
item = menuBar->FindItem( ID_MENU3D_FL_RAYTRACING_ANTI_ALIASING );
|
||||
item->Check( m_settings.GetFlag( FL_RENDER_RAYTRACING_ANTI_ALIASING ) );
|
||||
|
||||
item = menuBar->FindItem( ID_MENU3D_FL_RAYTRACING_PROCEDURAL_TEXTURES );
|
||||
item->Check( m_settings.GetFlag( FL_RENDER_RAYTRACING_PROCEDURAL_TEXTURES ) );
|
||||
|
||||
|
||||
item = menuBar->FindItem( ID_MENU3D_AXIS_ONOFF );
|
||||
item->Check( m_settings.GetFlag( FL_AXIS ) );
|
||||
|
||||
}
|
||||
|
||||
@@ -4,7 +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) 1992-2019 KiCad Developers, see AUTHORS.txt for contributors.
|
||||
* Copyright (C) 1992-2018 KiCad Developers, see AUTHORS.txt for contributors.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
@@ -38,113 +38,103 @@
|
||||
|
||||
void EDA_3D_VIEWER::ReCreateMainToolbar()
|
||||
{
|
||||
wxLogTrace( m_logTrace, "EDA_3D_VIEWER::ReCreateMainToolbar" );
|
||||
wxLogTrace( m_logTrace, wxT( "EDA_3D_VIEWER::ReCreateMainToolbar" ) );
|
||||
|
||||
wxWindowUpdateLocker dummy( this );
|
||||
if( m_mainToolBar != NULL )
|
||||
{
|
||||
// Simple update to the list of old files.
|
||||
SetToolbars();
|
||||
return;
|
||||
}
|
||||
|
||||
if( m_mainToolBar )
|
||||
{
|
||||
m_mainToolBar->Clear();
|
||||
}
|
||||
else
|
||||
{
|
||||
m_mainToolBar = new wxAuiToolBar( this, ID_H_TOOLBAR, wxDefaultPosition, wxDefaultSize,
|
||||
KICAD_AUI_TB_STYLE | wxAUI_TB_HORZ_LAYOUT );
|
||||
}
|
||||
m_mainToolBar = new wxAuiToolBar( this, ID_H_TOOLBAR, wxDefaultPosition, wxDefaultSize,
|
||||
KICAD_AUI_TB_STYLE | wxAUI_TB_HORZ_LAYOUT );
|
||||
|
||||
// Set up toolbar
|
||||
m_mainToolBar->AddTool( ID_RELOAD3D_BOARD, wxEmptyString,
|
||||
KiScaledBitmap( import3d_xpm, this ), _( "Reload board" ) );
|
||||
KiBitmap( import3d_xpm ), _( "Reload board" ) );
|
||||
|
||||
KiScaledSeparator( m_mainToolBar, this );
|
||||
m_mainToolBar->AddSeparator();
|
||||
|
||||
m_mainToolBar->AddTool( ID_TOOL_SCREENCOPY_TOCLIBBOARD, wxEmptyString,
|
||||
KiScaledBitmap( copy_xpm, this ),
|
||||
KiBitmap( copy_xpm ),
|
||||
_( "Copy 3D image to clipboard" ) );
|
||||
|
||||
KiScaledSeparator( m_mainToolBar, this );
|
||||
m_mainToolBar->AddSeparator();
|
||||
|
||||
m_mainToolBar->AddTool( ID_TOOL_SET_VISIBLE_ITEMS, wxEmptyString,
|
||||
KiScaledBitmap( read_setup_xpm, this ),
|
||||
KiBitmap( read_setup_xpm ),
|
||||
_( "Set display options, and some layers visibility" ) );
|
||||
m_mainToolBar->AddSeparator();
|
||||
|
||||
m_mainToolBar->AddTool( ID_RENDER_CURRENT_VIEW, wxEmptyString,
|
||||
KiScaledBitmap( render_mode_xpm, this ),
|
||||
_( "Render current view using Raytracing" ), wxITEM_CHECK );
|
||||
KiBitmap( render_mode_xpm ),
|
||||
_( "Render current view using Raytracing" ) );
|
||||
|
||||
KiScaledSeparator( m_mainToolBar, this );
|
||||
m_mainToolBar->AddSeparator();
|
||||
|
||||
m_mainToolBar->AddTool( ID_ZOOM_IN, wxEmptyString,
|
||||
KiScaledBitmap( zoom_in_xpm, this ),
|
||||
m_mainToolBar->AddTool( ID_ZOOM_IN, wxEmptyString, KiBitmap( zoom_in_xpm ),
|
||||
_( "Zoom in" ) );
|
||||
|
||||
m_mainToolBar->AddTool( ID_ZOOM_OUT, wxEmptyString,
|
||||
KiScaledBitmap( zoom_out_xpm, this ),
|
||||
m_mainToolBar->AddTool( ID_ZOOM_OUT, wxEmptyString, KiBitmap( zoom_out_xpm ),
|
||||
_( "Zoom out" ) );
|
||||
|
||||
m_mainToolBar->AddTool( ID_ZOOM_REDRAW, wxEmptyString,
|
||||
KiScaledBitmap( zoom_redraw_xpm, this ),
|
||||
KiBitmap( zoom_redraw_xpm ),
|
||||
_( "Redraw view" ) );
|
||||
|
||||
m_mainToolBar->AddTool( ID_ZOOM_PAGE, wxEmptyString,
|
||||
KiScaledBitmap( zoom_fit_in_page_xpm, this ),
|
||||
m_mainToolBar->AddTool( ID_ZOOM_PAGE, wxEmptyString, KiBitmap( zoom_fit_in_page_xpm ),
|
||||
_( "Zoom to fit 3D model" ) );
|
||||
|
||||
KiScaledSeparator( m_mainToolBar, this );
|
||||
|
||||
m_mainToolBar->AddSeparator();
|
||||
m_mainToolBar->AddTool( ID_ROTATE3D_X_NEG, wxEmptyString,
|
||||
KiScaledBitmap( rotate_neg_x_xpm, this ),
|
||||
KiBitmap( rotate_neg_x_xpm ),
|
||||
_( "Rotate X Clockwise" ) );
|
||||
|
||||
m_mainToolBar->AddTool( ID_ROTATE3D_X_POS, wxEmptyString,
|
||||
KiScaledBitmap( rotate_pos_x_xpm, this ),
|
||||
KiBitmap( rotate_pos_x_xpm ),
|
||||
_( "Rotate X Counterclockwise" ) );
|
||||
|
||||
KiScaledSeparator( m_mainToolBar, this );
|
||||
|
||||
m_mainToolBar->AddSeparator();
|
||||
m_mainToolBar->AddTool( ID_ROTATE3D_Y_NEG, wxEmptyString,
|
||||
KiScaledBitmap( rotate_neg_y_xpm, this ),
|
||||
KiBitmap( rotate_neg_y_xpm ),
|
||||
_( "Rotate Y Clockwise" ) );
|
||||
|
||||
m_mainToolBar->AddTool( ID_ROTATE3D_Y_POS, wxEmptyString,
|
||||
KiScaledBitmap( rotate_pos_y_xpm, this ),
|
||||
KiBitmap( rotate_pos_y_xpm ),
|
||||
_( "Rotate Y Counterclockwise" ) );
|
||||
|
||||
KiScaledSeparator( m_mainToolBar, this );
|
||||
|
||||
m_mainToolBar->AddSeparator();
|
||||
m_mainToolBar->AddTool( ID_ROTATE3D_Z_NEG, wxEmptyString,
|
||||
KiScaledBitmap( rotate_neg_z_xpm, this ),
|
||||
KiBitmap( rotate_neg_z_xpm ),
|
||||
_( "Rotate Z Clockwise" ) );
|
||||
|
||||
m_mainToolBar->AddTool( ID_ROTATE3D_Z_POS, wxEmptyString,
|
||||
KiScaledBitmap( rotate_pos_z_xpm, this ),
|
||||
KiBitmap( rotate_pos_z_xpm ),
|
||||
_( "Rotate Z Counterclockwise" ) );
|
||||
|
||||
KiScaledSeparator( m_mainToolBar, this );
|
||||
|
||||
m_mainToolBar->AddTool( ID_MOVE3D_LEFT, wxEmptyString,
|
||||
KiScaledBitmap( left_xpm, this ),
|
||||
m_mainToolBar->AddSeparator();
|
||||
m_mainToolBar->AddTool( ID_MOVE3D_LEFT, wxEmptyString, KiBitmap( left_xpm ),
|
||||
_( "Move left" ) );
|
||||
|
||||
m_mainToolBar->AddTool( ID_MOVE3D_RIGHT, wxEmptyString,
|
||||
KiScaledBitmap( right_xpm, this ),
|
||||
m_mainToolBar->AddTool( ID_MOVE3D_RIGHT, wxEmptyString, KiBitmap( right_xpm ),
|
||||
_( "Move right" ) );
|
||||
|
||||
m_mainToolBar->AddTool( ID_MOVE3D_UP, wxEmptyString,
|
||||
KiScaledBitmap( up_xpm, this ),
|
||||
m_mainToolBar->AddTool( ID_MOVE3D_UP, wxEmptyString, KiBitmap( up_xpm ),
|
||||
_( "Move up" ) );
|
||||
|
||||
m_mainToolBar->AddTool( ID_MOVE3D_DOWN, wxEmptyString,
|
||||
KiScaledBitmap( down_xpm, this ),
|
||||
m_mainToolBar->AddTool( ID_MOVE3D_DOWN, wxEmptyString, KiBitmap( down_xpm ),
|
||||
_( "Move down" ) );
|
||||
|
||||
KiScaledSeparator( m_mainToolBar, this );
|
||||
|
||||
m_mainToolBar->AddTool( ID_ORTHO, wxEmptyString,
|
||||
KiScaledBitmap( ortho_xpm, this ),
|
||||
m_mainToolBar->AddSeparator();
|
||||
m_mainToolBar->AddTool( ID_ORTHO, wxEmptyString, KiBitmap( ortho_xpm ),
|
||||
_( "Enable/Disable orthographic projection" ),
|
||||
wxITEM_CHECK );
|
||||
|
||||
m_mainToolBar->Realize();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void EDA_3D_VIEWER::SetToolbars()
|
||||
{
|
||||
}
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
* This program source code file is part of KiCad, a free EDA CAD application.
|
||||
*
|
||||
* Copyright (C) 2017 Jean-Pierre Charras, jp.charras at wanadoo.fr
|
||||
* Copyright (C) 2014-2018 KiCad Developers, see AUTHORS.txt for contributors.
|
||||
* Copyright (C) 2014-2017 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
|
||||
@@ -52,6 +52,8 @@ void EDA_3D_VIEWER::Install3DViewOptionDialog( wxCommandEvent& event )
|
||||
|
||||
if( dlg.ShowModal() == wxID_OK )
|
||||
{
|
||||
SetMenuBarOptionsState();
|
||||
|
||||
NewDisplay( true );
|
||||
}
|
||||
}
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -3,8 +3,8 @@
|
||||
*
|
||||
* 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) 1992-2019 KiCad Developers, see AUTHORS.txt for contributors.
|
||||
* Copyright (C) 2011 Wayne Stambaugh <stambaughw@verizon.net>
|
||||
* Copyright (C) 1992-2017 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
|
||||
@@ -32,25 +32,19 @@
|
||||
#ifndef EDA_3D_VIEWER_H
|
||||
#define EDA_3D_VIEWER_H
|
||||
|
||||
|
||||
#include "../3d_canvas/cinfo3d_visu.h"
|
||||
#include "../3d_canvas/eda_3d_canvas.h"
|
||||
#include <kiway_player.h>
|
||||
#include <wx/colourdata.h>
|
||||
#include <../common/dialogs/dialog_color_picker.h> // for CUSTOM_COLORS_LIST definition
|
||||
|
||||
|
||||
/// A variable name whose value holds the path of 3D shape files.
|
||||
/// Currently an environment variable, eventually a project variable.
|
||||
#define KISYS3DMOD wxT( "KISYS3DMOD" )
|
||||
|
||||
|
||||
#define KICAD_DEFAULT_3D_DRAWFRAME_STYLE (wxDEFAULT_FRAME_STYLE | wxWANTS_CHARS)
|
||||
|
||||
#define VIEWER3D_FRAMENAME wxT( "Viewer3DFrameName" )
|
||||
#define QUALIFIED_VIEWER3D_FRAMENAME( parent ) \
|
||||
( wxString( VIEWER3D_FRAMENAME ) + wxT( ":" ) + parent->GetName() )
|
||||
|
||||
/**
|
||||
* Class EDA_3D_VIEWER
|
||||
* Create and handle a window for the 3d viewer connected to a Kiway and a pcbboard
|
||||
*/
|
||||
class EDA_3D_VIEWER : public KIWAY_PLAYER
|
||||
@@ -91,23 +85,44 @@ class EDA_3D_VIEWER : public KIWAY_PLAYER
|
||||
void NewDisplay( bool aForceImmediateRedraw = false );
|
||||
|
||||
/**
|
||||
* Function SetDefaultFileName
|
||||
* Set the default file name (eg: to be suggested to a screenshot)
|
||||
* @param aFn = file name to assign
|
||||
*/
|
||||
void SetDefaultFileName( const wxString &aFn )
|
||||
{
|
||||
wxFileName fn( aFn );
|
||||
m_defaultSaveScreenshotFileName = fn.GetName();
|
||||
}
|
||||
|
||||
/**
|
||||
* Function GetDefaultFileName
|
||||
* @return the default suggested file name
|
||||
*/
|
||||
const wxString &GetDefaultFileName() const { return m_defaultSaveScreenshotFileName; }
|
||||
|
||||
/**
|
||||
* Function GetSettings
|
||||
* @return current settings
|
||||
*/
|
||||
CINFO3D_VISU &GetSettings() { return m_settings; }
|
||||
|
||||
/**
|
||||
* Function Set3DColorFromUser
|
||||
* Get a SFVEC3D from a wx colour dialog
|
||||
* @param aColor is the SFVEC3D to change
|
||||
* @param aTitle is the title displayed in the colordialog selector
|
||||
* @param aPredefinedColors is a reference to a CUSTOM_COLOR_ITEM list
|
||||
* @param aPredefinedColors is a reference to a wxColourData
|
||||
* which contains a few predefined colors
|
||||
* if empty, no predefined colors are used.
|
||||
* no change if aborted by user
|
||||
* if it is NULL, no predefined colors are used
|
||||
* @return true if a new color is chosen, false if
|
||||
* no change or aborted by user
|
||||
*/
|
||||
bool Set3DColorFromUser( SFVEC3D &aColor, const wxString& aTitle,
|
||||
CUSTOM_COLORS_LIST* aPredefinedColors );
|
||||
wxColourData* aPredefinedColors = NULL );
|
||||
|
||||
/**
|
||||
* Function Set3DSolderMaskColorFromUser
|
||||
* Set the solder mask color from a set of colors
|
||||
* @return true if a new color is chosen, false if
|
||||
* no change or aborted by user
|
||||
@@ -115,6 +130,7 @@ class EDA_3D_VIEWER : public KIWAY_PLAYER
|
||||
bool Set3DSolderMaskColorFromUser();
|
||||
|
||||
/**
|
||||
* Function Set3DSolderPasteColorFromUser
|
||||
* Set the solder mask color from a set of colors
|
||||
* @return true if a new color is chosen, false if
|
||||
* no change or aborted by user
|
||||
@@ -122,6 +138,7 @@ class EDA_3D_VIEWER : public KIWAY_PLAYER
|
||||
bool Set3DSolderPasteColorFromUser();
|
||||
|
||||
/**
|
||||
* Function Set3DCopperColorFromUser
|
||||
* Set the copper color from a set of colors
|
||||
* @return true if a new color is chosen, false if
|
||||
* no change or aborted by user
|
||||
@@ -129,6 +146,7 @@ class EDA_3D_VIEWER : public KIWAY_PLAYER
|
||||
bool Set3DCopperColorFromUser();
|
||||
|
||||
/**
|
||||
* Function Set3DBoardBodyBodyColorFromUser
|
||||
* Set the copper color from a set of colors
|
||||
* @return true if a new color is chosen, false if
|
||||
* no change or aborted by user
|
||||
@@ -136,21 +154,13 @@ class EDA_3D_VIEWER : public KIWAY_PLAYER
|
||||
bool Set3DBoardBodyColorFromUser();
|
||||
|
||||
/**
|
||||
* Function Set3DSilkScreenColorFromUser
|
||||
* Set the silkscreen color from a set of colors
|
||||
* @return true if a new color is chosen, false if
|
||||
* no change or aborted by user
|
||||
*/
|
||||
bool Set3DSilkScreenColorFromUser();
|
||||
|
||||
/**
|
||||
* Notification that common settings are updated.
|
||||
*
|
||||
* This would be private (and only called by the Kiway), but we
|
||||
* need to do this manually from the PCB frame because the 3D viewer isn't
|
||||
* updated via the #KIWAY.
|
||||
*/
|
||||
void CommonSettingsChanged( bool aEnvVarsChanged ) override;
|
||||
|
||||
private:
|
||||
/// Called when user press the File->Exit
|
||||
void Exit3DFrame( wxCommandEvent &event );
|
||||
@@ -162,7 +172,8 @@ class EDA_3D_VIEWER : public KIWAY_PLAYER
|
||||
void On3DGridSelection( wxCommandEvent &event );
|
||||
|
||||
void OnRenderEngineSelection( wxCommandEvent &event );
|
||||
void OnDisableRayTracing( wxCommandEvent& aEvent );
|
||||
|
||||
void OnUpdateMenus(wxUpdateUIEvent& event);
|
||||
|
||||
void ProcessZoom( wxCommandEvent &event );
|
||||
|
||||
@@ -172,23 +183,31 @@ class EDA_3D_VIEWER : public KIWAY_PLAYER
|
||||
|
||||
void Install3DViewOptionDialog( wxCommandEvent &event );
|
||||
|
||||
void OnUpdateUIEngine( wxUpdateUIEvent& aEvent );
|
||||
void OnUpdateUIMaterial( wxUpdateUIEvent& aEvent );
|
||||
|
||||
void CreateMenuBar();
|
||||
|
||||
void DisplayHotKeys();
|
||||
|
||||
/**
|
||||
* Equivalent of EDA_DRAW_FRAME::ReCreateHToolbar
|
||||
* Set the state of toggle menus according to the current display options
|
||||
*/
|
||||
void SetMenuBarOptionsState();
|
||||
|
||||
void ReCreateMainToolbar();
|
||||
|
||||
void SetToolbars();
|
||||
|
||||
void SaveSettings( wxConfigBase *aCfg ) override;
|
||||
|
||||
void LoadSettings( wxConfigBase *aCfg ) override;
|
||||
|
||||
void OnLeftClick( wxDC *DC, const wxPoint &MousePos );
|
||||
void OnRightClick( const wxPoint &MousePos, wxMenu *PopMenu );
|
||||
void OnKeyEvent( wxKeyEvent& event );
|
||||
|
||||
void RedrawActiveWindow( wxDC *DC, bool EraseBg );
|
||||
|
||||
/**
|
||||
* Function TakeScreenshot
|
||||
* Create a Screenshot of the current 3D view.
|
||||
* Output file format is png or jpeg, or image is copied to the clipboard
|
||||
*/
|
||||
@@ -204,17 +223,19 @@ class EDA_3D_VIEWER : public KIWAY_PLAYER
|
||||
private:
|
||||
|
||||
/**
|
||||
* Load configuration from common settings.
|
||||
* Filename to propose for save a screenshot
|
||||
*/
|
||||
void loadCommonSettings();
|
||||
wxString m_defaultSaveScreenshotFileName;
|
||||
|
||||
wxFileName m_defaultSaveScreenshotFileName;
|
||||
/**
|
||||
* The canvas where the openGL context will be rendered
|
||||
*/
|
||||
EDA_3D_CANVAS *m_canvas;
|
||||
|
||||
wxAuiToolBar* m_mainToolBar;
|
||||
EDA_3D_CANVAS* m_canvas;
|
||||
CINFO3D_VISU m_settings;
|
||||
|
||||
bool m_disable_ray_tracing;
|
||||
/**
|
||||
* Store all the settings and options to be used by the renders
|
||||
*/
|
||||
CINFO3D_VISU m_settings;
|
||||
|
||||
/**
|
||||
* Trace mask used to enable or disable the trace output of this class.
|
||||
|
||||
@@ -0,0 +1,99 @@
|
||||
/*
|
||||
* This program source code file is part of KiCad, a free EDA CAD application.
|
||||
*
|
||||
* Copyright (C) 1992-2018 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 hotkeys.cpp
|
||||
* @brief list of hotkeys used in 3D viewer
|
||||
*/
|
||||
|
||||
#include <hotkeys_basic.h>
|
||||
#include "eda_3d_viewer.h"
|
||||
#include "../3d_viewer_id.h"
|
||||
|
||||
// Define 3D Viewer Hotkeys
|
||||
static EDA_HOTKEY HkHotkeysHelp( _HKI( "Help (this window)" ), HK_HELP, GR_KB_CTRL + WXK_F1 );
|
||||
static EDA_HOTKEY Hk3D_PivotCenter( _HKI( "Center pivot rotation (Middle mouse click)" ), 0, WXK_SPACE );
|
||||
static EDA_HOTKEY Hk3D_MoveLeft( _HKI( "Move board Left" ), ID_POPUP_MOVE3D_LEFT, WXK_LEFT );
|
||||
static EDA_HOTKEY Hk3D_MoveRight( _HKI( "Move board Right" ), ID_POPUP_MOVE3D_RIGHT, WXK_RIGHT );
|
||||
static EDA_HOTKEY Hk3D_MoveUp( _HKI( "Move board Up" ), ID_POPUP_MOVE3D_UP, WXK_UP );
|
||||
static EDA_HOTKEY Hk3D_MoveDown( _HKI( "Move board Down" ), ID_POPUP_MOVE3D_DOWN, WXK_DOWN );
|
||||
static EDA_HOTKEY Hk3D_HomeView( _HKI( "Home view" ), 0, WXK_HOME );
|
||||
static EDA_HOTKEY Hk3D_ResetView( _HKI( "Reset view" ), 0, 'R' );
|
||||
|
||||
static EDA_HOTKEY Hk3D_ViewFront( _HKI( "View Front" ), ID_POPUP_VIEW_YPOS, 'Y' );
|
||||
static EDA_HOTKEY Hk3D_ViewBack( _HKI( "View Back" ), ID_POPUP_VIEW_YNEG, GR_KB_SHIFT + 'Y' );
|
||||
static EDA_HOTKEY Hk3D_ViewLeft( _HKI( "View Left" ), ID_POPUP_VIEW_XNEG, GR_KB_SHIFT + 'X' );
|
||||
static EDA_HOTKEY Hk3D_ViewRight( _HKI( "View Right" ), ID_POPUP_VIEW_XPOS, 'X' );
|
||||
static EDA_HOTKEY Hk3D_ViewTop( _HKI( "View Top" ), ID_POPUP_VIEW_ZPOS, 'Z' );
|
||||
static EDA_HOTKEY Hk3D_ViewBot( _HKI( "View Bot" ), ID_POPUP_VIEW_ZNEG, GR_KB_SHIFT + 'Z' );
|
||||
|
||||
static EDA_HOTKEY Hk3D_Rotate45axisZ( _HKI( "Rotate 45 degrees over Z axis" ), 0, WXK_TAB );
|
||||
static EDA_HOTKEY Hk3D_ZoomIn( _HKI( "Zoom in " ), ID_POPUP_ZOOMIN, WXK_F1 );
|
||||
static EDA_HOTKEY Hk3D_ZoomOut( _HKI( "Zoom out" ), ID_POPUP_ZOOMOUT, WXK_F2 );
|
||||
static EDA_HOTKEY Hk3D_AttributesTHT( _HKI( "Toggle 3D models with type Through Hole" ), 0, 'T' );
|
||||
static EDA_HOTKEY Hk3D_AttributesSMD( _HKI( "Toggle 3D models with type Surface Mount" ), 0, 'S' );
|
||||
static EDA_HOTKEY Hk3D_AttributesVirtual( _HKI( "Toggle 3D models with type Virtual" ), 0, 'V' );
|
||||
|
||||
static wxString viewer3DSectionTitle( _HKI( "Viewer 3D" ) );
|
||||
|
||||
// List of hotkey descriptors for the 3D Viewer only
|
||||
// !TODO: this is used just for help menu, the structured are not used yet in the viewer
|
||||
static EDA_HOTKEY* viewer3d_Hotkey_List[] =
|
||||
{
|
||||
&HkHotkeysHelp,
|
||||
&Hk3D_PivotCenter,
|
||||
&Hk3D_MoveLeft,
|
||||
&Hk3D_MoveRight,
|
||||
&Hk3D_MoveUp,
|
||||
&Hk3D_MoveDown,
|
||||
&Hk3D_HomeView,
|
||||
&Hk3D_ResetView,
|
||||
&Hk3D_ViewFront,
|
||||
&Hk3D_ViewBack,
|
||||
&Hk3D_ViewLeft,
|
||||
&Hk3D_ViewRight,
|
||||
&Hk3D_ViewTop,
|
||||
&Hk3D_ViewBot,
|
||||
&Hk3D_Rotate45axisZ,
|
||||
&Hk3D_ZoomIn,
|
||||
&Hk3D_ZoomOut,
|
||||
&Hk3D_AttributesTHT,
|
||||
&Hk3D_AttributesSMD,
|
||||
&Hk3D_AttributesVirtual,
|
||||
NULL
|
||||
};
|
||||
|
||||
|
||||
// list of sections and corresponding hotkey list for the 3D Viewer
|
||||
// (used to list current hotkeys)
|
||||
struct EDA_HOTKEY_CONFIG g_3DViewer_Hokeys_Descr[] =
|
||||
{
|
||||
{ &g_CommonSectionTag, viewer3d_Hotkey_List, &viewer3DSectionTitle },
|
||||
{ NULL, NULL, NULL }
|
||||
};
|
||||
|
||||
|
||||
void EDA_3D_VIEWER::DisplayHotKeys()
|
||||
{
|
||||
DisplayHotkeyList( this, g_3DViewer_Hokeys_Descr );
|
||||
}
|
||||
+16
-10
@@ -32,13 +32,13 @@ enum id_3dview_frm
|
||||
ID_ORTHO,
|
||||
ID_MENU3D_COLOR,
|
||||
ID_MENU3D_BGCOLOR,
|
||||
ID_MENU3D_BGCOLOR_BOTTOM,
|
||||
ID_MENU3D_BGCOLOR_TOP,
|
||||
ID_MENU3D_SILKSCREEN_COLOR,
|
||||
ID_MENU3D_SOLDERMASK_COLOR,
|
||||
ID_MENU3D_SOLDERPASTE_COLOR,
|
||||
ID_MENU3D_PCB_BODY_COLOR,
|
||||
ID_MENU3D_COPPER_COLOR,
|
||||
ID_MENU3D_BGCOLOR_BOTTOM_SELECTION,
|
||||
ID_MENU3D_BGCOLOR_TOP_SELECTION,
|
||||
ID_MENU3D_SILKSCREEN_COLOR_SELECTION,
|
||||
ID_MENU3D_SOLDERMASK_COLOR_SELECTION,
|
||||
ID_MENU3D_SOLDERPASTE_COLOR_SELECTION,
|
||||
ID_MENU3D_PCB_BODY_COLOR_SELECTION,
|
||||
ID_MENU3D_COPPER_COLOR_SELECTION,
|
||||
ID_MENU3D_AXIS_ONOFF,
|
||||
|
||||
ID_MENU3D_MODULE_ONOFF,
|
||||
@@ -56,6 +56,7 @@ enum id_3dview_frm
|
||||
ID_MENU3D_COMMENTS_ONOFF,
|
||||
ID_MENU3D_ECO_ONOFF,
|
||||
ID_MENU3D_SHOW_BOARD_BODY,
|
||||
ID_MENU3D_MOUSEWHEEL_PANNING,
|
||||
ID_MENU3D_REALISTIC_MODE,
|
||||
|
||||
ID_MENU3D_FL,
|
||||
@@ -78,6 +79,8 @@ enum id_3dview_frm
|
||||
ID_MENU3D_FL_RAYTRACING_ANTI_ALIASING,
|
||||
ID_MENU3D_FL_RAYTRACING_PROCEDURAL_TEXTURES,
|
||||
|
||||
ID_RENDER_CURRENT_VIEW,
|
||||
|
||||
ID_MENU_SCREENCOPY_PNG,
|
||||
ID_MENU_SCREENCOPY_JPEG,
|
||||
ID_MENU_SCREENCOPY_TOCLIBBOARD,
|
||||
@@ -85,9 +88,9 @@ enum id_3dview_frm
|
||||
ID_MENU3D_RESET_DEFAULTS,
|
||||
|
||||
// Help
|
||||
ID_MENU_COMMAND_END,
|
||||
ID_MENU3D_HELP_HOTKEY_SHOW_CURRENT_LIST,
|
||||
|
||||
ID_RENDER_CURRENT_VIEW,
|
||||
ID_MENU_COMMAND_END,
|
||||
|
||||
ID_TOOL_SET_VISIBLE_ITEMS,
|
||||
|
||||
@@ -99,7 +102,10 @@ enum id_3dview_frm
|
||||
ID_MENU3D_GRID_1_MM,
|
||||
ID_MENU3D_GRID_END,
|
||||
|
||||
ID_DISABLE_RAY_TRACING,
|
||||
ID_MENU3D_ENGINE,
|
||||
ID_MENU3D_ENGINE_OPENGL_LEGACY,
|
||||
ID_MENU3D_ENGINE_RAYTRACING,
|
||||
ID_MENU3D_ENGINE_END,
|
||||
|
||||
ID_POPUP_3D_VIEW_START,
|
||||
ID_POPUP_ZOOMIN,
|
||||
|
||||
@@ -7,6 +7,7 @@ include_directories(BEFORE ${INC_BEFORE})
|
||||
include_directories(
|
||||
${CMAKE_CURRENT_BINARY_DIR}
|
||||
../pcbnew
|
||||
../polygon
|
||||
3d_canvas
|
||||
3d_cache
|
||||
3d_rendering
|
||||
@@ -32,7 +33,10 @@ set(3D-VIEWER_SRCS
|
||||
3d_cache/3d_cache_wrapper.cpp
|
||||
3d_cache/3d_cache.cpp
|
||||
3d_cache/3d_plugin_manager.cpp
|
||||
3d_cache/3d_filename_resolver.cpp
|
||||
${DIR_DLG}/3d_cache_dialogs.cpp
|
||||
${DIR_DLG}/dlg_3d_pathconfig_base.cpp
|
||||
${DIR_DLG}/dlg_3d_pathconfig.cpp
|
||||
${DIR_DLG}/dlg_select_3dmodel.cpp
|
||||
${DIR_DLG}/panel_prev_3d_base.cpp
|
||||
${DIR_DLG}/panel_prev_model.cpp
|
||||
@@ -87,8 +91,8 @@ set(3D-VIEWER_SRCS
|
||||
3d_rendering/cpostshader.cpp
|
||||
3d_rendering/cpostshader_ssao.cpp
|
||||
3d_rendering/ctrack_ball.cpp
|
||||
3d_viewer/3d_actions.cpp
|
||||
3d_viewer/3d_menubar.cpp
|
||||
3d_viewer/hotkeys.cpp
|
||||
3d_rendering/test_cases.cpp
|
||||
3d_rendering/trackball.cpp
|
||||
3d_viewer/3d_toolbar.cpp
|
||||
@@ -106,7 +110,6 @@ add_dependencies( 3d-viewer pcbcommon )
|
||||
|
||||
target_link_libraries( 3d-viewer
|
||||
gal
|
||||
polygon
|
||||
${Boost_}
|
||||
${wxWidgets_LIBRARIES}
|
||||
${OPENGL_LIBRARIES}
|
||||
|
||||
@@ -75,7 +75,7 @@ const int COGL_ATT_LIST::m_openGL_attributes_list[] = {
|
||||
#define ATT_WX_GL_SAMPLE_BUFFERS_DATA 11
|
||||
|
||||
int COGL_ATT_LIST::m_openGL_attributes_list_to_use[
|
||||
arrayDim( COGL_ATT_LIST::m_openGL_attributes_list ) ] = { 0 };
|
||||
DIM( COGL_ATT_LIST::m_openGL_attributes_list ) ] = { 0 };
|
||||
|
||||
|
||||
const int *COGL_ATT_LIST::GetAttributesList( bool aUseAntiAliasing )
|
||||
|
||||
+2
-4
@@ -1,5 +1,5 @@
|
||||
* Copyright (C) 1992-2015 Jean-Pierre Charras
|
||||
* Copyright (C) 1992-2019 Kicad Developers Team
|
||||
* Copyright (C) 1992-2017 Kicad Developers Team
|
||||
* under GNU General Public License (see copyright.txt)
|
||||
|
||||
== Main Authors
|
||||
@@ -55,7 +55,7 @@ https://code.launchpad.net/~kicad-product-committers/kicad/+git/product-git/+ref
|
||||
Jean-Pierre Charras <jean-pierre.charras[at]gipsa-lab.inpg-dot-fr>
|
||||
Igor Plyatov <plyatov[at]gmail-dot-com>
|
||||
Fabrizio Tappero <fabrizio-dot-tappero[at]gmail-dot-com>
|
||||
Marco Ciampa <ciampix[at]posteo-dot-net>
|
||||
Marco Ciampa <ciampix[at]libero-dot-it>
|
||||
Wayne Stambaugh <stambaughw[at]gmail-dot-com
|
||||
|
||||
|
||||
@@ -64,7 +64,6 @@ Czech (CZ) Martin Kratoška <martin[at]ok1rr-dot-com>
|
||||
Dutch (NL) Jerry Jacobs <xor.gate.engineering[at]gmail-dot-com>
|
||||
Finnish (FI) Vesa Solonen <vesa.solonen[at]hut-dot-fi>
|
||||
French (FR) Jean-Pierre Charras <jean-pierre.charras[at]inpg-dot-fr>
|
||||
Italian (IT) Marco Ciampa <ciampix[at]posteo-dot-net>
|
||||
Polish (PL) Mateusz Skowro¿ski <skowri[at]gmail-dot-com>
|
||||
Polish (PL) Kerusey Karyu <keruseykaryu[at]o2.pl>
|
||||
Portuguese (PT) Renie Marquet <reniemarquet[at]uol-dot-com-dot-br>"
|
||||
@@ -75,7 +74,6 @@ Spanish (ES) Pedro Martin del Valle <pkicad[at]yahoo-dot-es>
|
||||
Spanish (ES) Iñigo Zuluaga <inigo_zuluaga[at]yahoo-dot-es>
|
||||
German (DE) Rafael Sokolowski <Rafael.Sokolowski[at]web-dot-de
|
||||
Japanese (JA) Kenta Yonekura <yoneken[at]kicad-dot-jp>
|
||||
Simplified Chinese (zh_CN) taotieren <admin[at]taotieren-dot-com>
|
||||
|
||||
Remy Halvick, David Briscoe, Dominique Laigle, Paul Burke
|
||||
|
||||
|
||||
+195
-262
@@ -1,7 +1,7 @@
|
||||
#
|
||||
# This program source code file is part of KICAD, a free EDA CAD application.
|
||||
#
|
||||
# Copyright (C) 2007-2018 Kicad Developers, see AUTHORS.txt for contributors.
|
||||
# Copyright (C) 2007-2016 Kicad Developers, see AUTHORS.txt for contributors.
|
||||
#
|
||||
# This program is free software; you can redistribute it and/or
|
||||
# modify it under the terms of the GNU General Public License
|
||||
@@ -21,7 +21,7 @@
|
||||
# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
|
||||
#
|
||||
|
||||
cmake_minimum_required( VERSION 3.0.2 FATAL_ERROR )
|
||||
cmake_minimum_required( VERSION 2.8.12 FATAL_ERROR )
|
||||
# because of http://public.kitware.com/Bug/view.php?id=10395
|
||||
|
||||
# See https://gitlab.kitware.com/cmake/cmake/issues/15943
|
||||
@@ -60,26 +60,24 @@ option( BUILD_SMALL_DEBUG_FILES "In debug build: create smaller binaries." OFF )
|
||||
# so that build option settings can be included in bug reports.
|
||||
#
|
||||
|
||||
option( USE_WX_GRAPHICS_CONTEXT
|
||||
"Use wxGraphicsContext for rendering (default OFF). Warning, this is experimental" )
|
||||
|
||||
option( USE_WX_OVERLAY
|
||||
"Use wxOverlay: Always ON for MAC (default OFF). Warning, this is experimental" )
|
||||
|
||||
option( KICAD_SCRIPTING
|
||||
"Build the Python scripting support inside KiCad binaries (default ON)."
|
||||
"Build the Python scripting support inside KiCad binaries (default OFF)."
|
||||
ON )
|
||||
|
||||
option( KICAD_SCRIPTING_MODULES
|
||||
"Build native portion of the pcbnew Python module: _pcbnew.{pyd,so} for OS command line use of Python."
|
||||
ON )
|
||||
|
||||
option( KICAD_SCRIPTING_PYTHON3
|
||||
"Build for Python 3 instead of 2 (default OFF)."
|
||||
OFF )
|
||||
|
||||
option( KICAD_SCRIPTING_WXPYTHON
|
||||
"Build wxPython implementation for wx interface building in Python and py.shell (default ON)."
|
||||
"Build wxPython implementation for wx interface building in Python and py.shell (default OFF)."
|
||||
ON )
|
||||
|
||||
option( KICAD_SCRIPTING_WXPYTHON_PHOENIX
|
||||
"Use new wxPython binding (default OFF)."
|
||||
OFF )
|
||||
|
||||
option( KICAD_SCRIPTING_ACTION_MENU
|
||||
"Build a tools menu with registered python plugins: actions plugins (default ON)."
|
||||
ON )
|
||||
@@ -93,82 +91,44 @@ option( KICAD_USE_OCC
|
||||
OFF )
|
||||
|
||||
option( KICAD_INSTALL_DEMOS
|
||||
"Install KiCad demos and examples (default ON)"
|
||||
"Install kicad demos and examples (default ON)"
|
||||
ON )
|
||||
|
||||
option( KICAD_BUILD_QA_TESTS
|
||||
"Build software Quality assurance unit tests (default ON)"
|
||||
ON )
|
||||
|
||||
option( BUILD_GITHUB_PLUGIN
|
||||
"Build the GITHUB_PLUGIN for pcbnew."
|
||||
ON )
|
||||
|
||||
option( KICAD_SPICE
|
||||
"Build KiCad with internal Spice simulator."
|
||||
ON )
|
||||
|
||||
# Not supported by all platforms (for instance mingw)
|
||||
option( KICAD_SANITIZE
|
||||
"Build KiCad with sanitizer options. WARNING: Not compatible with gold linker"
|
||||
OFF )
|
||||
|
||||
option( KICAD_STDLIB_DEBUG
|
||||
"Build KiCad with libstdc++ debug flags enabled."
|
||||
OFF )
|
||||
|
||||
option( KICAD_STDLIB_LIGHT_DEBUG
|
||||
"Build KiCad with libstdc++ with -Wp,-D_GLIBCXX_ASSERTIONS flag enabled. Not as intrusive as KICAD_STDLIB_DEBUG"
|
||||
OFF )
|
||||
|
||||
option( KICAD_BUILD_PARALLEL_CL_MP
|
||||
"Build in parallel using the /MP compiler option (default OFF for safety reasons)"
|
||||
OFF )
|
||||
|
||||
option( KICAD_USE_VALGRIND
|
||||
"Build KiCad with valgrind stack tracking enabled."
|
||||
OFF )
|
||||
|
||||
# when option KICAD_SCRIPTING OR KICAD_SCRIPTING_MODULES is enabled:
|
||||
# PYTHON_EXECUTABLE can be defined when invoking cmake
|
||||
# ( use -DPYTHON_EXECUTABLE=<python path>/python.exe or python2 )
|
||||
# when not defined by user, the default is python.exe under Windows and python2 for others
|
||||
# python binary file should be in exec path.
|
||||
# python binary file should be is exec path.
|
||||
|
||||
# KICAD_SCRIPTING controls the entire python scripting system. If it is off, no other scripting
|
||||
# functions are available.
|
||||
if ( NOT KICAD_SCRIPTING )
|
||||
message( STATUS "KICAD_SCRIPTING is OFF: Disabling all python scripting support" )
|
||||
set( KICAD_SCRIPTING_MODULES OFF )
|
||||
set( KICAD_SCRIPTING_ACTION_MENU OFF )
|
||||
set( KICAD_SCRIPTING_PYTHON3 OFF )
|
||||
set( KICAD_SCRIPTING_WXPYTHON OFF )
|
||||
set( KICAD_SCRIPTING_WXPYTHON_PHOENIX OFF)
|
||||
# KICAD_SCRIPTING_MODULES requires KICAD_SCRIPTING enable it here if KICAD_SCRIPTING_MODULES is ON
|
||||
if ( KICAD_SCRIPTING_MODULES AND NOT KICAD_SCRIPTING )
|
||||
message(STATUS "Changing KICAD_SCRIPTING to ON as needed by KICAD_SCRIPTING_MODULES")
|
||||
set ( KICAD_SCRIPTING ON )
|
||||
endif()
|
||||
|
||||
# KICAD_SCRIPTING_WXPYTHON_PHOENIX requires enabling the KICAD_SCRIPTING_WXPYTHON flag
|
||||
# so that the wxWidgets library is properly versioned
|
||||
if ( KICAD_SCRIPTING AND NOT KICAD_SCRIPTING_WXPYTHON AND KICAD_SCRIPTING_WXPYTHON_PHOENIX )
|
||||
message( STATUS
|
||||
"KICAD_SCRIPTING_WXPYTHON_PHOENIX has been requested, setting KICAD_SCRIPTING_WXPYTHON to ON")
|
||||
set( KICAD_SCRIPTING_WXPYTHON ON)
|
||||
# same with KICAD_SCRIPTING_ACTION_MENUS
|
||||
if ( KICAD_SCRIPTING_ACTION_MENU AND NOT KICAD_SCRIPTING )
|
||||
message(STATUS "Changing KICAD_SCRIPTING to ON as needed by KICAD_SCRIPTING_ACTION_MENU")
|
||||
set ( KICAD_SCRIPTING ON )
|
||||
endif()
|
||||
|
||||
option( BUILD_GITHUB_PLUGIN "Build the GITHUB_PLUGIN for pcbnew." ON )
|
||||
|
||||
option( KICAD_SPICE "Build Kicad with internal Spice simulator." ON )
|
||||
|
||||
# Global setting: exports are explicit
|
||||
set( CMAKE_CXX_VISIBILITY_PRESET "hidden" )
|
||||
set( CMAKE_VISIBILITY_INLINES_HIDDEN ON )
|
||||
|
||||
|
||||
# Global setting: build everything position independent
|
||||
set( CMAKE_POSITION_INDEPENDENT_CODE ON )
|
||||
|
||||
# Global setting: Use C++14
|
||||
set(CMAKE_CXX_STANDARD 14)
|
||||
|
||||
# Global setting: Use C++11
|
||||
set(CMAKE_CXX_STANDARD 11)
|
||||
set(CMAKE_CXX_STANDARD_REQUIRED ON)
|
||||
|
||||
# Enable additional valgrind instrumentation for stack tracking in libcontext
|
||||
if( KICAD_USE_VALGRIND )
|
||||
add_definitions( -DKICAD_USE_VALGRIND )
|
||||
endif()
|
||||
|
||||
# CMP0063: CMake < 3.3 does not handle hidden visibility for static libraries,
|
||||
# and 3.3 is backwards compatible when the minimum version is smaller than 3.3.
|
||||
@@ -192,9 +152,12 @@ endif()
|
||||
# Add option to add user directories for linker, if any
|
||||
LINK_DIRECTORIES( ${LINK_DIRECTORIES_PATH} )
|
||||
|
||||
set( KICAD_CONFIG_DIR "kicad" CACHE STRING "Location of user specific KiCad config files" )
|
||||
mark_as_advanced( KICAD_CONFIG_DIR )
|
||||
add_definitions( -DKICAD_CONFIG_DIR=${KICAD_CONFIG_DIR} )
|
||||
if( UNIX )
|
||||
set( KICAD_USER_CONFIG_DIR $ENV{HOME} CACHE PATH "Location of user specific KiCad config files" )
|
||||
elseif( MINGW )
|
||||
set( KICAD_USER_CONFIG_DIR $ENV{APPDATA} CACHE PATH "Location of user specific KiCad config files" )
|
||||
endif()
|
||||
mark_as_advanced( KICAD_USER_CONFIG_DIR )
|
||||
|
||||
# Set default data file path to CMAKE_INSTALL_PREFIX if it wasn't specified during the
|
||||
# CMake configuration. The value of DEFAULT_INSTALL_PATH is expanded in config.h and
|
||||
@@ -207,7 +170,7 @@ if( NOT DEFAULT_INSTALL_PATH )
|
||||
"Location of KiCad data files." )
|
||||
endif()
|
||||
|
||||
message( STATUS "KiCad install dir: <${DEFAULT_INSTALL_PATH}>" )
|
||||
message( STATUS "Kicad install dir: <${DEFAULT_INSTALL_PATH}>" )
|
||||
|
||||
# Generate build system specific header file.
|
||||
include( PerformFeatureChecks )
|
||||
@@ -222,12 +185,12 @@ endif()
|
||||
if( CMAKE_VERSION VERSION_LESS 3.1 AND ( CMAKE_COMPILER_IS_GNUCXX OR CMAKE_CXX_COMPILER_ID MATCHES "Clang" ) )
|
||||
include(CheckCXXCompilerFlag)
|
||||
|
||||
CHECK_CXX_COMPILER_FLAG("-std=gnu++14" COMPILER_SUPPORTS_CXX14)
|
||||
CHECK_CXX_COMPILER_FLAG("-std=c++11" COMPILER_SUPPORTS_CXX11)
|
||||
|
||||
if(COMPILER_SUPPORTS_CXX14)
|
||||
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=gnu++14")
|
||||
if(COMPILER_SUPPORTS_CXX11)
|
||||
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11")
|
||||
else()
|
||||
message(STATUS "The compiler ${CMAKE_CXX_COMPILER} has no C++14 support. Please use a different C++ compiler.")
|
||||
message(STATUS "The compiler ${CMAKE_CXX_COMPILER} has no C++11 support. Please use a different C++ compiler.")
|
||||
endif()
|
||||
endif()
|
||||
|
||||
@@ -241,13 +204,6 @@ if( CMAKE_COMPILER_IS_GNUCXX OR CMAKE_CXX_COMPILER_ID MATCHES "Clang" )
|
||||
if(COMPILER_SUPPORTS_WSUGGEST_OVERRIDE)
|
||||
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wsuggest-override")
|
||||
endif()
|
||||
|
||||
CHECK_CXX_COMPILER_FLAG("-Wvla" COMPILER_SUPPORTS_WVLA)
|
||||
|
||||
if(COMPILER_SUPPORTS_WVLA)
|
||||
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Werror=vla")
|
||||
endif()
|
||||
|
||||
endif()
|
||||
|
||||
|
||||
@@ -255,7 +211,7 @@ endif()
|
||||
# Unfortunately, the swig autogenerated files have a lot of shadowed variables
|
||||
# and -Wno-shadow does not exist.
|
||||
# Adding -Wshadow can be made only for .cpp files
|
||||
# and will be added later in CMakeLists.txt
|
||||
#and will be added later in CMakeLists.txt
|
||||
if( CMAKE_COMPILER_IS_GNUCXX OR CMAKE_CXX_COMPILER_ID MATCHES "Clang" )
|
||||
include(CheckCXXCompilerFlag)
|
||||
|
||||
@@ -266,16 +222,6 @@ if( CMAKE_COMPILER_IS_GNUCXX OR CMAKE_CXX_COMPILER_ID MATCHES "Clang" )
|
||||
endif()
|
||||
endif()
|
||||
|
||||
if( WIN32 )
|
||||
# define UNICODE and_UNICODE definition on Windows. KiCad uses unicode.
|
||||
# Both definitions are required
|
||||
add_definitions(-DUNICODE -D_UNICODE)
|
||||
|
||||
# In fully standards-compliant mode, M_PI et al. are defined only if
|
||||
# _USE_MATH_DEFINES is set.
|
||||
add_definitions( -D_USE_MATH_DEFINES )
|
||||
endif()
|
||||
|
||||
|
||||
#================================================
|
||||
# Provide access to CCACHE
|
||||
@@ -299,7 +245,7 @@ endif(USE_CCACHE)
|
||||
|
||||
|
||||
#================================================
|
||||
# Provide access to DISTCC
|
||||
# Provide access to CCACHE
|
||||
#================================================
|
||||
if (USE_DISTCC)
|
||||
find_program(DISTCC_FOUND distcc)
|
||||
@@ -320,9 +266,18 @@ endif(USE_DISTCC)
|
||||
|
||||
if( CMAKE_COMPILER_IS_GNUCXX OR CMAKE_CXX_COMPILER_ID MATCHES "Clang" )
|
||||
|
||||
# Set 32-bit flag for GCC to prevent excess precision
|
||||
if( CMAKE_SIZEOF_VOID_P EQUAL 4 )
|
||||
set( CMAKE_CXX_FLAGS "-ffloat-store ${CMAKE_CXX_FLAGS}" )
|
||||
execute_process( COMMAND ${CMAKE_C_COMPILER} -dumpversion
|
||||
OUTPUT_VARIABLE GCC_VERSION
|
||||
OUTPUT_STRIP_TRAILING_WHITESPACE )
|
||||
|
||||
if( CMAKE_CXX_COMPILER_ID MATCHES "Clang" )
|
||||
set( TO_LINKER -XLinker )
|
||||
else()
|
||||
set( TO_LINKER -Wl )
|
||||
# Set 32-bit flag for GCC to prevent excess precision
|
||||
if( CMAKE_SIZEOF_VOID_P EQUAL 4 )
|
||||
set( CMAKE_CXX_FLAGS "-ffloat-store ${CMAKE_CXX_FLAGS}" )
|
||||
endif()
|
||||
endif()
|
||||
|
||||
# Establish -Wall early, so specialized relaxations of this may come
|
||||
@@ -343,24 +298,16 @@ if( CMAKE_COMPILER_IS_GNUCXX OR CMAKE_CXX_COMPILER_ID MATCHES "Clang" )
|
||||
set( CMAKE_CXX_FLAGS_DEBUG "-g3 -ggdb3 -DDEBUG -Wno-deprecated-declarations" )
|
||||
endif()
|
||||
|
||||
if( KICAD_SANITIZE )
|
||||
add_definitions( -DKICAD_SANITIZE )
|
||||
set( CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -D_GLIBCXX_SANITIZE_VECTOR -fsanitize=address -fno-optimize-sibling-calls -fsanitize-address-use-after-scope -fno-omit-frame-pointer" )
|
||||
endif()
|
||||
|
||||
if( KICAD_STDLIB_DEBUG )
|
||||
add_definitions( -DKICAD_STDLIB_DEBUG )
|
||||
set( CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} -D_GLIBCXX_DEBUG" )
|
||||
elseif( KICAD_STDLIB_LIGHT_DEBUG )
|
||||
# useless if KICAD_STDLIB_DEBUG is ON.
|
||||
# this option makes some controls to trap out of bound memory access.
|
||||
add_definitions( -DKICAD_STDLIB_LIGHT_DEBUG )
|
||||
set( CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} -Wp,-D_GLIBCXX_ASSERTIONS" )
|
||||
endif()
|
||||
|
||||
if( MINGW )
|
||||
set( CMAKE_EXE_LINKER_FLAGS_RELEASE "-s" )
|
||||
|
||||
# _UNICODE definition seems needed under mingw/gcc 4.8
|
||||
# (Kicad uses unicode, and on Windows, wxWidgets >= 2.9.4 is mandatory
|
||||
# and uses unicode)
|
||||
if( GCC_VERSION VERSION_EQUAL 4.8.0 OR GCC_VERSION VERSION_GREATER 4.8.0 )
|
||||
add_definitions(-D_UNICODE)
|
||||
endif()
|
||||
|
||||
# Since version 2.8.5, Cmake uses a response file (.rsp) to
|
||||
# pass the list of include paths to gcc
|
||||
# unfortunately, under mingw32+msys, at least with gcc 4.8 and previous,
|
||||
@@ -386,51 +333,37 @@ if( CMAKE_COMPILER_IS_GNUCXX OR CMAKE_CXX_COMPILER_ID MATCHES "Clang" )
|
||||
# snprintf
|
||||
add_definitions(-D__USE_MINGW_ANSI_STDIO=1)
|
||||
|
||||
elseif( NOT APPLE )
|
||||
# Thou shalt not link vaporware and tell us it's a valid DSO (apple ld doesn't support it)
|
||||
# temporarily disabled due to breaking ASAN-enabled builds - Tom
|
||||
# set( CMAKE_SHARED_LINKER_FLAGS "-Wl,--no-undefined" )
|
||||
# set( CMAKE_MODULE_LINKER_FLAGS "-Wl,--no-undefined" )
|
||||
else()
|
||||
if( NOT APPLE )
|
||||
# Thou shalt not link vaporware and tell us it's a valid DSO (apple ld doesn't support it)
|
||||
set( CMAKE_SHARED_LINKER_FLAGS "${TO_LINKER},--no-undefined" )
|
||||
set( CMAKE_MODULE_LINKER_FLAGS "${TO_LINKER},--no-undefined" )
|
||||
|
||||
set( CMAKE_EXE_LINKER_FLAGS_RELEASE "-s" )
|
||||
|
||||
# Defeat ELF's ability to use the GOT to replace locally implemented functions
|
||||
# with ones from another module.
|
||||
# https://bugs.launchpad.net/kicad/+bug/1322354
|
||||
set( CMAKE_SHARED_LINKER_FLAGS "${CMAKE_SHARED_LINKER_FLAGS} ${TO_LINKER},-Bsymbolic" )
|
||||
set( CMAKE_MODULE_LINKER_FLAGS "${CMAKE_MODULE_LINKER_FLAGS} ${TO_LINKER},-Bsymbolic" )
|
||||
endif()
|
||||
|
||||
set( CMAKE_EXE_LINKER_FLAGS_RELEASE "-s" )
|
||||
endif()
|
||||
|
||||
# quiet GCC while in boost
|
||||
if( GCC_VERSION VERSION_GREATER 4.8 OR GCC_VERSION VERSION_EQUAL 4.8 OR CMAKE_CXX_COMPILER_ID MATCHES "Clang" )
|
||||
set( CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wno-unused-local-typedefs" )
|
||||
endif()
|
||||
set( CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wno-strict-aliasing" )
|
||||
|
||||
if( APPLE )
|
||||
set( CMAKE_LD_FLAGS "${CMAKE_LD_FLAGS} -headerpad_max_install_names") # needed by fixbundle
|
||||
endif()
|
||||
|
||||
endif( CMAKE_COMPILER_IS_GNUCXX OR CMAKE_CXX_COMPILER_ID MATCHES "Clang" )
|
||||
|
||||
if( MSVC )
|
||||
# Disallow implicit linking for Boost
|
||||
add_definitions( -DBOOST_ALL_NO_LIB )
|
||||
# Disable MSVC's deprecation warnings
|
||||
add_definitions( -D_CRT_SECURE_NO_WARNINGS -D_CRT_NONSTDC_NO_DEPRECATE -D_SCL_SECURE_NO_WARNINGS )
|
||||
# Hide Windows's min() and max() macros
|
||||
add_definitions( -DNOMINMAX )
|
||||
# source and execution charset are UTF-8
|
||||
string( APPEND CMAKE_CXX_FLAGS " /utf-8" )
|
||||
# C4290: throw() is interpreted as declspec(nothrow)
|
||||
string( APPEND CMAKE_CXX_FLAGS " /wd4290" )
|
||||
# C4800: non-bool is explicitly cast to bool, forcing value of 0 or 1
|
||||
string( APPEND CMAKE_CXX_FLAGS " /wd4800" )
|
||||
# /Zi: create PDB
|
||||
string( APPEND CMAKE_CXX_FLAGS " /Zi" )
|
||||
# /GF: enable string pooling
|
||||
string( APPEND CMAKE_CXX_FLAGS_RELEASE " /GF" )
|
||||
foreach( type EXE SHARED MODULE)
|
||||
# /DEBUG: create PDB
|
||||
string( APPEND CMAKE_${type}_LINKER_FLAGS " /DEBUG" )
|
||||
# /OPT:REF: omit unreferenced code
|
||||
string( APPEND CMAKE_${type}_LINKER_FLAGS_RELEASE " /OPT:REF" )
|
||||
# /OPT:ICF: fold common data
|
||||
string( APPEND CMAKE_${type}_LINKER_FLAGS_RELEASE " /OPT:ICF" )
|
||||
endforeach()
|
||||
|
||||
# Let cl.exe parallelize builds
|
||||
if( KICAD_BUILD_PARALLEL_CL_MP )
|
||||
string( APPEND CMAKE_CXX_FLAGS " /MP" )
|
||||
endif()
|
||||
if( USE_WX_OVERLAY OR APPLE )
|
||||
add_definitions( -DUSE_WX_OVERLAY )
|
||||
endif()
|
||||
|
||||
if( KICAD_SCRIPTING )
|
||||
@@ -441,18 +374,10 @@ if( KICAD_SCRIPTING_MODULES )
|
||||
add_definitions( -DKICAD_SCRIPTING_MODULES )
|
||||
endif()
|
||||
|
||||
if( KICAD_SCRIPTING_PYTHON3 )
|
||||
add_definitions( -DKICAD_SCRIPTING_PYTHON3 )
|
||||
endif()
|
||||
|
||||
if( KICAD_SCRIPTING_WXPYTHON )
|
||||
add_definitions( -DKICAD_SCRIPTING_WXPYTHON )
|
||||
endif()
|
||||
|
||||
if( KICAD_SCRIPTING_WXPYTHON_PHOENIX )
|
||||
add_definitions( -DKICAD_SCRIPTING_WXPYTHON_PHOENIX )
|
||||
endif()
|
||||
|
||||
if( KICAD_SCRIPTING_ACTION_MENU )
|
||||
add_definitions( -DKICAD_SCRIPTING_ACTION_MENU )
|
||||
endif()
|
||||
@@ -475,6 +400,10 @@ if( KICAD_USE_CUSTOM_PADS )
|
||||
add_definitions( -DKICAD_USE_CUSTOM_PADS )
|
||||
endif()
|
||||
|
||||
if( USE_WX_GRAPHICS_CONTEXT OR APPLE )
|
||||
add_definitions( -DUSE_WX_GRAPHICS_CONTEXT )
|
||||
endif()
|
||||
|
||||
|
||||
# KIFACE_SUFFIX is the file extension used for top level program modules which
|
||||
# implement the KIFACE interface. A valid suffix starts with a period '.'.
|
||||
@@ -618,6 +547,38 @@ include( ExternalProject )
|
||||
#================================================
|
||||
include( CheckFindPackageResult )
|
||||
|
||||
#
|
||||
# Find wxWidgets library, required
|
||||
#
|
||||
|
||||
# Here you can define what libraries of wxWidgets you need for your
|
||||
# application. You can figure out what libraries you need here;
|
||||
# http://www.wxwidgets.org/manuals/2.8/wx_librarieslist.html
|
||||
|
||||
# Turn on wxWidgets compatibility mode for some classes
|
||||
add_definitions( -DWX_COMPATIBILITY )
|
||||
|
||||
# See line 41 of CMakeModules/FindwxWidgets.cmake
|
||||
set( wxWidgets_CONFIG_OPTIONS ${wxWidgets_CONFIG_OPTIONS} --static=no )
|
||||
|
||||
find_package( wxWidgets 3.0.0 COMPONENTS gl aui adv html core net base xml stc REQUIRED )
|
||||
|
||||
# Include wxWidgets macros.
|
||||
include( ${wxWidgets_USE_FILE} )
|
||||
|
||||
# Check the toolkit used to build wxWidgets
|
||||
execute_process( COMMAND sh -c "${wxWidgets_CONFIG_EXECUTABLE} --query-toolkit"
|
||||
RESULT_VARIABLE wxWidgets_TOOLKIT_RESULT
|
||||
OUTPUT_VARIABLE wxWidgets_TOOLKIT_FOUND
|
||||
OUTPUT_STRIP_TRAILING_WHITESPACE
|
||||
)
|
||||
|
||||
if( wxWidgets_TOOLKIT_FOUND STREQUAL "gtk3" )
|
||||
message( WARNING "\nwxWidgets library has been built against GTK3, it causes a lot of problems in KiCad" )
|
||||
add_definitions( -DUSE_WX_GRAPHICS_CONTEXT )
|
||||
add_definitions( -DWXGTK3 )
|
||||
endif()
|
||||
|
||||
#
|
||||
# Find OpenGL library, required
|
||||
#
|
||||
@@ -636,6 +597,7 @@ endif()
|
||||
# Find GLM library, required
|
||||
#
|
||||
find_package( GLM 0.9.5.1 REQUIRED )
|
||||
|
||||
add_definitions( -DGLM_FORCE_CTOR_INIT )
|
||||
|
||||
#
|
||||
@@ -648,7 +610,7 @@ endif()
|
||||
#
|
||||
# Find Cairo library, required
|
||||
#
|
||||
find_package( Cairo 1.12 REQUIRED )
|
||||
find_package( Cairo 1.8.8 REQUIRED )
|
||||
find_package( Pixman 0.30 REQUIRED )
|
||||
|
||||
#
|
||||
@@ -658,9 +620,10 @@ find_package( Boost 1.54.0 REQUIRED )
|
||||
# Include MinGW resource compiler.
|
||||
include( MinGWResourceCompiler )
|
||||
|
||||
if( WIN32 )
|
||||
# we need the gdiplus library for cairo printing on windows
|
||||
set( GDI_PLUS_LIBRARIES gdiplus )
|
||||
# Find GDI+ on windows if wxGraphicsContext is available.
|
||||
if( MINGW AND USE_WX_GRAPHICS_CONTEXT )
|
||||
find_package( GdiPlus )
|
||||
check_find_package_result( GDI_PLUS_FOUND "GDI+" )
|
||||
endif()
|
||||
|
||||
# Find ngspice library, required for integrated circuit simulator
|
||||
@@ -709,36 +672,30 @@ set( INC_AFTER
|
||||
${CMAKE_BINARY_DIR}
|
||||
)
|
||||
|
||||
#
|
||||
|
||||
# Find Python and other scripting resources
|
||||
#
|
||||
if( KICAD_SCRIPTING OR KICAD_SCRIPTING_MODULES )
|
||||
|
||||
# SWIG 3.0 or later require for C++11 support.
|
||||
find_package( SWIG 3.0 REQUIRED )
|
||||
include( ${SWIG_USE_FILE} )
|
||||
|
||||
if( KICAD_SCRIPTING_PYTHON3 )
|
||||
set( PythonInterp_FIND_VERSION 3.3 )
|
||||
set( PythonLibs_FIND_VERSION 3.3 )
|
||||
else()
|
||||
# force a python version < 3.0
|
||||
set( PythonInterp_FIND_VERSION 2.6 )
|
||||
set( PythonLibs_FIND_VERSION 2.6 )
|
||||
endif()
|
||||
# force a python version < 3.0
|
||||
set( PythonInterp_FIND_VERSION 2.6 )
|
||||
set( PythonLibs_FIND_VERSION 2.6 )
|
||||
|
||||
find_package( PythonInterp )
|
||||
|
||||
check_find_package_result( PYTHONINTERP_FOUND "Python Interpreter" )
|
||||
|
||||
if( NOT KICAD_SCRIPTING_PYTHON3 AND NOT PYTHON_VERSION_MAJOR EQUAL 2 )
|
||||
if( NOT PYTHON_VERSION_MAJOR EQUAL 2 )
|
||||
message( FATAL_ERROR "Python 2.x is required." )
|
||||
endif()
|
||||
|
||||
# Get the correct Python site package install path from the Python interpreter found by
|
||||
# FindPythonInterp unless the user specifically defined a custom path.
|
||||
if( NOT PYTHON_SITE_PACKAGE_PATH )
|
||||
execute_process( COMMAND ${PYTHON_EXECUTABLE} -c "import distutils.sysconfig;print(\"%s\"%distutils.sysconfig.get_python_lib(plat_specific=0, standard_lib=0, prefix=''))"
|
||||
execute_process( COMMAND ${PYTHON_EXECUTABLE} -c "import distutils.sysconfig;print\"%s\"%distutils.sysconfig.get_python_lib(plat_specific=0, standard_lib=0, prefix='')"
|
||||
OUTPUT_VARIABLE PYTHON_SITE_PACKAGE_PATH
|
||||
OUTPUT_STRIP_TRAILING_WHITESPACE
|
||||
)
|
||||
@@ -763,99 +720,78 @@ if( KICAD_SCRIPTING OR KICAD_SCRIPTING_MODULES )
|
||||
mark_as_advanced( PYTHON_DEST )
|
||||
message( STATUS "Python module install path: ${PYTHON_DEST}" )
|
||||
|
||||
if( KICAD_SCRIPTING_PYTHON3 )
|
||||
find_package( PythonLibs 3.3 REQUIRED )
|
||||
else()
|
||||
find_package( PythonLibs 2.6 REQUIRED )
|
||||
find_package( PythonLibs 2.6 )
|
||||
|
||||
if( KICAD_SCRIPTING_WXPYTHON )
|
||||
# Check to see if the correct version of wxPython is installed based on the version of
|
||||
# wxWidgets found. At least the major an minor version should match.
|
||||
set( _wxpy_version "${wxWidgets_VERSION_MAJOR}.${wxWidgets_VERSION_MINOR}" )
|
||||
set( _py_cmd "import wxversion;print wxversion.checkInstalled('${_wxpy_version}')" )
|
||||
|
||||
# Add user specified Python site package path.
|
||||
if( PYTHON_SITE_PACKAGE_PATH )
|
||||
set( _py_cmd
|
||||
"import sys;sys.path.insert(0, \"${PYTHON_SITE_PACKAGE_PATH}\");${_py_cmd}" )
|
||||
endif()
|
||||
|
||||
execute_process( COMMAND ${PYTHON_EXECUTABLE} -c "${_py_cmd}"
|
||||
RESULT_VARIABLE WXPYTHON_VERSION_RESULT
|
||||
OUTPUT_VARIABLE WXPYTHON_VERSION_FOUND
|
||||
OUTPUT_STRIP_TRAILING_WHITESPACE
|
||||
)
|
||||
|
||||
# message( STATUS "WXPYTHON_VERSION_FOUND: ${WXPYTHON_VERSION_FOUND}" )
|
||||
# message( STATUS "WXPYTHON_VERSION_RESULT: ${WXPYTHON_VERSION_RESULT}" )
|
||||
|
||||
# Check to see if any version of wxPython is installed on the system.
|
||||
if( WXPYTHON_VERSION_RESULT GREATER 0 )
|
||||
message( FATAL_ERROR "wxPython does not appear to be installed on the system." )
|
||||
endif()
|
||||
|
||||
if( NOT WXPYTHON_VERSION_FOUND STREQUAL "True" )
|
||||
message( FATAL_ERROR
|
||||
"wxPython version ${_wxpy_version} does not appear to be installed on the system." )
|
||||
endif()
|
||||
|
||||
set( WXPYTHON_VERSION ${_wxpy_version} CACHE STRING "wxPython version found." )
|
||||
message( STATUS "wxPython version ${_wxpy_version} found." )
|
||||
|
||||
|
||||
# Compare wxPython and wxWidgets toolkits
|
||||
set( _py_cmd "import wx; print(wx.version().split(' ')[1])" )
|
||||
|
||||
# Add user specified Python site package path.
|
||||
if( PYTHON_SITE_PACKAGE_PATH )
|
||||
set( _py_cmd
|
||||
"import sys;sys.path.insert(0, \"${PYTHON_SITE_PACKAGE_PATH}\");${_py_cmd}" )
|
||||
endif()
|
||||
|
||||
execute_process( COMMAND ${PYTHON_EXECUTABLE} -c "${_py_cmd}"
|
||||
RESULT_VARIABLE WXPYTHON_TOOLKIT_RESULT
|
||||
OUTPUT_VARIABLE WXPYTHON_TOOLKIT_FOUND
|
||||
OUTPUT_STRIP_TRAILING_WHITESPACE
|
||||
)
|
||||
|
||||
# Check if wxWidgets toolkits match, it is a Linux-only issue
|
||||
if( UNIX AND NOT APPLE AND NOT wxWidgets_TOOLKIT_FOUND STREQUAL WXPYTHON_TOOLKIT_FOUND )
|
||||
message( FATAL_ERROR "\nwxWidgets and wxPython use different toolkits "
|
||||
"(${wxWidgets_TOOLKIT_FOUND} vs ${WXPYTHON_TOOLKIT_FOUND}). "
|
||||
"It will result in a broken build. Please either install wxPython built using "
|
||||
"${wxWidgets_TOOLKIT_FOUND} or add '-DKICAD_SCRIPTING_WXPYTHON=OFF' to cmake "
|
||||
"parameters to disable wxPython support." )
|
||||
endif()
|
||||
endif()
|
||||
|
||||
#message( STATUS "PYTHON_INCLUDE_DIRS:${PYTHON_INCLUDE_DIRS}" )
|
||||
|
||||
# Infrequently needed headers go at end of search paths, append to INC_AFTER which
|
||||
# although is used for all components, should be a harmless hit for something like eeschema
|
||||
# so long as unused search paths are at the end like this.
|
||||
set( INC_AFTER ${INC_AFTER} ${PYTHON_INCLUDE_DIRS} ${CMAKE_CURRENT_SOURCE_DIR}/scripting )
|
||||
|
||||
#message( STATUS "/ INC_AFTER:${INC_AFTER}" )
|
||||
endif()
|
||||
|
||||
# Find the wxPython installation if requested
|
||||
if( KICAD_SCRIPTING_WXPYTHON )
|
||||
find_package( wxPython REQUIRED )
|
||||
|
||||
if( KICAD_SCRIPTING_WXPYTHON_PHOENIX AND WXPYTHON_VERSION VERSION_LESS 4.0.0 )
|
||||
message( FATAL_ERROR
|
||||
"Unable to find wxPython Phoenix,"
|
||||
" instead found wxPython Classic ${WXPYTHON_VERSION}" )
|
||||
endif()
|
||||
|
||||
# The test VERSION_GREATER_EQUAL is only available in cmake >3.7, so use the max possible
|
||||
# version for the 3.0 line as the basis of the comparison
|
||||
if( NOT KICAD_SCRIPTING_WXPYTHON_PHOENIX AND WXPYTHON_VERSION VERSION_GREATER 3.9.999 )
|
||||
message( FATAL_ERROR
|
||||
"Unable to find wxPython Classic,"
|
||||
" instead found wxPython Phoenix ${WXPYTHON_VERSION}" )
|
||||
endif()
|
||||
|
||||
message( STATUS "Found ${WXPYTHON_FLAVOR} "
|
||||
"${WXPYTHON_VERSION}/${WXPYTHON_TOOLKIT} "
|
||||
"(wxWidgets ${WXPYTHON_WXVERSION})" )
|
||||
endif()
|
||||
|
||||
|
||||
#
|
||||
# Find wxWidgets library, required
|
||||
#
|
||||
|
||||
# Turn on wxWidgets compatibility mode for some classes
|
||||
add_definitions( -DWX_COMPATIBILITY )
|
||||
|
||||
if( KICAD_SCRIPTING_WXPYTHON )
|
||||
# Check if '--toolkit=xxx' option has been passed
|
||||
string( REGEX MATCH "--toolkit=([a-zA-Z0-9]+)"
|
||||
WXWIDGETS_REQUESTED_TOOLKIT "${wxWidgets_CONFIG_OPTIONS}" )
|
||||
|
||||
if( WXWIDGETS_REQUESTED_TOOLKIT
|
||||
AND NOT WXWIDGETS_REQUESTED_TOOLKIT STREQUAL "--toolkit=${WXPYTHON_TOOLKIT}" )
|
||||
message( WARNING "wxWidgets and wxPython must be based on the same toolkit.\n"
|
||||
"It will be fixed automatically if you skip the '--toolkit=xxx' "
|
||||
"wxWidgets_CONFIG_OPTIONS parameter.")
|
||||
else()
|
||||
# Use the same toolkit as wxPython otherwise there will be a symbol conflict
|
||||
set( wxWidgets_CONFIG_OPTIONS ${wxWidgets_CONFIG_OPTIONS} "--toolkit=${WXPYTHON_TOOLKIT}" )
|
||||
endif()
|
||||
|
||||
# Require the same wxWidgets version as is used by wxPython
|
||||
set( wxWidgets_REQ_VERSION ${WXPYTHON_WXVERSION} )
|
||||
else()
|
||||
# Require wxWidgets 3.0.0 as the minimum when wxPython is disabled
|
||||
set( wxWidgets_REQ_VERSION 3.0.0 )
|
||||
endif()
|
||||
|
||||
# See line 49 of CMakeModules/FindwxWidgets.cmake
|
||||
set( wxWidgets_CONFIG_OPTIONS ${wxWidgets_CONFIG_OPTIONS} --static=no )
|
||||
|
||||
find_package( wxWidgets ${wxWidgets_REQ_VERSION} COMPONENTS gl aui adv html core net base xml stc REQUIRED )
|
||||
|
||||
# Include wxWidgets macros.
|
||||
include( ${wxWidgets_USE_FILE} )
|
||||
|
||||
if( KICAD_SCRIPTING_WXPYTHON AND NOT KICAD_SCRIPTING_WXPYTHON_PHOENIX )
|
||||
# wxPython appears to be installed and valid so make sure the headers are available.
|
||||
foreach( path ${wxWidgets_INCLUDE_DIRS} )
|
||||
#message( STATUS "Searching for wx/wxPython/wxPython.h in ${path}" )
|
||||
|
||||
find_path( wxPYTHON_INCLUDE_DIRS wx/wxPython/wxPython.h
|
||||
PATHS "${path}" )
|
||||
|
||||
if( wxPYTHON_INCLUDE_DIRS )
|
||||
message( STATUS "Found wxPython.h in ${path}/wx/wxPython" )
|
||||
break()
|
||||
endif()
|
||||
endforeach()
|
||||
|
||||
if( NOT wxPYTHON_INCLUDE_DIRS )
|
||||
message( FATAL_ERROR "Cannot find wxPython.h" )
|
||||
endif()
|
||||
endif()
|
||||
|
||||
|
||||
if( APPLE )
|
||||
# Remove app bundles in ${KICAD_BIN} before installing anything new.
|
||||
# Must be defined before all includes so that it is executed first.
|
||||
@@ -894,8 +830,6 @@ if( DOXYGEN_FOUND )
|
||||
DEPENDS Doxyfile
|
||||
COMMENT "building developer's resource docs into directory Documentation/development/doxygen/html"
|
||||
)
|
||||
|
||||
add_subdirectory(Documentation/docset)
|
||||
else()
|
||||
message( STATUS "WARNING: Doxygen not found - doxygen-docs (Source Docs) target not created" )
|
||||
endif()
|
||||
@@ -1006,13 +940,12 @@ endif()
|
||||
|
||||
# Binaries ( CMake targets )
|
||||
add_subdirectory( bitmaps_png )
|
||||
add_subdirectory( libs )
|
||||
add_subdirectory( common )
|
||||
add_subdirectory( 3d-viewer )
|
||||
add_subdirectory( cvpcb )
|
||||
add_subdirectory( eeschema )
|
||||
add_subdirectory( gerbview )
|
||||
add_subdirectory( dxflib_qcad )
|
||||
add_subdirectory( lib_dxf )
|
||||
add_subdirectory( pcbnew )
|
||||
add_subdirectory( polygon )
|
||||
add_subdirectory( pagelayout_editor )
|
||||
|
||||
@@ -39,6 +39,7 @@ macro( create_git_version_header _git_src_path )
|
||||
ERROR_VARIABLE _git_log_error
|
||||
RESULT_VARIABLE _git_log_result
|
||||
OUTPUT_STRIP_TRAILING_WHITESPACE)
|
||||
endif()
|
||||
|
||||
set( ENV{LC_ALL} ${_Git_SAVED_LC_ALL} )
|
||||
endif( GIT_FOUND )
|
||||
|
||||
@@ -0,0 +1,342 @@
|
||||
#.rst:
|
||||
# FindOpenSSL
|
||||
# -----------
|
||||
#
|
||||
# Try to find the OpenSSL encryption library
|
||||
#
|
||||
# Once done this will define
|
||||
#
|
||||
# ::
|
||||
#
|
||||
# OPENSSL_ROOT_DIR - Set this variable to the root installation of OpenSSL
|
||||
#
|
||||
#
|
||||
#
|
||||
# Read-Only variables:
|
||||
#
|
||||
# ::
|
||||
#
|
||||
# OPENSSL_FOUND - system has the OpenSSL library
|
||||
# OPENSSL_INCLUDE_DIR - the OpenSSL include directory
|
||||
# OPENSSL_LIBRARIES - The libraries needed to use OpenSSL
|
||||
# OPENSSL_VERSION - This is set to $major.$minor.$revision$path (eg. 0.9.8s)
|
||||
|
||||
#=============================================================================
|
||||
# Copyright 2006-2009 Kitware, Inc.
|
||||
# Copyright 2006 Alexander Neundorf <neundorf@kde.org>
|
||||
# Copyright 2009-2011 Mathieu Malaterre <mathieu.malaterre@gmail.com>
|
||||
#
|
||||
# Distributed under the OSI-approved BSD License (the "License");
|
||||
# see accompanying file Copyright.txt for details.
|
||||
#
|
||||
# This software is distributed WITHOUT ANY WARRANTY; without even the
|
||||
# implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||
# See the License for more information.
|
||||
#=============================================================================
|
||||
# (To distribute this file outside of CMake, substitute the full
|
||||
# License text for the above reference.)
|
||||
|
||||
if (UNIX)
|
||||
find_package(PkgConfig QUIET)
|
||||
pkg_check_modules(_OPENSSL QUIET openssl)
|
||||
endif ()
|
||||
|
||||
if (WIN32)
|
||||
# http://www.slproweb.com/products/Win32OpenSSL.html
|
||||
set(_OPENSSL_ROOT_HINTS
|
||||
${OPENSSL_ROOT_DIR}
|
||||
"[HKEY_LOCAL_MACHINE\\SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Uninstall\\OpenSSL (32-bit)_is1;Inno Setup: App Path]"
|
||||
"[HKEY_LOCAL_MACHINE\\SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Uninstall\\OpenSSL (64-bit)_is1;Inno Setup: App Path]"
|
||||
ENV OPENSSL_ROOT_DIR
|
||||
)
|
||||
file(TO_CMAKE_PATH "$ENV{PROGRAMFILES}" _programfiles)
|
||||
set(_OPENSSL_ROOT_PATHS
|
||||
"${_programfiles}/OpenSSL"
|
||||
"${_programfiles}/OpenSSL-Win32"
|
||||
"${_programfiles}/OpenSSL-Win64"
|
||||
"C:/OpenSSL/"
|
||||
"C:/OpenSSL-Win32/"
|
||||
"C:/OpenSSL-Win64/"
|
||||
)
|
||||
unset(_programfiles)
|
||||
else ()
|
||||
set(_OPENSSL_ROOT_HINTS
|
||||
${OPENSSL_ROOT_DIR}
|
||||
ENV OPENSSL_ROOT_DIR
|
||||
)
|
||||
endif ()
|
||||
|
||||
set(_OPENSSL_ROOT_HINTS_AND_PATHS
|
||||
HINTS ${_OPENSSL_ROOT_HINTS}
|
||||
PATHS ${_OPENSSL_ROOT_PATHS}
|
||||
)
|
||||
|
||||
find_path(OPENSSL_INCLUDE_DIR
|
||||
NAMES
|
||||
openssl/ssl.h
|
||||
${_OPENSSL_ROOT_HINTS_AND_PATHS}
|
||||
HINTS
|
||||
${_OPENSSL_INCLUDEDIR}
|
||||
PATH_SUFFIXES
|
||||
include
|
||||
)
|
||||
|
||||
if(WIN32 AND NOT CYGWIN)
|
||||
if(MSVC)
|
||||
# /MD and /MDd are the standard values - if someone wants to use
|
||||
# others, the libnames have to change here too
|
||||
# use also ssl and ssleay32 in debug as fallback for openssl < 0.9.8b
|
||||
# TODO: handle /MT and static lib
|
||||
# In Visual C++ naming convention each of these four kinds of Windows libraries has it's standard suffix:
|
||||
# * MD for dynamic-release
|
||||
# * MDd for dynamic-debug
|
||||
# * MT for static-release
|
||||
# * MTd for static-debug
|
||||
|
||||
# Implementation details:
|
||||
# We are using the libraries located in the VC subdir instead of the parent directory eventhough :
|
||||
# libeay32MD.lib is identical to ../libeay32.lib, and
|
||||
# ssleay32MD.lib is identical to ../ssleay32.lib
|
||||
find_library(LIB_EAY_DEBUG
|
||||
NAMES
|
||||
libeay32MDd
|
||||
libeay32d
|
||||
${_OPENSSL_ROOT_HINTS_AND_PATHS}
|
||||
PATH_SUFFIXES
|
||||
"lib"
|
||||
"VC"
|
||||
"lib/VC"
|
||||
)
|
||||
|
||||
find_library(LIB_EAY_RELEASE
|
||||
NAMES
|
||||
libeay32MD
|
||||
libeay32
|
||||
${_OPENSSL_ROOT_HINTS_AND_PATHS}
|
||||
PATH_SUFFIXES
|
||||
"lib"
|
||||
"VC"
|
||||
"lib/VC"
|
||||
)
|
||||
|
||||
find_library(SSL_EAY_DEBUG
|
||||
NAMES
|
||||
ssleay32MDd
|
||||
ssleay32d
|
||||
${_OPENSSL_ROOT_HINTS_AND_PATHS}
|
||||
PATH_SUFFIXES
|
||||
"lib"
|
||||
"VC"
|
||||
"lib/VC"
|
||||
)
|
||||
|
||||
find_library(SSL_EAY_RELEASE
|
||||
NAMES
|
||||
ssleay32MD
|
||||
ssleay32
|
||||
ssl
|
||||
${_OPENSSL_ROOT_HINTS_AND_PATHS}
|
||||
PATH_SUFFIXES
|
||||
"lib"
|
||||
"VC"
|
||||
"lib/VC"
|
||||
)
|
||||
|
||||
set(LIB_EAY_LIBRARY_DEBUG "${LIB_EAY_DEBUG}")
|
||||
set(LIB_EAY_LIBRARY_RELEASE "${LIB_EAY_RELEASE}")
|
||||
set(SSL_EAY_LIBRARY_DEBUG "${SSL_EAY_DEBUG}")
|
||||
set(SSL_EAY_LIBRARY_RELEASE "${SSL_EAY_RELEASE}")
|
||||
|
||||
include(${CMAKE_CURRENT_LIST_DIR}/SelectLibraryConfigurations.cmake)
|
||||
select_library_configurations(LIB_EAY)
|
||||
select_library_configurations(SSL_EAY)
|
||||
|
||||
mark_as_advanced(LIB_EAY_LIBRARY_DEBUG LIB_EAY_LIBRARY_RELEASE
|
||||
SSL_EAY_LIBRARY_DEBUG SSL_EAY_LIBRARY_RELEASE)
|
||||
set( OPENSSL_LIBRARIES ${SSL_EAY_LIBRARY} ${LIB_EAY_LIBRARY} )
|
||||
elseif(MINGW)
|
||||
message( STATUS "Searching for OpenSSL in MinGW." )
|
||||
# same player, for MinGW
|
||||
set(LIB_EAY_NAMES libeay32)
|
||||
set(SSL_EAY_NAMES ssleay32)
|
||||
list(APPEND LIB_EAY_NAMES crypto)
|
||||
list(APPEND SSL_EAY_NAMES ssl)
|
||||
|
||||
find_library(LIB_EAY
|
||||
NAMES
|
||||
${LIB_EAY_NAMES}
|
||||
${_OPENSSL_ROOT_HINTS_AND_PATHS}
|
||||
PATH_SUFFIXES
|
||||
"lib"
|
||||
"lib/MinGW"
|
||||
# Do not search system path. Otherwise the DLL will be found rather than the link library.
|
||||
NO_SYSTEM_ENVIRONMENT_PATH
|
||||
NO_CMAKE_SYSTEM_PATH
|
||||
)
|
||||
|
||||
find_library(SSL_EAY
|
||||
NAMES
|
||||
${SSL_EAY_NAMES}
|
||||
${_OPENSSL_ROOT_HINTS_AND_PATHS}
|
||||
PATH_SUFFIXES
|
||||
"lib"
|
||||
"lib/MinGW"
|
||||
# Do not search system path. Otherwise the DLL will be found rather than the link library.
|
||||
NO_SYSTEM_ENVIRONMENT_PATH
|
||||
NO_CMAKE_SYSTEM_PATH
|
||||
)
|
||||
|
||||
mark_as_advanced(SSL_EAY LIB_EAY)
|
||||
set( OPENSSL_LIBRARIES ${SSL_EAY} ${LIB_EAY} )
|
||||
unset(LIB_EAY_NAMES)
|
||||
unset(SSL_EAY_NAMES)
|
||||
else()
|
||||
# Not sure what to pick for -say- intel, let's use the toplevel ones and hope someone report issues:
|
||||
find_library(LIB_EAY
|
||||
NAMES
|
||||
libeay32
|
||||
${_OPENSSL_ROOT_HINTS_AND_PATHS}
|
||||
HINTS
|
||||
${_OPENSSL_LIBDIR}
|
||||
PATH_SUFFIXES
|
||||
lib
|
||||
)
|
||||
|
||||
find_library(SSL_EAY
|
||||
NAMES
|
||||
ssleay32
|
||||
${_OPENSSL_ROOT_HINTS_AND_PATHS}
|
||||
HINTS
|
||||
${_OPENSSL_LIBDIR}
|
||||
PATH_SUFFIXES
|
||||
lib
|
||||
)
|
||||
|
||||
mark_as_advanced(SSL_EAY LIB_EAY)
|
||||
set( OPENSSL_LIBRARIES ${SSL_EAY} ${LIB_EAY} )
|
||||
endif()
|
||||
else()
|
||||
|
||||
find_library(OPENSSL_SSL_LIBRARY
|
||||
NAMES
|
||||
ssl
|
||||
ssleay32
|
||||
ssleay32MD
|
||||
${_OPENSSL_ROOT_HINTS_AND_PATHS}
|
||||
HINTS
|
||||
${_OPENSSL_LIBDIR}
|
||||
PATH_SUFFIXES
|
||||
lib
|
||||
)
|
||||
|
||||
find_library(OPENSSL_CRYPTO_LIBRARY
|
||||
NAMES
|
||||
crypto
|
||||
${_OPENSSL_ROOT_HINTS_AND_PATHS}
|
||||
HINTS
|
||||
${_OPENSSL_LIBDIR}
|
||||
PATH_SUFFIXES
|
||||
lib
|
||||
)
|
||||
|
||||
mark_as_advanced(OPENSSL_CRYPTO_LIBRARY OPENSSL_SSL_LIBRARY)
|
||||
|
||||
# compat defines
|
||||
set(OPENSSL_SSL_LIBRARIES ${OPENSSL_SSL_LIBRARY})
|
||||
set(OPENSSL_CRYPTO_LIBRARIES ${OPENSSL_CRYPTO_LIBRARY})
|
||||
|
||||
set(OPENSSL_LIBRARIES ${OPENSSL_SSL_LIBRARY} ${OPENSSL_CRYPTO_LIBRARY})
|
||||
|
||||
endif()
|
||||
|
||||
function(from_hex HEX DEC)
|
||||
string(TOUPPER "${HEX}" HEX)
|
||||
set(_res 0)
|
||||
string(LENGTH "${HEX}" _strlen)
|
||||
|
||||
while (_strlen GREATER 0)
|
||||
math(EXPR _res "${_res} * 16")
|
||||
string(SUBSTRING "${HEX}" 0 1 NIBBLE)
|
||||
string(SUBSTRING "${HEX}" 1 -1 HEX)
|
||||
if (NIBBLE STREQUAL "A")
|
||||
math(EXPR _res "${_res} + 10")
|
||||
elseif (NIBBLE STREQUAL "B")
|
||||
math(EXPR _res "${_res} + 11")
|
||||
elseif (NIBBLE STREQUAL "C")
|
||||
math(EXPR _res "${_res} + 12")
|
||||
elseif (NIBBLE STREQUAL "D")
|
||||
math(EXPR _res "${_res} + 13")
|
||||
elseif (NIBBLE STREQUAL "E")
|
||||
math(EXPR _res "${_res} + 14")
|
||||
elseif (NIBBLE STREQUAL "F")
|
||||
math(EXPR _res "${_res} + 15")
|
||||
else()
|
||||
math(EXPR _res "${_res} + ${NIBBLE}")
|
||||
endif()
|
||||
|
||||
string(LENGTH "${HEX}" _strlen)
|
||||
endwhile()
|
||||
|
||||
set(${DEC} ${_res} PARENT_SCOPE)
|
||||
endfunction()
|
||||
|
||||
if (OPENSSL_INCLUDE_DIR)
|
||||
if (_OPENSSL_VERSION)
|
||||
set(OPENSSL_VERSION "${_OPENSSL_VERSION}")
|
||||
elseif(OPENSSL_INCLUDE_DIR AND EXISTS "${OPENSSL_INCLUDE_DIR}/openssl/opensslv.h")
|
||||
file(STRINGS "${OPENSSL_INCLUDE_DIR}/openssl/opensslv.h" openssl_version_str
|
||||
REGEX "^#[\t ]*define[\t ]+OPENSSL_VERSION_NUMBER[\t ]+0x([0-9a-fA-F])+.*")
|
||||
|
||||
# The version number is encoded as 0xMNNFFPPS: major minor fix patch status
|
||||
# The status gives if this is a developer or prerelease and is ignored here.
|
||||
# Major, minor, and fix directly translate into the version numbers shown in
|
||||
# the string. The patch field translates to the single character suffix that
|
||||
# indicates the bug fix state, which 00 -> nothing, 01 -> a, 02 -> b and so
|
||||
# on.
|
||||
|
||||
message(STATUS "OPENSSL_VERSION_STR=${openssl_version_str}")
|
||||
|
||||
string(REGEX REPLACE "^.*OPENSSL_VERSION_NUMBER[\t ]+0x([0-9a-fA-F])([0-9a-fA-F][0-9a-fA-F])([0-9a-fA-F][0-9a-fA-F])([0-9a-fA-F][0-9a-fA-F])([0-9a-fA-F]).*$"
|
||||
"\\1;\\2;\\3;\\4;\\5" OPENSSL_VERSION_LIST "${openssl_version_str}")
|
||||
list(GET OPENSSL_VERSION_LIST 0 OPENSSL_VERSION_MAJOR)
|
||||
list(GET OPENSSL_VERSION_LIST 1 OPENSSL_VERSION_MINOR)
|
||||
from_hex("${OPENSSL_VERSION_MINOR}" OPENSSL_VERSION_MINOR)
|
||||
list(GET OPENSSL_VERSION_LIST 2 OPENSSL_VERSION_FIX)
|
||||
from_hex("${OPENSSL_VERSION_FIX}" OPENSSL_VERSION_FIX)
|
||||
list(GET OPENSSL_VERSION_LIST 3 OPENSSL_VERSION_PATCH)
|
||||
|
||||
if (NOT OPENSSL_VERSION_PATCH STREQUAL "00")
|
||||
from_hex("${OPENSSL_VERSION_PATCH}" _tmp)
|
||||
# 96 is the ASCII code of 'a' minus 1
|
||||
math(EXPR OPENSSL_VERSION_PATCH_ASCII "${_tmp} + 96")
|
||||
unset(_tmp)
|
||||
# Once anyone knows how OpenSSL would call the patch versions beyond 'z'
|
||||
# this should be updated to handle that, too. This has not happened yet
|
||||
# so it is simply ignored here for now.
|
||||
string(ASCII "${OPENSSL_VERSION_PATCH_ASCII}" OPENSSL_VERSION_PATCH_STRING)
|
||||
endif ()
|
||||
|
||||
set(OPENSSL_VERSION "${OPENSSL_VERSION_MAJOR}.${OPENSSL_VERSION_MINOR}.${OPENSSL_VERSION_FIX}${OPENSSL_VERSION_PATCH_STRING}")
|
||||
endif ()
|
||||
endif ()
|
||||
|
||||
include(FindPackageHandleStandardArgs)
|
||||
|
||||
if (OPENSSL_VERSION)
|
||||
find_package_handle_standard_args(OpenSSL
|
||||
REQUIRED_VARS
|
||||
OPENSSL_LIBRARIES
|
||||
OPENSSL_INCLUDE_DIR
|
||||
VERSION_VAR
|
||||
OPENSSL_VERSION
|
||||
FAIL_MESSAGE
|
||||
"Could NOT find OpenSSL, try to set the path to OpenSSL root folder in the system variable OPENSSL_ROOT_DIR"
|
||||
)
|
||||
else ()
|
||||
find_package_handle_standard_args(OpenSSL "Could NOT find OpenSSL, try to set the path to OpenSSL root folder in the system variable OPENSSL_ROOT_DIR"
|
||||
OPENSSL_LIBRARIES
|
||||
OPENSSL_INCLUDE_DIR
|
||||
)
|
||||
endif ()
|
||||
|
||||
mark_as_advanced(OPENSSL_INCLUDE_DIR OPENSSL_LIBRARIES)
|
||||
@@ -37,7 +37,7 @@ unset(_Python_NAMES)
|
||||
|
||||
set(_PYTHON1_VERSIONS 1.6 1.5)
|
||||
set(_PYTHON2_VERSIONS 2.7 2.6 2.5 2.4 2.3 2.2 2.1 2.0)
|
||||
set(_PYTHON3_VERSIONS 3.8 3.7 3.6 3.5 3.4 3.3 3.2 3.1 3.0)
|
||||
set(_PYTHON3_VERSIONS 3.3 3.2 3.1 3.0)
|
||||
|
||||
if(PythonInterp_FIND_VERSION)
|
||||
if(PythonInterp_FIND_VERSION MATCHES "^[0-9]+\\.[0-9]+(\\.[0-9]+.*)?$")
|
||||
|
||||
@@ -44,7 +44,7 @@ cmake_find_frameworks(Python)
|
||||
|
||||
set(_PYTHON1_VERSIONS 1.6 1.5)
|
||||
set(_PYTHON2_VERSIONS 2.7 2.6 2.5 2.4 2.3 2.2 2.1 2.0)
|
||||
set(_PYTHON3_VERSIONS 3.8 3.7 3.6 3.5 3.4 3.3 3.2 3.1 3.0)
|
||||
set(_PYTHON3_VERSIONS 3.3 3.2 3.1 3.0)
|
||||
|
||||
if(PythonLibs_FIND_VERSION)
|
||||
if(PythonLibs_FIND_VERSION MATCHES "^[0-9]+\\.[0-9]+(\\.[0-9]+.*)?$")
|
||||
|
||||
@@ -1,28 +1,9 @@
|
||||
# CMake script for finding libngspice
|
||||
|
||||
# Copyright (C) 2016 CERN
|
||||
# (C) CERN 2016
|
||||
# Author: Maciej Suminski <maciej.suminski@cern.ch>
|
||||
#
|
||||
# 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
|
||||
|
||||
find_path( NGSPICE_INCLUDE_DIR ngspice/sharedspice.h
|
||||
PATHS ${NGSPICE_ROOT_DIR} $ENV{NGSPICE_ROOT_DIR} ${NGSPICE_INCLUDE_PATH}
|
||||
${NGSPICE_ROOT_DIR}/include
|
||||
PATH_SUFFIXES src/include share/ngspice/include share/ngspice/include/ngspice
|
||||
)
|
||||
|
||||
@@ -48,7 +29,7 @@ if( ${NGSPICE_INCLUDE_DIR} STREQUAL "NGSPICE_INCLUDE_DIR-NOTFOUND" OR ${NGSPICE_
|
||||
message( "Most of ngspice packages do not provide the required libngspice library." )
|
||||
message( "You can either compile ngspice configured with --with-ngshared parameter" )
|
||||
message( "or run a script that does the job for you:" )
|
||||
message( " cd ./scripting/build_tools" )
|
||||
message( " cd ./scripts" )
|
||||
message( " chmod +x get_libngspice_so.sh" )
|
||||
message( " ./get_libngspice_so.sh" )
|
||||
message( " sudo ./get_libngspice_so.sh install" )
|
||||
|
||||
@@ -1,101 +0,0 @@
|
||||
# CMake script for finding wxPython/Phoenix library
|
||||
|
||||
# Copyright (C) 2018 CERN
|
||||
# Author: Maciej Suminski <maciej.suminski@cern.ch>
|
||||
#
|
||||
# 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
|
||||
|
||||
# Exported variables:
|
||||
# WXPYTHON_VERSION: wxPython/Phoenix version,
|
||||
# normally 3.x.x for wxPython, 4.x.x for Phoenix
|
||||
# WXPYTHON_FLAVOR: 'Phoenix' or 'wxPython'
|
||||
# WXPYTHON_TOOLKIT: base library toolkit (e.g. gtk2, gtk3, msw, osx_cocoa)
|
||||
# WXPYTHON_WXVERSION: wxWidgets version used by wxPython/Phoenix
|
||||
|
||||
# Create a CMake list containing wxPython version
|
||||
set( _py_cmd "import wx;print(wx.version())" )
|
||||
|
||||
# Add user specified Python site package path
|
||||
if( PYTHON_SITE_PACKAGE_PATH )
|
||||
set( _py_site_path
|
||||
"import sys;sys.path.insert(0, \"${PYTHON_SITE_PACKAGE_PATH}\");" )
|
||||
|
||||
if( APPLE ) # extra path for macOS, so that 'wx' module is accessible
|
||||
set( _py_site_path
|
||||
"${_py_site_path}sys.path.insert(0, \"${PYTHON_SITE_PACKAGE_PATH}/wx-3.0-osx_cocoa\");" )
|
||||
endif()
|
||||
endif()
|
||||
|
||||
execute_process( COMMAND ${PYTHON_EXECUTABLE} -c "${_py_site_path}${_py_cmd}"
|
||||
RESULT_VARIABLE _WXPYTHON_VERSION_RESULT
|
||||
OUTPUT_VARIABLE _WXPYTHON_VERSION_FOUND
|
||||
OUTPUT_STRIP_TRAILING_WHITESPACE
|
||||
)
|
||||
|
||||
# Check to see if any version of wxPython is installed on the system.
|
||||
if( _WXPYTHON_VERSION_RESULT GREATER 0 )
|
||||
message( FATAL_ERROR "wxPython/Phoenix does not appear to be installed on the system" )
|
||||
endif()
|
||||
|
||||
|
||||
# Turn the version string to a list for easier processing
|
||||
set( _WXPYTHON_VERSION_LIST ${_WXPYTHON_VERSION_FOUND})
|
||||
separate_arguments( _WXPYTHON_VERSION_LIST )
|
||||
list( LENGTH _WXPYTHON_VERSION_LIST _VERSION_LIST_LEN )
|
||||
|
||||
if( _VERSION_LIST_LEN LESS 3 )
|
||||
message( FATAL_ERROR "Unknown wxPython/Phoenix version string: ${_WXPYTHON_VERSION_FOUND}" )
|
||||
endif()
|
||||
|
||||
# wxPython style, e.g. '3.0.2.0;gtk3;(classic) or Pheonix style: e.g. 4.0.1;gtk3;(phoenix)
|
||||
list( GET _WXPYTHON_VERSION_LIST 0 WXPYTHON_VERSION )
|
||||
list( GET _WXPYTHON_VERSION_LIST 1 WXPYTHON_TOOLKIT )
|
||||
list( GET _WXPYTHON_VERSION_LIST 2 WXPYTHON_FLAVOR )
|
||||
|
||||
# Determine wxWidgets version used by wxPython/Phoenix
|
||||
if( WXPYTHON_FLAVOR MATCHES "phoenix" )
|
||||
# 4.0.1;gtk3;(phoenix) does not contain wxWidgets version, request it explicitly
|
||||
set( _py_cmd "import wx;print(wx.wxWidgets_version.split(' ')[1])")
|
||||
execute_process( COMMAND ${PYTHON_EXECUTABLE} -c "${_py_site_path}${_py_cmd}"
|
||||
RESULT_VARIABLE WXPYTHON_WXVERSION_RESULT
|
||||
OUTPUT_VARIABLE WXPYTHON_WXVERSION
|
||||
OUTPUT_STRIP_TRAILING_WHITESPACE
|
||||
)
|
||||
|
||||
if( NOT WXPYTHON_WXVERSION_RESULT EQUAL 0 )
|
||||
set( WXPYTHON_WXVERSION "3.0.2" )
|
||||
message( WARNING "Could not determine wxWidgets version used by Phoenix, "
|
||||
"requesting ${WXPYTHON_WXVERSION}" )
|
||||
endif()
|
||||
|
||||
set( WXPYTHON_FLAVOR "Phoenix" )
|
||||
|
||||
elseif( WXPYTHON_FLAVOR MATCHES "classic" )
|
||||
# 3.0.2.0;gtk3;(classic) has the wxWidgets version in the first part
|
||||
set( WXPYTHON_WXVERSION ${WXPYTHON_VERSION} )
|
||||
set( WXPYTHON_FLAVOR "wxPython" )
|
||||
|
||||
else()
|
||||
message( FATAL_ERROR "Unknown wxPython/Phoenix type: ${WXPYTHON_FLAVOR}")
|
||||
endif()
|
||||
|
||||
|
||||
# Fix an incosistency between the toolkit names reported by wx.version() and wx-config for cocoa
|
||||
if( WXPYTHON_TOOLKIT STREQUAL "osx-cocoa" )
|
||||
set( WXPYTHON_TOOLKIT "osx_cocoa" )
|
||||
endif()
|
||||
@@ -25,32 +25,34 @@
|
||||
# Function make_lexer
|
||||
# is a standard way to invoke TokenList2DsnLexer.cmake.
|
||||
# Extra arguments are treated as source files which depend on the generated
|
||||
# files. Some detail here on the indirection:
|
||||
# - Parallel builds all depend on the same files, and CMake will generate the same file multiple times in the same location.
|
||||
# This can be problematic if the files are generated at the same time and overwrite each other.
|
||||
# - To fix this, we create a custom target (outputTarget) that the parallel builds depend on.
|
||||
# AND build dependencies. This creates the needed rebuild for appropriate source object changes.
|
||||
function( make_lexer outputTarget inputFile outHeaderFile outCppFile enum )
|
||||
# outHeaderFile
|
||||
|
||||
function( make_lexer inputFile outHeaderFile outCppFile enum )
|
||||
add_custom_command(
|
||||
OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/${outHeaderFile}
|
||||
${CMAKE_CURRENT_BINARY_DIR}/${outCppFile}
|
||||
OUTPUT ${outHeaderFile}
|
||||
${outCppFile}
|
||||
COMMAND ${CMAKE_COMMAND}
|
||||
-Denum=${enum}
|
||||
-DinputFile=${CMAKE_CURRENT_SOURCE_DIR}/${inputFile}
|
||||
-DoutHeaderFile=${CMAKE_CURRENT_BINARY_DIR}/${outHeaderFile}
|
||||
-DoutCppFile=${CMAKE_CURRENT_BINARY_DIR}/${outCppFile}
|
||||
-DinputFile=${inputFile}
|
||||
-DoutHeaderFile=${outHeaderFile}
|
||||
-DoutCppFile=${outCppFile}
|
||||
-P ${CMAKE_MODULE_PATH}/TokenList2DsnLexer.cmake
|
||||
DEPENDS ${inputFile}
|
||||
${CMAKE_MODULE_PATH}/TokenList2DsnLexer.cmake
|
||||
COMMENT "TokenList2DsnLexer.cmake creating:
|
||||
${outHeaderFile} and
|
||||
${outCppFile} from
|
||||
${inputFile}"
|
||||
DEPENDS ${CMAKE_CURRENT_SOURCE_DIR}/${inputFile}
|
||||
${CMAKE_MODULE_PATH}/TokenList2DsnLexer.cmake
|
||||
)
|
||||
|
||||
target_sources( ${outputTarget} PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/${outCppFile} )
|
||||
target_include_directories( ${outputTarget} PUBLIC ${CMAKE_CURRENT_BINARY_DIR} )
|
||||
# extra_args, if any, are treated as source files (typically headers) which
|
||||
# are known to depend on the generated outHeader.
|
||||
foreach( extra_arg ${ARGN} )
|
||||
set_source_files_properties( ${extra_arg}
|
||||
PROPERTIES OBJECT_DEPENDS ${outHeaderFile}
|
||||
)
|
||||
endforeach()
|
||||
|
||||
endfunction()
|
||||
|
||||
|
||||
|
||||
@@ -1,100 +0,0 @@
|
||||
# This program source code file is part of KiCad, a free EDA CAD application.
|
||||
#
|
||||
# Copyright (C) 2019 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
|
||||
|
||||
#
|
||||
# Utility CMake functions and targets for marshalling the builds of QA
|
||||
# tests and tools
|
||||
#
|
||||
|
||||
# CI tools can use this to force tests to output machine-readable formats
|
||||
# when possible
|
||||
option( KICAD_TEST_XML_OUTPUT
|
||||
"Cause unit tests to output xUnit results where possible for more granular CI reporting."
|
||||
OFF
|
||||
)
|
||||
mark_as_advanced( KICAD_TEST_XML_OUTPUT ) # Only CI tools need this
|
||||
|
||||
# This is a "meta" target that is used to collect all tests
|
||||
add_custom_target( qa_all_tests )
|
||||
|
||||
# This is a "meta" target used to collect all utility tools
|
||||
add_custom_target( qa_all_tools )
|
||||
|
||||
# This "meta" target builds all QA tools, utils, etc
|
||||
add_custom_target( qa_all
|
||||
DEPENDS qa_all_tests qa_all_tools
|
||||
)
|
||||
|
||||
# Add a target as a "QA test" executable:
|
||||
# * Added as a CTest test with the given name
|
||||
# * Excluded from ALL when KICAD_BUILD_QA_TESTS not set
|
||||
# * Is a dependency of qa_all_tests
|
||||
function( kicad_add_boost_test TEST_EXEC_TARGET TEST_NAME)
|
||||
|
||||
set(BOOST_TEST_PARAMS "")
|
||||
|
||||
if( KICAD_TEST_XML_OUTPUT )
|
||||
# Provide Boost-test-y XML params if asked
|
||||
# Due to Boost issue in 1.62, have to use the --logger parameter, rather than
|
||||
# separate --log_format, --log_sink, etc parameter
|
||||
# https://svn.boost.org/trac10/ticket/12507
|
||||
set(BOOST_TEST_PARAMS --logger=XML,all,${TEST_NAME}.boost-results.xml --report_level=no --result_code=no)
|
||||
endif()
|
||||
|
||||
# Add the test to the CTest registry
|
||||
add_test( NAME ${TEST_NAME}
|
||||
COMMAND $<TARGET_FILE:${TEST_EXEC_TARGET}> ${BOOST_TEST_PARAMS}
|
||||
)
|
||||
|
||||
# Make the overall test meta-target depend on this test
|
||||
add_dependencies( qa_all_tests ${TEST_EXEC_TARGET} )
|
||||
|
||||
# If tests are not enabled by default, remove from the ALL target
|
||||
# They can still be built manually, or all together with the qa_all_test target
|
||||
if( NOT KICAD_BUILD_QA_TESTS )
|
||||
|
||||
set_target_properties( ${TEST_EXEC_TARGET}
|
||||
PROPERTIES EXCLUDE_FROM_ALL TRUE
|
||||
)
|
||||
|
||||
endif()
|
||||
|
||||
endfunction()
|
||||
|
||||
# Add a target as a "QA tool" executable:
|
||||
# * Excluded from ALL when KICAD_BUILD_QA_TESTS not set
|
||||
# * Is a dependency of qa_all_tools
|
||||
function( kicad_add_utils_executable TARGET)
|
||||
|
||||
# If tests are not enabled by default, remove from the ALL target
|
||||
# They can still be built manually, or all together with the qa_all_tools
|
||||
if( NOT KICAD_BUILD_QA_TESTS )
|
||||
|
||||
set_target_properties( ${TARGET}
|
||||
PROPERTIES EXCLUDE_FROM_ALL TRUE
|
||||
)
|
||||
|
||||
endif()
|
||||
|
||||
# Make the overall test meta-target depend on this test
|
||||
add_dependencies( qa_all_tools ${TARGET} )
|
||||
|
||||
endfunction()
|
||||
@@ -1,8 +1,8 @@
|
||||
#
|
||||
# This program source code file is part of KICAD, a free EDA CAD application.
|
||||
#
|
||||
# Copyright (C) 2016 Wayne Stambaugh <stambaughw@gmail.com>
|
||||
# Copyright (C) 2016 - 2019 KiCad Developers, see AUTHORS.txt for contributors.
|
||||
# Copyright (C) 2016 Wayne Stambaugh <stambaughw@gmail.com>
|
||||
# Copyright (C) 2016 - 2018 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,10 +29,10 @@
|
||||
# releases is a shooting offense.
|
||||
#
|
||||
# This file gets included in the WriteVersionHeader.cmake file to set
|
||||
# the default KiCad version when the source is provided in an archive
|
||||
# file or git is not available on the build system. When KiCad is
|
||||
# cloned using git, the git version is used. This version string should
|
||||
# be set after each version tag is added to the git repo. This will
|
||||
# give developers a reasonable idea where which branch was used to build
|
||||
# KiCad.
|
||||
set( KICAD_VERSION "5.99.0-unknown" )
|
||||
# the default KiCad version when the source is provided in an archive
|
||||
# file or git is not available on the build system. When KiCad is
|
||||
# cloned using git, the git version is used. This version string should
|
||||
# be set after each version tag is added to the git repo. This will
|
||||
# give developers a reasonable idea where which branch was used to build
|
||||
# KiCad.
|
||||
set( KICAD_VERSION "5.0.2" )
|
||||
|
||||
@@ -47,7 +47,7 @@ set( output_begin "
|
||||
* PNG2cpp CMake script, using a *.png file as input.
|
||||
*/
|
||||
|
||||
#include <bitmaps_png/bitmaps_list.h>
|
||||
#include <bitmaps.h>
|
||||
|
||||
static const unsigned char png[] = {"
|
||||
)
|
||||
|
||||
@@ -150,7 +150,7 @@ set( sourceFileHeader
|
||||
* your DSN lexer.
|
||||
*/
|
||||
|
||||
#include <${outHeaderFile}>
|
||||
#include <${result}_lexer.h>
|
||||
|
||||
using namespace ${enum};
|
||||
|
||||
@@ -268,7 +268,7 @@ public:
|
||||
|
||||
/**
|
||||
* Constructor ( LINE_READER* )
|
||||
* initializes a lexer and prepares to read from @a aLineReader which
|
||||
* intializes a lexer and prepares to read from @a aLineReader which
|
||||
* is assumed ready, and may be in use by other DSNLEXERs also. No ownership
|
||||
* is taken of @a aLineReader. This enables it to be used by other lexers also.
|
||||
* The transition between grammars in such a case, must happen on a text
|
||||
|
||||
@@ -194,7 +194,7 @@ jp charras:
|
||||
|
||||
* Add item clarification context menu to EESchema when multiple unresolved
|
||||
items are found at the current cross hair position.
|
||||
* Add collector class EE_COLLECTOR for supporting multiple item hit testing.
|
||||
* Add collector class SCH_COLLECTOR for supporting multiple item hit testing.
|
||||
* Removed bit wise masked filtering from schematic item hit testing.
|
||||
* Removed all old hit testing functions and methods scattered about the
|
||||
EESchema source code.
|
||||
|
||||
+902
-1568
File diff suppressed because it is too large
Load Diff
@@ -50,63 +50,6 @@ developers. The other KiCad developers will appreciate your effort.
|
||||
**Do not modify this document without the consent of the project
|
||||
leader. All changes to this document require approval.**
|
||||
|
||||
## 1.3 Tools ## {#tools}
|
||||
|
||||
There are some tools that can help you format your code easily.
|
||||
|
||||
[`clang-format`][clang-format] is a formatting tool that can both be used to
|
||||
provide code-style automation to your editor of choice, as well as allow git to
|
||||
check formatting when committing (using a "Git hook"). You should install this
|
||||
program to be able to use the Git hooks.
|
||||
|
||||
The style config file is `_clang-format`, and should be picked up automatically
|
||||
by `clang-format` when the `--style=file` option is set.
|
||||
|
||||
To enable the Git hooks (only needs to be done once per Git repo):
|
||||
|
||||
git config core.hooksPath .githooks
|
||||
|
||||
Set the `git clang-format` tool to use the provided `_clang-format` file:
|
||||
|
||||
git config clangFormat.style file
|
||||
|
||||
Then, to enable the format checker, set the `kicad.check-format` Git config
|
||||
to "true" for the KiCad repo:
|
||||
|
||||
git config kicad.check-format true
|
||||
|
||||
Without this config, the format checker will not run on commit, but you can
|
||||
still check files staged for commit manually (see below).
|
||||
|
||||
If the hook is enabled, when you commit a change, you will be told if you
|
||||
have caused any style violations (only in your changed code). You can then fix
|
||||
the errors, either manually, or with the tools below.
|
||||
|
||||
If you are warned about formatting errors, but you are sure your style is correct,
|
||||
you can still commit:
|
||||
|
||||
git commit --no-verify
|
||||
|
||||
### Correcting Formatting Errors ## {#correcting-formatting-errors}
|
||||
|
||||
There is a Git aliases file that provides the right commands to show and correct
|
||||
formatting errors. Add to your repository config by running this command from
|
||||
the source directory:
|
||||
|
||||
git config --add include.path $(pwd)/helpers/git/format_alias
|
||||
|
||||
Then you can use the following aliases:
|
||||
|
||||
* `git check-format`: show any formatting warnings (but make no changes)
|
||||
* `git fix-format`: correct formatting (you will need to `git add` afterwards)
|
||||
|
||||
These aliases use a script, `tools/check-coding.sh`, which takes care of only
|
||||
checking the formatting for files that should be formatted. This script has
|
||||
other uses:
|
||||
|
||||
* Make (or see only) violations in files modified in the previous commit (useful
|
||||
when interactive-rebasing):
|
||||
* `check_coding.sh --amend [--diff]`
|
||||
|
||||
# 2. Naming Conventions # {#naming_conventions}
|
||||
Before delving into anything as esoteric as indentation and formatting,
|
||||
@@ -258,8 +201,8 @@ good practice to actually generate the Doxygen \*.html files by
|
||||
building target doxygen-docs, and then to review the quality of your
|
||||
Doxygen comments with a web browser before submitting a patch.
|
||||
|
||||
[doccode]: http://www.doxygen.nl/manual/docblocks.html
|
||||
[manual]: http://www.doxygen.nl/manual
|
||||
[doccode]: http://www.stack.nl/~dimitri/doxygen/manual/docblocks.html
|
||||
[manual]: http://www.stack.nl/~dimitri/doxygen/manual.html
|
||||
|
||||
### 3.2.1 Function Comments ### {#function_comments}
|
||||
These go into a header file, unless the function is a private (i.e.
|
||||
@@ -479,20 +422,6 @@ The case statement is to be indented to the same level as the switch.
|
||||
}
|
||||
~~~~~~~~~~~~~
|
||||
|
||||
It is permitted to place all cases on a single line each, if that makes the
|
||||
code more readable. This is often done for look-ups or translation functions. In
|
||||
this case, you will have to manually align for readability as appropriate and
|
||||
reject clang-format's suggested changes, if you use it:
|
||||
|
||||
~~~~~~~~~~~~~{.cpp}
|
||||
switch( m_orientation )
|
||||
{
|
||||
case PIN_RIGHT: m_orientation = PIN_UP; break;
|
||||
case PIN_UP: m_orientation = PIN_LEFT; break;
|
||||
case PIN_LEFT: m_orientation = PIN_DOWN; break;
|
||||
case PIN_DOWN: m_orientation = PIN_RIGHT; break;
|
||||
}
|
||||
~~~~~~~~~~~~~
|
||||
|
||||
# 5. License Statement # {#license_statement}
|
||||
There is a the file copyright.h which you can copy into the top of
|
||||
@@ -859,8 +788,7 @@ learn something new.
|
||||
- [C++ Operator Overloading Guidelines][overloading]
|
||||
- [Wikipedia's Programming Style Page][style]
|
||||
|
||||
[clang-format]: https://clang.llvm.org/docs/ClangFormat.html
|
||||
[cppstandard]:http://www.possibility.com/Cpp/CppCodingStandard.html
|
||||
[kernel]:https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git/tree/Documentation/process/coding-style.rst
|
||||
[kernel]:http://git.kernel.org/cgit/linux/kernel/git/stable/linux-stable.git/tree/Documentation/CodingStyle
|
||||
[overloading]:http://www.cs.caltech.edu/courses/cs11/material/cpp/donnie/cpp-ops.html
|
||||
[style]:http://en.wikipedia.org/wiki/Programming_style
|
||||
|
||||
@@ -113,19 +113,15 @@ The [Curl Multi-Protocol File Transfer Library][libcurl] is used to provide secu
|
||||
file transfer access for the [GitHub][] plug in. This library needs to be installed unless
|
||||
the GitHub plug build option is disabled.
|
||||
|
||||
## OpenCascade Library ## {#oce}
|
||||
## OpenCascade Community Edition (OCE) ## {#oce}
|
||||
|
||||
The [OpenCascade Community Edition (OCE)][liboce] is used to provide support for loading and saving
|
||||
The [OpenCascade Community Edition][liboce] is used to provide support for loading and saving
|
||||
3D model file formats such as STEP. This library needs to be installed unless the OCE build
|
||||
option is disabled.
|
||||
|
||||
[Open CASCSADE Technology (OCC)][libocc] should also work as an alternative to OCE. Selection of
|
||||
library Cascade library can be specified at build time. See the [STEP/IGES support](#oce_opt)
|
||||
section.
|
||||
|
||||
## Ngspice Library ## {#ngspice}
|
||||
|
||||
The [Ngspice Library][libngspice] is used to provide Spice simulation support in the schematic
|
||||
The [Ngspice Library][libngsice] is used to provide Spice simulation support in the schematic
|
||||
editor. Make sure the the version of ngspice library used was built with the--with-ngshared
|
||||
option. This library needs to be installed unless the Spice build option is disabled.
|
||||
|
||||
@@ -135,43 +131,31 @@ KiCad has many build options that can be configured to build different options d
|
||||
the availability of support for each option on a given platform. This section documents
|
||||
these options and their default values.
|
||||
|
||||
## Advanced Graphics Context ## {#graphics_context_opt}
|
||||
|
||||
The USE_WX_GRAPHICS_CONTEXT option replaces wxDC with wxGraphicsContext for graphics rendering.
|
||||
This option is disabled by default. Warning: the is experimental and has not been maintained
|
||||
so use at your own risk.
|
||||
|
||||
## Graphics Context Overlay ## {#overlay_opt}
|
||||
|
||||
The USE_WX_OVERLAY option is used to enable the optional wxOverlay class for graphics rendering
|
||||
on macOS. This is enabled on macOS by default and disabled on all other platforms.
|
||||
|
||||
## Scripting Support ## {#scripting_opt}
|
||||
|
||||
The KICAD_SCRIPTING option is used to enable building the Python scripting support into Pcbnew.
|
||||
This options is enabled by default, and will disable all other KICAD_SCRIPTING_* options when
|
||||
it is disabled.
|
||||
|
||||
## Python 3 Scripting Support ## {#python3}
|
||||
|
||||
The KICAD_SCRIPTING_PYTHON3 option is used to enable using Python 3 for the scripting support
|
||||
instead of Python 2. This option is disabled by default and only is relevant if
|
||||
[KICAD_SCRIPTING](#scripting_opt) is enabled.
|
||||
This options is enabled by default.
|
||||
|
||||
## Scripting Module Support ## {#scripting_mod_opt}
|
||||
|
||||
The KICAD_SCRIPTING_MODULES option is used to enable building and installing the Python modules
|
||||
supplied by KiCad. This option is enabled by default, but will be disabled if
|
||||
[KICAD_SCRIPTING](#scripting_opt) is disabled.
|
||||
supplied by KiCad. This option is enabled by default.
|
||||
|
||||
## wxPython Scripting Support ## {#wxpython_opt}
|
||||
|
||||
The KICAD_SCRIPTING_WXPYTHON option is used to enable building the wxPython interface into
|
||||
Pcbnew including the wxPython console. This option is enabled by default, but will be disabled if
|
||||
[KICAD_SCRIPTING](#scripting_opt) is disabled.
|
||||
|
||||
## wxPython Phoenix Scripting Support ## {#wxpython_phoenix}
|
||||
|
||||
The KICAD_SCRIPTING_WXPYTHON_PHOENIX option is used to enable building the wxPython interface with
|
||||
the new Phoenix binding instead of the legacy one. This option is disabled by default, and
|
||||
enabling it requires [KICAD_SCRIPTING](#scripting_opt) to be enabled.
|
||||
|
||||
## Python Scripting Action Menu Support ## {#python_action_menu_opt}
|
||||
|
||||
The KICAD_SCRIPTING_ACTION_MENU option allows Python scripts to be added directly to the Pcbnew
|
||||
menu. This option is enabled by default, but will be disabled if
|
||||
[KICAD_SCRIPTING](#scripting_opt) is disabled. Please note that this option is highly
|
||||
experimental and can cause Pcbnew to crash if Python scripts create an invalid object state
|
||||
within Pcbnew.
|
||||
Pcbnew including the wxPython console. This option is enabled by default.
|
||||
|
||||
## GitHub Plugin ## {#github_opt}
|
||||
|
||||
@@ -188,12 +172,9 @@ library. This option is enabled by default.
|
||||
|
||||
The KICAD_USE_OCE is used for the 3D viewer plugin to support STEP and IGES 3D models. Build tools
|
||||
and plugins related to OpenCascade Community Edition (OCE) are enabled with this option. When
|
||||
enabled it requires [liboce][] to be available, and the location of the installed OCE library to be
|
||||
enabled it requires [OCE][] to be available, and the location of the installed OCE library to be
|
||||
passed via the OCE_DIR flag. This option is enabled by default.
|
||||
|
||||
Alternatively KICAD_USE_OCC can be used instead of OCE. Both options are not supposed to be enabled
|
||||
at the same time.
|
||||
|
||||
## Demos and Examples ## {#demo_install_opt}
|
||||
|
||||
The KiCad source code includes some demos and examples to showcase the program. You can choose
|
||||
@@ -201,20 +182,11 @@ whether install them or not with the KICAD_INSTALL_DEMOS option. You can also se
|
||||
install them with the KICAD_DEMOS variable. On Linux the demos are installed in
|
||||
$PREFIX/share/kicad/demos by default.
|
||||
|
||||
## Quality assurance (QA) unit tests ## {#quality_assurance_tests_opt}
|
||||
## Python Scripting Action Menu Support ## {#python_action_menu_opt}
|
||||
|
||||
The KICAD_BUILD_QA_TESTS option allows building unit tests binaries for quality assurance as part
|
||||
of the default build. This option is enabled by default.
|
||||
|
||||
If this option is disabled, the QA binaries can still be built by manually specifying the target.
|
||||
For example, with `make`:
|
||||
|
||||
* Build all QA binaries: `make qa_all`
|
||||
* Build a specific test: `make qa_pcbnew`
|
||||
* Build all unit tests: `make qa_all_tests`
|
||||
* Build all test tool binaries: `make qa_all_tools`
|
||||
|
||||
For more information about testing KiCad, see [this page](testing.md).
|
||||
The KICAD_SCRIPTING_ACTION_MENU option allows Python scripts to be added directly to the Pcbnew
|
||||
menu. This option is disabled by default. Please note that this option is highly experimental
|
||||
and can cause Pcbnew to crash if Python scripts create an invalid object state within Pcbnew.
|
||||
|
||||
## KiCad Build Version ## {#build_version_opt}
|
||||
|
||||
@@ -233,18 +205,6 @@ information as follows:
|
||||
|
|
||||
output of `git describe --dirty` if git is available.
|
||||
|
||||
|
||||
## KiCad Config Directory ## {#config_dir_opt}
|
||||
|
||||
The default KiCad configuration directory is `kicad`. On Linux this is located at
|
||||
`~/.config/kicad`, on MSW, this is `C:\Documents and Settings\username\Application Data\kicad` and
|
||||
on MacOS, this is `~/Library/Preferences/kicad`. If the installation package would like to, it may
|
||||
specify an alternate configuration name instead of `kicad`. This may be useful for versioning
|
||||
the configuration parameters and allowing the use of, e.g. `kicad5` and `kicad6` concurrently without
|
||||
losing configuration data.
|
||||
|
||||
This is set by specifying the KICAD_CONFIG_DIR string at compile time.
|
||||
|
||||
# Getting the KiCad Source Code ## {#getting_src}
|
||||
|
||||
There are several ways to get the KiCad source. If you want to build the stable version you
|
||||
@@ -252,7 +212,7 @@ can down load the source archive from the [KiCad Launchpad][] developers page.
|
||||
other archive program to extract the source on your system. If you are using tar, use the
|
||||
following command:
|
||||
|
||||
tar -xaf kicad_src_archive.tar.xz
|
||||
tar -xzf kicad_src_archive.tar.gz
|
||||
|
||||
If you are contributing directly to the KiCad project on Launchpad, you can create a local
|
||||
copy on your machine by using the following command:
|
||||
@@ -261,7 +221,7 @@ copy on your machine by using the following command:
|
||||
|
||||
Here is a list of source links:
|
||||
|
||||
Stable release archive: https://launchpad.net/kicad/5.0/5.0.2/+download/kicad-5.0.2.tar.xz
|
||||
Stable release archive: https://launchpad.net/kicad/4.0/4.0.7/+download/kicad-4.0.7.tar.xz
|
||||
|
||||
Development branch: https://code.launchpad.net/~kicad-product-committers/kicad/+git/product-git/+ref/master
|
||||
|
||||
@@ -359,12 +319,6 @@ configure pacman to prevent upgrading the 64-bit Boost package by adding:
|
||||
|
||||
to your /etc/pacman.conf file.
|
||||
|
||||
### Building with Boost 1.70 ### {#ki_msys2_boost_1_70}
|
||||
|
||||
There is an issue building KiCad with Boost version 1.70 due to CMake not defining the proper
|
||||
link libraries during configuration. Boost 1.70 can be used but `-DBoost_NO_BOOST_CMAKE=ON`
|
||||
needs to be added during CMake configuration to insure the link libraries are properly generated.
|
||||
|
||||
### Building OCE from source
|
||||
|
||||
KiCad requires OCE by default, and the version installed by `pacman` can cause build errors in
|
||||
@@ -382,16 +336,11 @@ compilation errors about missing files, it is probably because your path is too
|
||||
|
||||
# Building KiCad on macOS # {#build_osx}
|
||||
|
||||
As of V5, building and packaging for macOS can be done using [kicad-mac-builder][],
|
||||
which downloads, patches, builds, and packages for macOS. It is used to create the official
|
||||
releases and nightlies, and it reduces the complexity of setting up a build environment to a command
|
||||
or two. Usage of kicad-mac-builder is detailed at on its website.
|
||||
Building on macOS is challenging at best. It typically requires building dependency libraries
|
||||
that require patching in order to work correctly. For more information on the complexities of
|
||||
building and packaging KiCad on macOS, see the [macOS bundle build scripts][].
|
||||
|
||||
If you wish to build without kicad-mac-builder, please use the following and its source code
|
||||
as reference. Building on macOS requires building dependency libraries that require patching
|
||||
in order to work correctly.
|
||||
|
||||
In the following set of commands, replace the macOS version number (i.e. 10.11) with the desired
|
||||
In the following set of commands, replace the macOS version number (i.e. 10.9) with the desired
|
||||
minimum version. It may be easiest to build for the same version you are running.
|
||||
|
||||
KiCad currently won't work with a stock version of wxWidgets that can be downloaded or
|
||||
@@ -419,7 +368,7 @@ To perform a wxWidgets build, execute the following commands:
|
||||
--with-zlib=builtin \
|
||||
--with-expat=builtin \
|
||||
--without-liblzma \
|
||||
--with-macosx-version-min=10.11 \
|
||||
--with-macosx-version-min=10.9 \
|
||||
--enable-universal-binary=i386,x86_64 \
|
||||
CC=clang \
|
||||
CXX=clang++
|
||||
@@ -435,7 +384,7 @@ Now, build a basic KiCad without Python scripting using the following commands:
|
||||
cd build/release
|
||||
cmake -DCMAKE_C_COMPILER=clang \
|
||||
-DCMAKE_CXX_COMPILER=clang++ \
|
||||
-DCMAKE_OSX_DEPLOYMENT_TARGET=10.11 \
|
||||
-DCMAKE_OSX_DEPLOYMENT_TARGET=10.9 \
|
||||
-DwxWidgets_CONFIG_EXECUTABLE=<your wxWidgets build folder>/wx-bin/bin/wx-config \
|
||||
-DKICAD_SCRIPTING=OFF \
|
||||
-DKICAD_SCRIPTING_MODULES=OFF \
|
||||
@@ -491,7 +440,7 @@ you will have to apply the Boost patches in the KiCad source [patches folder][].
|
||||
[GIT]: https://git-scm.com/
|
||||
[GitHub]: https://github.com/KiCad/kicad-source-mirror
|
||||
[ngspice]: http://ngspice.sourceforge.net/
|
||||
[Doxygen]: http://www.doxygen.nl
|
||||
[Doxygen]: http://www.stack.nl/~dimitri/doxygen/
|
||||
[mailing list]: https://launchpad.net/~kicad-developers
|
||||
[SWIG]: http://www.swig.org/
|
||||
[wxWidgets]: http://wxwidgets.org/
|
||||
@@ -506,7 +455,7 @@ you will have to apply the Boost patches in the KiCad source [patches folder][].
|
||||
[MSYS2 32-bit Installer]: http://repo.msys2.org/distrib/i686/msys2-i686-20161025.exe
|
||||
[MSYS2 64-bit Installer]: http://repo.msys2.org/distrib/x86_64/msys2-x86_64-20161025.exe
|
||||
[PKGBUILD]: https://github.com/Alexpux/MINGW-packages/blob/master/mingw-w64-kicad-git/PKGBUILD
|
||||
[kicad-mac-builder]:https://github.com/KiCad/kicad-mac-builder
|
||||
[macOS bundle build scripts]:http://bazaar.launchpad.net/~adamwolf/+junk/kicad-mac-packaging/files
|
||||
[KiCad fork of wxWidgets]:https://github.com/KiCad/wxWidgets
|
||||
[MinGW]: http://mingw.org/
|
||||
[build Boost]: http://www.boost.org/doc/libs/1_59_0/more/getting_started/index.html
|
||||
@@ -514,6 +463,6 @@ you will have to apply the Boost patches in the KiCad source [patches folder][].
|
||||
[libcurl]: http://curl.haxx.se/libcurl/
|
||||
[GLM]: http://glm.g-truc.net/
|
||||
[git]: https://git-scm.com/
|
||||
[OCE]: https://github.com/tpaviot/oce
|
||||
[liboce]: https://github.com/tpaviot/oce
|
||||
[libocc]: https://www.opencascade.com/content/overview
|
||||
[libngspice]: https://sourceforge.net/projects/ngspice/
|
||||
|
||||
@@ -25,13 +25,13 @@ Another documentation source is the auto-generated Doxygen reference of the
|
||||
API. It can be found
|
||||
[here](http://docs.kicad-pcb.org/doxygen-python/namespacepcbnew.html).
|
||||
|
||||
# \`Action Plugin\` Support # {#ppi_action_pi}
|
||||
# `Action Plugin` Support # {#ppi_action_pi}
|
||||
Besides the stand-alone usage of the generated Python plugin interface,
|
||||
additional support regarding online manipulation of board projects is available
|
||||
for Pcbnew. Plugins using this feature are called `Action Plugins` and they are
|
||||
accessible using a Pcbnew menu entry that can be found under `Tools->External
|
||||
Plugins`. KiCad plugins that follow the `Action Plugin` conventions can be made
|
||||
to show up as external plugins in that menu and optionally as top toolbar button.
|
||||
to show up as external plugins in that menu.
|
||||
The user can run the plugin resulting in calling a defined entry function in the
|
||||
Python plugin's code.
|
||||
This function can then be used to access and manipulate the currently loaded
|
||||
@@ -43,28 +43,9 @@ packages and Python script files in specific directories on startup.
|
||||
In order for the discovery process to work, the following requirements must be met.
|
||||
|
||||
* The plugin must be installed in the KiCad plugins search paths as documented
|
||||
in `scripting/kicadplugins.i`. You can always discover the search path for your
|
||||
setup by opening the scripting console and entering the command:
|
||||
|
||||
`import pcbnew; print pcbnew.PLUGIN_DIRECTORIES_SEARCH`
|
||||
|
||||
Currently on a Linux Installation the plugins search path is
|
||||
|
||||
* /usr/share/kicad/scripting/plugins/
|
||||
* ~/.kicad/scripting/plugins
|
||||
* ~/.kicad_plugins/
|
||||
|
||||
On Windows
|
||||
|
||||
* \%KICAD_INSTALL_PATH%/share/kicad/scripting/plugins
|
||||
* \%APPDATA%/Roaming/kicad/scripting/plugins
|
||||
|
||||
On macOS, there is a security feature that makes it easier to add scripting plugins
|
||||
to the ~/Library... path than to kicad.app, but the search path is
|
||||
|
||||
* /Applications/kicad/Kicad/Contents/SharedSupport/scripting/plugins
|
||||
* ~/Library/Application Support/kicad/scripting/plugins
|
||||
|
||||
in `scripting/kicadplugins.i`.
|
||||
(Currently on a Linux Mint Installation this is
|
||||
/usr/share/kicad/scripting/plugins/ and ~/.kicad_plugins/)
|
||||
* Alternatively a symbolic link can be created in the KiCad plugin path link to
|
||||
the plugin file/folder in another location of the file system. This can be
|
||||
useful for development.
|
||||
@@ -88,20 +69,16 @@ KiCad plugin path.
|
||||
|
||||
+ ~/.kicad_plugins/ # A folder in the KiCad plugin path
|
||||
- simple_plugin.py
|
||||
- simple_plugin.png (optional)
|
||||
|
||||
The file `simple_plugin.py` contains the following.
|
||||
|
||||
import pcbnew
|
||||
import os
|
||||
|
||||
class SimplePlugin(pcbnew.ActionPlugin):
|
||||
def defaults(self):
|
||||
self.name = "Plugin Name as shown in Pcbnew: Tools->External Plugins"
|
||||
self.category = "A descriptive category name"
|
||||
self.description = "A description of the plugin and what it does"
|
||||
self.show_toolbar_button = False # Optional, defaults to False
|
||||
self.icon_file_name = os.path.join(os.path.dirname(__file__), 'simple_plugin.png') # Optional, defaults to ""
|
||||
|
||||
def Run(self):
|
||||
# The entry function of the plugin that is executed on user action
|
||||
@@ -109,13 +86,6 @@ The file `simple_plugin.py` contains the following.
|
||||
|
||||
SimplePlugin().register() # Instantiate and register to Pcbnew
|
||||
|
||||
Note that if specified `icon_file_name` must contain absolute path to the plugin icon.
|
||||
It must be png file, recommended size is 26x26 pixels. Alpha channel for opacity is supported.
|
||||
If icon is not specified a generic tool icon will be used.
|
||||
|
||||
`show_toolbar_button` only defines a default state for plugin toolbar button. Users can override
|
||||
it in pcbnew preferences.
|
||||
|
||||
## Complex Plugin Example ## {#ppi_complex_example}
|
||||
The complex plugin example represents a single Python package that is imported
|
||||
on Pcbnew startup. When the Python package is imported, the `__init__.py` file
|
||||
@@ -133,7 +103,6 @@ The following folder structure shows how complex plugins are implemented:
|
||||
- __main__.py # This file is optional. See below
|
||||
- complex_plugin_action.py # The ActionPlugin derived class lives here
|
||||
- complex_plugin_utils.py # Other Python parts of the plugin
|
||||
- icon.png
|
||||
+ otherstuff/
|
||||
- otherfile.png
|
||||
- misc.txt
|
||||
@@ -144,15 +113,12 @@ In this case the file is named `complex_plugin_action.py` with the following
|
||||
contents:
|
||||
|
||||
import pcbnew
|
||||
import os
|
||||
|
||||
class ComplexPluginAction(pcbnew.ActionPlugin)
|
||||
def defaults(self):
|
||||
self.name = "A complex action plugin"
|
||||
self.category = "A descriptive category name"
|
||||
self.description "A description of the plugin"
|
||||
self.show_toolbar_button = True # Optional, defaults to False
|
||||
self.icon_file_name = os.path.join(os.path.dirname(__file__), 'icon.png') # Optional
|
||||
|
||||
def Run(self):
|
||||
# The entry function of the plugin that is executed on user action
|
||||
|
||||
@@ -0,0 +1,461 @@
|
||||
# Version 5 Road Map # {#v5_road_map}
|
||||
|
||||
This document is the KiCad version 5 Developer's road map document. It is
|
||||
living document that should be maintained during the version 5 development
|
||||
cycle. The goal of this document is to provide an overview for developers
|
||||
of the goals for the project for the version 5 release of KiCad. It is
|
||||
broken into sections for each major component of the KiCad source code and
|
||||
documentation. It defines tasks that developers an use to contribute to the
|
||||
project and provides updated status information. Tasks should define clear
|
||||
objectives and avoid vague generalizations so that a new developer can complete
|
||||
the task. It is not a place for developers to add their own personal wish.
|
||||
list. It should only be updated with approval of the project manager after
|
||||
discussion with the lead developers.
|
||||
|
||||
Each entry in the road map is made up of four sections. The goal should
|
||||
be a brief description of the what the road map entry will accomplish. The
|
||||
task section should be a list of deliverable items that are specific enough
|
||||
hat they can be documented as completed. The dependencies sections is a list
|
||||
of requirements that must be completed before work can begin on any of the
|
||||
tasks. The status section should include a list of completed tasks or marked
|
||||
as complete as when the goal is met.
|
||||
|
||||
[TOC]
|
||||
|
||||
# Project # {#v5_project}
|
||||
This section defines the tasks for the project related goals that are not
|
||||
related to coding or documentation. It is a catch all for issues such as
|
||||
developer and user relations, dissemination of information on websites,
|
||||
policies, etc.
|
||||
|
||||
|
||||
# General # {#v5_general}
|
||||
This section defines the tasks that affect all or most of KiCad or do not
|
||||
fit under as specific part of the code such as the board editor or the
|
||||
schematic editor.
|
||||
|
||||
## Search Tree Control ## {#v5_re_search_control}
|
||||
|
||||
**Goal:**
|
||||
Create a user interface element that allows searching through a list of
|
||||
items in a tree control for library searching.
|
||||
|
||||
**Task:**
|
||||
- Create hybrid tree control with search text control for displaying filtered
|
||||
objects (both symbol and footprint libraries) in a parent window.
|
||||
|
||||
**Dependencies:**
|
||||
- None
|
||||
|
||||
**Status:**
|
||||
- Initial container searching code completed.
|
||||
- Wildcard and regular expression container searching completed.
|
||||
- Control code in progress.
|
||||
|
||||
# Common Library # {#v5_common_lib}
|
||||
This section covers the source code shared between all of the KiCad
|
||||
applications
|
||||
|
||||
## Unified Rendering Framework ## {#v5_unified_rendering}
|
||||
**Goal:**
|
||||
|
||||
Provide a single framework for developing new tools. Port existing tools
|
||||
to the new framework and remove the legacy framework tools.
|
||||
|
||||
**Task:**
|
||||
- Port wxDC to GAL or get Cairo rendering to nearly the performance of the
|
||||
current wxDC rendering so that we have a single framework to develop new
|
||||
tools and we can continue to support systems that don't have a complete
|
||||
OpenGL stack.
|
||||
|
||||
**Dependencies**
|
||||
- [Tool framework](http://www.ohwr.org/projects/cern-kicad/wiki/WorkPackages)
|
||||
|
||||
**Status**
|
||||
- In progress
|
||||
|
||||
## Printing Improvements ## {#v5_print}
|
||||
**Goal:**
|
||||
|
||||
Make printing quality consistent across platforms.
|
||||
|
||||
**Task:**
|
||||
- Resolve printing issues on all platforms.
|
||||
|
||||
**Dependencies**
|
||||
- None
|
||||
|
||||
**Status**
|
||||
- No progress.
|
||||
|
||||
## Object Properties and Introspection ## {#v5_object_props}
|
||||
**Goal:**
|
||||
|
||||
Provide an object introspection system using properties.
|
||||
|
||||
**Task:**
|
||||
- Select existing or develop property system.
|
||||
- Add definable properties to base objects.
|
||||
- Create introspection framework for manipulating object properties.
|
||||
- Serialization of properties to and from files and/or other I/O structures.
|
||||
- Create tool to edit property namespace/object name/name/type/value table.
|
||||
|
||||
**Dependencies:**
|
||||
- None
|
||||
|
||||
**Status:**
|
||||
- No progress.
|
||||
|
||||
## 3D Viewer Dynamic Library Plugin ## {#v5_plugin_base}
|
||||
**Goal:**
|
||||
|
||||
Create a base library plugin for handling external file I/O for the 3D viewer.
|
||||
This will allow plugins to be provided that are external to the project such
|
||||
as providing solid model file support (STEP, IGES, etc.) using OpenCascade
|
||||
without making it a project dependency.
|
||||
|
||||
**Task:**
|
||||
- Create a plugin to handle dynamically registered plugins for loading and
|
||||
saving file formats.
|
||||
- This object should be flexible enough to be extended for handling all file
|
||||
plugin types including schematic, board, footprint library, component
|
||||
library, etc. (optional)
|
||||
- See [blueprint](https://blueprints.launchpad.net/kicad/+spec/pluggable-file-io)
|
||||
on Launchpad for more information.
|
||||
|
||||
**Dependencies:**
|
||||
- None
|
||||
|
||||
**Status:**
|
||||
- 3D plugin code complete and legacy formats implemented.
|
||||
|
||||
|
||||
# Eeschema: Schematic Editor # {#v5_eeschema}
|
||||
This section applies to the source code for the Eeschema schematic editor.
|
||||
|
||||
## Coherent SCHEMATIC Object ## {#v5_sch_object}
|
||||
**Goal:**
|
||||
|
||||
Clean up the code related to the schematic object(s) into a coherent object for
|
||||
managing and manipulating the schematic that can be used by third party tools
|
||||
and Python scripting.
|
||||
|
||||
**Task:**
|
||||
- Move handling of root sheet object to SCHEMATIC object.
|
||||
- Move SCH_SCREENS code into SCH_OBJECT.
|
||||
- Build and maintain schematic hierarchy in SCHEMATIC object rather than
|
||||
recreating on the fly every time the hierarchical information is required.
|
||||
- Optionally build and maintain netlist during editing for extended editing
|
||||
features.
|
||||
- Add any missing functionality to the SCHEMATIC object.
|
||||
|
||||
**Dependencies:**
|
||||
- [Schematic and Component Library Plugin](#v5_sch_plugin)
|
||||
|
||||
**Status:**
|
||||
- In progress.
|
||||
|
||||
## Schematic and Component Library I/O Manager Plugin ## {#v5_sch_plugin}
|
||||
**Goal:**
|
||||
Create a plugin manager for loading and saving schematics and component
|
||||
libraries similar to the board plugin manager.
|
||||
|
||||
**Task:**
|
||||
- Design plugin manager for schematics and component libraries.
|
||||
- Port the current schematic and component library file formats to use the
|
||||
plugin.
|
||||
|
||||
**Dependencies:**
|
||||
- None
|
||||
|
||||
**Status:**
|
||||
- I/O manager and plugin objects are complete.
|
||||
- Legacy schematic file parser almost ready to commit.
|
||||
|
||||
|
||||
## S-Expression File Format ## {#v5_sch_sexpr}
|
||||
**Goal:**
|
||||
|
||||
Make schematic file format more readable, add new features, and take advantage
|
||||
of the s-expression parser and formatter capability used in Pcbnew.
|
||||
|
||||
**Task:**
|
||||
- Finalize feature set and file format.
|
||||
- Discuss the possibility of dropping the unit-less proposal temporarily to get
|
||||
the s-expression file format and SWEET library format implemented without
|
||||
completely rewriting Eeschema.
|
||||
- Add new s-expression file format to plugin.
|
||||
|
||||
**Dependencies:**
|
||||
- [Schematic and component I/O manager plugin](#v5_sch_plugin)
|
||||
|
||||
**Status:**
|
||||
- File format document nearly complete.
|
||||
|
||||
## Implement Sweet Component Libraries ## {#v5_sch_sweet}
|
||||
**Goal:**
|
||||
|
||||
Make component library design more robust and feature rich. Use s-expressions
|
||||
to make component library files more readable.
|
||||
|
||||
**Task:**
|
||||
- Use sweet component file format for component libraries.
|
||||
|
||||
**Dependencies:**
|
||||
- [S-expression file format](#v5_sch_sexpr).
|
||||
[Schematic and component I/O manager plugin](#v5_sch_plugin)
|
||||
|
||||
**Status:**
|
||||
- Initial SWEET library file format document written.
|
||||
|
||||
## Component Library Editor Usability Improvements ## {#v5_lib_editor_usability}
|
||||
**Goal:**
|
||||
|
||||
Make editing schematic symbol libraries easier to manage.
|
||||
|
||||
**Task:**
|
||||
- Determine usability improvements in the library editor for components with
|
||||
multiple units and/or alternate graphical representations.
|
||||
- Replace current library/symbols selection process with new hybrid tree search
|
||||
widget in new window pain for selection libraries and symbols. Provide drag
|
||||
and drop symbol copy/move between libraries.
|
||||
- Allow editing of symbol libraries not defined in footprint library table(s)
|
||||
using the file/path dialog to open a library.
|
||||
|
||||
**Dependencies:**
|
||||
- [Search Tree Control](#v5_re_search_control)
|
||||
|
||||
**Status:**
|
||||
- Determined alternate UI designs using new hybrid search tree control.
|
||||
|
||||
## Component and Netlist Attributes ## {#v5_netlist_attributes}
|
||||
**Goal:**
|
||||
|
||||
Provide a method of passing information to other tools via the net list.
|
||||
|
||||
**Task:**
|
||||
- Add virtual components and attributes to netlist to define properties that
|
||||
can be used by other tools besides the board editor.
|
||||
- Attributes (properties) are automatically included as part of the new file
|
||||
format.
|
||||
|
||||
**Dependencies:**
|
||||
- [S-expression schematic file format](#v5_sch_sexpr).
|
||||
|
||||
**Status:**
|
||||
- No progress.
|
||||
|
||||
|
||||
# Circuit Simulation # {#simulation}
|
||||
**Goal:**
|
||||
|
||||
Provide quality circuit simulation capabilities similar to commercial products.
|
||||
|
||||
**Task:**
|
||||
- Evaluate and select simulation library (ngspice, gnucap, qucs, etc).
|
||||
- Evaluate and select plotting library with wxWidgets support.
|
||||
- Confirm current spice netlist export is up to the task and add missing
|
||||
support for simulations.
|
||||
- Use plotting library to handle simulator output in a consistent manor similar
|
||||
to LTSpice.
|
||||
- Develop a tool that allows fine tuning of components on the fly.
|
||||
- Use plugin for the simulation code to allow support of different simulation
|
||||
libraries.
|
||||
- Create dialogs for configuring of simulation of Spice primitive components
|
||||
such as voltage sources, current sources, etc.
|
||||
- Create dialog(s) for configuration of simulation types transient, DC operating
|
||||
point, AC analysis, etc.
|
||||
|
||||
**Dependencies:**
|
||||
- None
|
||||
|
||||
**Status:**
|
||||
- Complete ([announcement message](https://lists.launchpad.net/kicad-developers/msg25483.html))
|
||||
|
||||
|
||||
# Pcbnew: Circuit Board Editor # {#v5_pcbnew}
|
||||
This section covers the source code of the board editing application Pcbnew.
|
||||
|
||||
## Tool Framework ## {#v5_pcb_tool_framework}
|
||||
**Goal:**
|
||||
|
||||
Unify all board editing tools under a single framework.
|
||||
|
||||
**Task:**
|
||||
- Drop footprint edit mode.
|
||||
- Port auto-router to GAL.
|
||||
- Complete porting of all board editing tools to new tool framework so they
|
||||
are available in the OpenGL and Cairo canvases.
|
||||
- Remove all duplicate legacy editing tools.
|
||||
|
||||
**Dependencies:**
|
||||
- In progress.
|
||||
|
||||
**Status:**
|
||||
- Initial porting work in progress.
|
||||
|
||||
## Modeling ## {#v5_modeling}
|
||||
|
||||
**Goal:**
|
||||
|
||||
Provide improved solid modeling support for KiCad including the file formats
|
||||
available in OpenCascade.
|
||||
|
||||
**Task:**
|
||||
- Improve low level code design.
|
||||
- Design plugin architecture to handle loading and saving 3D models.
|
||||
- Back port existing 3D formats (IDF and S3D) to plugin
|
||||
|
||||
**Dependencies:**
|
||||
- [Dynamic library plugin](#v5_plugin_base).
|
||||
|
||||
**Status:**
|
||||
- Completed.
|
||||
|
||||
## Push and Shove Router Improvements ## {#v5_ps_router_improvements}
|
||||
|
||||
**Goal:**
|
||||
|
||||
Add finishing touches to push and shove router.
|
||||
|
||||
**Task:**
|
||||
- Determine which features are feasible.
|
||||
- Factor out KiCad-specific code from PNS_ROUTER class.
|
||||
- Delete and backspace in idle mode
|
||||
- Differential pair clearance fixes.
|
||||
- Differential pair optimizer improvements (recognize differential pairs)
|
||||
- Persistent differential pair gap/width setting.
|
||||
- Walk around in drag mode.
|
||||
- Optimize trace being dragged too. (currently no optimization)
|
||||
- Backspace to erase last routed segment.
|
||||
- Auto-finish traces (if time permits)
|
||||
- Additional optimization pass for spring back algorithm using area-minimization
|
||||
strategy. (improves tightness of routing)
|
||||
- Restrict optimization area to view port (if user wants to)
|
||||
- Support 45 degree tuning meanders.
|
||||
- Respect trace/via locking!
|
||||
- Keep out zone support.
|
||||
|
||||
**Dependencies:**
|
||||
- None
|
||||
|
||||
**Status:**
|
||||
- Feature feasibility determined.
|
||||
- In Progress.
|
||||
|
||||
## Selection Filtering ## {#v5_pcb_selection_filtering}
|
||||
**Goal:**
|
||||
|
||||
Make the selection tool easier for the user to determine which object(s) are
|
||||
being selected by filtering.
|
||||
|
||||
**Task:**
|
||||
- Provide filtered object selection by adding a third tab to the layer manager
|
||||
or possibly some other UI element to provide filtered selection options.
|
||||
|
||||
**Dependencies:**
|
||||
- None
|
||||
|
||||
**Status:**
|
||||
- Initial design concept discussed.
|
||||
|
||||
## Segment End Point Snapping. ## {#v5_segment_snapping}
|
||||
**Goal:**
|
||||
|
||||
It is not uncommon for board edge segment end points to inadvertently not
|
||||
be closed causing issues for the 3D viewer and exporting to different file
|
||||
formats due the board outline not being a fully enclosed polygon. This
|
||||
feature would add segment end snapping support to allow the board outline
|
||||
to be fully enclosed. This feature would only need to be supported by the
|
||||
GAL rendering.
|
||||
|
||||
**Tasks**
|
||||
- Mark board edge segment ends with a drag indicator to make it visible to the
|
||||
user that the segment end does not have an endpoint with any other board edge
|
||||
segment.
|
||||
- Allow the user to snap the unconnected segment end to the nearest segment end
|
||||
point.
|
||||
- Automatically connect unconnected segments with and additional segment when
|
||||
opening the 3D viewer or exporting the board to another format. Warn the
|
||||
user that an addition segment has be added and should be verified.
|
||||
|
||||
**Dependencies:**
|
||||
- None
|
||||
|
||||
**Progress:**
|
||||
- Initial discussion.
|
||||
|
||||
## Stitching Via Support ## {#v5_pcb_stitching_vias}
|
||||
**Goal:**
|
||||
|
||||
Add capability to add vias for stitching and thermal transfer purposes
|
||||
that do not require being attached to tracks.
|
||||
|
||||
**Task:**
|
||||
- Develop more robust connectivity checking algorithm.
|
||||
- Create a UI element to allow the user to select a net from the list of
|
||||
valid nets.
|
||||
- Connection propagation fix for the current issue of vias that are not
|
||||
connected to tracks being tagged as unassigned and removed.
|
||||
- Manual via placement tool.
|
||||
- Improve the DRC to handle cases of orphaned vias.
|
||||
|
||||
**Dependencies:**
|
||||
- None
|
||||
|
||||
**Progress:**
|
||||
- Patch available to fix via propagation issue.
|
||||
|
||||
|
||||
# Documentation # {#v5_documentation}
|
||||
This section defines the tasks for both the user and developer documentation.
|
||||
|
||||
## Grammar Check ## {#v5_doc_grammar}
|
||||
**Goal:**
|
||||
|
||||
Improve user documentation readability and make life easier to for translators.
|
||||
|
||||
**Task:**
|
||||
- Review and revise all of the English documentation so that it is update with
|
||||
the current functionality of the code.
|
||||
- Translate the update documentation into other languages.
|
||||
|
||||
**Dependencies:**
|
||||
- None
|
||||
|
||||
**Status:**
|
||||
- No progress.
|
||||
|
||||
## Maintenance ## {#v5_doc_maintenance}
|
||||
**Task:**
|
||||
- Keep screen shots current with the source changes.
|
||||
|
||||
**Dependencies:**
|
||||
- None.
|
||||
|
||||
**Status:**
|
||||
- No progress.
|
||||
|
||||
## Convert Developer Documentation to Markup/down Format ## {#v5_dev_doc_format}
|
||||
**Goal:**
|
||||
|
||||
Improve developers documentation to make life easier for new developers to get
|
||||
involved with the project.
|
||||
|
||||
**Task:**
|
||||
- Convert platform build instructions from plain text to new format to be
|
||||
merged with the developer documentation.
|
||||
- Convert how to contribute to KiCad instructions from plain text to the new
|
||||
format to merged with the developer documentation.
|
||||
|
||||
**Dependencies:**
|
||||
- None.
|
||||
|
||||
**Status:**
|
||||
- In progress. Most of the developer documentation has been converted to
|
||||
[Doxygen markdown](http://www.stack.nl/~dimitri/doxygen/manual/markdown.html)
|
||||
and the [output][kicad-docs] is rebuilt automatically when a commit is
|
||||
made to the KiCad repo.
|
||||
|
||||
[kicad-website]:http://kicad-pcb.org/
|
||||
[kicad-docs]:http://ci.kicad-pcb.org/job/kicad-doxygen/ws/Documentation/doxygen/html/index.html
|
||||
@@ -54,84 +54,10 @@ Create perspectives to allow users to arrange dockable windows as they prefer.
|
||||
**Status:**
|
||||
- No progress.
|
||||
|
||||
## Object Properties and Introspection ## {#v6_object_props}
|
||||
**Goal:**
|
||||
|
||||
Provide an object introspection system using properties.
|
||||
|
||||
**Task:**
|
||||
- Select existing or develop property system.
|
||||
- Add definable properties to base objects.
|
||||
- Create introspection framework for manipulating object properties.
|
||||
- Serialization of properties to and from files and/or other I/O structures.
|
||||
- Create tool to edit property namespace/object name/name/type/value table.
|
||||
|
||||
**Dependencies:**
|
||||
- None
|
||||
|
||||
**Status:**
|
||||
- In progress.
|
||||
|
||||
|
||||
# Eeschema: Schematic Editor # {#v6_eeschema}
|
||||
This section applies to the source code for the Eeschema schematic editor.
|
||||
|
||||
## Coherent SCHEMATIC Object ## {#v6_sch_object}
|
||||
**Goal:**
|
||||
|
||||
Clean up the code related to the schematic object(s) into a coherent object for
|
||||
managing and manipulating the schematic that can be used by third party tools
|
||||
and Python scripting.
|
||||
|
||||
**Task:**
|
||||
- Move handling of root sheet object to SCHEMATIC object.
|
||||
- Move SCH_SCREENS code into SCH_OBJECT.
|
||||
- Build and maintain schematic hierarchy in SCHEMATIC object rather than
|
||||
recreating on the fly every time the hierarchical information is required.
|
||||
- Optionally build and maintain netlist during editing for extended editing
|
||||
features.
|
||||
- Add any missing functionality to the SCHEMATIC object.
|
||||
|
||||
**Dependencies:**
|
||||
- None
|
||||
|
||||
**Status:**
|
||||
- In progress.
|
||||
|
||||
## Implement Sweet (S-Expression) Symbol Libraries ## {#v6_sch_sweet}
|
||||
**Goal:**
|
||||
|
||||
Make symbol library design more robust and feature rich. Use s-expressions
|
||||
to make component library files more readable.
|
||||
|
||||
**Task:**
|
||||
- Use sweet component file format for component libraries.
|
||||
|
||||
**Dependencies:**
|
||||
- None
|
||||
|
||||
**Status:**
|
||||
- Initial SWEET library file format document written.
|
||||
|
||||
## S-Expression File Format ## {#v6_sch_sexpr}
|
||||
**Goal:**
|
||||
|
||||
Make schematic file format more readable, add new features, and take advantage
|
||||
of the s-expression parser and formatter capability used in Pcbnew.
|
||||
|
||||
**Task:**
|
||||
- Finalize feature set and file format.
|
||||
- Discuss the possibility of dropping the unit-less proposal temporarily to get
|
||||
the s-expression file format and SWEET library format implemented without
|
||||
completely rewriting Eeschema.
|
||||
- Add new s-expression file format to plugin.
|
||||
|
||||
**Dependencies:**
|
||||
- [S-expression file format](#v6_sch_sweet).
|
||||
|
||||
**Status:**
|
||||
- File format document initial draft complete.
|
||||
|
||||
## Move Common Schematic Code into a Shared Object ## {#v6_sch_shared_object}
|
||||
**Goal:**
|
||||
|
||||
@@ -167,22 +93,37 @@ Improve the coverage and usability of the electrical rules checker (ERC).
|
||||
**Status:**
|
||||
- No progress.
|
||||
|
||||
## Port Editing Tools to New Tool Framework ## {#v6_sch_tool_framework}
|
||||
## Implement GAL and New Tool Framework ## {#v6_sch_gal}
|
||||
**Goal:**
|
||||
|
||||
Implement the GAL and the tool framework used by Pcbnew in Eechema to
|
||||
provide advanced graphics and tool capabilities.
|
||||
|
||||
**Task:**
|
||||
- Implement graphics abstraction layer along side current legacy rendering
|
||||
framework.
|
||||
|
||||
**Dependencies:**
|
||||
- None
|
||||
|
||||
**Status:**
|
||||
- Initial Discussion..
|
||||
|
||||
## Port Editing Tools ## {#v6_sch_tool_framework}
|
||||
**Goal:**
|
||||
|
||||
Convert all editing tool to new tool framework.
|
||||
|
||||
**Task:**
|
||||
-**Task:**
|
||||
- Rewrite existing editing tools using the new tool framework.
|
||||
- Add new capabilities supported by the new tool framework to existing
|
||||
editing tools.
|
||||
- Remove legacy tool framework.
|
||||
|
||||
**Dependencies:**
|
||||
- None.
|
||||
-**Dependencies:**
|
||||
- [GAL and new tool framework port](#v6_sch_gal).
|
||||
|
||||
**Status:**
|
||||
- Schematic editor complete.
|
||||
-**Status:**
|
||||
- Initial Discussion..
|
||||
|
||||
## Net Highlighting ## {#v6_sch_net_highlight}
|
||||
**Goal:**
|
||||
@@ -193,11 +134,28 @@ Highlight wires, buses, and junctions when corresponding net in Pcbnew is select
|
||||
- Implement highlight algorithm for net objects.
|
||||
- Highlight objects connected to net selected in Pcbnew.
|
||||
|
||||
**Dependencies:**
|
||||
- [GAL and new tool framework port, maybe](#v6_sch_gal).
|
||||
|
||||
**Status:**
|
||||
- No progress.
|
||||
|
||||
## Component Library Editor Improvements ## {#lib_editor_usability}
|
||||
**Goal:**
|
||||
|
||||
Make editing components with multiple units and/or alternate graphical
|
||||
representations easier.
|
||||
|
||||
**Task:**
|
||||
- Determine usability improvements in the library editor for components with
|
||||
multiple units and/or alternate graphical representations.
|
||||
- Implement said usability improvements.
|
||||
|
||||
**Dependencies:**
|
||||
- None.
|
||||
|
||||
**Status:**
|
||||
- Complete.
|
||||
- No progress.
|
||||
|
||||
## Allow Use of System Fonts ## {#v6_sch_sys_fonts}
|
||||
**Goal:**
|
||||
@@ -212,112 +170,33 @@ for schematic text.
|
||||
- Add support for selecting text object fonts.
|
||||
|
||||
**Dependencies:**
|
||||
- [S-expression schematic file format](#v6_sch_sexpr).
|
||||
- [S-expression schematic file format](#sch_sexpr).
|
||||
|
||||
**Status:**
|
||||
- No progress.
|
||||
|
||||
## Symbol and Netlist Attributes ## {#v6_netlist_attributes}
|
||||
**Goal:**
|
||||
|
||||
Provide a method of passing information to other tools via the net list.
|
||||
|
||||
**Task:**
|
||||
- Add virtual components and attributes to netlist to define properties that
|
||||
can be used by other tools besides the board editor.
|
||||
- Attributes (properties) are automatically included as part of the new file
|
||||
format.
|
||||
|
||||
**Dependencies:**
|
||||
- [S-expression schematic file format](#v6_sch_sexpr).
|
||||
|
||||
**Status:**
|
||||
- No progress.
|
||||
|
||||
## Orthogonal Wire Drag ## {#v6_orthogonal_drag}
|
||||
**Goal:**
|
||||
|
||||
Keep wires and buses orthogonal when dragging a symbol.
|
||||
|
||||
**Task:**
|
||||
- Add code to new tool framework to allow for orthogonal dragging of symbols.
|
||||
|
||||
**Dependencies:**
|
||||
- [New tool framework](#v6_sch_tool_framework).
|
||||
|
||||
**Status:**
|
||||
- No progress.
|
||||
|
||||
## Custom Wire and Bus Attributes ## {#v6_sch_bus_wire_attr}
|
||||
**Goal:**
|
||||
|
||||
Allow for wires and buses to have different widths, colors, and line types.
|
||||
|
||||
**Task:**
|
||||
- Add code to support custom wire and bus attributes.
|
||||
- Add user interface element to support changing wire and bus attributes.
|
||||
|
||||
**Dependencies:**
|
||||
- [S-Expression File Format](#v6_sch_sexpr).
|
||||
|
||||
**Status:**
|
||||
- No progress.
|
||||
|
||||
## Connectivity Improvements ## {#v6_sch_connectivity}
|
||||
**Goal:**
|
||||
|
||||
Support structured buses, real time netlist calculations, and other
|
||||
connectivity improvements.
|
||||
|
||||
**Task:**
|
||||
- Keep netlist up to date real time.
|
||||
- Add support for structured bus definitions.
|
||||
- Possible real time ERC checking.
|
||||
|
||||
**Dependencies:**
|
||||
- None.
|
||||
|
||||
**Status:**
|
||||
- Real time netlist and structured bus support complete.
|
||||
|
||||
## ERC Improvements ## {#v6_sch_erc}
|
||||
**Goal:**
|
||||
|
||||
Improve ERC test coverage and other ERC usability features.
|
||||
|
||||
**Task:**
|
||||
- Add missing ERC tests to improve coverage.
|
||||
- Save ERC settings in project file.
|
||||
- Add mechanism to allow import and export of ERC settings.
|
||||
- ERC user interface improvements.
|
||||
|
||||
**Dependencies:**
|
||||
- None.
|
||||
|
||||
**Status:**
|
||||
- Preliminary specification draft complete.
|
||||
|
||||
## Python Support ## {#v6_sch_python}
|
||||
**Goal:**
|
||||
|
||||
SWIG all schematic low level objects and coherent schematic object to
|
||||
provide Python interface for manipulating schematic objects.
|
||||
|
||||
**Task:**-
|
||||
- Create SWIG wrappers for all low level schematic, symbol library, and
|
||||
coherent schematic object code.
|
||||
- Add Python interpreter launcher.
|
||||
|
||||
**Dependencies:**
|
||||
- [Coherent Schematic Object](#v6_sch_object).
|
||||
|
||||
**Status:**
|
||||
- No Progress.
|
||||
|
||||
|
||||
# CvPcb: Footprint Association Tool # {#v6_cvpcb}
|
||||
This section covers the source code of the footprint assignment tool CvPcb.
|
||||
|
||||
## Improved Footprint Search Tool ## {#v6_cvpcb_search}
|
||||
|
||||
**Goal:**
|
||||
|
||||
Provide advanced search features such as wild card and regular expression
|
||||
searches using the type as you go feature of the current search dialog.
|
||||
|
||||
**Task:**
|
||||
- Add code for wild card and regular expression pattern matching to search
|
||||
container objects.
|
||||
- Add search dialog to CvPcb to search container of footprint names.
|
||||
|
||||
**Dependencies:**
|
||||
- [Search Tree Control](#v6_re_search_control)
|
||||
|
||||
**Status:**
|
||||
- Pattern matching added to search container objects.
|
||||
|
||||
|
||||
# Pcbnew: Circuit Board Editor # {#v6_pcbnew}
|
||||
This section covers the source code of the board editing application Pcbnew.
|
||||
@@ -329,45 +208,14 @@ This section covers the source code of the board editing application Pcbnew.
|
||||
Add finishing touches to push and shove router.
|
||||
|
||||
**Task:**
|
||||
- Delete and backspace in idle mode
|
||||
- Differential pair clearance fixes.
|
||||
- Differential pair optimizer improvements (recognize differential pairs)
|
||||
- Persistent differential pair gap/width setting.
|
||||
- Walk around in drag mode.
|
||||
- Optimize trace being dragged too. (currently no optimization)
|
||||
- Auto-finish traces (if time permits)
|
||||
- Additional optimization pass for spring back algorithm using area-minimization
|
||||
strategy. (improves tightness of routing)
|
||||
- Restrict optimization area to view port (if user wants to)
|
||||
- Support 45 degree tuning meanders.
|
||||
- Respect trace/via locking!
|
||||
- Keep out zone support.
|
||||
- Microwave tools to be added as parameterized shapes generated by Python
|
||||
- Microwave tools to be added as parametrized shapes generated by Python
|
||||
scripts.
|
||||
- BGA fan out support.
|
||||
- Drag footprints with traces connected.
|
||||
|
||||
**Dependencies:**
|
||||
- None.
|
||||
|
||||
**Status:**
|
||||
- In progress.
|
||||
|
||||
## Selection Filtering ## {#v6_pcb_selection_filtering}
|
||||
**Goal:**
|
||||
|
||||
Make the selection tool easier for the user to determine which object(s) are
|
||||
being selected by filtering.
|
||||
|
||||
**Task:**
|
||||
- Provide filtered object selection by adding a third tab to the layer manager
|
||||
or possibly some other UI element to provide filtered selection options.
|
||||
|
||||
**Dependencies:**
|
||||
- None
|
||||
|
||||
**Status:**
|
||||
- In progress.
|
||||
- None
|
||||
|
||||
## Design Rule Check (DRC) Improvements. ## {#v6_drc_improvements}
|
||||
**Goal:**
|
||||
@@ -375,6 +223,7 @@ being selected by filtering.
|
||||
Create additional DRC tests for improved error checking.
|
||||
|
||||
**Task:**
|
||||
- Replace geometry code with [unified geometry library](#v6_geometry_lib).
|
||||
- Remove floating point code from clearance calculations to prevent rounding
|
||||
errors.
|
||||
- Add checks for component, silk screen, and mask clearances.
|
||||
@@ -383,7 +232,7 @@ Create additional DRC tests for improved error checking.
|
||||
- Add option for saving and loading DRC options.
|
||||
|
||||
**Dependencies:**
|
||||
- [Constraint Management System](#v6_pcb_constraint).
|
||||
- [Unified geometry library.](#v6_geometry_lib)
|
||||
|
||||
**Progress:**
|
||||
- In progress.
|
||||
@@ -424,7 +273,7 @@ does not have to do it in Eeschema and re-import the net list.
|
||||
- Add support to handle net label back annotation changes.
|
||||
|
||||
**Dependencies:**
|
||||
- [S-Expression File Format](#v6_sch_sexpr).
|
||||
- None
|
||||
|
||||
**Status:**
|
||||
- No progress.
|
||||
@@ -443,7 +292,7 @@ Add support for keepout zones on boards and footprints.
|
||||
- [DRC Improvements.](#v6_drc_improvements)
|
||||
|
||||
**Progress:**
|
||||
- In progress.
|
||||
- Planning
|
||||
|
||||
## Clipboard Support ## {#v6_fp_edit_clipboard}
|
||||
**Goal:**
|
||||
@@ -458,7 +307,7 @@ Provide clipboard cut and paste for footprints.
|
||||
- None
|
||||
|
||||
**Status:**
|
||||
- Complete.
|
||||
- No progress.
|
||||
|
||||
## Net Highlighting ## {#v6_pcb_net_highlight}
|
||||
**Goal:**
|
||||
@@ -474,7 +323,7 @@ Highlight rats nest links and/or traces when corresponding net in Eeschema is se
|
||||
- None.
|
||||
|
||||
**Status:**
|
||||
- Complete.
|
||||
- No progress.
|
||||
|
||||
## Hatched Zone Filling ## {#v6_pcb_hatched_zones}
|
||||
**Goal:**
|
||||
@@ -490,7 +339,7 @@ with hatching.
|
||||
- None.
|
||||
|
||||
**Status:**
|
||||
- Complete.
|
||||
- No progress.
|
||||
|
||||
## Board Stack Up Impedance Calculator ## {#v6_pcb_impedance_calc}
|
||||
**Goal:**
|
||||
@@ -505,7 +354,7 @@ Maybe this should be included in the PCB calculator application.
|
||||
- None.
|
||||
|
||||
**Status:**
|
||||
- In progress.
|
||||
- No progress.
|
||||
|
||||
## Net Class Improvements ## {#v6_pcb_net_class_improvements}
|
||||
**Goal:**
|
||||
@@ -529,323 +378,33 @@ Add support for route impedance, color selection, etc in net class object.
|
||||
## Ratsnest Improvements ## {#v6_pcb_ratsnest_improvements}
|
||||
**Goal:**
|
||||
|
||||
Add support for curved rats and per net color and visibility settings.
|
||||
Add support for per net color and visibility settings.
|
||||
|
||||
**Task:**
|
||||
- Implement rat curving to minimize overlapped rats.
|
||||
- Implement UI code to configure ratsnest color and visibility.
|
||||
- Update ratsnest code to handle per net color and visibility.
|
||||
|
||||
**Dependencies:**
|
||||
- None.
|
||||
|
||||
**Status:**
|
||||
- Curved rat support complete.
|
||||
|
||||
## DXF Improvements ## {#v6_pcb_dxf_import}
|
||||
**Goal:**
|
||||
|
||||
- Allow for anchor point setting and layer mapping support on DXF import and
|
||||
export multiple board layers to a single DXF file.
|
||||
|
||||
**Task:**
|
||||
- Provide method to select DXF import anchor point.
|
||||
- Add user interface to allow mapping DXF layers to board layers.
|
||||
- Modify DXF plotting to export multiple layers to a single file.
|
||||
|
||||
**Dependencies:**
|
||||
- None.
|
||||
|
||||
**Status:**
|
||||
- No progress.
|
||||
|
||||
## Improve Dimension Tool ## {#v6_pcb_dim_tool}
|
||||
**Goal:**
|
||||
|
||||
Make dimensions link to objects and change when objects are modified and add
|
||||
basic mechanical constraints.
|
||||
|
||||
**Task:**
|
||||
- Add code to link dimension to objects.
|
||||
- Add basic mechanical constraints like linear distance and angle.
|
||||
|
||||
**Dependencies:**
|
||||
- None.
|
||||
|
||||
**Status:**
|
||||
- In progress.
|
||||
|
||||
## Constraint Management System ## {#v6_pcb_constraint}
|
||||
**Goal:**
|
||||
|
||||
Implement full featured constraint management system to allow for complex
|
||||
board constraints instead of netclass only constraints.
|
||||
|
||||
**Task:**
|
||||
- Write specification to define requirement of new constraint system.
|
||||
- Implement new constraint system including file format changes.
|
||||
- Allow constraints to be defined in schematic editor and passed to board
|
||||
editor via netlist.
|
||||
- Update netlist file format to support constraints.
|
||||
- Update DRC to test new constraints.
|
||||
|
||||
**Dependencies:**
|
||||
- None.
|
||||
|
||||
**Status**
|
||||
- No Progress.
|
||||
|
||||
## Append Board in Project Mode ## {#v6_pcb_append}
|
||||
**Goal:**
|
||||
|
||||
Allow appending to the board when running Pcbnew in the project mode.
|
||||
|
||||
**Task:**
|
||||
- Enable append board feature in project mode.
|
||||
- Extend copy/paste feature to introduce paste special tool to add prefix
|
||||
and/or suffix to nets of pasted/appended objects.
|
||||
|
||||
**Dependencies:**
|
||||
- None.
|
||||
|
||||
**Status:**
|
||||
- No progress.
|
||||
|
||||
## Grid and Auxiliary Origin Improvements ## {#v6_pcb_origin}
|
||||
**Goal:**
|
||||
|
||||
Allow reset grid and auxiliary origin without hotkey only. Add support to
|
||||
make all coordinates relative to the plot origin.
|
||||
|
||||
**Task:**
|
||||
- Add reset grid and auxiliary origin commands to menu entry and/or toolbar
|
||||
button.
|
||||
- Add code to dialogs to allow coordinates to be specified relative to the
|
||||
plot origin.
|
||||
|
||||
**Dependencies:**
|
||||
- None.
|
||||
|
||||
**Status:**
|
||||
- Relative coordinate entry in progress.
|
||||
|
||||
## Addition Mechanical Layers ## {#v6_pcb_mech_layers}
|
||||
**Goal:**
|
||||
|
||||
Add more mechanical layers.
|
||||
|
||||
**Task:**
|
||||
- Add remaining mechanical layers for a total of 32.
|
||||
|
||||
**Dependencies:**
|
||||
- None.
|
||||
|
||||
**Status:**
|
||||
- No progress.
|
||||
|
||||
## Layer Renaming ## {#v6_pcb_layer_rename}
|
||||
**Goal:**
|
||||
|
||||
Allow mechanical layers to be renamed.
|
||||
|
||||
**Task:**
|
||||
- Quote layer names in file format to support any printable characters in
|
||||
layer names.
|
||||
- Add user interface to allow mechanical layers to be renamed.
|
||||
|
||||
**Dependencies:**
|
||||
- None.
|
||||
|
||||
**Status:**
|
||||
- Quoted layer names complete.
|
||||
|
||||
## Stable Python API ## {#v6_pcb_python_api}
|
||||
**Goal:**
|
||||
|
||||
Create a Python wrapper to hide the SWIG generated API.
|
||||
|
||||
**Task:**
|
||||
- Document new Python API.
|
||||
- Write Python API.
|
||||
|
||||
**Dependencies:**
|
||||
- None.
|
||||
|
||||
**Status:**
|
||||
- Initial technical specification drafted.
|
||||
|
||||
## Track Refining ## {#v6_pcb_track_refine}
|
||||
**Goal:**
|
||||
|
||||
Add support for teardrops and automatically updating length tuning
|
||||
meandering.
|
||||
|
||||
**Task:**
|
||||
- Draft specification for track refining.
|
||||
- Implement support for teardrops.
|
||||
- Implement support for changing tuned length meandering.
|
||||
|
||||
**Dependencies:**
|
||||
- None.
|
||||
|
||||
**Status:**
|
||||
- Initial technical specification drafted.
|
||||
|
||||
## Groups and Rooms ## {#v6_pcb_groups}
|
||||
**Goal:**
|
||||
|
||||
Support grouping board objects into reusable snippets.
|
||||
|
||||
**Task:**
|
||||
- Write design specification.
|
||||
- Update board file format to support grouped objects.
|
||||
- Add user interface code to support grouped board objects.
|
||||
|
||||
**Dependencies:**
|
||||
- None.
|
||||
|
||||
**Status:**
|
||||
- Initial technical specification drafted.
|
||||
|
||||
## Pad Stack Support ## {#v6_pcb_padstack}
|
||||
**Goal:**
|
||||
|
||||
Add padstack support.
|
||||
|
||||
**Task:**
|
||||
- Write pad stack design specification.
|
||||
- Update board file format to support pad stacks.
|
||||
- Add user interface code to support designing pad stack objects.
|
||||
- Update push and shove router to handle pad stacks.
|
||||
- Update zone filling to handle pad stacks.
|
||||
- Update DRC to handle pad stacks.
|
||||
|
||||
**Dependencies:**
|
||||
- None.
|
||||
|
||||
**Status:**
|
||||
- Initial technical specification drafted.
|
||||
|
||||
## Net Ties ## {#v6_pcb_net_ties}
|
||||
**Goal:**
|
||||
|
||||
Add support for net ties.
|
||||
|
||||
**Task:**
|
||||
- Write net tie design specification.
|
||||
- Implement board file support for net ties.
|
||||
- Implement schematic file support for net ties.
|
||||
- Update ERC and DRC to handle net ties.
|
||||
- Update netlist to pass net tie information from schematic to board.
|
||||
- Add user interface support for net ties to editors.
|
||||
|
||||
**Dependencies:**
|
||||
- [S-Expression File Format](#v6_sch_sexpr).
|
||||
|
||||
**Status:**
|
||||
- No Progress.
|
||||
|
||||
## Anti-pad Improvements ## {#v6_pcb_anti_pad}
|
||||
**Goal:**
|
||||
|
||||
Use anti-pads on vias and through hold pads on internal layers as required.
|
||||
|
||||
**Task:**-
|
||||
- Revise zone filling algorithm to create anti-pad on internal layers.
|
||||
|
||||
**Dependencies:**
|
||||
- None.
|
||||
|
||||
**Status:**
|
||||
- No Progress.
|
||||
|
||||
## Thermal Relief Improvements ## {#v6_pcb_thermal_relief}
|
||||
**Goal:**
|
||||
|
||||
Allow for custom thermal reliefs in zones and custom pad shapes.
|
||||
|
||||
**Task:**-
|
||||
- Write technical specification to define requirements, alternate unions,
|
||||
knockouts, union spokes, etc.
|
||||
- Revise zone filling thermal relief support to handle new requirements.
|
||||
- Update board file format for new thermal relief requirements.
|
||||
- Add user interface support for thermal relief definitions.
|
||||
|
||||
**Dependencies:**
|
||||
- None.
|
||||
|
||||
**Status:**
|
||||
- No Progress.
|
||||
|
||||
## Merge KiCad2Step ## {#v6_pcb_kicad2step}
|
||||
**Goal:**
|
||||
|
||||
Merge export to STEP file code from KiCad2Step so that conversion does
|
||||
not run in a separate process.
|
||||
|
||||
**Task:**-
|
||||
- Merge KiCad2Step code into Pcbnew code base.
|
||||
- Remove unused parser code.
|
||||
|
||||
**Dependencies:**
|
||||
- None.
|
||||
|
||||
**Status:**
|
||||
- No Progress.
|
||||
|
||||
## 3D Model Improvements ## {#v6_pcb_3d_model_opacity}
|
||||
**Goal:**
|
||||
|
||||
Add opacity to 3D model support and convert from path look up to library
|
||||
table to access 3D models.
|
||||
|
||||
**Task:**-
|
||||
- Add opacity support to footprint library file format.
|
||||
- Add library table 3D model support to footprint library file format.
|
||||
- Create remapping utility to map from path look up to library table look up.
|
||||
- Add user interface support for 3D model opacity.
|
||||
- Add user interface support accessing 3D models via library table.
|
||||
|
||||
**Dependencies:**
|
||||
- None.
|
||||
|
||||
**Status:**
|
||||
- No Progress.
|
||||
|
||||
## IPC-2581 Support ## {#v6_pcb_ipc_2581}
|
||||
**Goal:**
|
||||
|
||||
Add support for exporting to and importing from IPC-2581.
|
||||
|
||||
**Task:**-
|
||||
- Add IPC-2581 export code.
|
||||
- Add IPC-2581 import code.
|
||||
|
||||
**Dependencies:**
|
||||
- None.
|
||||
|
||||
**Status:**
|
||||
- No Progress.
|
||||
|
||||
## Curved Trace Support ## {#v6_pcb}
|
||||
**Goal:**
|
||||
|
||||
Add curved trace support to the board editor.
|
||||
|
||||
**Task:**-
|
||||
- Add curved trace support to track object code.
|
||||
- Add support to board file format for curved traces.
|
||||
- Update zone fill algorithm to support curved fills.
|
||||
- Update router to support curved traces.
|
||||
- Update DRC to handle curved traces and fills.
|
||||
|
||||
**Dependencies:**
|
||||
- None.
|
||||
|
||||
**Status:**
|
||||
- No Progress.
|
||||
|
||||
|
||||
# GerbView: Gerber File Viewer # {#v6_gerbview}
|
||||
|
||||
This section covers the source code for the GerbView gerber file viewer.
|
||||
|
||||
## Graphics Abstraction Layer ## {#v6_gerbview_gal}
|
||||
**Goal:**
|
||||
|
||||
Graphics rendering unification.
|
||||
|
||||
**Task:**
|
||||
- Port graphics rendering layer to GAL.
|
||||
|
||||
**Dependencies:**
|
||||
- None.
|
||||
|
||||
**Status**
|
||||
- No progress.
|
||||
|
||||
@@ -3,16 +3,14 @@
|
||||
This document is the KiCad Developer's road map document. It is a living
|
||||
document that should be maintained as the project progresses. The goal of
|
||||
this document is to provide an overview for developers of where the project
|
||||
is headed beyond the current development cycle road map (currently
|
||||
[version 6](./v6_road_map.html) to prevent resource conflicts and endless
|
||||
rehashing of previously discussed topics. It is broken into sections for
|
||||
each major component of the KiCad source code and documentation. It defines
|
||||
tasks that developers an use to contribute to the project and provides updated
|
||||
status information. Tasks should define clear objectives and avoid vague
|
||||
generalizations so that a new developer can complete the task. It is not a
|
||||
place for developers to add their own personal wish list It should only be
|
||||
updated with approval of the project manager after discussion with the lead
|
||||
developers.
|
||||
is headed to prevent resource conflicts and endless rehashing of previously
|
||||
discussed topics. It is broken into sections for each major component of
|
||||
the KiCad source code and documentation. It defines tasks that developers
|
||||
an use to contribute to the project and provides updated status information.
|
||||
Tasks should define clear objective and avoid vague generalizations so that
|
||||
a new developer can complete the task. It is not a place for developers to
|
||||
add their own personal wish list It should only be updated with approval
|
||||
of the project manager after discussion with the lead developers.
|
||||
|
||||
Each entry in the road map is made up of four sections. The goal should
|
||||
be a brief description of the what the road map entry will accomplish. The
|
||||
@@ -36,16 +34,59 @@ This section defines the tasks that affect all or most of KiCad or do not
|
||||
fit under as specific part of the code such as the board editor or the
|
||||
schematic editor.
|
||||
|
||||
## User Interface Modernization ## {#wxaui}
|
||||
**Goal:**
|
||||
|
||||
Give KiCad a more modern user interface with dockable tool bars and windows.
|
||||
Create perspectives to allow users to arrange dockable windows as they prefer.
|
||||
|
||||
**Task:**
|
||||
- Take advantage of the advanced UI features in wxAui such as detaching and
|
||||
hiding.
|
||||
- Study ergonomics of various commercial/proprietary PCB applications (when
|
||||
in doubt about any particular UI solution, check how it has been done in a
|
||||
certain proprietary app that is very popular among OSHW folks and do exactly
|
||||
opposite).
|
||||
- Clean up menu structure. Menus must allow access to all features of the
|
||||
program in a clear and logical way. Currently some functions of Pcbnew are
|
||||
accessible only through tool bars
|
||||
- Redesign dialogs, make sure they are following same style rules.
|
||||
- Check quality of translations. Either fix or remove bad quality translations.
|
||||
- Develop a global shortcut manager that allows the user assign arbitrary
|
||||
shortcuts for any tool or action.
|
||||
|
||||
**Dependencies:**
|
||||
- [wxWidgets 3](#wxwidgets3)
|
||||
|
||||
**Status:**
|
||||
- No progress.
|
||||
|
||||
|
||||
# Build Tools # {#build_tools}
|
||||
This section covers build tools for both the KiCad source as well as the
|
||||
custom dependency builds required to build KiCad.
|
||||
|
||||
|
||||
# Common Library # {#common_lib}
|
||||
This section covers the source code shared between all of the KiCad
|
||||
applications
|
||||
|
||||
## Unified Rendering Framework ## {#unified_rendering}
|
||||
**Goal:**
|
||||
|
||||
Provide a single framework for developing new tools. Port existing tools
|
||||
to the new framework and remove the legacy framework tools.
|
||||
|
||||
**Task:**
|
||||
- Port wxDC to GAL or get Cairo rendering to nearly the performance of the
|
||||
current wxDC rendering so that we have a single framework to develop new
|
||||
tools and we can continue to support systems that don't have a complete
|
||||
OpenGL stack.
|
||||
|
||||
**Dependencies**
|
||||
- [Tool framework](http://www.ohwr.org/projects/cern-kicad/wiki/WorkPackages)
|
||||
|
||||
**Status**
|
||||
- No progress
|
||||
|
||||
# KiCad: Application Launcher # {#kicad}
|
||||
This section applies to the source code for the KiCad application launcher.
|
||||
@@ -54,19 +95,277 @@ This section applies to the source code for the KiCad application launcher.
|
||||
# Eeschema: Schematic Editor # {#eeschema}
|
||||
This section applies to the source code for the Eeschema schematic editor.
|
||||
|
||||
## Graphics Abstraction Layer Conversion ## {#sch_gal}
|
||||
**Goal:**
|
||||
|
||||
Take advantage of advanced graphics rendering in Eeschema.
|
||||
|
||||
**Task:**
|
||||
- Port graphics rendering to GAL.
|
||||
|
||||
**Dependencies:**
|
||||
- None
|
||||
|
||||
**Status:**
|
||||
- No progress.
|
||||
|
||||
## Port Editing Tools ## {#sch_tool_framework}
|
||||
**Goal:**
|
||||
|
||||
Use standard tool framework across all applications.
|
||||
|
||||
**Task:**
|
||||
- Rewrite editing tools using the new tool framework.
|
||||
|
||||
**Dependencies:**
|
||||
- [GAL port](#sch_gal).
|
||||
|
||||
**Status:**
|
||||
- No progress.
|
||||
|
||||
## Allow Use of System Fonts ## {#sch_sys_fonts}
|
||||
**Goal:**
|
||||
|
||||
Currently the schematic editor uses the stroke drawn fonts which aren't really
|
||||
necessary for accurated printing of schematics. Allow the use of system fonts
|
||||
for schematic text.
|
||||
|
||||
**Task:**
|
||||
- Determine which library for font handling makes the most sense, wxWidgets or
|
||||
freetype.
|
||||
- Add support for selecting text object fonts.
|
||||
|
||||
**Dependencies:**
|
||||
- [S-expression schematic file format](#sch_sexpr).
|
||||
|
||||
**Status:**
|
||||
- No progress.
|
||||
|
||||
# CvPcb: Footprint Association Tool # {#cvpcb}
|
||||
This section covers the source code of the footprint assignment tool CvPcb.
|
||||
|
||||
|
||||
# Pcbnew: Circuit Board Editor # {#pcbnew}
|
||||
This section covers the source code of the board editing application Pcbnew.
|
||||
|
||||
## Model Export ## {#model_export}
|
||||
|
||||
**Goal:**
|
||||
|
||||
Provide improved solid modeling export to the file formats available in
|
||||
OpenCascade.
|
||||
|
||||
**Task:**
|
||||
- Add STEP 3D modeling capability.
|
||||
- Add IGES 3D modeling capability.
|
||||
- Add any other file formats supported by OpenCascade that make sense for
|
||||
KiCad.
|
||||
|
||||
**Dependencies:**
|
||||
- None
|
||||
|
||||
**Status:**
|
||||
- None
|
||||
|
||||
## Linked Objects ## {#pcb_linked_objects}
|
||||
**Goal:**
|
||||
|
||||
Provide a way to allow external objects such as footprints to be externally
|
||||
linked in the board file so that changes in the footprint are automatically
|
||||
updated. This will all a one to many object relationship which can pave the
|
||||
way for real board modules.
|
||||
|
||||
**Task:**
|
||||
- Add externally and internally linked objects to the file format to allow for
|
||||
footprints and/or other board objects to be shared (one to many relationship)
|
||||
instead of only supporting embedded objects (one to one relationship) that
|
||||
can only be edited in place.
|
||||
|
||||
**Dependencies:**
|
||||
- None.
|
||||
|
||||
**Status:**
|
||||
- No progress.
|
||||
|
||||
## Pin and Part Swapping ## {#pcb_drc}
|
||||
**Goal:**
|
||||
|
||||
Allow Pcbnew to perform pin and/or part swapping during layout so the user
|
||||
does not have to do it in Eeschema and re-import the net list.
|
||||
|
||||
**Task:**
|
||||
- Provide forward and back annotation between the schematic and board editors.
|
||||
- Define netlist file format changes required to handle pin/part swapping.
|
||||
- Update netlist file formatter and parser to handle file format changes.
|
||||
- Develop a netlist comparison engine that will produce a netlist diff that
|
||||
can be passed between the schematic and board editors.
|
||||
- Create pin/part swap dialog to manipulate swappable pins and parts.
|
||||
- Add support to handle net label back annotation changes.
|
||||
|
||||
**Dependencies:**
|
||||
- [S-expression schematic file format](#sch_sexpr).
|
||||
- [Convert to a single process application](#kiway).
|
||||
|
||||
**Status:**
|
||||
- No progress.
|
||||
|
||||
## Clipboard Support ## {#fp_edit_clipboard}
|
||||
**Goal:**
|
||||
|
||||
Provide clipboard cut and paste for footprints..
|
||||
|
||||
**Task:**
|
||||
- Clipboard cut and paste to and from clipboard of footprints in footprint
|
||||
editor.
|
||||
|
||||
**Dependencies:**
|
||||
- None
|
||||
|
||||
**Status:**
|
||||
- No progress.
|
||||
|
||||
## Segment End Point Snapping. ## {#segment_snapping}
|
||||
**Goal:**
|
||||
|
||||
It is not uncommon for board edge segment end points to inadvertently not
|
||||
be closed causing issues for the 3D viewer and exporting to different file
|
||||
formats due the board outline not being a fully enclosed polygon. This
|
||||
feature would add segment end snapping support to allow the board outline
|
||||
to be fully enclosed. This feature would only need to be supported by the
|
||||
GAL rendering.
|
||||
|
||||
**Tasks**
|
||||
- Mark board edge segment ends with a drag indicator to make it visible to the
|
||||
user that the segment end does not have an endpoint with any other board edge
|
||||
segment.
|
||||
- Allow the user to smap the unconnected segment end to the nearest segment end
|
||||
point.
|
||||
- Automatically connect unconnected segments with and additional segment when
|
||||
opening the 3D viewer or exporting the board to another format. Warn the
|
||||
user that an addition segment has be added and should be verified.
|
||||
|
||||
**Dependencies:**
|
||||
- None
|
||||
|
||||
**Progress:**
|
||||
- Initial discussion.
|
||||
|
||||
## Keepout Zones. ## {#keepout_zones}
|
||||
**Goal:**
|
||||
|
||||
Add support for keepout zones on boards and footprints.
|
||||
|
||||
**Task:**
|
||||
- Add keepout support to zone classes.
|
||||
- Add keepout zone support to board editor.
|
||||
- Add keepout zone support to library editor.
|
||||
|
||||
**Dependencies:**
|
||||
- [DRC Improvements.](#drc_improvements)
|
||||
|
||||
**Progress:**
|
||||
- Planning
|
||||
|
||||
|
||||
## Net Highlighting ## {#pcb_net_highlight}
|
||||
**Goal:**
|
||||
|
||||
Highlight rats nest links and/or traces when corresponding net in Eeschema is selected.
|
||||
|
||||
**Task:**
|
||||
- Add communications link to handle net selection from Eeschema.
|
||||
- Implement highlight algorithm for objects connected to the selected net.
|
||||
- Highlight objects connected to net selected in Eeschema
|
||||
|
||||
**Dependencies:**
|
||||
- None.
|
||||
|
||||
**Status:**
|
||||
- No progress.
|
||||
|
||||
## Hatched Zone Filling ## {#pcb_hatched_zones}
|
||||
**Goal:**
|
||||
|
||||
Currently Pcbnew only supports solid zone files. Add option to fill zones
|
||||
with hatching.
|
||||
|
||||
**Task:**
|
||||
- Determine zone fill method, required filling code, and file format requirements.
|
||||
- Add hatch option and hatch configuration to zone dialog.
|
||||
|
||||
**Dependencies:**
|
||||
- None.
|
||||
|
||||
**Status:**
|
||||
- No progress.
|
||||
|
||||
|
||||
## Board Stack Up Impedance Calculator ## {#pcb_impedance_calc}
|
||||
**Goal:**
|
||||
|
||||
Provide a calculator to compute trace impedances using a full board stackup.
|
||||
Maybe this should be included in the PCB calculator application.
|
||||
|
||||
**Task:**
|
||||
- Design a trace impedance calculator that includes full board stackup.
|
||||
|
||||
**Dependencies:**
|
||||
- None.
|
||||
|
||||
**Status:**
|
||||
- No progress.
|
||||
|
||||
## Net Class Improvements ## {#pcb_net_class_improvements}
|
||||
**Goal:**
|
||||
|
||||
Add support for route impedance, color selection, etc in net class object.
|
||||
|
||||
**Task:**
|
||||
- Determine parameters to add to net class object.
|
||||
- Implement file parser and formatter changes to support net class object
|
||||
changes.
|
||||
- Implement tools to work with new net class parameters.
|
||||
- Create UI elements to configure new net class parameters.
|
||||
- Update the render tab UI code to view traces by net class.
|
||||
|
||||
**Dependencies:**
|
||||
- None.
|
||||
|
||||
**Status:**
|
||||
- No progress.
|
||||
|
||||
## Ratsnest Improvements ## {#pcb_ratsnest_improvements}
|
||||
**Goal:**
|
||||
|
||||
Add support for per net color and visibility settings.
|
||||
|
||||
**Task:**
|
||||
- Implement UI code to configure ratsnest color and visibility.
|
||||
- Update ratsnest code to handle per net color and visibility.
|
||||
|
||||
**Dependencies:**
|
||||
- None.
|
||||
|
||||
**Status:**
|
||||
- No progress.
|
||||
|
||||
|
||||
# GerbView: Gerber File Viewer # {#gerbview}
|
||||
|
||||
This section covers the source code for the GerbView gerber file viewer.
|
||||
|
||||
## Graphics Abstraction Layer ## {#gerbview_gal}
|
||||
**Goal:**
|
||||
|
||||
Graphics rendering unification.
|
||||
|
||||
**Task:**
|
||||
- Port graphics rendering layer to GAL.
|
||||
|
||||
**Dependencies:**
|
||||
- None.
|
||||
|
||||
**Status**
|
||||
- No progress.
|
||||
|
||||
# Documentation # {#documentation}
|
||||
This section defines the tasks for both the user and developer documentation.
|
||||
@@ -81,7 +380,6 @@ This section defines the tasks for both the user and developer documentation.
|
||||
**Status:**
|
||||
- No progress.
|
||||
|
||||
|
||||
# Unit Testing # {#unittest}
|
||||
**Goal:**
|
||||
|
||||
|
||||
@@ -1,170 +0,0 @@
|
||||
# Technical To-Do List {#technical_todo}
|
||||
|
||||
Some work is blocked for technical reasons, and can only be done once
|
||||
certain other criteria are met (e.g. library versions).
|
||||
|
||||
Because KiCad supports distributions with relatively long support cycles,
|
||||
many of these workarounds will be required for some time, so they are easily
|
||||
forgotten.
|
||||
|
||||
This section collects these so they can be dealt with when the project's
|
||||
minimum version for that dependency is met. This kind of code should always be
|
||||
documented in detail at the place of use, so that it's clear what action should
|
||||
be taken in future.
|
||||
|
||||
[TOC]
|
||||
|
||||
# C++ Versions {#todo_cpp_version}
|
||||
|
||||
Newer C++ versions include features that make some of our current code unnecessary.
|
||||
|
||||
## C++11 {#todo_cpp_11}
|
||||
|
||||
This C++ standard version is already used by KiCad, but much code that pre-dates
|
||||
the version switch exists and can be tidied.
|
||||
|
||||
* [`std::auto_ptr`](https://en.cppreference.com/w/cpp/memory/auto_ptr)
|
||||
should be changed to [`std::unique_ptr`](https://en.cppreference.com/w/cpp/memory/unique_ptr).
|
||||
`auto_ptr` is removed entirely in C++17.
|
||||
|
||||
## C++14 {#todo_cpp_14}
|
||||
|
||||
Compiler support:
|
||||
|
||||
* GCC: complete by GCC 5: [GCC C++14 support](https://gcc.gnu.org/projects/cxx-status.html#cxx14).
|
||||
|
||||
Provides:
|
||||
|
||||
* [`std::make_unique`](https://en.cppreference.com/w/cpp/memory/unique_ptr/make_unique)
|
||||
is available. The "polyfill" in `make_unique.h` is no longer required and can
|
||||
be removed.
|
||||
|
||||
## C++17 {#todo_cpp_17}
|
||||
|
||||
Compiler support:
|
||||
|
||||
* GCC: from GCC 5 to 7: [GCC C++17 support](https://gcc.gnu.org/projects/cxx-status.html#cxx17).
|
||||
|
||||
Provides:
|
||||
|
||||
* `OPT<>` can be replaced with [`std::optional`](https://en.cppreference.com/w/cpp/utility/optional).
|
||||
Header `core/optional.h` can be removed and replaced with the built-in `<optional>`.
|
||||
Needs [GCC 7][].
|
||||
* [`std::filesystem`](https://en.cppreference.com/w/cpp/filesystem)
|
||||
can replace `boost::filesystem` and the Boost dependency can be dropped entirely
|
||||
from the CMake files.
|
||||
|
||||
# Compilers {#compilers}
|
||||
|
||||
Some compilers have bugs or limitations to C++ standard support.
|
||||
|
||||
## GCC {#todo_gcc}
|
||||
|
||||
Current versions:
|
||||
|
||||
* Debian Stretch: [6.3.0](https://packages.debian.org/stretch/gcc)
|
||||
* Debian Buster: [8.3.0](https://packages.debian.org/buster/gcc)
|
||||
* Ubuntu 14.04: [4.8.2](https://packages.ubuntu.com/trusty/gcc)
|
||||
* Ubuntu 16.04: [5.3.1](https://packages.ubuntu.com/xenial/gcc)
|
||||
* Ubuntu 18.04: [7.3.0](https://packages.ubuntu.com/bionic/gcc)
|
||||
|
||||
### GCC 7 {#todo_gcc_7}
|
||||
|
||||
* Fixes [bug #56480](https://gcc.gnu.org/bugzilla/show_bug.cgi?id=56480)
|
||||
(Explicit specialization in a different namespace). This
|
||||
means the `BOOST_TEST_PRINT_NAMESPACE_OPEN` macro is not required, a namespace
|
||||
alias can be used instead.
|
||||
|
||||
# 3rd Party Libraries # {#todo_third_party}
|
||||
|
||||
There are several places in KiCad where workarounds exist for defects in 3rd
|
||||
party library limitations or defects.
|
||||
|
||||
## Boost ## {#todo_boost}
|
||||
|
||||
Current versions:
|
||||
|
||||
* Debian Stretch: [1.62](https://packages.debian.org/stretch/libboost-dev)
|
||||
* Ubuntu 14.04: [1.54](https://packages.ubuntu.com/trusty/libboost-dev)
|
||||
* Ubuntu 16.04: [1.58](https://packages.ubuntu.com/xenial/libboost-dev)
|
||||
* Ubuntu 18.04: [1.65](https://packages.ubuntu.com/bionic/libboost-dev)
|
||||
|
||||
### 1.59 {#boost_1_59}
|
||||
|
||||
* Boost 1.59 brings a major overhaul of the [Boost test][] library.
|
||||
* Many "Polyfills" un `unit_test_utils.h` can be removed:
|
||||
* `BOOST_TEST_CONTEXT` and `BOOST_TEST_INFO` are available, remove the
|
||||
polyfill macros.
|
||||
* `boost::unit_test::expected_failures` is available, so can remove the
|
||||
`HAVE_EXPECTED_FAILURES` guard macro.
|
||||
* `BOOST_TEST_PRINT_NAMESPACE_OPEN` doesn't need to switch the namespace
|
||||
|
||||
### 1.64 #### {#todo_boost_1_64}
|
||||
|
||||
* [Boost test][]
|
||||
* Boost test print helper for `nullptr_t` exists, can remove our polyfill
|
||||
* The [`boost_test_print_type`](https://www.boost.org/doc/libs/master/libs/test/doc/html/boost_test/test_output/test_tools_support_for_logging/testing_tool_output_disable.html)
|
||||
customisation point exists and the old code using `BOOST_TEST_PRINT_NAMESPACE_OPEN`
|
||||
can be converted to use that.
|
||||
|
||||
## CMake ### {#todo_cmake}
|
||||
|
||||
Current versions:
|
||||
|
||||
* Debian Stretch: [3.7.2](https://packages.debian.org/stretch/cmake)
|
||||
* Ubuntu 14.04: [2.8.12](https://packages.ubuntu.com/trusty/cmake)
|
||||
* Ubuntu 16.04: [3.5.1](https://packages.ubuntu.com/xenial/cmake)
|
||||
* Ubuntu 18.04: [3.10.2](https://packages.ubuntu.com/bionic/cmake)
|
||||
|
||||
### 3.1 {#todo_cmake_3_1}
|
||||
|
||||
* Can remove [CMake policy CMP0025](https://cmake.org/cmake/help/v3.0/policy/CMP0025.html)
|
||||
from root CMake
|
||||
|
||||
### 3.3 {#todo_cmake_3_3}
|
||||
|
||||
* Can remove check for [CMake policy CMP0063](https://cmake.org/cmake/help/git-stage/policy/CMP0063.html)
|
||||
entirely (the policy exists as of v3.3 and the default is correct).
|
||||
|
||||
### 3.5 {#todo_cmake_3_5}
|
||||
|
||||
* Can use `target_link_libraries(foo Boost::boost)` for Boost header-only libraries,
|
||||
rather than `${Boost_INCLUDE_DIRS}`.
|
||||
C.f. [Github commit](https://github.com/Kitware/CMake/commit/3f9b081f6ee85e0691c36496d989edbe8382589d)
|
||||
|
||||
## OpenSSL {#todo_openssl}
|
||||
|
||||
Current versions:
|
||||
|
||||
* Debian Stretch: [1.0.1](https://packages.debian.org/stretch/openssl)
|
||||
* Ubuntu 14.04: [1.0.1](https://packages.ubuntu.com/trusty/openssl)
|
||||
* Ubuntu 16.04: [1.0.2](https://packages.ubuntu.com/xenial/openssl)
|
||||
* Ubuntu 18.04: [1.1.0](https://packages.ubuntu.com/bionic/openssl)
|
||||
|
||||
### 1.1.0 {#todo_openssl_1_1_0}
|
||||
|
||||
* Can remove all locking code from `kicad_curl.cpp`. From v1.1.0, this is no
|
||||
longer required. C.f. [OpenSSL issue 1260](https://github.com/openssl/openssl/issues/1260)
|
||||
|
||||
## wxWidgets {#todo_wx}
|
||||
|
||||
Current versions:
|
||||
|
||||
* Debian Stretch: [3.0.2](https://packages.debian.org/stretch/wx-common)
|
||||
* Ubuntu 14.04: [3.0.0](https://packages.ubuntu.com/trusty/wx-common)
|
||||
* Ubuntu 16.04: [3.0.2](https://packages.ubuntu.com/xenial/wx-common)
|
||||
* Ubuntu 18.04: [3.0.4](https://packages.ubuntu.com/bionic/wx-common)
|
||||
|
||||
### 3.1 {#todo_wx_3_1}
|
||||
|
||||
This is a development release, but it brings its own set of features and fixes.
|
||||
Most of these will not be available in general distributions until v3.2.
|
||||
|
||||
* DPI scaling on GTK+ available (also needs GTK+ 3.10).
|
||||
C.f. [this commit](https://github.com/wxWidgets/wxWidgets/commit/f95fd11e08482697c3b0c0a9d2ccd661134480ee)
|
||||
`dpi_scaling.cpp` should continue to work normally, but the config should
|
||||
no longer be required and the scaling should auto-detect.
|
||||
|
||||
|
||||
[Boost test]: https://github.com/boostorg/test
|
||||
[GCC 7]: https://gcc.gnu.org/gcc-7/changes.html
|
||||
@@ -1,152 +1,18 @@
|
||||
# Testing KiCad #
|
||||
|
||||
[TOC]
|
||||
|
||||
# Unit tests {#unit-tests}
|
||||
# Unit tests #
|
||||
|
||||
KiCad has a limited number of unit tests, which can be used to
|
||||
check that certain functionality works.
|
||||
|
||||
Tests are registered using [CTest][], part of CMake. CTest gathers all the
|
||||
disparate test programs and runs them. Most C++ unit
|
||||
tests are written using the [Boost Unit Test framework][], but this is not
|
||||
required to add a test to the testing suite.
|
||||
|
||||
The test CMake targets generally start with `qa_`, the names of the tests
|
||||
within CTest are the same but without the `qa_` prefix.
|
||||
|
||||
## Running tests {#running-tests}
|
||||
|
||||
You can run all tests after building with `make test` or `ctest`. The latter
|
||||
option allows many CTest options which can be useful, especially in automated
|
||||
or CI environments.
|
||||
|
||||
### Running specific tests {#running-specific-tests}
|
||||
|
||||
To run a specific test executable, you can just run with `ctest` or run
|
||||
the executable directly. Running directly is often the simplest way when
|
||||
working on a specific test and you want access to the test executable's
|
||||
arguments. For example:
|
||||
|
||||
# run the libcommon tests
|
||||
cd /path/to/kicad/build
|
||||
qa/common/qa_common [parameters]
|
||||
|
||||
For Boost unit tests, you can see the options for the test with `<test> --help`.
|
||||
Common useful patterns:
|
||||
|
||||
* `<test> -t "Utf8/*"` runs all tests in the `Utf8` test suite.
|
||||
* `<test> -t "Utf8/UniIterNull"` runs only a single test in a specific suite.
|
||||
* `<test> -l all` adds more verbose debugging to the output.
|
||||
* `<test> --list_content` lists the test suites and test cases within the
|
||||
test program. You can use these for arguments to `-t`.
|
||||
|
||||
You can rebuild just a specific test with CMake to avoid rebuilding
|
||||
everything when working on a small area, e.g. `make qa_common`.
|
||||
|
||||
### Automated testing {#automated-testing}
|
||||
|
||||
The unit tests can be run on automated Continuous Integration (CI) systems.
|
||||
|
||||
By default, tests output human-readable results, which is useful when
|
||||
developing or debugging, but not so useful for automated test reporting.
|
||||
Systems that can parse XML test results can enable these by setting the
|
||||
`KICAD_TEST_XML_OUTPUT` option to `ON`. The test results are then output
|
||||
as files ending in `.xml` in the `qa` subdirectory.
|
||||
|
||||
Test results are written to the build directory as follows:
|
||||
|
||||
* Boost units tests: one XML file per test with the extension `.boost-results.xml`
|
||||
* Python unit tests: one directory per test with the extension `.xunit-results.xml`.
|
||||
These directories contain one `.xml` file per Python test case file.
|
||||
|
||||
## Writing Boost tests {#writing-boost-tests}
|
||||
|
||||
Boost unit tests are straightforward to write. Individual test cases can be
|
||||
registered with:
|
||||
|
||||
BOOST_AUTO_TEST_CASE( SomeTest )
|
||||
{
|
||||
BOOST_CHECK_EQUAL( 1, 1 );
|
||||
}
|
||||
|
||||
There is a range of functions like `BOOST_CHECK`, which are documented
|
||||
[here][boost-test-functions]. Using the most specific function is preferred, as that
|
||||
allows Boost to provide more detailed failures: `BOOST_CHECK( foo == bar )` only
|
||||
reports a mismatch, `BOOST_CHECK_EQUAL( foo, bar )` will show the values of
|
||||
each.
|
||||
|
||||
To output debug messages, you can use `BOOST_TEST_MESSAGE` in the unit tests,
|
||||
which will be visible only if you set the `-l` parameter to `message` or higher.
|
||||
This colours the text differently to make it stand out from other testing
|
||||
messages and standard output.
|
||||
|
||||
You can also use `std::cout`, `printf`, `wxLogDebug` and so on for debug
|
||||
messages inside tested functions (i.e. where you don't have access to the Boost
|
||||
unit test headers). These will always be printed, so take care
|
||||
to remove them before committing, or they'll show up when KiCad runs normally!
|
||||
|
||||
### Expected failures {#expected-failures}
|
||||
|
||||
Sometimes, it is helpful to check in tests that do not pass. However, it is bad
|
||||
practise to intentionally check in commits that break builds (which is what
|
||||
happens if you cause `make test` to fail).
|
||||
|
||||
Boost provides a method of declaring that some specific tests are allowed to fail.
|
||||
This syntax is not consistently available in all supported Boost versions, so you
|
||||
should use the following construct:
|
||||
|
||||
```
|
||||
#include <unit_test_utils/unit_test_utils.h>
|
||||
|
||||
// On platforms with older boosts, the test will be excluded entirely
|
||||
#ifdef HAVE_EXPECTED_FAILURES
|
||||
|
||||
// Declare a test case with 1 "allowed" failure (out of 2, in this case)
|
||||
BOOST_AUTO_TEST_CASE( SomeTest, *boost::unit_test::expected_failures( 1 ) )
|
||||
{
|
||||
BOOST_CHECK_EQUAL( 1, 1 );
|
||||
|
||||
// This check fails, but does not cause a test suite failure
|
||||
BOOST_CHECK_EQUAL( 1, 2 );
|
||||
|
||||
// Further failures *would* be a test suit failure
|
||||
}
|
||||
|
||||
#endif
|
||||
```
|
||||
|
||||
When run, this produces output somewhat like this:
|
||||
|
||||
```
|
||||
qa/common/test_mytest.cpp(123): error: in "MyTests/SomeTest": check 1 == 2 has failed [1 != 2
|
||||
*** No errors detected
|
||||
```
|
||||
|
||||
And the unit test executable returns `0` (success).
|
||||
|
||||
Checking in a failing test is a strictly temporary situation, used to illustrate
|
||||
the triggering of a bug prior to fixing it. This is advantageous, not only from
|
||||
a "project history" perspective, but also to ensure that the test you write to
|
||||
catch the bug in question does, in fact, catch the bug in the first place.
|
||||
|
||||
### Assertions {#test-assertions}
|
||||
|
||||
It is possible to check for assertions in unit tests. When running the unit
|
||||
tests, `wxASSERT` calls are caught and re-thrown as exceptions. You can then use
|
||||
the `CHECK_WX_ASSERT` macro to check this is called in Debug builds. In Release
|
||||
builds, the check is not run, as `wxASSERT` is disabled in these builds.
|
||||
|
||||
You can use this to ensure that code rejects invalid input correctly.
|
||||
|
||||
## Python modules {#python-tests}
|
||||
## Python modules ##
|
||||
|
||||
The Pcbnew Python modules have some test programs in the `qa` directory.
|
||||
You must have the `KICAD_SCRIPTING_MODULES` option on in CMake to
|
||||
build the modules and enable this target.
|
||||
|
||||
The main test script is `qa/test.py` and the test units are in
|
||||
`qa/testcases`. All the test units can by run using `ctest python`, which
|
||||
`qa/testcases`. All the test units can by run using `make qa`, which
|
||||
runs `test.py`.
|
||||
|
||||
You can also run an individual case manually, by making sure the
|
||||
@@ -158,7 +24,7 @@ from the source tree:
|
||||
cd /path/to/kicad/source/qa
|
||||
python2 testcase/test_001_pcb_load.py
|
||||
|
||||
### Diagnosing segfaults {#python-segfaults}
|
||||
### Diagnosing segfaults ###
|
||||
|
||||
Although the module is Python, it links against a C++ library
|
||||
(the same one used by KiCad Pcbnew), so it can segfault if the library
|
||||
@@ -173,162 +39,3 @@ You can run the tests in GDB to trace this:
|
||||
|
||||
If the test segfaults, you will get a familiar backtrace, just like
|
||||
if you were running pcbnew under GDB.
|
||||
|
||||
# Utility programs {#utility-programs}
|
||||
|
||||
KiCad includes some utility programs that can be used for debugging, profiling,
|
||||
analysing or developing certain parts of the code without having to invoke the full
|
||||
GUI program.
|
||||
|
||||
Generally, they are part of the `qa_*_tools` QA executables, each one containing
|
||||
the relevant tools for that library. To list the tools in a given program, pass
|
||||
the `-l` parameter. Most tools provide help with the `-h` argument.
|
||||
To invoke a program:
|
||||
|
||||
qa_<lib>_tools <tool name> [-h] [tool arguments]
|
||||
|
||||
Below is a brief outline of some available tools. For full information and command-line
|
||||
parameters, refer to the tools' usage test (`-h`).
|
||||
|
||||
* `common_tools` (the common library and core functions):
|
||||
* `coroutine`: A simple coroutine example
|
||||
* `io_benchmark`: Show relative speeds of reading files using various IO techniques.
|
||||
* `qa_pcbnew_tools` (pcbnew-related functions):
|
||||
* `drc`: Run and benchmark certain DRC functions on a user-provided `.kicad_pcb` files
|
||||
* `pcb_parser`: Parse user-provided `.kicad_pcb` files
|
||||
* `polygon_generator`: Dump polygons found on a PCB to the console
|
||||
* `polygon_triangulation`: Perform triangulation of zone polygons on PCBs
|
||||
|
||||
# Fuzz testing {#fuzz-testing}
|
||||
|
||||
It is possible to run fuzz testing on some parts of KiCad. To do this for a
|
||||
generic function, you need to be able to pass some kind of input from the fuzz
|
||||
testing tool to the function under test.
|
||||
|
||||
For example, to use the [AFL fuzzing tool][], you will need:
|
||||
|
||||
* A test executable that can:
|
||||
* Receive input from `stdin` to be run by `afl-fuzz`.
|
||||
* Optional: process input from a filename to allow `afl-tmin` to minimise the
|
||||
input files.
|
||||
* To compile this executable with an AFL compiler, to enable the instrumentation
|
||||
that allows the fuzzer to detect the fuzzing state.
|
||||
|
||||
For example, the `qa_pcbnew_tools` executable (which contains `pcb_parser`,
|
||||
a fuzz testing tool for `.kicad_pcb` file parsing) can be compiled like this:
|
||||
|
||||
mkdir build
|
||||
cd build
|
||||
cmake -DCMAKE_CXX_COMPILER=/usr/bin/afl-clang-fast++ -DCMAKE_C_COMPILER=/usr/bin/afl-clang-fast ../kicad_src
|
||||
make qa_pcbnew_tools
|
||||
|
||||
You may need to disable core dumps and CPU frequency scaling on your system (AFL
|
||||
will warn you if you should do this). For example, as root:
|
||||
|
||||
# echo core >/proc/sys/kernel/core_pattern
|
||||
# echo performance | tee cpu*/cpufreq/scaling_governor
|
||||
|
||||
To fuzz, run the executable via `afl-fuzz`:
|
||||
|
||||
afl-fuzz -i fuzzin -o fuzzout -m500 qa/pcbnew_tools/qa_pcbnew_tools pcb_parser
|
||||
|
||||
where:
|
||||
|
||||
* `-i` is a directory of files to use as fuzz input "seeds"
|
||||
* `-o` is a directory to write the results (including inputs that provoke crashes
|
||||
or hangs)
|
||||
* `-t` is the maximum time that a run is allowed to take before being declared a "hang"
|
||||
* `-m` is the memory allowed to use (this often needs to be bumped, as KiCad code
|
||||
tends to use a lot of memory to initialise)
|
||||
|
||||
The AFL TUI will then display the fuzzing progress, and you can use the hang- or
|
||||
crash-provoking inputs to debug code as needed.
|
||||
|
||||
# Run-time debugging {#run-time}
|
||||
|
||||
KiCad can be debugged at run-time, either under a full debugger
|
||||
such as GDB, or using simple methods like logging debug to the
|
||||
console.
|
||||
|
||||
## Printing debug {#print-debug}
|
||||
|
||||
If you are compiling KiCad yourself, you can simply add debugging statements to
|
||||
relevant places in the code, for example:
|
||||
|
||||
wxLogDebug( "Value of variable: %d", my_int );
|
||||
|
||||
This produces debug output that can only be seen when compiling
|
||||
in Debug mode.
|
||||
|
||||
You can also use `std::cout` and `printf`.
|
||||
|
||||
Ensure you do not leave this kind of debugging in place when
|
||||
submitting code.
|
||||
|
||||
## Printing trace {#trace-debug}
|
||||
|
||||
Some parts of the code have "trace" that can be enabled selectively according to
|
||||
a "mask", for example:
|
||||
|
||||
wxLogTrace( "TRACEMASK", "My trace, value: %d", my_int );
|
||||
|
||||
This will not be printed by default. To show it, set the `WXTRACE` environment
|
||||
variable when you run KiCad to include the masks you wish to enable:
|
||||
|
||||
$ WXTRACE="TRACEMASK,OTHERMASK" kicad
|
||||
|
||||
When printed, the debug will be prefixed with a timestamp and the trace mask:
|
||||
|
||||
11:22:33: Trace: (TRACEMASK) My trace, value: 42
|
||||
|
||||
If you add a trace mask, define and document the mask as a variable in
|
||||
`include/trace_helpers.h`. This will add it to the [trace mask documentation][].
|
||||
|
||||
Some available masks:
|
||||
|
||||
* Core KiCad functions:
|
||||
* `KICAD_KEY_EVENTS`
|
||||
* `KicadScrollSettings`
|
||||
* `KICAD_FIND_ITEM`
|
||||
* `KICAD_FIND_REPLACE`
|
||||
* `KICAD_NGSPICE`
|
||||
* `KICAD_PLUGINLOADER`
|
||||
* `GAL_PROFILE`
|
||||
* `GAL_CACHED_CONTAINER`
|
||||
* `PNS`
|
||||
* `CN`
|
||||
* `SCROLL_ZOOM` - for the scroll-wheel zooming logic in GAL
|
||||
* Plugin-specific (including "standard" KiCad formats):
|
||||
* `3D_CACHE`
|
||||
* `3D_SG`
|
||||
* `3D_RESOLVER`
|
||||
* `3D_PLUGIN_MANAGER`
|
||||
* `KI_TRACE_CCAMERA`
|
||||
* `PLUGIN_IDF`
|
||||
* `PLUGIN_VRML`
|
||||
* `KICAD_SCH_LEGACY_PLUGIN`
|
||||
* `KICAD_GEDA_PLUGIN`
|
||||
* `KICAD_PCB_PLUGIN`
|
||||
|
||||
# Advanced configuration {#advanced-configuration}
|
||||
|
||||
There are some advance configuration options, which are mostly used for
|
||||
development or testing purposes.
|
||||
|
||||
To set these options, you can create the file `kicad_advanced` and set the keys
|
||||
as desired (the [advanced config documentation][] for a current list. You should
|
||||
never need to set these keys for normal usage - if you do, that's a bug.
|
||||
|
||||
Any features enabled though the advanced configuration system are
|
||||
considered experimental and therefore unsuitable for production use. These
|
||||
features are explicitly not supported or considered fully tested.
|
||||
Issues are still welcome for defects discovered.
|
||||
|
||||
|
||||
[CTest]: https://cmake.org/cmake/help/latest/module/CTest.html
|
||||
[Boost Unit Test framework]: https://www.boost.org/doc/libs/1_68_0/libs/test/doc/html/index.html
|
||||
[boost-test-functions]: https://www.boost.org/doc/libs/1_68_0/libs/test/doc/html/boost_test/utf_reference/testing_tool_ref.html
|
||||
[AFL fuzzing tool]: http://lcamtuf.coredump.cx/afl/
|
||||
[trace mask documentation]: http://docs.kicad-pcb.org/doxygen/group__trace__env__vars.html
|
||||
[trace mask documentation]: http://docs.kicad-pcb.org/doxygen/group__trace__env__vars.html
|
||||
[advanced config documentation]: http://docs.kicad-pcb.org/doxygen/namespaceAC__KEYS.html
|
||||
|
||||
@@ -30,7 +30,7 @@ Some examples of tools in the Pcbnew GAL are:
|
||||
* The drawing tool - this tool controls the process of drawing graphics
|
||||
elements such as line segments and circles.
|
||||
(pcbnew/tools/drawing_tool.cpp,pcbnew/tools/drawing_tool.h)
|
||||
* The zoom tool - allows the user to zoom in and out.
|
||||
* The zoom tool - allows the user to zoom in and out
|
||||
|
||||
# Major parts of a tool # {#major-parts}
|
||||
|
||||
@@ -60,10 +60,7 @@ or not, has a `TOOL_ACTION` instance. This provides:
|
||||
tooltip and provides a more detailed description if needed.
|
||||
* An "icon", which is shown in menus and on buttons for the action
|
||||
* "Flags" which include:
|
||||
* `AF_ACTIVATE` which indicates that the tool enters an active state. When
|
||||
a tool is active it will keep receiving UI events, such as mouse clicks
|
||||
or key presses, which are normally handled in an event loop (see
|
||||
TOOL_INTERACTIVE::Wait()).
|
||||
* `AF_ACTIVATE` which indicates that the tool enters an active state
|
||||
* A parameter, which allows different actions to call the same function
|
||||
with different effects, for example "step left" and "step right".
|
||||
|
||||
@@ -71,7 +68,8 @@ or not, has a `TOOL_ACTION` instance. This provides:
|
||||
|
||||
GAL tools inherit the `TOOL_BASE` class. A Pcbnew tool will generally
|
||||
inherit from `PCB_TOOL`, which is a `TOOL_INTERACTIVE`, which is
|
||||
a `TOOL_BASE`. Eeschema tools inherit directly from `TOOL_INTERACTIVE`.
|
||||
a `TOOL_BASE`. In the future, Eeschema tools will be developed in a similar
|
||||
manner.
|
||||
|
||||
The tool class for a tool can be fairly lightweight - much of the
|
||||
functionality is inherited from the tool's base classes. These base
|
||||
@@ -104,18 +102,18 @@ The major parts of tool's implementation are the functions used by the
|
||||
when the GAL canvas is switched, and also just after tool registration.
|
||||
Any resource claimed from the GAL view or the model must be released
|
||||
in this function, as they could become invalid.
|
||||
* `setTransitions()` function, which maps tool actions to functions
|
||||
* `SetTransitions()` function, which maps tool actions to functions
|
||||
within the tool class.
|
||||
* One or more functions to call when actions are invoked. Many actions
|
||||
can invoke the same function if desired. The functions have the
|
||||
following signature:
|
||||
* int TOOL_CLASS::FunctionName( const TOOL_EVENT& aEvent )
|
||||
* Returning 0 means success.
|
||||
* Returning 0 means success.
|
||||
* These functions are called by the `TOOL_MANAGER` in case an associated
|
||||
event arrives (association is created with TOOL_INTERACTIVE::Go() function).
|
||||
* These can generally be private, as they are not called directly
|
||||
by any other code, but are invoked by the tool manager's coroutine
|
||||
framework according to the `setTransitions()` map.
|
||||
framework according to the `SetTransitions()` map.
|
||||
|
||||
### Interactive actions {#interactive-actions}
|
||||
|
||||
@@ -131,7 +129,7 @@ a cursor change and by setting a status string.
|
||||
auto& frame = *getEditFrame<PCB_EDIT_FRAME>();
|
||||
|
||||
// set tool hint and cursor (actually looks like a crosshair)
|
||||
frame.SetToolID( ID_LOCAL_RATSNEST_BUTT,
|
||||
frame.SetToolID( ID_PCB_SHOW_1_RATSNEST_BUTT,
|
||||
wxCURSOR_PENCIL, _( "Select item to move left" ) );
|
||||
getViewControls()->ShowCursor( true );
|
||||
|
||||
@@ -170,7 +168,7 @@ provide their own context menu. Tools that are called only from other
|
||||
tools' interactive modes add their menu items to those tools' menus.
|
||||
|
||||
To use a `TOOL_MENU` in a top level tool, simply add one as a member
|
||||
and initialize it with a reference to the tools at construction time:
|
||||
and initialise it with a reference to the tools at construction time:
|
||||
|
||||
TOOL_NAME: public PCB_TOOL
|
||||
{
|
||||
@@ -214,7 +212,7 @@ The procedure of a commit is:
|
||||
unless you are going to abort the commit.
|
||||
* When removing an item, call `Remove( item )`. You should not delete the
|
||||
removed item, it will be stored in the undo buffer.
|
||||
* Finalize the commit with `Push( "Description" )`. If you performed
|
||||
* Finalise the commit with `Push( "Description" )`. If you performed
|
||||
no modifications, additions or removals, this is a no-op, so you
|
||||
don't need to check if you made any changes before pushing.
|
||||
|
||||
@@ -283,7 +281,7 @@ In `pcbnew/tools/pcb_actions.h`, we add the following to the
|
||||
static TOOL_ACTION uselessFixedCircle;
|
||||
|
||||
Definitions of actions generally happen in the .cpp of the relevant tool.
|
||||
It doesn't actually matter where the definition occurs (the declaration
|
||||
It doesn't actually matter where the defintion occurs (the declaration
|
||||
is enough to use the action), as long as it's linked in the end.
|
||||
Similar tools should always be defined together.
|
||||
|
||||
@@ -336,11 +334,11 @@ the following class:
|
||||
///> React to model/view changes
|
||||
void Reset( RESET_REASON aReason ) override;
|
||||
|
||||
///> Basic initialization
|
||||
///> Basic initalization
|
||||
bool Init() override;
|
||||
|
||||
///> Bind handlers to corresponding TOOL_ACTIONs
|
||||
void setTransitions() override;
|
||||
void SetTransitions() override;
|
||||
|
||||
private:
|
||||
///> 'Move selected left' interactive tool
|
||||
@@ -391,7 +389,7 @@ Below you will find the contents of useless_tool.cpp:
|
||||
|
||||
|
||||
/*
|
||||
* Tool-specific action definitions
|
||||
* Tool-specific action defintions
|
||||
*/
|
||||
TOOL_ACTION PCB_ACTIONS::uselessMoveItemLeft(
|
||||
"pcbnew.UselessTool.MoveItemLeft",
|
||||
@@ -442,7 +440,7 @@ Below you will find the contents of useless_tool.cpp:
|
||||
void USELESS_TOOL::moveLeftInt()
|
||||
{
|
||||
// we will call actions on the selection tool to get the current
|
||||
// selection. The selection tools will handle item disambiguation
|
||||
// selection. The selection tools will handle item deisambiguation
|
||||
SELECTION_TOOL* selectionTool = m_toolMgr->GetTool<SELECTION_TOOL>();
|
||||
assert( selectionTool );
|
||||
|
||||
@@ -534,7 +532,7 @@ Below you will find the contents of useless_tool.cpp:
|
||||
}
|
||||
|
||||
|
||||
void USELESS_TOOL::setTransitions()
|
||||
void USELESS_TOOL::SetTransitions()
|
||||
{
|
||||
Go( &USELESS_TOOL::fixedCircle, PCB_ACTIONS::uselessFixedCircle.MakeEvent() );
|
||||
Go( &USELESS_TOOL::moveLeft, PCB_ACTIONS::uselessMoveItemLeft.MakeEvent() );
|
||||
@@ -545,8 +543,22 @@ Below you will find the contents of useless_tool.cpp:
|
||||
|
||||
The last step is to register the tool in the tool manager.
|
||||
|
||||
This is done in the frame's `setupTools()` function for whichever
|
||||
`EDA_DRAW_FRAME` support that tool.
|
||||
This is done by adding a new instance of the tool to the
|
||||
`registerAllTools()` function in `pcbnew/tools/tools_common.cpp`.
|
||||
|
||||
// add your tool header
|
||||
#include <tools/useless_tool.h>
|
||||
|
||||
void registerAllTools( TOOL_MANAGER *aToolManager )
|
||||
{
|
||||
....
|
||||
aToolManager->RegisterTool( new USELESS_TOOL );
|
||||
....
|
||||
}
|
||||
|
||||
If your new tool applies in the module editor, you also need to do this
|
||||
in `FOOTPRINT_EDIT_FRAME::setupTools()`. Generally, each kind of
|
||||
`EDA_DRAW_FRAME` that can use GAL will have a place to do this.
|
||||
|
||||
## Build and run {#tutorial-summary}
|
||||
|
||||
|
||||
@@ -71,12 +71,12 @@ Webpage titles and navigational elements | Header
|
||||
|
||||
This section defines how dialog boxes should be designed. The KiCad project
|
||||
uses the [GNOME User Interface Guidelines][gnome-ui-guidelines] for laying out
|
||||
dialogs. When designing dialogs, follow the [visual layout section of the GNOME
|
||||
User Interface Guidelines][gnome-ui-layout]. KiCad's dialogs may either be
|
||||
designed with [wxFormBuilder][wxformbuilder] or created by hand. However,
|
||||
existing dialogs must be maintained in the same way as they have been
|
||||
implemented. Please use [wxFormBuilder v3.8.0 or later][wxformbuilder-releases]
|
||||
to avoid version mismatch between developers.
|
||||
dialogs. KiCad's dialogs must be designed with [wxFormBuilder][wxformbuilder].
|
||||
As wxFormBuilder available in packages is likely to be a different version than
|
||||
what other developers have installed, it has been decided to use the version
|
||||
kept in a Github repository, branch [wxFB3.5RC-1][wxformbuilder-github] to avoid
|
||||
version mismatch. When designing dialogs, follow the [visual layout section of
|
||||
the GNOME User Interface Guidelines][gnome-ui-layout].
|
||||
|
||||
## Escape Key Termination ## {#dialogs-esc-key}
|
||||
Please note that the escape key termination only works properly if there is a
|
||||
@@ -168,8 +168,8 @@ controls so text should be quoted with single quotes ''. e.g.:
|
||||
[gnome-ui-guidelines]:https://developer.gnome.org/hig/stable/
|
||||
[gnome-ui-layout]:https://developer.gnome.org/hig/stable/visual-layout.html.en
|
||||
[gnome-ui-style]:https://developer.gnome.org/hig/stable/writing-style.html.en
|
||||
[wxformbuilder]:https://github.com/wxFormBuilder/wxFormBuilder
|
||||
[wxformbuilder-releases]:https://github.com/wxFormBuilder/wxFormBuilder/releases
|
||||
[wxformbuilder]:https://sourceforge.net/projects/wxformbuilder/
|
||||
[wxformbuilder-github]:https://github.com/marekr/wxFormBuilder/tree/wxFB3.5-RC1
|
||||
[wxwidgets-doc]:http://docs.wxwidgets.org/3.0/
|
||||
[wxdialog-setescapeid]:http://docs.wxwidgets.org/3.0/classwx_dialog.html#a585869988e308f549128a6a065f387c6
|
||||
[wxwidgets-sizers]:http://docs.wxwidgets.org/3.0/overview_sizer.html
|
||||
|
||||
@@ -1,131 +0,0 @@
|
||||
#
|
||||
# This program source code file is part of KICAD, a free EDA CAD application.
|
||||
#
|
||||
# Copyright (C) 2018 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
|
||||
|
||||
# Build file for docset generation.
|
||||
#
|
||||
# Docsets are generated from the Doxygen docs by this process:
|
||||
# * Modify the existing doxygen file for a docset-friendly output
|
||||
# * Run doxygen to generate normal docygen output
|
||||
# * Run a makefile made by doxygen to start the docset
|
||||
# * Run doxytag2zealdb to generate the docset index
|
||||
# * Make a couple of changes to the Plist file and add icons
|
||||
|
||||
find_program(DOXYTAG2ZEALDB doxytag2zealdb)
|
||||
find_program(SED sed)
|
||||
|
||||
if(DOXYGEN_FOUND AND DOXYTAG2ZEALDB AND SED)
|
||||
|
||||
function(get_kicad_doc_version RESULT_NAME)
|
||||
|
||||
include( ${CMAKE_MODULE_PATH}/CreateGitVersionHeader.cmake )
|
||||
create_git_version_header(${CMAKE_SOURCE_DIR})
|
||||
|
||||
# Now we have KICAD_VERSION, but it's got () around it
|
||||
string(REPLACE "(" "" KICAD_VERSION ${KICAD_VERSION})
|
||||
string(REPLACE ")" "" KICAD_VERSION ${KICAD_VERSION})
|
||||
|
||||
set (${RESULT_NAME} ${KICAD_VERSION} PARENT_SCOPE)
|
||||
|
||||
endfunction()
|
||||
|
||||
# The DocSet's bundle ID, which is used for most of the ID's
|
||||
set(BUNDLE_ID KiCad)
|
||||
|
||||
# The source for the doxygen config
|
||||
set(SRC_DOXYFILE ${CMAKE_SOURCE_DIR}/Doxyfile)
|
||||
|
||||
# A new doxyfile with the original, plus some extra config
|
||||
set(DOCSET_DOXYFILE ${CMAKE_CURRENT_BINARY_DIR}/Doxyfile)
|
||||
|
||||
# Various pieces of the docset
|
||||
set(DOCSET_LOC ${CMAKE_CURRENT_BINARY_DIR}/doxygen/html/${BUNDLE_ID}.docset)
|
||||
set(DOXY_MAKEFILE ${CMAKE_CURRENT_BINARY_DIR}/doxygen/html/Makefile)
|
||||
set(DOXY_TAG_FILE ${CMAKE_CURRENT_BINARY_DIR}/${BUNDLE_ID}.tag)
|
||||
set(DOCSET_PLIST ${DOCSET_LOC}/Contents/Info.plist)
|
||||
set(DOCSET_DSIDX ${DOCSET_LOC}/Contents/Resources/docSet.dsidx)
|
||||
|
||||
#icon files
|
||||
set(DOCSET_SRC_ICON16 ${CMAKE_CURRENT_SOURCE_DIR}/icon-16.png)
|
||||
set(DOCSET_ICON16 ${DOCSET_LOC}/icon.png)
|
||||
|
||||
get_kicad_doc_version(KICAD_DOC_VERSION)
|
||||
|
||||
# copy and modify the "normal" Doxyfile
|
||||
file(COPY ${SRC_DOXYFILE} DESTINATION ${CMAKE_CURRENT_BINARY_DIR})
|
||||
file(APPEND ${DOCSET_DOXYFILE} "
|
||||
|
||||
# Added for DocSet generation
|
||||
OUTPUT_DIRECTORY = ${CMAKE_CURRENT_BINARY_DIR}/doxygen
|
||||
PROJECT_NAME = ${BUNDLE_ID}
|
||||
PROJECT_NUMBER = ${KICAD_DOC_VERSION}
|
||||
GENERATE_DOCSET = YES
|
||||
DOCSET_FEEDNAME = ${BUNDLE_ID}
|
||||
DOCSET_BUNDLE_ID = ${BUNDLE_ID}
|
||||
DISABLE_INDEX = YES
|
||||
GENERATE_TREEVIEW = NO
|
||||
SEARCHENGINE = NO
|
||||
GENERATE_TAGFILE = ${DOXY_TAG_FILE}"
|
||||
)
|
||||
|
||||
add_custom_command(
|
||||
COMMAND ${DOXYGEN_EXECUTABLE} ${DOCSET_DOXYFILE}
|
||||
WORKING_DIRECTORY ${CMAKE_SOURCE_DIR}
|
||||
OUTPUT ${DOXY_TAG_FILE} ${DOXY_MAKEFILE}
|
||||
DEPENDS ${DOCSET_DOXYFILE}
|
||||
COMMENT "Generating Doxygen for DocSet"
|
||||
)
|
||||
|
||||
# Generate the skeleton of the docset
|
||||
# And modify the plist: DocSetPlatformFamily is used for the prefix in Zeal,
|
||||
add_custom_command(
|
||||
COMMAND make || true
|
||||
COMMAND ${SED} -i "/<key>DocSetPlatformFamily<\\/key>/!b;n;s/doxygen/${BUNDLE_ID}/" ${DOCSET_PLIST}
|
||||
WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/doxygen/html
|
||||
DEPENDS ${DOXY_MAKEFILE}
|
||||
OUTPUT ${DOCSET_PLIST}
|
||||
COMMENT "Running doxygen-generated makefile"
|
||||
VERBATIM
|
||||
)
|
||||
|
||||
add_custom_command(
|
||||
COMMAND ${DOXYTAG2ZEALDB} --tag ${DOXY_TAG_FILE}
|
||||
--db ${DOCSET_DSIDX}
|
||||
--include-parent-scopes
|
||||
--include-function-signatures
|
||||
WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/doxygen/html
|
||||
DEPENDS ${DOCSET_PLIST} ${DOXY_TAG_FILE}
|
||||
OUTPUT ${DOCSET_DSIDX}
|
||||
COMMENT "Generating docset index"
|
||||
)
|
||||
|
||||
add_custom_command(
|
||||
COMMAND ${CMAKE_COMMAND} -E copy ${DOCSET_SRC_ICON16} ${DOCSET_ICON16}
|
||||
DEPENDS ${DOCSET_DSIDX} ${DOCSET_SRC_ICON16}
|
||||
OUTPUT ${DOCSET_ICON16}
|
||||
COMMENT "Copying docset icons"
|
||||
)
|
||||
|
||||
add_custom_target(docset
|
||||
DEPENDS ${DOCSET_ICON16}
|
||||
)
|
||||
|
||||
endif()
|
||||
Binary file not shown.
|
Before Width: | Height: | Size: 271 B |
Binary file not shown.
|
Before Width: | Height: | Size: 1.5 KiB After Width: | Height: | Size: 8.7 KiB |
+1
-1
@@ -114,7 +114,7 @@ GLM >= 9.5.4 http://glm.g-truc.net/
|
||||
|
||||
pkg-config http://pkgconfig.freedesktop.org/
|
||||
|
||||
Doxygen (optional) http://www.doxygen.nl
|
||||
Doxygen (optional) http://www.stack.nl/~dimitri/doxygen/index.html
|
||||
|
||||
python >= 2.6 (optional) http://python.org/
|
||||
|
||||
|
||||
@@ -1,23 +0,0 @@
|
||||
Boost Software License - Version 1.0 - August 17th, 2003
|
||||
|
||||
Permission is hereby granted, free of charge, to any person or organization
|
||||
obtaining a copy of the software and accompanying documentation covered by
|
||||
this license (the "Software") to use, reproduce, display, distribute,
|
||||
execute, and transmit the Software, and to prepare derivative works of the
|
||||
Software, and to permit third-parties to whom the Software is furnished to
|
||||
do so, all subject to the following:
|
||||
|
||||
The copyright notices in the Software and this entire statement, including
|
||||
the above license grant, this restriction and the following disclaimer,
|
||||
must be included in all copies of the Software, in whole or in part, and
|
||||
all derivative works of the Software, unless such copies or derivative
|
||||
works are solely in the form of machine-executable object code generated by
|
||||
a source language processor.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT
|
||||
SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE
|
||||
FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE,
|
||||
ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||
DEALINGS IN THE SOFTWARE.
|
||||
@@ -1,255 +0,0 @@
|
||||
Creative Commons Attribution-ShareAlike 4.0 International Public License
|
||||
|
||||
By exercising the Licensed Rights (defined below), You accept and agree to
|
||||
be bound by the terms and conditions of this Creative Commons
|
||||
Attribution-ShareAlike 4.0 International Public License ("Public License").
|
||||
To the extent this Public License may be interpreted as a contract, You are
|
||||
granted the Licensed Rights in consideration of Your acceptance of these
|
||||
terms and conditions, and the Licensor grants You such rights in
|
||||
consideration of benefits the Licensor receives from making the Licensed
|
||||
Material available under these terms and conditions.
|
||||
|
||||
Section 1 – Definitions.
|
||||
|
||||
a. Adapted Material means material subject to Copyright and Similar Rights
|
||||
that is derived from or based upon the Licensed Material and in which the
|
||||
Licensed Material is translated, altered, arranged, transformed, or
|
||||
otherwise modified in a manner requiring permission under the Copyright
|
||||
and Similar Rights held by the Licensor. For purposes of this Public
|
||||
License, where the Licensed Material is a musical work, performance, or
|
||||
sound recording, Adapted Material is always produced where the Licensed
|
||||
Material is synched in timed relation with a moving image.
|
||||
b. Adapter's License means the license You apply to Your Copyright and
|
||||
Similar Rights in Your contributions to Adapted Material in accordance
|
||||
with the terms and conditions of this Public License.
|
||||
c. BY-SA Compatible License means a license listed at
|
||||
creativecommons.org/compatiblelicenses, approved by Creative Commons as
|
||||
essentially the equivalent of this Public License.
|
||||
d. Copyright and Similar Rights means copyright and/or similar rights closely
|
||||
related to copyright including, without limitation, performance,
|
||||
broadcast, sound recording, and Sui Generis Database Rights, without
|
||||
regard to how the rights are labeled or categorized. For purposes of this
|
||||
Public License, the rights specified in Section 2(b)(1)-(2) are not
|
||||
Copyright and Similar Rights.
|
||||
e. Effective Technological Measures means those measures that, in the absence
|
||||
of proper authority, may not be circumvented under laws fulfilling
|
||||
obligations under Article 11 of the WIPO Copyright Treaty adopted on
|
||||
December 20, 1996, and/or similar international agreements.
|
||||
f. Exceptions and Limitations means fair use, fair dealing, and/or any other
|
||||
exception or limitation to Copyright and Similar Rights that applies to
|
||||
Your use of the Licensed Material.
|
||||
g. License Elements means the license attributes listed in the name of a
|
||||
Creative Commons Public License. The License Elements of this Public
|
||||
License are Attribution and ShareAlike.
|
||||
h. Licensed Material means the artistic or literary work, database, or other
|
||||
material to which the Licensor applied this Public License.
|
||||
i. Licensed Rights means the rights granted to You subject to the terms and
|
||||
conditions of this Public License, which are limited to all Copyright and
|
||||
Similar Rights that apply to Your use of the Licensed Material and that
|
||||
the Licensor has authority to license.
|
||||
j. Licensor means the individual(s) or entity(ies) granting rights under this
|
||||
Public License.
|
||||
k. Share means to provide material to the public by any means or process thati
|
||||
requires permission under the Licensed Rights, such as reproduction,
|
||||
public display, public performance, distribution, dissemination,
|
||||
communication, or importation, and to make material available to the
|
||||
public including in ways that members of the public may access the
|
||||
material from a place and at a time individually chosen by them.
|
||||
l. Sui Generis Database Rights means rights other than copyright resulting
|
||||
from Directive 96/9/EC of the European Parliament and of the Council of 11
|
||||
March 1996 on the legal protection of databases, as amended and/or
|
||||
succeeded, as well as other essentially equivalent rights anywhere in the
|
||||
world.
|
||||
m. You means the individual or entity exercising the Licensed Rights under
|
||||
this Public License. Your has a corresponding meaning.
|
||||
|
||||
Section 2 – Scope.
|
||||
|
||||
a. License grant.
|
||||
1. Subject to the terms and conditions of this Public License, the
|
||||
Licensor hereby grants You a worldwide, royalty-free,
|
||||
non-sublicensable, non-exclusive, irrevocable license to exercise the
|
||||
Licensed Rights in the Licensed Material to:
|
||||
A. reproduce and Share the Licensed Material, in whole or in part; and
|
||||
B. produce, reproduce, and Share Adapted Material.
|
||||
2. Exceptions and Limitations. For the avoidance of doubt, where Exceptions
|
||||
and Limitations apply to Your use, this Public License does not apply,
|
||||
and you do not need to comply with its terms and conditions.
|
||||
3. Term. The term of this Public License is specified in Section 6(a).
|
||||
4. Media and formats; technical modifications allowed. The Licensor
|
||||
authorizes You to exercise the Licensed Rights in all media and formats
|
||||
whether now known or hereafter created, and to make technical
|
||||
modifications necessary to do so. The Licensor waives and/or agrees not
|
||||
to assert any right or authority to forbid You from making technical
|
||||
modifications necessary to exercise the Licensed Rights, including
|
||||
technical modifications necessary to circumvent Effective Technological
|
||||
Measures. For purposes of this Public License, simply making
|
||||
modifications authorized by this Section 2(a)(4) never produces Adapted
|
||||
Material.
|
||||
5. Downstream recipients.
|
||||
A. Offer from the Licensor – Licensed Material. Every recipient of the
|
||||
Licensed Material automatically receives an offer from the Licensor
|
||||
to exercise the Licensed Rights under the terms and conditions of
|
||||
this Public License.
|
||||
B. Additional offer from the Licensor – Adapted Material. Every
|
||||
recipient of Adapted Material from You automatically receives an
|
||||
offer from the Licensor to exercise the Licensed Rights in the
|
||||
Adapted Material under the conditions of the Adapter’s License You
|
||||
apply.
|
||||
C. No downstream restrictions. You may not offer or impose any
|
||||
additional or different terms or conditions on, or apply any
|
||||
Effective Technological Measures to, the Licensed Material if doing
|
||||
so restricts exercise of the Licensed Rights by any recipient of
|
||||
the Licensed Material.
|
||||
6. No endorsement. Nothing in this Public License constitutes or may be
|
||||
construed as permission to assert or imply that You are, or that Your
|
||||
use of the Licensed Material is, connected with, or sponsored,
|
||||
endorsed, or granted official status by, the Licensor or others
|
||||
designated to receive attribution as provided in Section 3(a)(1)(A)(i).
|
||||
|
||||
b. Other rights.
|
||||
1. Moral rights, such as the right of integrity, are not licensed under
|
||||
this Public License, nor are publicity, privacy, and/or other similar
|
||||
personality rights; however, to the extent possible, the Licensor
|
||||
waives and/or agrees not to assert any such rights held by the Licensor
|
||||
to the limited extent necessary to allow You to exercise the Licensed
|
||||
Rights, but not otherwise.
|
||||
2. Patent and trademark rights are not licensed under this Public License.
|
||||
3. To the extent possible, the Licensor waives any right to collect
|
||||
royalties from You for the exercise of the Licensed Rights, whether
|
||||
directly or through a collecting society under any voluntary or
|
||||
waivable statutory or compulsory licensing scheme. In all other cases
|
||||
the Licensor expressly reserves any right to collect such royalties.
|
||||
|
||||
Section 3 – License Conditions.
|
||||
|
||||
Your exercise of the Licensed Rights is expressly made subject to the
|
||||
following conditions.
|
||||
|
||||
a. Attribution.
|
||||
1. If You Share the Licensed Material (including in modified form), You
|
||||
must:
|
||||
A. retain the following if it is supplied by the Licensor with the
|
||||
Licensed Material:
|
||||
i. identification of the creator(s) of the Licensed Material and any
|
||||
others designated to receive attribution, in any reasonable manner
|
||||
requested by the Licensor (including by pseudonym if designated);
|
||||
ii. a copyright notice;
|
||||
iii. a notice that refers to this Public License;
|
||||
iv. a notice that refers to the disclaimer of warranties;
|
||||
v. a URI or hyperlink to the Licensed Material to the extent
|
||||
reasonably practicable;
|
||||
B. indicate if You modified the Licensed Material and retain an
|
||||
indication of any previous modifications; and
|
||||
C. indicate the Licensed Material is licensed under this Public
|
||||
License, and include the text of, or the URI or hyperlink to, this
|
||||
Public License.
|
||||
2. You may satisfy the conditions in Section 3(a)(1) in any reasonable
|
||||
manner based on the medium, means, and context in which You Share the
|
||||
Licensed Material. For example, it may be reasonable to satisfy the
|
||||
conditions by providing a URI or hyperlink to a resource that includes
|
||||
the required information.
|
||||
3. If requested by the Licensor, You must remove any of the information
|
||||
required by Section 3(a)(1)(A) to the extent reasonably practicable.
|
||||
|
||||
b. ShareAlike.
|
||||
In addition to the conditions in Section 3(a), if You Share Adapted
|
||||
Material You produce, the following conditions also apply.
|
||||
1. The Adapter’s License You apply must be a Creative Commons license with
|
||||
the same License Elements, this version or later, or a BY-SA Compatible
|
||||
License.
|
||||
2. You must include the text of, or the URI or hyperlink to, the Adapter's
|
||||
License You apply. You may satisfy this condition in any reasonable
|
||||
manner based on the medium, means, and context in which You Share
|
||||
Adapted Material.
|
||||
3. You may not offer or impose any additional or different terms or
|
||||
conditions on, or apply any Effective Technological Measures to,
|
||||
Adapted Material that restrict exercise of the rights granted under the
|
||||
Adapter's License You apply.
|
||||
|
||||
Section 4 – Sui Generis Database Rights.
|
||||
|
||||
Where the Licensed Rights include Sui Generis Database Rights that apply to
|
||||
Your use of the Licensed Material:
|
||||
a. for the avoidance of doubt, Section 2(a)(1) grants You the right to
|
||||
extract, reuse, reproduce, and Share all or a substantial portion of the
|
||||
contents of the database;
|
||||
b. if You include all or a substantial portion of the database contents in a
|
||||
database in which You have Sui Generis Database Rights, then the database
|
||||
in which You have Sui Generis Database Rights (but not its individual
|
||||
contents) is Adapted Material, including for purposes of Section 3(b); and
|
||||
c. You must comply with the conditions in Section 3(a) if You Share all or a
|
||||
substantial portion of the contents of the database.
|
||||
|
||||
For the avoidance of doubt, this Section 4 supplements and does not replace
|
||||
Your obligations under this Public License where the Licensed Rights include
|
||||
other Copyright and Similar Rights.
|
||||
|
||||
Section 5 – Disclaimer of Warranties and Limitation of Liability.
|
||||
|
||||
a. Unless otherwise separately undertaken by the Licensor, to the extent
|
||||
possible, the Licensor offers the Licensed Material as-is and as-available,
|
||||
and makes no representations or warranties of any kind concerning the
|
||||
Licensed Material, whether express, implied, statutory, or other. This
|
||||
includes, without limitation, warranties of title, merchantability, fitness
|
||||
for a particular purpose, non-infringement, absence of latent or other
|
||||
defects, accuracy, or the presence or absence of errors, whether or not
|
||||
known or discoverable. Where disclaimers of warranties are not allowed in
|
||||
full or in part, this disclaimer may not apply to You.
|
||||
b. To the extent possible, in no event will the Licensor be liable to You on
|
||||
any legal theory (including, without limitation, negligence) or otherwise
|
||||
for any direct, special, indirect, incidental, consequential, punitive,
|
||||
exemplary, or other losses, costs, expenses, or damages arising out of
|
||||
this Public License or use of the Licensed Material, even if the Licensor
|
||||
has been advised of the possibility of such losses, costs, expenses, or
|
||||
damages. Where a limitation of liability is not allowed in full or in
|
||||
part, this limitation may not apply to You.
|
||||
c. The disclaimer of warranties and limitation of liability provided above
|
||||
shall be interpreted in a manner that, to the extent possible, most
|
||||
closely approximates an absolute disclaimer and waiver of all liability.
|
||||
|
||||
Section 6 – Term and Termination.
|
||||
|
||||
a. This Public License applies for the term of the Copyright and Similar
|
||||
Rights licensed here. However, if You fail to comply with this Public
|
||||
License, then Your rights under this Public License terminate
|
||||
automatically.
|
||||
b. Where Your right to use the Licensed Material has terminated under
|
||||
Section 6(a), it reinstates:
|
||||
1. automatically as of the date the violation is cured, provided it is
|
||||
cured within 30 days of Your discovery of the violation; or
|
||||
2. upon express reinstatement by the Licensor.
|
||||
For the avoidance of doubt, this Section 6(b) does not affect any right
|
||||
the Licensor may have to seek remedies for Your violations of this Public
|
||||
License.
|
||||
c. For the avoidance of doubt, the Licensor may also offer the Licensed
|
||||
Material under separate terms or conditions or stop distributing the
|
||||
Licensed Material at any time; however, doing so will not terminate this
|
||||
Public License.
|
||||
d. Sections 1, 5, 6, 7, and 8 survive termination of this Public License.
|
||||
|
||||
Section 7 – Other Terms and Conditions.
|
||||
|
||||
a. The Licensor shall not be bound by any additional or different terms or
|
||||
conditions communicated by You unless expressly agreed.
|
||||
b. Any arrangements, understandings, or agreements regarding the Licensed
|
||||
Material not stated herein are separate from and independent of the terms
|
||||
and conditions of this Public License.
|
||||
|
||||
Section 8 – Interpretation.
|
||||
|
||||
a. For the avoidance of doubt, this Public License does not, and shall not
|
||||
be interpreted to, reduce, limit, restrict, or impose conditions on any use
|
||||
of the Licensed Material that could lawfully be made without permission
|
||||
under this Public License.
|
||||
b. To the extent possible, if any provision of this Public License is deemed
|
||||
unenforceable, it shall be automatically reformed to the minimum extent
|
||||
necessary to make it enforceable. If the provision cannot be reformed, it
|
||||
shall be severed from this Public License without affecting the
|
||||
enforceability of the remaining terms and conditions.
|
||||
c. No term or condition of this Public License will be waived and no failure
|
||||
to comply consented to unless expressly agreed to by the Licensor.
|
||||
d. Nothing in this Public License constitutes or may be interpreted as a
|
||||
limitation upon, or waiver of, any privileges and immunities that apply to
|
||||
the Licensor or You, including from the legal processes of any jurisdiction
|
||||
or authority.
|
||||
-10
@@ -1,10 +0,0 @@
|
||||
Permission to use, copy, modify, and/or distribute this software for any purpose
|
||||
with or without fee is hereby granted, provided that the above copyright notice
|
||||
and this permission notice appear in all copies.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH
|
||||
REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
|
||||
FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT,
|
||||
OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA
|
||||
OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
|
||||
ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
-17
@@ -1,17 +0,0 @@
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
+2
-12
@@ -1,9 +1,8 @@
|
||||
The majority of KiCad's source code is developed and distributed under the terms
|
||||
of the GPLv3 or later. However, It does include some third-party code licensed
|
||||
under AGPLv3 or later as well as sections licensed under the BOOST license v1.0,
|
||||
the ISC license and the MIT license.
|
||||
under AGPLv3 or later.
|
||||
|
||||
These licenses are compatible, but a combined works as is will be governed under
|
||||
Both licenses are compatible, but a combined works as is will be governed under
|
||||
the terms of the AGPLv3 (or later). This includes any binary distribution of the
|
||||
KiCad EDA suite by the KiCad project or any third party, e.g. Linux distributor.
|
||||
|
||||
@@ -11,13 +10,4 @@ You are free to use the *sources* under the terms of their respective licenses.
|
||||
|
||||
Licensed under AGPLv3 (or later):
|
||||
- TTL [https://www.sintef.no/projectweb/geometry-toolkits/ttl/], sources in include/ttl/*
|
||||
Licensed under BOOSTv1:
|
||||
- libcontext [https://github.com/boostorg/context], sources in common/system/libcontext.cpp
|
||||
Licensed under ISC:
|
||||
- portions of code in include/geometry/polygon_triangulation.h
|
||||
Licensed under MIT:
|
||||
- tinyspline_lib in dxflib_qcad/tinyspline_lib
|
||||
Licensed under CC-BY-SA-4.0:
|
||||
- All the demo files provided in demos/*
|
||||
Licensed under GPLv3 (or later):
|
||||
- All remaining code not listed above
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user