Compare commits

..

1 Commits

Author SHA1 Message Date
Wayne Stambaugh b23b48b9a7 Tag version 5.0.1-dev. 2018-07-13 16:33:17 -04:00
2953 changed files with 481240 additions and 377843 deletions
-31
View File
@@ -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
-49
View File
@@ -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
View File
@@ -1 +0,0 @@
hook-chain
-91
View File
@@ -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
View File
@@ -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
+123 -62
View File
@@ -2,7 +2,6 @@
* This program source code file is part of KiCad, a free EDA CAD application.
*
* Copyright (C) 2015-2016 Cirilo Bernardo <cirilo.bernardo@gmail.com>
* Copyright (C) 2018 KiCad Developers, see AUTHORS.txt for contributors.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
@@ -35,13 +34,7 @@
#include <wx/log.h>
#include <wx/stdpaths.h>
#include <boost/version.hpp>
#if BOOST_VERSION >= 106800
#include <boost/uuid/detail/sha1.hpp>
#else
#include <boost/uuid/sha1.hpp>
#endif
#include <glm/glm.hpp>
#include <glm/ext.hpp>
@@ -50,7 +43,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"
@@ -59,7 +52,6 @@
static wxCriticalSection lock3D_cache;
static bool isSHA1Same( const unsigned char* shaA, const unsigned char* shaB )
{
for( int i = 0; i < 20; ++i )
@@ -69,7 +61,6 @@ static bool isSHA1Same( const unsigned char* shaA, const unsigned char* shaB )
return true;
}
static bool checkTag( const char* aTag, void* aPluginMgrPtr )
{
if( NULL == aTag || NULL == aPluginMgrPtr )
@@ -80,7 +71,6 @@ static bool checkTag( const char* aTag, void* aPluginMgrPtr )
return pp->CheckTag( aTag );
}
static const wxString sha1ToWXString( const unsigned char* aSHA1Sum )
{
unsigned char uc;
@@ -161,8 +151,14 @@ void S3D_CACHE_ENTRY::SetSHA1( const unsigned char* aSHA1Sum )
{
if( NULL == aSHA1Sum )
{
wxLogTrace( MASK_3D_CACHE, "%s:%s:%d\n * [BUG] NULL passed for aSHA1Sum",
__FILE__, __FUNCTION__, __LINE__ );
#ifdef DEBUG
do {
std::ostringstream ostr;
ostr << __FILE__ << ": " << __FUNCTION__ << ": " << __LINE__ << "\n";
ostr << " * [BUG] NULL passed for aSHA1Sum";
wxLogTrace( MASK_3D_CACHE, "%s\n", ostr.str().c_str() );
} while( 0 );
#endif
return;
}
@@ -184,13 +180,12 @@ 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;
}
S3D_CACHE::~S3D_CACHE()
{
FlushCache();
@@ -215,14 +210,14 @@ SCENEGRAPH* S3D_CACHE::load( const wxString& aModelFile, S3D_CACHE_ENTRY** aCach
if( full3Dpath.empty() )
{
// the model cannot be found; we cannot proceed
wxLogTrace( MASK_3D_CACHE, "%s:%s:%d\n * [3D model] could not find model '%s'\n",
__FILE__, __FUNCTION__, __LINE__, aModelFile );
wxLogTrace( MASK_3D_CACHE, " * [3D model] could not find model '%s'\n",
aModelFile.GetData() );
return NULL;
}
// 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() )
@@ -299,8 +294,15 @@ SCENEGRAPH* S3D_CACHE::checkCache( const wxString& aFileName, S3D_CACHE_ENTRY**
if( m_CacheMap.insert( std::pair< wxString, S3D_CACHE_ENTRY* >
( aFileName, ep ) ).second == false )
{
wxLogTrace( MASK_3D_CACHE, "%s:%s:%d\n * [BUG] duplicate entry in map file; key = '%s'",
__FILE__, __FUNCTION__, __LINE__, aFileName );
#ifdef DEBUG
do {
std::ostringstream ostr;
ostr << __FILE__ << ": " << __FUNCTION__ << ": " << __LINE__ << "\n";
ostr << " * [BUG] duplicate entry in map file; key = '";
ostr << aFileName.ToUTF8() << "'";
wxLogTrace( MASK_3D_CACHE, "%s\n", ostr.str().c_str() );
} while( 0 );
#endif
m_CacheList.pop_back();
delete ep;
@@ -323,8 +325,15 @@ SCENEGRAPH* S3D_CACHE::checkCache( const wxString& aFileName, S3D_CACHE_ENTRY**
if( m_CacheMap.insert( std::pair< wxString, S3D_CACHE_ENTRY* >
( aFileName, ep ) ).second == false )
{
wxLogTrace( MASK_3D_CACHE, "%s:%s:%d\n * [BUG] duplicate entry in map file; key = '%s'",
__FILE__, __FUNCTION__, __LINE__, aFileName );
#ifdef DEBUG
do {
std::ostringstream ostr;
ostr << __FILE__ << ": " << __FUNCTION__ << ": " << __LINE__ << "\n";
ostr << " * [BUG] duplicate entry in map file; key = '";
ostr << aFileName.ToUTF8() << "'";
wxLogTrace( MASK_3D_CACHE, "%s\n", ostr.str().c_str() );
} while( 0 );
#endif
m_CacheList.pop_back();
delete ep;
@@ -355,21 +364,33 @@ bool S3D_CACHE::getSHA1( const wxString& aFileName, unsigned char* aSHA1Sum )
{
if( aFileName.empty() )
{
wxLogTrace( MASK_3D_CACHE, "%s:%s:%d\n * [BUG] empty filename",
__FILE__, __FUNCTION__, __LINE__ );
#ifdef DEBUG
do {
std::ostringstream ostr;
ostr << __FILE__ << ": " << __FUNCTION__ << ": " << __LINE__ << "\n";
ostr << " * [BUG] empty filename";
wxLogTrace( MASK_3D_CACHE, "%s\n", ostr.str().c_str() );
} while( 0 );
#endif
return false;
}
if( NULL == aSHA1Sum )
{
wxLogTrace( MASK_3D_CACHE, "%s\n * [BUG] NULL pointer passed for aMD5Sum",
__FILE__, __FUNCTION__, __LINE__ );
#ifdef DEBUG
do {
std::ostringstream ostr;
ostr << __FILE__ << ": " << __FUNCTION__ << ": " << __LINE__ << "\n";
ostr << " * [BUG] NULL pointer passed for aMD5Sum";
wxLogTrace( MASK_3D_CACHE, "%s\n", ostr.str().c_str() );
} while( 0 );
#endif
return false;
}
#ifdef _WIN32
#ifdef WIN32
FILE* fp = _wfopen( aFileName.wc_str(), L"rb" );
#else
FILE* fp = fopen( aFileName.ToUTF8(), "rb" );
@@ -413,16 +434,17 @@ bool S3D_CACHE::loadCacheData( S3D_CACHE_ENTRY* aCacheItem )
if( bname.empty() )
{
wxLogTrace( MASK_3D_CACHE,
" * [3D model] cannot load cached model; no file hash available" );
#ifdef DEBUG
wxLogTrace( MASK_3D_CACHE, " * [3D model] cannot load cached model; no file hash available\n" );
#endif
return false;
}
if( m_CacheDir.empty() )
{
wxLogTrace( MASK_3D_CACHE,
" * [3D model] cannot load cached model; config directory unknown" );
wxString errmsg = "cannot load cached model; config directory unknown";
wxLogTrace( MASK_3D_CACHE, " * [3D model] %s\n", errmsg.GetData() );
return false;
}
@@ -432,7 +454,8 @@ bool S3D_CACHE::loadCacheData( S3D_CACHE_ENTRY* aCacheItem )
if( !wxFileName::FileExists( fname ) )
{
wxString errmsg = "cannot open file";
wxLogTrace( MASK_3D_CACHE, " * [3D model] %s '%s'", errmsg.GetData(), fname.GetData() );
wxLogTrace( MASK_3D_CACHE, " * [3D model] %s '%s'\n",
errmsg.GetData(), fname.GetData() );
return false;
}
@@ -452,16 +475,28 @@ bool S3D_CACHE::saveCacheData( S3D_CACHE_ENTRY* aCacheItem )
{
if( NULL == aCacheItem )
{
wxLogTrace( MASK_3D_CACHE, "%s:%s:%d\n * NULL passed for aCacheItem",
__FILE__, __FUNCTION__, __LINE__ );
#ifdef DEBUG
do {
std::ostringstream ostr;
ostr << __FILE__ << ": " << __FUNCTION__ << ": " << __LINE__ << "\n";
ostr << " * NULL passed for aCacheItem";
wxLogTrace( MASK_3D_CACHE, "%s\n", ostr.str().c_str() );
} while( 0 );
#endif
return false;
}
if( NULL == aCacheItem->sceneData )
{
wxLogTrace( MASK_3D_CACHE, "%s:%s:%d\n * aCacheItem has no valid scene data",
__FILE__, __FUNCTION__, __LINE__ );
#ifdef DEBUG
do {
std::ostringstream ostr;
ostr << __FILE__ << ": " << __FUNCTION__ << ": " << __LINE__ << "\n";
ostr << " * aCacheItem has no valid scene data";
wxLogTrace( MASK_3D_CACHE, "%s\n", ostr.str().c_str() );
} while( 0 );
#endif
return false;
}
@@ -470,16 +505,17 @@ bool S3D_CACHE::saveCacheData( S3D_CACHE_ENTRY* aCacheItem )
if( bname.empty() )
{
wxLogTrace( MASK_3D_CACHE,
" * [3D model] cannot load cached model; no file hash available" );
#ifdef DEBUG
wxLogTrace( MASK_3D_CACHE, " * [3D model] cannot load cached model; no file hash available\n" );
#endif
return false;
}
if( m_CacheDir.empty() )
{
wxLogTrace( MASK_3D_CACHE,
" * [3D model] cannot load cached model; config directory unknown" );
wxString errmsg = "cannot load cached model; config directory unknown";
wxLogTrace( MASK_3D_CACHE, " * [3D model] %s\n", errmsg.GetData() );
return false;
}
@@ -490,8 +526,9 @@ bool S3D_CACHE::saveCacheData( S3D_CACHE_ENTRY* aCacheItem )
{
if( !wxFileName::FileExists( fname ) )
{
wxLogTrace( MASK_3D_CACHE, " * [3D model] path exists but is not a regular file '%s'",
fname );
wxString errmsg = _( "path exists but is not a regular file" );
wxLogTrace( MASK_3D_CACHE, " * [3D model] %s '%s'\n", errmsg.GetData(),
fname.ToUTF8() );
return false;
}
@@ -522,9 +559,14 @@ bool S3D_CACHE::Set3DConfigDir( const wxString& aConfigDir )
if( !cfgdir.DirExists() )
{
wxLogTrace( MASK_3D_CACHE,
"%s:%s:%d\n * failed to create 3D configuration directory '%s'",
__FILE__, __FUNCTION__, __LINE__, cfgdir.GetPath() );
std::ostringstream ostr;
ostr << __FILE__ << ": " << __FUNCTION__ << ": " << __LINE__ << "\n";
wxString errmsg = _( "failed to create 3D configuration directory" );
ostr << " * " << errmsg.ToUTF8() << "\n";
errmsg = _( "config directory" );
ostr << " * " << errmsg.ToUTF8() << " '";
ostr << cfgdir.GetPath().ToUTF8() << "'";
wxLogTrace( MASK_3D_CACHE, "%s\n", ostr.str().c_str() );
return false;
}
@@ -535,10 +577,15 @@ bool S3D_CACHE::Set3DConfigDir( const wxString& aConfigDir )
// inform the file resolver of the config directory
if( !m_FNResolver->Set3DConfigDir( m_ConfigDir ) )
{
wxLogTrace( MASK_3D_CACHE,
"%s:%s:%d\n * could not set 3D Config Directory on filename resolver\n"
" * config directory: '%s'",
__FILE__, __FUNCTION__, __LINE__, m_ConfigDir );
#ifdef DEBUG
do {
std::ostringstream ostr;
ostr << __FILE__ << ": " << __FUNCTION__ << ": " << __LINE__ << "\n";
ostr << " * could not set 3D Config Directory on filename resolver\n";
ostr << " * config directory: '" << m_ConfigDir.ToUTF8() << "'";
wxLogTrace( MASK_3D_CACHE, "%s\n", ostr.str().c_str() );
} while( 0 );
#endif
}
// 3D cache data must go to a user's cache directory;
@@ -550,20 +597,20 @@ bool S3D_CACHE::Set3DConfigDir( const wxString& aConfigDir )
// 3. MSWin: AppData\Local\kicad\3d
wxString cacheDir;
#if defined(_WIN32)
#if defined(_WIN32)
wxStandardPaths::Get().UseAppInfo( wxStandardPaths::AppInfo_None );
cacheDir = wxStandardPaths::Get().GetUserLocalDataDir();
cacheDir.append( "\\kicad\\3d" );
#elif defined(__APPLE)
#elif defined(__APPLE)
cacheDir = "${HOME}/Library/Caches/kicad/3d";
#else // assume Linux
#else // assume Linux
cacheDir = ExpandEnvVarSubstitutions( "${XDG_CACHE_HOME}" );
if( cacheDir.empty() || cacheDir == "${XDG_CACHE_HOME}" )
cacheDir = "${HOME}/.cache";
cacheDir.append( "/kicad/3d" );
#endif
#endif
cacheDir = ExpandEnvVarSubstitutions( cacheDir );
cfgdir.Assign( cacheDir, "" );
@@ -574,8 +621,14 @@ bool S3D_CACHE::Set3DConfigDir( const wxString& aConfigDir )
if( !cfgdir.DirExists() )
{
wxLogTrace( MASK_3D_CACHE, "%s:%s:%d\n * failed to create 3D cache directory '%s'",
__FILE__, __FUNCTION__, __LINE__, cfgdir.GetPath() );
std::ostringstream ostr;
ostr << __FILE__ << ": " << __FUNCTION__ << ": " << __LINE__ << "\n";
wxString errmsg = "failed to create 3D cache directory";
ostr << " * " << errmsg.ToUTF8() << "\n";
errmsg = "cache directory";
ostr << " * " << errmsg.ToUTF8() << " '";
ostr << cfgdir.GetPath().ToUTF8() << "'";
wxLogTrace( MASK_3D_CACHE, "%s\n", ostr.str().c_str() );
return false;
}
@@ -628,8 +681,11 @@ wxString S3D_CACHE::Get3DConfigDir( bool createDefault )
if( !cfgpath.DirExists() )
{
wxLogTrace( MASK_3D_CACHE, "%s:%s:%d\n * failed to create 3D configuration directory '%s'",
__FILE__, __FUNCTION__, __LINE__, cfgpath.GetPath() );
std::ostringstream ostr;
wxString errmsg = "failed to create 3D configuration directory";
ostr << __FILE__ << ": " << __FUNCTION__ << ": " << __LINE__ << "\n";
ostr << " * " << errmsg.ToUTF8();
wxLogTrace( MASK_3D_CACHE, "%s\n", ostr.str().c_str() );
return wxT( "" );
}
@@ -680,7 +736,7 @@ wxString S3D_CACHE::GetProjectDir( void )
}
FILENAME_RESOLVER* S3D_CACHE::GetResolver( void )
S3D_FILENAME_RESOLVER* S3D_CACHE::GetResolver( void )
{
return m_FNResolver;
}
@@ -732,9 +788,14 @@ S3DMODEL* S3D_CACHE::GetModel( const wxString& aModelFileName )
if( !cp )
{
wxLogTrace( MASK_3D_CACHE,
"%s:%s:%d\n * [BUG] model loaded with no associated S3D_CACHE_ENTRY",
__FILE__, __FUNCTION__, __LINE__ );
#ifdef DEBUG
do {
std::ostringstream ostr;
ostr << __FILE__ << ": " << __FUNCTION__ << ": " << __LINE__ << "\n";
ostr << " * [BUG] model loaded with no associated S3D_CACHE_ENTRY";
wxLogTrace( MASK_3D_CACHE, "%s\n", ostr.str().c_str() );
} while( 0 );
#endif
return NULL;
}
@@ -757,7 +818,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() )
+6 -6
View File
@@ -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
-6
View File
@@ -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 );
-2
View File
@@ -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
+8 -4
View File
@@ -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();
}
@@ -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;
+353 -310
View File
@@ -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
+110 -107
View File
@@ -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__
+462 -165
View File
@@ -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() );
}
+80 -59
View File
@@ -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
+6 -3
View File
@@ -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;
}
+87
View File
@@ -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
+9 -4
View File
@@ -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 );
}
+16 -7
View File
@@ -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;
+202 -124
View File
@@ -40,7 +40,7 @@
#include "../3d_rendering/3d_render_raytracing/accelerators/ccontainer2d.h"
#include "../3d_rendering/3d_render_raytracing/shapes3D/ccylinder.h"
#include "../3d_rendering/3d_render_raytracing/shapes3D/clayeritem.h"
#include <openmp_mutex.h>
#include <class_board.h>
#include <class_module.h>
#include <class_pad.h>
@@ -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 );
}
}
@@ -404,24 +418,27 @@ void CINFO3D_VISU::createNewPadWithClearance( const D_PAD* aPad,
*aPad ) );
// Add the PAD contours
// Round segments cannot have 0-length elements, so we approximate them
// as a small circle
for( int i = 1; i <= 4; i++ )
{
if( Is_segment_a_circle( corners3DU[i - 1], corners3DU[i & 3] ) )
{
aDstContainer->Add( new CFILLEDCIRCLE2D( corners3DU[i - 1],
aClearanceValue.x * m_biuTo3Dunits,
*aPad ) );
}
else
{
aDstContainer->Add( new CROUNDSEGMENT2D( corners3DU[i - 1],
corners3DU[i & 3],
aClearanceValue.x * 2.0f * m_biuTo3Dunits,
*aPad ) );
}
}
// !TODO: check the corners because it cannot add
// roundsegments that are in the same start and end position
aDstContainer->Add( new CROUNDSEGMENT2D( corners3DU[0],
corners3DU[1],
aClearanceValue.x * 2.0f * m_biuTo3Dunits,
*aPad ) );
aDstContainer->Add( new CROUNDSEGMENT2D( corners3DU[1],
corners3DU[2],
aClearanceValue.x * 2.0f * m_biuTo3Dunits,
*aPad ) );
aDstContainer->Add( new CROUNDSEGMENT2D( corners3DU[2],
corners3DU[3],
aClearanceValue.x * 2.0f * m_biuTo3Dunits,
*aPad ) );
aDstContainer->Add( new CROUNDSEGMENT2D( corners3DU[3],
corners3DU[0],
aClearanceValue.x * 2.0f * m_biuTo3Dunits,
*aPad ) );
}
break;
@@ -456,46 +473,30 @@ void CINFO3D_VISU::createNewPadWithClearance( const D_PAD* aPad,
*aPad ) );
// Add the PAD contours
// Round segments cannot have 0-length elements, so we approximate them
// as a small circle
for( int i = 1; i <= 4; i++ )
{
if( Is_segment_a_circle( corners3DU[i - 1], corners3DU[i & 3] ) )
{
aDstContainer->Add( new CFILLEDCIRCLE2D( corners3DU[i - 1],
rounding_radius * m_biuTo3Dunits,
*aPad ) );
}
else
{
aDstContainer->Add( new CROUNDSEGMENT2D( corners3DU[i - 1],
corners3DU[i & 3],
rounding_radius * 2.0f * m_biuTo3Dunits,
*aPad ) );
}
}
// !TODO: check the corners because it cannot add
// roundsegments that are in the same start and end position
aDstContainer->Add( new CROUNDSEGMENT2D( corners3DU[0],
corners3DU[1],
rounding_radius * 2.0f * m_biuTo3Dunits,
*aPad ) );
aDstContainer->Add( new CROUNDSEGMENT2D( corners3DU[1],
corners3DU[2],
rounding_radius * 2.0f * m_biuTo3Dunits,
*aPad ) );
aDstContainer->Add( new CROUNDSEGMENT2D( corners3DU[2],
corners3DU[3],
rounding_radius * 2.0f * m_biuTo3Dunits,
*aPad ) );
aDstContainer->Add( new CROUNDSEGMENT2D( corners3DU[3],
corners3DU[0],
rounding_radius * 2.0f * m_biuTo3Dunits,
*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
@@ -505,6 +506,10 @@ void CINFO3D_VISU::createNewPadWithClearance( const D_PAD* aPad,
if( aClearanceValue.x )
polyList.Inflate( aClearanceValue.x, 32 );
// This convert the poly in outline and holes
polyList.Simplify( SHAPE_POLY_SET::PM_FAST );
polyList.Simplify( SHAPE_POLY_SET::PM_STRICTLY_SIMPLE );
// Add the PAD polygon
Convert_shape_line_polygon_to_triangles( polyList, *aDstContainer, m_biuTo3Dunits, *aPad );
@@ -568,15 +573,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 +674,7 @@ void CINFO3D_VISU::AddPadsShapesWithClearanceToContainer( const MODULE* aModule,
break;
}
createNewPadWithClearance( pad, aDstContainer, margin );
createNewPad( pad, aDstContainer, margin );
}
}
@@ -713,9 +762,8 @@ void CINFO3D_VISU::AddShapeWithClearanceToContainer( const DRAWSEGMENT* aDrawSeg
PCB_LAYER_ID aLayerId,
int aClearanceValue )
{
// The full width of the lines to create
// The extra 1 protects the inner/outer radius values from degeneracy
const int linewidth = aDrawSegment->GetWidth() + (2 * aClearanceValue) + 1;
// The full width of the lines to create:
const int linewidth = aDrawSegment->GetWidth() + (2 * aClearanceValue);
switch( aDrawSegment->GetShape() )
{
@@ -724,13 +772,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,14 +821,19 @@ 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 );
// This convert the poly in outline and holes
// Note: This two sequencial calls are need in order to get
// the triangulation function to work properly.
polyList.Simplify( SHAPE_POLY_SET::PM_FAST );
polyList.Simplify( SHAPE_POLY_SET::PM_STRICTLY_SIMPLE );
if( polyList.IsEmpty() ) // Just for caution
break;
@@ -790,6 +843,9 @@ void CINFO3D_VISU::AddShapeWithClearanceToContainer( const DRAWSEGMENT* aDrawSeg
}
break;
case S_CURVE: // Bezier curve (not yet in use in KiCad)
break;
default:
break;
}
@@ -804,19 +860,26 @@ void CINFO3D_VISU::AddSolidAreasShapesToContainer( const ZONE_CONTAINER* aZoneCo
PCB_LAYER_ID aLayerId )
{
// Copy the polys list because we have to simplify it
SHAPE_POLY_SET polyList = SHAPE_POLY_SET( aZoneContainer->GetFilledPolysList(), true );
SHAPE_POLY_SET polyList = SHAPE_POLY_SET(aZoneContainer->GetFilledPolysList());
// This convert the poly in outline and holes
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() )
// Note: This two sequencial calls are need in order to get
// the triangulation function to work properly.
polyList.Simplify( SHAPE_POLY_SET::PM_FAST );
polyList.Simplify( SHAPE_POLY_SET::PM_STRICTLY_SIMPLE );
if( polyList.IsEmpty() )
return;
float line_thickness = aZoneContainer->GetMinThickness() * m_biuTo3Dunits;
Convert_shape_line_polygon_to_triangles( polyList,
*aDstContainer,
m_biuTo3Dunits,
*aZoneContainer );
// add filled areas outlines, which are drawn with thick lines segments
// /////////////////////////////////////////////////////////////////////////
for( int i = 0; i < polyList.OutlineCount(); ++i )
{
// Add outline
@@ -832,15 +895,16 @@ void CINFO3D_VISU::AddSolidAreasShapesToContainer( const ZONE_CONTAINER* aZoneCo
if( Is_segment_a_circle( start3DU, end3DU ) )
{
float radius = line_thickness/2;
if( radius > 0.0 ) // degenerated circles crash 3D viewer
aDstContainer->Add( new CFILLEDCIRCLE2D( start3DU, radius,
*aZoneContainer ) );
aDstContainer->Add( new CFILLEDCIRCLE2D( start3DU,
(aZoneContainer->GetMinThickness() / 2) *
m_biuTo3Dunits,
*aZoneContainer ) );
}
else
{
aDstContainer->Add( new CROUNDSEGMENT2D( start3DU, end3DU, line_thickness,
aDstContainer->Add( new CROUNDSEGMENT2D( start3DU, end3DU,
aZoneContainer->GetMinThickness() *
m_biuTo3Dunits,
*aZoneContainer ) );
}
}
@@ -860,17 +924,18 @@ void CINFO3D_VISU::AddSolidAreasShapesToContainer( const ZONE_CONTAINER* aZoneCo
if( Is_segment_a_circle( start3DU, end3DU ) )
{
float radius = line_thickness/2;
if( radius > 0.0 ) // degenerated circles crash 3D viewer
aDstContainer->Add(
new CFILLEDCIRCLE2D( start3DU, radius,
*aZoneContainer ) );
aDstContainer->Add(
new CFILLEDCIRCLE2D( start3DU,
(aZoneContainer->GetMinThickness() / 2) *
m_biuTo3Dunits,
*aZoneContainer ) );
}
else
{
aDstContainer->Add(
new CROUNDSEGMENT2D( start3DU, end3DU, line_thickness,
new CROUNDSEGMENT2D( start3DU, end3DU,
aZoneContainer->GetMinThickness() *
m_biuTo3Dunits,
*aZoneContainer ) );
}
}
@@ -890,17 +955,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 +993,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 ) );
}
}
}
+196 -116
View File
@@ -40,7 +40,7 @@
#include "../3d_rendering/3d_render_raytracing/accelerators/ccontainer2d.h"
#include "../3d_rendering/3d_render_raytracing/shapes3D/ccylinder.h"
#include "../3d_rendering/3d_render_raytracing/shapes3D/clayeritem.h"
#include <openmp_mutex.h>
#include <class_board.h>
#include <class_module.h>
#include <class_pad.h>
@@ -52,9 +52,6 @@
#include <trigo.h>
#include <utility>
#include <vector>
#include <thread>
#include <algorithm>
#include <atomic>
#include <profile.h>
@@ -140,6 +137,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 +174,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 +216,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 +390,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 +422,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 +439,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 +494,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 +512,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 +546,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 +560,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 +602,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 +639,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 +687,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 +745,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;
}
}
}
@@ -731,43 +788,36 @@ void CINFO3D_VISU::createLayers( REPORTER *aStatusTextReporter )
// Add zones objects
// /////////////////////////////////////////////////////////////////////
std::atomic<size_t> nextZone( 0 );
std::atomic<size_t> threadsFinished( 0 );
size_t parallelThreadCount = std::max<size_t>( std::thread::hardware_concurrency(), 2 );
for( size_t ii = 0; ii < parallelThreadCount; ++ii )
for( unsigned int lIdx = 0; lIdx < layer_id.size(); ++lIdx )
{
std::thread t = std::thread( [&]()
const PCB_LAYER_ID curr_layer_id = layer_id[lIdx];
if( aStatusTextReporter )
aStatusTextReporter->Report( wxString::Format( _( "Create zones of layer %s" ),
LSET::Name( curr_layer_id ) ) );
wxASSERT( m_layers_container2D.find( curr_layer_id ) != m_layers_container2D.end() );
CBVHCONTAINER2D *layerContainer = m_layers_container2D[curr_layer_id];
// ADD COPPER ZONES
for( int ii = 0; ii < m_board->GetAreaCount(); ++ii )
{
for( size_t areaId = nextZone.fetch_add( 1 );
areaId < static_cast<size_t>( m_board->GetAreaCount() );
areaId = nextZone.fetch_add( 1 ) )
const ZONE_CONTAINER* zone = m_board->GetArea( ii );
const PCB_LAYER_ID zonelayer = zone->GetLayer();
if( zonelayer == curr_layer_id )
{
const ZONE_CONTAINER* zone = m_board->GetArea( areaId );
if( zone == nullptr )
break;
auto layerContainer = m_layers_container2D.find( zone->GetLayer() );
if( layerContainer != m_layers_container2D.end() )
AddSolidAreasShapesToContainer( zone, layerContainer->second,
zone->GetLayer() );
AddSolidAreasShapesToContainer( zone,
layerContainer,
curr_layer_id );
}
threadsFinished++;
} );
t.detach();
}
}
while( threadsFinished < parallelThreadCount )
std::this_thread::sleep_for( std::chrono::milliseconds( 10 ) );
}
#ifdef PRINT_STATISTICS_3D_VIEWER
printf( "fill zones T13: %.3f ms\n", (float)( GetRunningMicroSecs() - start_Time ) / 1e3 );
printf( "T13: %.3f ms\n", (float)( GetRunningMicroSecs() - start_Time ) / 1e3 );
start_Time = GetRunningMicroSecs();
#endif
@@ -775,18 +825,29 @@ void CINFO3D_VISU::createLayers( REPORTER *aStatusTextReporter )
GetFlag( FL_RENDER_OPENGL_COPPER_THICKNESS ) &&
(m_render_engine == RENDER_ENGINE_OPENGL_LEGACY) )
{
// ADD COPPER ZONES
for( int ii = 0; ii < m_board->GetAreaCount(); ++ii )
// Add zones poly contourns
// /////////////////////////////////////////////////////////////////////
for( unsigned int lIdx = 0; lIdx < layer_id.size(); ++lIdx )
{
const ZONE_CONTAINER* zone = m_board->GetArea( ii );
const PCB_LAYER_ID curr_layer_id = layer_id[lIdx];
if( zone == nullptr )
break;
wxASSERT( m_layers_poly.find( curr_layer_id ) != m_layers_poly.end() );
auto layerContainer = m_layers_poly.find( zone->GetLayer() );
SHAPE_POLY_SET *layerPoly = m_layers_poly[curr_layer_id];
if( layerContainer != m_layers_poly.end() )
zone->TransformSolidAreasShapesToPolygonSet( *layerContainer->second );
// ADD COPPER ZONES
for( int ii = 0; ii < m_board->GetAreaCount(); ++ii )
{
const ZONE_CONTAINER* zone = m_board->GetArea( ii );
const LAYER_NUM zonelayer = zone->GetLayer();
if( zonelayer == curr_layer_id )
{
zone->TransformSolidAreasShapesToPolygonSet( *layerPoly,
segcountforcircle,
correctionFactor );
}
}
}
}
@@ -804,35 +865,22 @@ void CINFO3D_VISU::createLayers( REPORTER *aStatusTextReporter )
if( GetFlag( FL_RENDER_OPENGL_COPPER_THICKNESS ) &&
(m_render_engine == RENDER_ENGINE_OPENGL_LEGACY) )
{
std::atomic<size_t> nextItem( 0 );
std::atomic<size_t> threadsFinished( 0 );
const int nLayers = layer_id.size();
size_t parallelThreadCount = std::min<size_t>(
std::max<size_t>( std::thread::hardware_concurrency(), 2 ),
layer_id.size() );
for( size_t ii = 0; ii < parallelThreadCount; ++ii )
#pragma omp parallel for
for( signed int lIdx = 0; lIdx < nLayers; ++lIdx )
{
std::thread t = std::thread( [&nextItem, &threadsFinished, &layer_id, this]()
{
for( size_t i = nextItem.fetch_add( 1 );
i < layer_id.size();
i = nextItem.fetch_add( 1 ) )
{
auto layerPoly = m_layers_poly.find( layer_id[i] );
const PCB_LAYER_ID curr_layer_id = layer_id[lIdx];
if( layerPoly != m_layers_poly.end() )
// This will make a union of all added contours
layerPoly->second->Simplify( SHAPE_POLY_SET::PM_FAST );
}
wxASSERT( m_layers_poly.find( curr_layer_id ) != m_layers_poly.end() );
threadsFinished++;
} );
SHAPE_POLY_SET *layerPoly = m_layers_poly[curr_layer_id];
t.detach();
wxASSERT( layerPoly != NULL );
// This will make a union of all added contourns
layerPoly->Simplify( SHAPE_POLY_SET::PM_FAST );
}
while( threadsFinished < parallelThreadCount )
std::this_thread::sleep_for( std::chrono::milliseconds( 10 ) );
}
#ifdef PRINT_STATISTICS_3D_VIEWER
@@ -913,7 +961,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 +1022,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 +1048,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 +1100,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 +1143,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 );
}
}
+41 -22
View File
@@ -2,7 +2,7 @@
* This program source code file is part of KiCad, a free EDA CAD application.
*
* Copyright (C) 2015-2016 Mario Luzeiro <mrluzeiro@ua.pt>
* Copyright (C) 1992-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;
+92 -111
View File
@@ -2,7 +2,7 @@
* This program source code file is part of KiCad, a free EDA CAD application.
*
* Copyright (C) 2015-2016 Mario Luzeiro <mrluzeiro@ua.pt>
* Copyright (C) 1992-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
@@ -1071,7 +1052,7 @@ bool EDA_3D_CANVAS::SetView3D( int aKeycode )
m_settings.CameraGet().SetInterpolateMode( INTERPOLATION_BEZIER );
m_settings.CameraGet().SetT0_and_T1_current_T();
m_settings.CameraGet().Reset_T1();
m_settings.CameraGet().RotateY_T1( glm::radians( 180.0f ) );
m_settings.CameraGet().RotateX_T1( glm::radians( -180.0f ) );
request_start_moving_camera(
glm::min( glm::max( m_settings.CameraGet().ZoomGet(), 0.5f ), 1.125f ) );
return true;
+3 -8
View File
@@ -2,7 +2,7 @@
* This program source code file is part of KiCad, a free EDA CAD application.
*
* Copyright (C) 2015-2016 Mario Luzeiro <mrluzeiro@ua.pt>
* Copyright (C) 1992-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
View File
@@ -1 +1 @@
#define PLUGINDIR "@CMAKE_INSTALL_FULL_LIBDIR@"
#define PLUGINDIR "@CMAKE_INSTALL_LIBDIR@"
@@ -369,8 +369,7 @@ void C3D_RENDER_OGL_LEGACY::reload( REPORTER *aStatusTextReporter )
// /////////////////////////////////////////////////////////////////////////
CCONTAINER2D boardContainer;
SHAPE_POLY_SET tmpBoard = m_settings.GetBoardPoly();
Convert_shape_line_polygon_to_triangles( tmpBoard,
Convert_shape_line_polygon_to_triangles( m_settings.GetBoardPoly(),
boardContainer,
m_settings.BiuTo3Dunits(),
(const BOARD_ITEM &)*m_settings.GetBoard() );
@@ -501,7 +500,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 +518,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 +530,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 +571,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;
}
}
@@ -601,9 +614,11 @@ void C3D_RENDER_OGL_LEGACY::reload( REPORTER *aStatusTextReporter )
{
const SHAPE_POLY_SET *polyList = map_poly.at( layer_id );
if( polyList->OutlineCount() > 0 )
layerTriangles->AddToMiddleContourns( *polyList, layer_z_bot, layer_z_top,
m_settings.BiuTo3Dunits(), false );
layerTriangles->AddToMiddleContourns( *polyList,
layer_z_bot,
layer_z_top,
m_settings.BiuTo3Dunits(),
false );
}
// Create display list
@@ -745,7 +760,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 +815,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 +838,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 +886,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 +899,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 +931,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 );
}
}
}
@@ -30,9 +30,6 @@
#include "clayer_triangles.h"
#include <wx/debug.h> // For the wxASSERT
#include <mutex>
#include <thread>
#include <atomic>
CLAYER_TRIANGLE_CONTAINER::CLAYER_TRIANGLE_CONTAINER( unsigned int aNrReservedTriangles,
@@ -150,7 +147,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 +161,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 +173,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 );
@@ -220,8 +219,8 @@ void CLAYER_TRIANGLES::AddToMiddleContourns( const std::vector< SFVEC2F > &aCont
const SFVEC2F &v0 = aContournPoints[i + 0];
const SFVEC2F &v1 = aContournPoints[i + 1];
#pragma omp critical
{
std::lock_guard<std::mutex> lock( m_middle_layer_lock );
m_layer_middle_contourns_quads->AddQuad( SFVEC3F( v0.x, v0.y, zTop ),
SFVEC3F( v1.x, v1.y, zTop ),
SFVEC3F( v1.x, v1.y, zBot ),
@@ -280,6 +279,8 @@ void CLAYER_TRIANGLES::AddToMiddleContourns( const SHAPE_POLY_SET &aPolySet,
double aBiuTo3Du,
bool aInvertFaceDirection )
{
wxASSERT( aPolySet.OutlineCount() > 0 );
if( aPolySet.OutlineCount() == 0 )
return;
@@ -304,7 +305,8 @@ 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++ )
#pragma omp parallel for
for( signed int i = 0; i < aPolySet.OutlineCount(); ++i )
{
// Add outline
const SHAPE_LINE_CHAIN& pathOutline = aPolySet.COutline( i );
@@ -35,7 +35,6 @@
#include <geometry/shape_line_chain.h>
#include <geometry/shape_poly_set.h>
#include <vector>
#include <mutex>
typedef std::vector< SFVEC3F > SFVEC3F_VECTOR;
@@ -175,8 +174,6 @@ public:
float zTop,
bool aInvertFaceDirection );
std::mutex m_middle_layer_lock;
CLAYER_TRIANGLE_CONTAINER *m_layer_top_segment_ends;
CLAYER_TRIANGLE_CONTAINER *m_layer_top_triangles;
CLAYER_TRIANGLE_CONTAINER *m_layer_middle_contourns_quads;
@@ -29,7 +29,6 @@
#include "ccontainer2d.h"
#include <vector>
#include <mutex>
#include <boost/range/algorithm/partition.hpp>
#include <boost/range/algorithm/nth_element.hpp>
#include <wx/debug.h>
@@ -47,7 +46,6 @@ CGENERICCONTAINER2D::CGENERICCONTAINER2D( OBJECT2D_TYPE aObjType )
void CGENERICCONTAINER2D::Clear()
{
std::lock_guard<std::mutex> lock( m_lock );
m_bbox.Reset();
for( LIST_OBJECT2D::iterator ii = m_objects.begin();
@@ -32,7 +32,6 @@
#include "../shapes2D/cobject2d.h"
#include <list>
#include <mutex>
typedef std::list<COBJECT2D *> LIST_OBJECT2D;
typedef std::list<const COBJECT2D *> CONST_LIST_OBJECT2D;
@@ -53,7 +52,6 @@ public:
{
if( aObject ) // Only add if it is a valid pointer
{
std::lock_guard<std::mutex> lock( m_lock );
m_objects.push_back( aObject );
m_bbox.Union( aObject->GetBBox() );
}
@@ -72,7 +70,6 @@ public:
CONST_LIST_OBJECT2D &aOutList ) const = 0;
private:
std::mutex m_lock;
};
@@ -918,6 +918,7 @@ void C3D_RENDER_RAYTRACING::reload( REPORTER *aStatusTextReporter )
}
m_accelerator = 0;
//m_accelerator = new CGRID( m_object_container );
m_accelerator = new CBVH_PBRT( m_object_container );
#ifdef PRINT_STATISTICS_3D_VIEWER
@@ -1076,7 +1077,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 +1091,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 +1172,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 +1184,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 +1200,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() ) )
File diff suppressed because it is too large Load Diff
@@ -131,7 +131,7 @@ private:
unsigned long int m_stats_start_rendering_time;
/// Save the number of blocks progress of the render
size_t m_nrBlocksRenderProgress;
long m_nrBlocksRenderProgress;
CPOSTSHADER_SSAO m_postshader_ssao;
@@ -165,7 +165,7 @@ private:
std::vector< SFVEC2UI > m_blockPositions;
/// this flags if a position was already processed (cleared each new render)
std::vector< int > m_blockPositionsWasProcessed;
std::vector< bool > m_blockPositionsWasProcessed;
/// this encodes the Morton code positions (on fast preview mode)
std::vector< SFVEC2UI > m_blockPositionsFast;
@@ -50,9 +50,9 @@ void RAY::Init( const SFVEC3F& o, const SFVEC3F& d )
// Amy Williams Steve Barrus R. Keith Morley Peter Shirley
// University of Utah
// http://people.csail.mit.edu/amy/papers/box-jgt.pdf
m_dirIsNeg[0] = m_Dir.x < 0.0f;
m_dirIsNeg[1] = m_Dir.y < 0.0f;
m_dirIsNeg[2] = m_Dir.z < 0.0f;
m_dirIsNeg[0] = m_Dir.x <= 0.0f;
m_dirIsNeg[1] = m_Dir.y <= 0.0f;
m_dirIsNeg[2] = m_Dir.z <= 0.0f;
// ray slope
@@ -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
@@ -35,9 +35,9 @@
#include <wx/glcanvas.h> // CALLBACK definition, needed on Windows
// alse needed on OSX to define __DARWIN__
#include <geometry/polygon_triangulation.h>
#include "../../../3d_fastmath.h"
#include "../../../3d_fastmath.h"
#include <poly2tri/poly2tri.h>
CTRIANGLE2D::CTRIANGLE2D ( const SFVEC2F &aV1,
@@ -126,28 +126,172 @@ bool CTRIANGLE2D::IsPointInside( const SFVEC2F &aPoint ) const
const float c = 1.0f - a - b;
return 0.0f <= c && c <= 1.0f;
/*
return 0.0f <= a && a <= 1.0f &&
0.0f <= b && b <= 1.0f &&
0.0f <= c && c <= 1.0f;*/
}
void Convert_shape_line_polygon_to_triangles( SHAPE_POLY_SET &aPolyList,
template <class C> void FreeClear( C & cntr )
{
for( typename C::iterator it = cntr.begin();
it != cntr.end();
++it )
{
delete * it;
}
cntr.clear();
}
// Note: Please check edgeshrink.cpp in order to learn the EdgeShrink propose
#define APPLY_EDGE_SHRINK
#ifdef APPLY_EDGE_SHRINK
extern void EdgeShrink( std::vector<SFVEC2I64> &aPath );
#define POLY_SCALE_FACT 256
#define POLY_SCALE_FACT_INVERSE (1.0 / (double)(POLY_SCALE_FACT))
#endif
void Convert_shape_line_polygon_to_triangles( const SHAPE_POLY_SET &aPolyList,
CGENERICCONTAINER2D &aDstContainer,
float aBiuTo3DunitsScale ,
const BOARD_ITEM &aBoardItem )
{
unsigned int nOutlines = aPolyList.OutlineCount();
aPolyList.CacheTriangulation();
const double conver_d = (double)aBiuTo3DunitsScale;
for( unsigned int j = 0; j < aPolyList.TriangulatedPolyCount(); j++ )
for( unsigned int idx = 0; idx < nOutlines; ++idx )
{
auto triPoly = aPolyList.TriangulatedPolygon( j );
const SHAPE_LINE_CHAIN &outlinePath = aPolyList.COutline( idx );
for( size_t i = 0; i < triPoly->GetTriangleCount(); i++ )
wxASSERT( outlinePath.PointCount() >= 3 );
std::vector<SFVEC2I64> scaledOutline;
scaledOutline.resize( outlinePath.PointCount() );
// printf("\nidx: %u\n", idx);
// Apply a scale to the points
for( unsigned int i = 0;
i < (unsigned int)outlinePath.PointCount();
++i )
{
VECTOR2I a;
VECTOR2I b;
VECTOR2I c;
triPoly->GetTriangle( i, a, b, c );
const VECTOR2I& a = outlinePath.CPoint( i );
#ifdef APPLY_EDGE_SHRINK
scaledOutline[i] = SFVEC2I64( (glm::int64)a.x * POLY_SCALE_FACT,
(glm::int64)a.y * POLY_SCALE_FACT );
#else
scaledOutline[i] = SFVEC2I64( (glm::int64)a.x,
(glm::int64)a.y );
#endif
}
#ifdef APPLY_EDGE_SHRINK
// Apply a modification to the points
EdgeShrink( scaledOutline );
#endif
// Copy to a array of pointers
std::vector<p2t::Point*> polyline;
polyline.resize( outlinePath.PointCount() );
for( unsigned int i = 0;
i < (unsigned int)scaledOutline.size();
++i )
{
const SFVEC2I64 &a = scaledOutline[i];
//printf("%lu %lu\n", a.x, a.y);
polyline[i] = new p2t::Point( (double)a.x,
(double)a.y );
}
// Start creating the structured to be triangulated
p2t::CDT* cdt = new p2t::CDT( polyline );
// Add holes for this outline
unsigned int nHoles = aPolyList.HoleCount( idx );
std::vector< std::vector<p2t::Point*> > polylineHoles;
polylineHoles.resize( nHoles );
for( unsigned int idxHole = 0; idxHole < nHoles; ++idxHole )
{
const SHAPE_LINE_CHAIN &outlineHoles = aPolyList.CHole( idx,
idxHole );
wxASSERT( outlineHoles.PointCount() >= 3 );
std::vector<SFVEC2I64> scaledHole;
scaledHole.resize( outlineHoles.PointCount() );
// Apply a scale to the points
for( unsigned int i = 0;
i < (unsigned int)outlineHoles.PointCount();
++i )
{
const VECTOR2I &h = outlineHoles.CPoint( i );
#ifdef APPLY_EDGE_SHRINK
scaledHole[i] = SFVEC2I64( (glm::int64)h.x * POLY_SCALE_FACT,
(glm::int64)h.y * POLY_SCALE_FACT );
#else
scaledHole[i] = SFVEC2I64( (glm::int64)h.x,
(glm::int64)h.y );
#endif
}
#ifdef APPLY_EDGE_SHRINK
// Apply a modification to the points
EdgeShrink( scaledHole );
#endif
// Resize and reserve space
polylineHoles[idxHole].resize( outlineHoles.PointCount() );
for( unsigned int i = 0;
i < (unsigned int)outlineHoles.PointCount();
++i )
{
const SFVEC2I64 &h = scaledHole[i];
polylineHoles[idxHole][i] = new p2t::Point( h.x, h.y );
}
cdt->AddHole( polylineHoles[idxHole] );
}
// Triangulate
cdt->Triangulate();
// Hint: if you find any crashes on the triangulation poly2tri library,
// you can use the following site to debug the points and it will mark
// the errors in the polygon:
// http://r3mi.github.io/poly2tri.js/
// Get and add triangles
std::vector<p2t::Triangle*> triangles;
triangles = cdt->GetTriangles();
#ifdef APPLY_EDGE_SHRINK
const double conver_d = (double)aBiuTo3DunitsScale *
POLY_SCALE_FACT_INVERSE;
#else
const double conver_d = (double)aBiuTo3DunitsScale;
#endif
for( unsigned int i = 0; i < triangles.size(); ++i )
{
p2t::Triangle& t = *triangles[i];
p2t::Point& a = *t.GetPoint( 0 );
p2t::Point& b = *t.GetPoint( 1 );
p2t::Point& c = *t.GetPoint( 2 );
aDstContainer.Add( new CTRIANGLE2D( SFVEC2F( a.x * conver_d,
-a.y * conver_d ),
@@ -158,5 +302,15 @@ void Convert_shape_line_polygon_to_triangles( SHAPE_POLY_SET &aPolyList,
aBoardItem ) );
}
// Delete created data
delete cdt;
// Free points
FreeClear(polyline);
for( unsigned int idxHole = 0; idxHole < nHoles; ++idxHole )
{
FreeClear( polylineHoles[idxHole] );
}
}
}
@@ -68,7 +68,7 @@ public:
};
void Convert_shape_line_polygon_to_triangles( SHAPE_POLY_SET &aPolyList,
void Convert_shape_line_polygon_to_triangles( const SHAPE_POLY_SET &aPolyList,
CGENERICCONTAINER2D &aDstContainer,
float aBiuTo3DunitsScale,
const BOARD_ITEM &aBoardItem );
@@ -0,0 +1,89 @@
/*
* This program source code file is part of KiCad, a free EDA CAD application.
*
* Copyright (C) 2016 Mario Luzeiro <mrluzeiro@ua.pt>
* 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
* 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 edgeshrink.cpp
* @brief The edgeShrink function was found in the project clip2tri by the:
* Bitfighter project (http://bitfighter.org)
* https://github.com/raptor/clip2tri
* https://github.com/raptor/clip2tri/blob/f62a734d22733814b8a970ed8a68a4d94c24fa5f/clip2tri/clip2tri.cpp#L150
*/
#include <plugins/3dapi/xv3d_types.h>
#include <vector>
// clip2tri is Licenced under:
// The MIT License (MIT)
// Copyright (c) 2014 Bitfighter developers
// 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.
// Shrink large polygons by reducing each coordinate by 1 in the
// general direction of the last point as we wind around
//
// This normally wouldn't work in every case, but our upscaled-by-1000 polygons
// have little chance to create new duplicate points with this method.
//
// For information on why this was needed, see:
//
// https://github.com/greenm01/poly2tri/issues/90
//
#define S_INC 1
void EdgeShrink( std::vector<SFVEC2I64> &aPath )
{
unsigned int prev = aPath.size() - 1;
for( unsigned int i = 0; i < aPath.size(); i++ )
{
// Adjust coordinate by 1 depending on the direction
(aPath[i].x - aPath[prev].x) > 0 ? aPath[i].x -= S_INC :
aPath[i].x += S_INC;
(aPath[i].y - aPath[prev].y) > 0 ? aPath[i].y -= S_INC :
aPath[i].y += S_INC;
prev = i;
}
}
@@ -271,7 +271,7 @@ SFVEC3F CBBOX::Offset( const SFVEC3F &p ) const
// https://github.com/mmp/pbrt-v2/blob/master/src/core/geometry.cpp#L68
// /////////////////////////////////////////////////////////////////////////
#if 0
bool CBBOX::Intersect( const RAY &aRay, float *aOutHitt0, float *aOutHitt1 ) const
bool CBBOX::Intersect( const RAY &aRay, float *aOutHitt0, float *aOutHitt1 )
{
float t0 = 0.0f;
float t1 = FLT_MAX;
@@ -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;
}
-19
View File
@@ -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
+2 -2
View File
@@ -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;
}
}
+18 -39
View File
@@ -31,10 +31,6 @@
#include "buffers_debug.h"
#include <string.h> // For memcpy
#include <atomic>
#include <thread>
#include <chrono>
#ifndef CLAMP
#define CLAMP(n, min, max) {if( n < min ) n=min; else if( n > max ) n = max;}
#endif
@@ -473,51 +469,34 @@ void CIMAGE::EfxFilter( CIMAGE *aInImg, E_FILTER aFilterType )
aInImg->m_wraping = WRAP_CLAMP;
m_wraping = WRAP_CLAMP;
std::atomic<size_t> nextRow( 0 );
std::atomic<size_t> threadsFinished( 0 );
size_t parallelThreadCount = std::max<size_t>( std::thread::hardware_concurrency(), 2 );
for( size_t ii = 0; ii < parallelThreadCount; ++ii )
#pragma omp parallel for
for( int iy = 0; iy < (int)m_height; iy++)
{
std::thread t = std::thread( [&]()
for( int ix = 0; ix < (int)m_width; ix++ )
{
for( size_t iy = nextRow.fetch_add( 1 );
iy < m_height;
iy = nextRow.fetch_add( 1 ) )
int v = 0;
for( int sy = 0; sy < 5; sy++ )
{
for( size_t ix = 0; ix < m_width; ix++ )
for( int sx = 0; sx < 5; sx++ )
{
int v = 0;
int factor = filter.kernel[sx][sy];
unsigned char pixelv = aInImg->Getpixel( ix + sx - 2,
iy + sy - 2 );
for( size_t sy = 0; sy < 5; sy++ )
{
for( size_t sx = 0; sx < 5; sx++ )
{
int factor = filter.kernel[sx][sy];
unsigned char pixelv = aInImg->Getpixel( ix + sx - 2,
iy + sy - 2 );
v += pixelv * factor;
}
}
v /= filter.div;
v += filter.offset;
CLAMP(v, 0, 255);
//TODO: This needs to write to a separate buffer
m_pixels[ix + iy * m_width] = v;
v += pixelv * factor;
}
}
threadsFinished++;
} );
v /= filter.div;
t.detach();
v += filter.offset;
CLAMP(v, 0, 255);
m_pixels[ix + iy * m_width] = v;
}
}
while( threadsFinished < parallelThreadCount )
std::this_thread::sleep_for( std::chrono::milliseconds( 10 ) );
}
+18 -23
View File
@@ -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_
-129
View File
@@ -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" );
-70
View File
@@ -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
View File
@@ -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 ) );
}
+44 -54
View File
@@ -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 );
}
}
@@ -1,8 +1,8 @@
///////////////////////////////////////////////////////////////////////////
// C++ code generated with wxFormBuilder (version Jul 11 2018)
// C++ code generated with wxFormBuilder (version Jul 2 2017)
// http://www.wxformbuilder.org/
//
// PLEASE DO *NOT* EDIT THIS FILE!
// PLEASE DO "NOT" EDIT THIS FILE!
///////////////////////////////////////////////////////////////////////////
#include "dialog_3D_view_option_base.h"
@@ -134,7 +134,7 @@ DIALOG_3D_VIEW_OPTIONS_BASE::DIALOG_3D_VIEW_OPTIONS_BASE( wxWindow* parent, wxWi
bSizeLeft->Add( fgSizer3DVisibility, 0, wxEXPAND, 5 );
bSizerUpper->Add( bSizeLeft, 1, wxEXPAND, 5 );
bSizerUpper->Add( bSizeLeft, 1, wxALIGN_CENTER_VERTICAL|wxEXPAND, 5 );
m_staticlineVertical = new wxStaticLine( this, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxLI_VERTICAL );
bSizerUpper->Add( m_staticlineVertical, 0, wxEXPAND | wxALL, 5 );
@@ -1,6 +1,6 @@
<?xml version="1.0" encoding="UTF-8" standalone="yes" ?>
<wxFormBuilder_Project>
<FileVersion major="1" minor="14" />
<FileVersion major="1" minor="13" />
<object class="Project" expanded="1">
<property name="class_decoration"></property>
<property name="code_generation">C++</property>
@@ -14,7 +14,6 @@
<property name="file">dialog_3D_view_option_base</property>
<property name="first_id">1000</property>
<property name="help_provider">none</property>
<property name="indent_with_spaces"></property>
<property name="internationalize">1</property>
<property name="name">dialog_3D_view_option_base</property>
<property name="namespace"></property>
@@ -55,20 +54,13 @@
<property name="window_style"></property>
<event name="OnActivate"></event>
<event name="OnActivateApp"></event>
<event name="OnAuiPaneActivated"></event>
<event name="OnAuiFindManager"></event>
<event name="OnAuiPaneButton"></event>
<event name="OnAuiPaneClose"></event>
<event name="OnAuiPaneMaximize"></event>
<event name="OnAuiPaneRestore"></event>
<event name="OnAuiRender"></event>
<event name="OnAux1DClick"></event>
<event name="OnAux1Down"></event>
<event name="OnAux1Up"></event>
<event name="OnAux2DClick"></event>
<event name="OnAux2Down"></event>
<event name="OnAux2Up"></event>
<event name="OnChar"></event>
<event name="OnCharHook"></event>
<event name="OnClose"></event>
<event name="OnEnterWindow"></event>
<event name="OnEraseBackground"></event>
@@ -83,23 +75,17 @@
<event name="OnLeftDClick"></event>
<event name="OnLeftDown"></event>
<event name="OnLeftUp"></event>
<event name="OnMaximize"></event>
<event name="OnMiddleDClick"></event>
<event name="OnMiddleDown"></event>
<event name="OnMiddleUp"></event>
<event name="OnMotion"></event>
<event name="OnMouseEvents"></event>
<event name="OnMouseWheel"></event>
<event name="OnMove"></event>
<event name="OnMoveEnd"></event>
<event name="OnMoveStart"></event>
<event name="OnMoving"></event>
<event name="OnPaint"></event>
<event name="OnRightDClick"></event>
<event name="OnRightDown"></event>
<event name="OnRightUp"></event>
<event name="OnSetFocus"></event>
<event name="OnShow"></event>
<event name="OnSize"></event>
<event name="OnUpdateUI"></event>
<object class="wxBoxSizer" expanded="1">
@@ -118,7 +104,7 @@
<property name="permission">none</property>
<object class="sizeritem" expanded="1">
<property name="border">5</property>
<property name="flag">wxEXPAND</property>
<property name="flag">wxALIGN_CENTER_VERTICAL|wxEXPAND</property>
<property name="proportion">1</property>
<object class="wxBoxSizer" expanded="1">
<property name="minimum_size"></property>
@@ -158,7 +144,6 @@
<property name="hidden">0</property>
<property name="id">wxID_ANY</property>
<property name="label">Render options:</property>
<property name="markup">0</property>
<property name="max_size"></property>
<property name="maximize_button">0</property>
<property name="maximum_size"></property>
@@ -184,14 +169,7 @@
<property name="window_name"></property>
<property name="window_style"></property>
<property name="wrap">-1</property>
<event name="OnAux1DClick"></event>
<event name="OnAux1Down"></event>
<event name="OnAux1Up"></event>
<event name="OnAux2DClick"></event>
<event name="OnAux2Down"></event>
<event name="OnAux2Up"></event>
<event name="OnChar"></event>
<event name="OnCharHook"></event>
<event name="OnEnterWindow"></event>
<event name="OnEraseBackground"></event>
<event name="OnKeyDown"></event>
@@ -298,14 +276,7 @@
<property name="window_extra_style"></property>
<property name="window_name"></property>
<property name="window_style"></property>
<event name="OnAux1DClick"></event>
<event name="OnAux1Down"></event>
<event name="OnAux1Up"></event>
<event name="OnAux2DClick"></event>
<event name="OnAux2Down"></event>
<event name="OnAux2Up"></event>
<event name="OnChar"></event>
<event name="OnCharHook"></event>
<event name="OnEnterWindow"></event>
<event name="OnEraseBackground"></event>
<event name="OnKeyDown"></event>
@@ -392,14 +363,7 @@
<property name="window_extra_style"></property>
<property name="window_name"></property>
<property name="window_style"></property>
<event name="OnAux1DClick"></event>
<event name="OnAux1Down"></event>
<event name="OnAux1Up"></event>
<event name="OnAux2DClick"></event>
<event name="OnAux2Down"></event>
<event name="OnAux2Up"></event>
<event name="OnChar"></event>
<event name="OnCharHook"></event>
<event name="OnCheckBox">OnCheckRealisticMode</event>
<event name="OnEnterWindow"></event>
<event name="OnEraseBackground"></event>
@@ -491,14 +455,7 @@
<property name="window_extra_style"></property>
<property name="window_name"></property>
<property name="window_style"></property>
<event name="OnAux1DClick"></event>
<event name="OnAux1Down"></event>
<event name="OnAux1Up"></event>
<event name="OnAux2DClick"></event>
<event name="OnAux2Down"></event>
<event name="OnAux2Up"></event>
<event name="OnChar"></event>
<event name="OnCharHook"></event>
<event name="OnEnterWindow"></event>
<event name="OnEraseBackground"></event>
<event name="OnKeyDown"></event>
@@ -585,14 +542,7 @@
<property name="window_extra_style"></property>
<property name="window_name"></property>
<property name="window_style"></property>
<event name="OnAux1DClick"></event>
<event name="OnAux1Down"></event>
<event name="OnAux1Up"></event>
<event name="OnAux2DClick"></event>
<event name="OnAux2Down"></event>
<event name="OnAux2Up"></event>
<event name="OnChar"></event>
<event name="OnCharHook"></event>
<event name="OnCheckBox"></event>
<event name="OnEnterWindow"></event>
<event name="OnEraseBackground"></event>
@@ -684,14 +634,7 @@
<property name="window_extra_style"></property>
<property name="window_name"></property>
<property name="window_style"></property>
<event name="OnAux1DClick"></event>
<event name="OnAux1Down"></event>
<event name="OnAux1Up"></event>
<event name="OnAux2DClick"></event>
<event name="OnAux2Down"></event>
<event name="OnAux2Up"></event>
<event name="OnChar"></event>
<event name="OnCharHook"></event>
<event name="OnEnterWindow"></event>
<event name="OnEraseBackground"></event>
<event name="OnKeyDown"></event>
@@ -778,14 +721,7 @@
<property name="window_extra_style"></property>
<property name="window_name"></property>
<property name="window_style"></property>
<event name="OnAux1DClick"></event>
<event name="OnAux1Down"></event>
<event name="OnAux1Up"></event>
<event name="OnAux2DClick"></event>
<event name="OnAux2Down"></event>
<event name="OnAux2Up"></event>
<event name="OnChar"></event>
<event name="OnCharHook"></event>
<event name="OnCheckBox"></event>
<event name="OnEnterWindow"></event>
<event name="OnEraseBackground"></event>
@@ -877,14 +813,7 @@
<property name="window_extra_style"></property>
<property name="window_name"></property>
<property name="window_style"></property>
<event name="OnAux1DClick"></event>
<event name="OnAux1Down"></event>
<event name="OnAux1Up"></event>
<event name="OnAux2DClick"></event>
<event name="OnAux2Down"></event>
<event name="OnAux2Up"></event>
<event name="OnChar"></event>
<event name="OnCharHook"></event>
<event name="OnEnterWindow"></event>
<event name="OnEraseBackground"></event>
<event name="OnKeyDown"></event>
@@ -971,14 +900,7 @@
<property name="window_extra_style"></property>
<property name="window_name"></property>
<property name="window_style"></property>
<event name="OnAux1DClick"></event>
<event name="OnAux1Down"></event>
<event name="OnAux1Up"></event>
<event name="OnAux2DClick"></event>
<event name="OnAux2Down"></event>
<event name="OnAux2Up"></event>
<event name="OnChar"></event>
<event name="OnCharHook"></event>
<event name="OnCheckBox"></event>
<event name="OnEnterWindow"></event>
<event name="OnEraseBackground"></event>
@@ -1070,14 +992,7 @@
<property name="window_extra_style"></property>
<property name="window_name"></property>
<property name="window_style"></property>
<event name="OnAux1DClick"></event>
<event name="OnAux1Down"></event>
<event name="OnAux1Up"></event>
<event name="OnAux2DClick"></event>
<event name="OnAux2Down"></event>
<event name="OnAux2Up"></event>
<event name="OnChar"></event>
<event name="OnCharHook"></event>
<event name="OnEnterWindow"></event>
<event name="OnEraseBackground"></event>
<event name="OnKeyDown"></event>
@@ -1164,14 +1079,7 @@
<property name="window_extra_style"></property>
<property name="window_name"></property>
<property name="window_style"></property>
<event name="OnAux1DClick"></event>
<event name="OnAux1Down"></event>
<event name="OnAux1Up"></event>
<event name="OnAux2DClick"></event>
<event name="OnAux2Down"></event>
<event name="OnAux2Up"></event>
<event name="OnChar"></event>
<event name="OnCharHook"></event>
<event name="OnCheckBox"></event>
<event name="OnEnterWindow"></event>
<event name="OnEraseBackground"></event>
@@ -1260,7 +1168,6 @@
<property name="hidden">0</property>
<property name="id">wxID_ANY</property>
<property name="label">3D model visibility:</property>
<property name="markup">0</property>
<property name="max_size"></property>
<property name="maximize_button">0</property>
<property name="maximum_size"></property>
@@ -1286,14 +1193,7 @@
<property name="window_name"></property>
<property name="window_style"></property>
<property name="wrap">-1</property>
<event name="OnAux1DClick"></event>
<event name="OnAux1Down"></event>
<event name="OnAux1Up"></event>
<event name="OnAux2DClick"></event>
<event name="OnAux2Down"></event>
<event name="OnAux2Up"></event>
<event name="OnChar"></event>
<event name="OnCharHook"></event>
<event name="OnEnterWindow"></event>
<event name="OnEraseBackground"></event>
<event name="OnKeyDown"></event>
@@ -1400,14 +1300,7 @@
<property name="window_extra_style"></property>
<property name="window_name"></property>
<property name="window_style"></property>
<event name="OnAux1DClick"></event>
<event name="OnAux1Down"></event>
<event name="OnAux1Up"></event>
<event name="OnAux2DClick"></event>
<event name="OnAux2Down"></event>
<event name="OnAux2Up"></event>
<event name="OnChar"></event>
<event name="OnCharHook"></event>
<event name="OnEnterWindow"></event>
<event name="OnEraseBackground"></event>
<event name="OnKeyDown"></event>
@@ -1494,14 +1387,7 @@
<property name="window_extra_style"></property>
<property name="window_name"></property>
<property name="window_style"></property>
<event name="OnAux1DClick"></event>
<event name="OnAux1Down"></event>
<event name="OnAux1Up"></event>
<event name="OnAux2DClick"></event>
<event name="OnAux2Down"></event>
<event name="OnAux2Up"></event>
<event name="OnChar"></event>
<event name="OnCharHook"></event>
<event name="OnCheckBox"></event>
<event name="OnEnterWindow"></event>
<event name="OnEraseBackground"></event>
@@ -1593,14 +1479,7 @@
<property name="window_extra_style"></property>
<property name="window_name"></property>
<property name="window_style"></property>
<event name="OnAux1DClick"></event>
<event name="OnAux1Down"></event>
<event name="OnAux1Up"></event>
<event name="OnAux2DClick"></event>
<event name="OnAux2Down"></event>
<event name="OnAux2Up"></event>
<event name="OnChar"></event>
<event name="OnCharHook"></event>
<event name="OnEnterWindow"></event>
<event name="OnEraseBackground"></event>
<event name="OnKeyDown"></event>
@@ -1687,14 +1566,7 @@
<property name="window_extra_style"></property>
<property name="window_name"></property>
<property name="window_style"></property>
<event name="OnAux1DClick"></event>
<event name="OnAux1Down"></event>
<event name="OnAux1Up"></event>
<event name="OnAux2DClick"></event>
<event name="OnAux2Down"></event>
<event name="OnAux2Up"></event>
<event name="OnChar"></event>
<event name="OnCharHook"></event>
<event name="OnCheckBox"></event>
<event name="OnEnterWindow"></event>
<event name="OnEraseBackground"></event>
@@ -1786,14 +1658,7 @@
<property name="window_extra_style"></property>
<property name="window_name"></property>
<property name="window_style"></property>
<event name="OnAux1DClick"></event>
<event name="OnAux1Down"></event>
<event name="OnAux1Up"></event>
<event name="OnAux2DClick"></event>
<event name="OnAux2Down"></event>
<event name="OnAux2Up"></event>
<event name="OnChar"></event>
<event name="OnCharHook"></event>
<event name="OnEnterWindow"></event>
<event name="OnEraseBackground"></event>
<event name="OnKeyDown"></event>
@@ -1880,14 +1745,7 @@
<property name="window_extra_style"></property>
<property name="window_name"></property>
<property name="window_style"></property>
<event name="OnAux1DClick"></event>
<event name="OnAux1Down"></event>
<event name="OnAux1Up"></event>
<event name="OnAux2DClick"></event>
<event name="OnAux2Down"></event>
<event name="OnAux2Up"></event>
<event name="OnChar"></event>
<event name="OnCharHook"></event>
<event name="OnCheckBox"></event>
<event name="OnEnterWindow"></event>
<event name="OnEraseBackground"></event>
@@ -1973,14 +1831,7 @@
<property name="window_extra_style"></property>
<property name="window_name"></property>
<property name="window_style"></property>
<event name="OnAux1DClick"></event>
<event name="OnAux1Down"></event>
<event name="OnAux1Up"></event>
<event name="OnAux2DClick"></event>
<event name="OnAux2Down"></event>
<event name="OnAux2Up"></event>
<event name="OnChar"></event>
<event name="OnCharHook"></event>
<event name="OnEnterWindow"></event>
<event name="OnEraseBackground"></event>
<event name="OnKeyDown"></event>
@@ -2056,7 +1907,6 @@
<property name="hidden">0</property>
<property name="id">wxID_ANY</property>
<property name="label">Board layers:</property>
<property name="markup">0</property>
<property name="max_size"></property>
<property name="maximize_button">0</property>
<property name="maximum_size"></property>
@@ -2082,14 +1932,7 @@
<property name="window_name"></property>
<property name="window_style"></property>
<property name="wrap">-1</property>
<event name="OnAux1DClick"></event>
<event name="OnAux1Down"></event>
<event name="OnAux1Up"></event>
<event name="OnAux2DClick"></event>
<event name="OnAux2Down"></event>
<event name="OnAux2Up"></event>
<event name="OnChar"></event>
<event name="OnCharHook"></event>
<event name="OnEnterWindow"></event>
<event name="OnEraseBackground"></event>
<event name="OnKeyDown"></event>
@@ -2196,14 +2039,7 @@
<property name="window_extra_style"></property>
<property name="window_name"></property>
<property name="window_style"></property>
<event name="OnAux1DClick"></event>
<event name="OnAux1Down"></event>
<event name="OnAux1Up"></event>
<event name="OnAux2DClick"></event>
<event name="OnAux2Down"></event>
<event name="OnAux2Up"></event>
<event name="OnChar"></event>
<event name="OnCharHook"></event>
<event name="OnEnterWindow"></event>
<event name="OnEraseBackground"></event>
<event name="OnKeyDown"></event>
@@ -2290,14 +2126,7 @@
<property name="window_extra_style"></property>
<property name="window_name"></property>
<property name="window_style"></property>
<event name="OnAux1DClick"></event>
<event name="OnAux1Down"></event>
<event name="OnAux1Up"></event>
<event name="OnAux2DClick"></event>
<event name="OnAux2Down"></event>
<event name="OnAux2Up"></event>
<event name="OnChar"></event>
<event name="OnCharHook"></event>
<event name="OnCheckBox"></event>
<event name="OnEnterWindow"></event>
<event name="OnEraseBackground"></event>
@@ -2389,14 +2218,7 @@
<property name="window_extra_style"></property>
<property name="window_name"></property>
<property name="window_style"></property>
<event name="OnAux1DClick"></event>
<event name="OnAux1Down"></event>
<event name="OnAux1Up"></event>
<event name="OnAux2DClick"></event>
<event name="OnAux2Down"></event>
<event name="OnAux2Up"></event>
<event name="OnChar"></event>
<event name="OnCharHook"></event>
<event name="OnEnterWindow"></event>
<event name="OnEraseBackground"></event>
<event name="OnKeyDown"></event>
@@ -2483,14 +2305,7 @@
<property name="window_extra_style"></property>
<property name="window_name"></property>
<property name="window_style"></property>
<event name="OnAux1DClick"></event>
<event name="OnAux1Down"></event>
<event name="OnAux1Up"></event>
<event name="OnAux2DClick"></event>
<event name="OnAux2Down"></event>
<event name="OnAux2Up"></event>
<event name="OnChar"></event>
<event name="OnCharHook"></event>
<event name="OnCheckBox"></event>
<event name="OnEnterWindow"></event>
<event name="OnEraseBackground"></event>
@@ -2582,14 +2397,7 @@
<property name="window_extra_style"></property>
<property name="window_name"></property>
<property name="window_style"></property>
<event name="OnAux1DClick"></event>
<event name="OnAux1Down"></event>
<event name="OnAux1Up"></event>
<event name="OnAux2DClick"></event>
<event name="OnAux2Down"></event>
<event name="OnAux2Up"></event>
<event name="OnChar"></event>
<event name="OnCharHook"></event>
<event name="OnEnterWindow"></event>
<event name="OnEraseBackground"></event>
<event name="OnKeyDown"></event>
@@ -2676,14 +2484,7 @@
<property name="window_extra_style"></property>
<property name="window_name"></property>
<property name="window_style"></property>
<event name="OnAux1DClick"></event>
<event name="OnAux1Down"></event>
<event name="OnAux1Up"></event>
<event name="OnAux2DClick"></event>
<event name="OnAux2Down"></event>
<event name="OnAux2Up"></event>
<event name="OnChar"></event>
<event name="OnCharHook"></event>
<event name="OnCheckBox"></event>
<event name="OnEnterWindow"></event>
<event name="OnEraseBackground"></event>
@@ -2775,14 +2576,7 @@
<property name="window_extra_style"></property>
<property name="window_name"></property>
<property name="window_style"></property>
<event name="OnAux1DClick"></event>
<event name="OnAux1Down"></event>
<event name="OnAux1Up"></event>
<event name="OnAux2DClick"></event>
<event name="OnAux2Down"></event>
<event name="OnAux2Up"></event>
<event name="OnChar"></event>
<event name="OnCharHook"></event>
<event name="OnEnterWindow"></event>
<event name="OnEraseBackground"></event>
<event name="OnKeyDown"></event>
@@ -2869,14 +2663,7 @@
<property name="window_extra_style"></property>
<property name="window_name"></property>
<property name="window_style"></property>
<event name="OnAux1DClick"></event>
<event name="OnAux1Down"></event>
<event name="OnAux1Up"></event>
<event name="OnAux2DClick"></event>
<event name="OnAux2Down"></event>
<event name="OnAux2Up"></event>
<event name="OnChar"></event>
<event name="OnCharHook"></event>
<event name="OnCheckBox"></event>
<event name="OnEnterWindow"></event>
<event name="OnEraseBackground"></event>
@@ -2947,7 +2734,6 @@
<property name="hidden">0</property>
<property name="id">wxID_ANY</property>
<property name="label">User layers (not shown in realistic mode):</property>
<property name="markup">0</property>
<property name="max_size"></property>
<property name="maximize_button">0</property>
<property name="maximum_size"></property>
@@ -2973,14 +2759,7 @@
<property name="window_name"></property>
<property name="window_style"></property>
<property name="wrap">-1</property>
<event name="OnAux1DClick"></event>
<event name="OnAux1Down"></event>
<event name="OnAux1Up"></event>
<event name="OnAux2DClick"></event>
<event name="OnAux2Down"></event>
<event name="OnAux2Up"></event>
<event name="OnChar"></event>
<event name="OnCharHook"></event>
<event name="OnEnterWindow"></event>
<event name="OnEraseBackground"></event>
<event name="OnKeyDown"></event>
@@ -3087,14 +2866,7 @@
<property name="window_extra_style"></property>
<property name="window_name"></property>
<property name="window_style"></property>
<event name="OnAux1DClick"></event>
<event name="OnAux1Down"></event>
<event name="OnAux1Up"></event>
<event name="OnAux2DClick"></event>
<event name="OnAux2Down"></event>
<event name="OnAux2Up"></event>
<event name="OnChar"></event>
<event name="OnCharHook"></event>
<event name="OnEnterWindow"></event>
<event name="OnEraseBackground"></event>
<event name="OnKeyDown"></event>
@@ -3181,14 +2953,7 @@
<property name="window_extra_style"></property>
<property name="window_name"></property>
<property name="window_style"></property>
<event name="OnAux1DClick"></event>
<event name="OnAux1Down"></event>
<event name="OnAux1Up"></event>
<event name="OnAux2DClick"></event>
<event name="OnAux2Down"></event>
<event name="OnAux2Up"></event>
<event name="OnChar"></event>
<event name="OnCharHook"></event>
<event name="OnCheckBox"></event>
<event name="OnEnterWindow"></event>
<event name="OnEraseBackground"></event>
@@ -3280,14 +3045,7 @@
<property name="window_extra_style"></property>
<property name="window_name"></property>
<property name="window_style"></property>
<event name="OnAux1DClick"></event>
<event name="OnAux1Down"></event>
<event name="OnAux1Up"></event>
<event name="OnAux2DClick"></event>
<event name="OnAux2Down"></event>
<event name="OnAux2Up"></event>
<event name="OnChar"></event>
<event name="OnCharHook"></event>
<event name="OnEnterWindow"></event>
<event name="OnEraseBackground"></event>
<event name="OnKeyDown"></event>
@@ -3374,14 +3132,7 @@
<property name="window_extra_style"></property>
<property name="window_name"></property>
<property name="window_style"></property>
<event name="OnAux1DClick"></event>
<event name="OnAux1Down"></event>
<event name="OnAux1Up"></event>
<event name="OnAux2DClick"></event>
<event name="OnAux2Down"></event>
<event name="OnAux2Up"></event>
<event name="OnChar"></event>
<event name="OnCharHook"></event>
<event name="OnCheckBox"></event>
<event name="OnEnterWindow"></event>
<event name="OnEraseBackground"></event>
@@ -3471,14 +3222,7 @@
<property name="window_extra_style"></property>
<property name="window_name"></property>
<property name="window_style"></property>
<event name="OnAux1DClick"></event>
<event name="OnAux1Down"></event>
<event name="OnAux1Up"></event>
<event name="OnAux2DClick"></event>
<event name="OnAux2Down"></event>
<event name="OnAux2Up"></event>
<event name="OnChar"></event>
<event name="OnCharHook"></event>
<event name="OnEnterWindow"></event>
<event name="OnEraseBackground"></event>
<event name="OnKeyDown"></event>
@@ -1,8 +1,8 @@
///////////////////////////////////////////////////////////////////////////
// C++ code generated with wxFormBuilder (version Jul 11 2018)
// C++ code generated with wxFormBuilder (version Jul 2 2017)
// http://www.wxformbuilder.org/
//
// PLEASE DO *NOT* EDIT THIS FILE!
// PLEASE DO "NOT" EDIT THIS FILE!
///////////////////////////////////////////////////////////////////////////
#ifndef __DIALOG_3D_VIEW_OPTION_BASE_H__
@@ -11,6 +11,8 @@
#include <wx/artprov.h>
#include <wx/xrc/xmlres.h>
#include <wx/intl.h>
class DIALOG_SHIM;
#include "dialog_shim.h"
#include <wx/string.h>
#include <wx/stattext.h>
File diff suppressed because it is too large Load Diff
+57 -36
View File
@@ -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.
+99
View File
@@ -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
View File
@@ -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,
+11 -2
View File
@@ -7,6 +7,7 @@ include_directories(BEFORE ${INC_BEFORE})
include_directories(
${CMAKE_CURRENT_BINARY_DIR}
../pcbnew
../polygon
3d_canvas
3d_cache
3d_rendering
@@ -32,10 +33,18 @@ 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
../polygon/poly2tri/common/shapes.cc
../polygon/poly2tri/sweep/advancing_front.cc
../polygon/poly2tri/sweep/cdt.cc
../polygon/poly2tri/sweep/sweep.cc
../polygon/poly2tri/sweep/sweep_context.cc
3d_canvas/cinfo3d_visu.cpp
3d_canvas/create_layer_items.cpp
3d_canvas/create_3Dgraphic_brd_items.cpp
@@ -70,6 +79,7 @@ set(3D-VIEWER_SRCS
${DIR_RAY_2D}/cring2d.cpp
${DIR_RAY_2D}/croundsegment2d.cpp
${DIR_RAY_2D}/ctriangle2d.cpp
${DIR_RAY_2D}/edgeshrink.cpp
${DIR_RAY_3D}/cbbox.cpp
${DIR_RAY_3D}/cbbox_ray.cpp
${DIR_RAY_3D}/ccylinder.cpp
@@ -87,8 +97,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 +116,6 @@ add_dependencies( 3d-viewer pcbcommon )
target_link_libraries( 3d-viewer
gal
polygon
${Boost_}
${wxWidgets_LIBRARIES}
${OPENGL_LIBRARIES}
+1 -1
View File
@@ -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 )
+81
View File
@@ -0,0 +1,81 @@
/*
* This program source code file is part of KiCad, a free EDA CAD application.
*
* Copyright (C) 2016 Mario Luzeiro <mrluzeiro@ua.pt>
* 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
* 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 openmp_mutex.h
* @brief a mutex for openmp got from the website:
* http://bisqwit.iki.fi/story/howto/openmp/
* by Joel Yliluoma <bisqwit@iki.fi>
*/
#ifndef _OPENMP_MUTEX_H
#define _OPENMP_MUTEX_H
#ifdef _OPENMP
# include <omp.h>
struct MutexType
{
MutexType() { omp_init_lock( &lock ); }
~MutexType() { omp_destroy_lock( &lock ); }
void Lock() { omp_set_lock( &lock ); }
void Unlock() { omp_unset_lock( &lock ); }
MutexType( const MutexType& ) { omp_init_lock( &lock ); }
MutexType& operator= ( const MutexType& ) { return *this; }
public:
omp_lock_t lock;
};
#else
/// A dummy mutex that doesn't actually exclude anything,
/// but as there is no parallelism either, no worries.
struct MutexType
{
void Lock() {}
void Unlock() {}
};
#endif
/// An exception-safe scoped lock-keeper.
struct ScopedLock
{
explicit ScopedLock( MutexType& m ) : mut( m ), locked( true ) { mut.Lock(); }
~ScopedLock() { Unlock(); }
void Unlock() { if( !locked ) return; locked = false; mut.Unlock(); }
void LockAgain() { if( locked ) return; mut.Lock(); locked = true; }
private:
MutexType& mut;
bool locked;
private: // prevent copying the scoped lock.
void operator=(const ScopedLock&);
ScopedLock(const ScopedLock&);
};
#endif // _OPENMP_MUTEX_H
+2 -4
View File
@@ -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
+216 -287
View File
@@ -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
@@ -30,6 +30,8 @@ if(POLICY CMP0025)
cmake_policy(SET CMP0025 NEW) # CMake 3.0
endif()
project( kicad )
# Default to CMAKE_BUILD_TYPE = Release unless overridden on command line
# http://www.cmake.org/pipermail/cmake/2008-September/023808.html
if( DEFINED CMAKE_BUILD_TYPE )
@@ -38,20 +40,11 @@ else()
set( CMAKE_BUILD_TYPE Release CACHE STRING "Set to either \"Release\" or \"Debug\"" )
endif()
project( kicad )
include( GNUInstallDirs )
# Path to local CMake modules.
set( CMAKE_MODULE_PATH ${PROJECT_SOURCE_DIR}/CMakeModules )
# On Windows, binaries created by link option -g3 are very large (more than 1Gb for pcbnew,
# and more than 3Gb for the full kicad suite)
# This option create binaries using link option -g1 that create much smaller files, but
# there are less info in debug (but the file names and line numbers are available)
option( BUILD_SMALL_DEBUG_FILES "In debug build: create smaller binaries." OFF )
#
# KiCad build options should be added below.
#
@@ -60,29 +53,27 @@ 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 )
"Build a tools menu with registred python plugins: actions plugins (default OFF)."
)
option( KICAD_USE_OCE
"Build tools and plugins related to OpenCascade Community Edition (default ON)"
@@ -93,82 +84,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 +145,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 +163,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 +178,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 +197,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 +204,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 +215,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 +238,7 @@ endif(USE_CCACHE)
#================================================
# Provide access to DISTCC
# Provide access to CCACHE
#================================================
if (USE_DISTCC)
find_program(DISTCC_FOUND distcc)
@@ -320,9 +259,14 @@ 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 )
endif()
# Establish -Wall early, so specialized relaxations of this may come
@@ -330,37 +274,19 @@ if( CMAKE_COMPILER_IS_GNUCXX OR CMAKE_CXX_COMPILER_ID MATCHES "Clang" )
set( CMAKE_C_FLAGS "-Wall ${CMAKE_C_FLAGS}" )
set( CMAKE_CXX_FLAGS "-Wall ${CMAKE_CXX_FLAGS}" )
# Link flags in Debug: -g1 and -ggdb1 or -g1 and -ggdb3 can be used.
# Level 1 produces minimal information, enough for making basic backtraces.
# This includes descriptions of functions and external variables, and line number tables,
# but no information about local variables.
# Level 3 includes full information, but binaries are much larger.
if( BUILD_SMALL_DEBUG_FILES )
set( CMAKE_C_FLAGS_DEBUG "-g1 -ggdb1 -DDEBUG" )
set( CMAKE_CXX_FLAGS_DEBUG "-g1 -ggdb1 -DDEBUG -Wno-deprecated-declarations" )
else()
set( CMAKE_C_FLAGS_DEBUG "-g3 -ggdb3 -DDEBUG" )
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()
set( CMAKE_C_FLAGS_DEBUG "-g3 -ggdb3 -DDEBUG" )
set( CMAKE_CXX_FLAGS_DEBUG "-g3 -ggdb3 -DDEBUG -Wno-deprecated-declarations" )
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 +312,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 +353,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 +379,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,10 +526,60 @@ include( ExternalProject )
#================================================
include( CheckFindPackageResult )
#
# Find OpenMP support, optional
#
find_package( OpenMP )
if( OPENMP_FOUND )
set( CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${OpenMP_C_FLAGS}" )
set( CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${OpenMP_CXX_FLAGS}" )
add_definitions( -DUSE_OPENMP )
# MinGW does not include the OpenMP link library and FindOpenMP.cmake does not
# set it either. Not sure this is the most elegant solution but it works.
if( MINGW )
set( OPENMP_LIBRARIES gomp )
endif()
endif()
#
# 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
#
set( OpenGL_GL_PREFERENCE "LEGACY" ) # CMake 3.11+ setting; see 'cmake --help-policy CMP0072'
set( OpenGL_GL_PREFERENCE "GLVND" ) # CMake 3.11+ setting; see 'cmake --help-policy CMP0072'
find_package( OpenGL REQUIRED )
#
@@ -636,6 +594,7 @@ endif()
# Find GLM library, required
#
find_package( GLM 0.9.5.1 REQUIRED )
add_definitions( -DGLM_FORCE_CTOR_INIT )
#
@@ -648,7 +607,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 +617,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 +669,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 +717,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 +827,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()
@@ -981,7 +912,6 @@ if( UNIX AND NOT APPLE )
endif()
#include( CTest )
enable_testing()
if( UNIX AND NOT APPLE )
@@ -1006,13 +936,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 )
+342
View File
@@ -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)
+1 -1
View File
@@ -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]+.*)?$")
+1 -1
View File
@@ -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]+.*)?$")
+6 -32
View File
@@ -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
)
@@ -31,15 +12,6 @@ find_library( NGSPICE_LIBRARY ngspice
PATH_SUFFIXES src/.libs lib
)
if( WIN32 AND MSYS )
# NGSPICE_LIBRARY points to libngspice.dll.a on Windows,
# but the goal is to find out the DLL name.
find_library( NGSPICE_DLL NAMES libngspice-0.dll libngspice-1.dll )
else()
set( NGSPICE_DLL "${NGSPICE_LIBRARY}" )
endif()
include( FindPackageHandleStandardArgs )
if( ${NGSPICE_INCLUDE_DIR} STREQUAL "NGSPICE_INCLUDE_DIR-NOTFOUND" OR ${NGSPICE_LIBRARY} STREQUAL "NGSPICE_LIBRARY-NOTFOUND" )
@@ -48,7 +20,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" )
@@ -56,10 +28,12 @@ if( ${NGSPICE_INCLUDE_DIR} STREQUAL "NGSPICE_INCLUDE_DIR-NOTFOUND" OR ${NGSPICE_
endif()
find_package_handle_standard_args( ngspice
REQUIRED_VARS NGSPICE_INCLUDE_DIR NGSPICE_LIBRARY NGSPICE_DLL )
REQUIRED_VARS
NGSPICE_INCLUDE_DIR
NGSPICE_LIBRARY
)
mark_as_advanced(
NGSPICE_INCLUDE_DIR
NGSPICE_LIBRARY
NGSPICE_DLL
)
-101
View File
@@ -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()
+17 -15
View File
@@ -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()
-100
View File
@@ -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()
+9 -9
View File
@@ -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.1-dev-unknown" )
+1 -1
View File
@@ -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[] = {"
)
+2 -2
View File
@@ -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
-3
View File
@@ -72,7 +72,4 @@
#define KIFACE_SUFFIX "@KIFACE_SUFFIX@"
#define KIFACE_PREFIX "@KIFACE_PREFIX@"
/// Allows scripts install directory to be referenced by the program code.
#define PYTHON_DEST "@PYTHON_DEST@"
#endif // CONFIG_H_
+1 -1
View File
@@ -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.
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
+33 -84
View File
@@ -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/
+5 -39
View File
@@ -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
+461
View File
@@ -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
+84 -525
View File
@@ -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.
+311 -13
View File
@@ -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:**

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