3D viewer code cleaning round 4.

This commit is contained in:
Wayne Stambaugh 2020-12-16 13:19:28 -05:00
parent 08730cf952
commit 978935d749
40 changed files with 1654 additions and 3572 deletions

View File

@ -69,8 +69,10 @@ static std::mutex mutex3D_cacheManager;
static bool isSHA1Same( const unsigned char* shaA, const unsigned char* shaB ) noexcept static bool isSHA1Same( const unsigned char* shaA, const unsigned char* shaB ) noexcept
{ {
for( int i = 0; i < 20; ++i ) for( int i = 0; i < 20; ++i )
{
if( shaA[i] != shaB[i] ) if( shaA[i] != shaB[i] )
return false; return false;
}
return true; return true;
} }
@ -123,13 +125,6 @@ static const wxString sha1ToWXString( const unsigned char* aSHA1Sum )
class S3D_CACHE_ENTRY class S3D_CACHE_ENTRY
{ {
private:
// prohibit assignment and default copy constructor
S3D_CACHE_ENTRY( const S3D_CACHE_ENTRY& source );
S3D_CACHE_ENTRY& operator=( const S3D_CACHE_ENTRY& source );
wxString m_CacheBaseName; // base name of cache file (a SHA1 digest)
public: public:
S3D_CACHE_ENTRY(); S3D_CACHE_ENTRY();
~S3D_CACHE_ENTRY(); ~S3D_CACHE_ENTRY();
@ -142,6 +137,13 @@ public:
std::string pluginInfo; // PluginName:Version string std::string pluginInfo; // PluginName:Version string
SCENEGRAPH* sceneData; SCENEGRAPH* sceneData;
S3DMODEL* renderData; S3DMODEL* renderData;
private:
// prohibit assignment and default copy constructor
S3D_CACHE_ENTRY( const S3D_CACHE_ENTRY& source );
S3D_CACHE_ENTRY& operator=( const S3D_CACHE_ENTRY& source );
wxString m_CacheBaseName; // base name of cache file (a SHA1 digest)
}; };
@ -266,7 +268,8 @@ SCENEGRAPH* S3D_CACHE::load( const wxString& aModelFile, S3D_CACHE_ENTRY** aCach
if( NULL != mi->second->renderData ) if( NULL != mi->second->renderData )
S3D::Destroy3DModel( &mi->second->renderData ); S3D::Destroy3DModel( &mi->second->renderData );
mi->second->sceneData = m_Plugins->Load3DModel( full3Dpath, mi->second->pluginInfo ); mi->second->sceneData = m_Plugins->Load3DModel( full3Dpath,
mi->second->pluginInfo );
} }
} }
@ -317,7 +320,6 @@ SCENEGRAPH* S3D_CACHE::checkCache( const wxString& aFileName, S3D_CACHE_ENTRY**
{ {
if( aCachePtr ) if( aCachePtr )
*aCachePtr = ep; *aCachePtr = ep;
} }
return NULL; return NULL;
@ -377,11 +379,11 @@ bool S3D_CACHE::getSHA1( const wxString& aFileName, unsigned char* aSHA1Sum )
return false; return false;
} }
#ifdef _WIN32 #ifdef _WIN32
FILE* fp = _wfopen( aFileName.wc_str(), L"rb" ); FILE* fp = _wfopen( aFileName.wc_str(), L"rb" );
#else #else
FILE* fp = fopen( aFileName.ToUTF8(), "rb" ); FILE* fp = fopen( aFileName.ToUTF8(), "rb" );
#endif #endif
if( NULL == fp ) if( NULL == fp )
return false; return false;
@ -506,7 +508,7 @@ bool S3D_CACHE::saveCacheData( S3D_CACHE_ENTRY* aCacheItem )
} }
return S3D::WriteCache( fname.ToUTF8(), true, (SGNODE*)aCacheItem->sceneData, return S3D::WriteCache( fname.ToUTF8(), true, (SGNODE*)aCacheItem->sceneData,
aCacheItem->pluginInfo.c_str() ); aCacheItem->pluginInfo.c_str() );
} }
@ -553,11 +555,11 @@ bool S3D_CACHE::Set3DConfigDir( const wxString& aConfigDir )
// 3. MSWin: AppData\Local\kicad\3d // 3. MSWin: AppData\Local\kicad\3d
wxString cacheDir; wxString cacheDir;
#if defined(_WIN32) #if defined( _WIN32 )
wxStandardPaths::Get().UseAppInfo( wxStandardPaths::AppInfo_None ); wxStandardPaths::Get().UseAppInfo( wxStandardPaths::AppInfo_None );
cacheDir = wxStandardPaths::Get().GetUserLocalDataDir(); cacheDir = wxStandardPaths::Get().GetUserLocalDataDir();
cacheDir.append( "\\kicad\\3d" ); cacheDir.append( "\\kicad\\3d" );
#elif defined(__APPLE) #elif defined( __APPLE )
cacheDir = "${HOME}/Library/Caches/kicad/3d"; cacheDir = "${HOME}/Library/Caches/kicad/3d";
#else // assume Linux #else // assume Linux
cacheDir = ExpandEnvVarSubstitutions( "${XDG_CACHE_HOME}", nullptr ); cacheDir = ExpandEnvVarSubstitutions( "${XDG_CACHE_HOME}", nullptr );
@ -728,6 +730,7 @@ void S3D_CACHE::CleanCacheDir( int aNumDaysOld )
} }
} }
S3D_CACHE* PROJECT::Get3DCacheManager( bool aUpdateProjDir ) S3D_CACHE* PROJECT::Get3DCacheManager( bool aUpdateProjDir )
{ {
std::lock_guard<std::mutex> lock( mutex3D_cacheManager ); std::lock_guard<std::mutex> lock( mutex3D_cacheManager );

View File

@ -2,6 +2,7 @@
* This program source code file is part of KiCad, a free EDA CAD application. * This program source code file is part of KiCad, a free EDA CAD application.
* *
* Copyright (C) 2015 Cirilo Bernardo <cirilo.bernardo@gmail.com> * Copyright (C) 2015 Cirilo Bernardo <cirilo.bernardo@gmail.com>
* Copyright (C) 2020 KiCad Developers, see AUTHORS.txt for contributors.
* *
* This program is free software; you can redistribute it and/or * This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License * modify it under the terms of the GNU General Public License
@ -23,7 +24,6 @@
/** /**
* @file 3d_cache.h * @file 3d_cache.h
* defines the display data cache manager for 3D models
*/ */
#ifndef CACHE_3D_H #ifndef CACHE_3D_H
@ -46,14 +46,126 @@ class S3D_PLUGIN_MANAGER;
/** /**
* S3D_CACHE
*
* Cache for storing the 3D shapes. This cache is able to be stored as a project * Cache for storing the 3D shapes. This cache is able to be stored as a project
* element (since it inherits from PROJECT::_ELEM). * element (since it inherits from PROJECT::_ELEM).
*/ */
class S3D_CACHE : public PROJECT::_ELEM class S3D_CACHE : public PROJECT::_ELEM
{ {
public:
S3D_CACHE();
virtual ~S3D_CACHE();
KICAD_T Type() noexcept override
{
return S3D_CACHE_T;
}
/**
* Sets the configuration directory to be used by the model manager for storing 3D
* model manager configuration data and the model cache.
*
* The config directory may only be set once in the lifetime of the object.
*
* @param aConfigDir is the configuration directory to use for 3D model manager data
* @return true on success
*/
bool Set3DConfigDir( const wxString& aConfigDir );
/**
* Set the current project's working directory; this affects the model search path.
*/
bool SetProject( PROJECT* aProject );
/**
* Set the filename resolver's pointer to the application's PGM_BASE instance.
*
* The pointer is used to extract the local environment variables.
*/
void SetProgramBase( PGM_BASE* aBase );
/**
* Attempt to load the scene data for a model.
*
* It will consult the internal cache list and load from cache if possible before invoking
* the load() function of the available plugins. The model may fail to load if, for example,
* the plugin does not support rendering of the 3D model.
*
* @param aModelFile is the partial or full path to the model to be loaded.
* @return true if the model was successfully loaded, otherwise false.
*/
SCENEGRAPH* Load( const wxString& aModelFile );
FILENAME_RESOLVER* GetResolver() noexcept;
/**
* Return the list of file filters retrieved from the plugins.
*
* This will contain at least the default "All Files (*.*)|*.*"
*
* @return a pointer to the filter list.
*/
std::list< wxString > const* GetFileFilters() const;
/**
* Free all data in the cache and by default closes all plugins.
*/
void FlushCache( bool closePlugins = true );
/**
* Unload plugins to free memory.
*/
void ClosePlugins();
/**
* Attempt to load the scene data for a model and to translate it into an S3D_MODEL
* structure for display by a renderer.
*
* @param aModelFileName is the full path to the model to be loaded.
* @return is a pointer to the render data or NULL if not available.
*/
S3DMODEL* GetModel( const wxString& aModelFileName );
/**
* Delete up old cache files in cache directory.
*
* Deletes ".3dc" files in the cache directory that are older than \a aNumDaysOld.
*
* @param aNumDaysOld is age threshold to delete ".3dc" cache files.
*/
void CleanCacheDir( int aNumDaysOld );
private: private:
/**
* Find or create cache entry for file name
*
* Searches the cache list for the given filename and retrieves the cache data; a cache
* entry is created if one does not already exist.
*
* @param aFileName is the file name (full or partial path).
* @param aCachePtr is an optional return address for cache entry pointer.
* @return SCENEGRAPH object associated with file name or NULL on error.
*/
SCENEGRAPH* checkCache( const wxString& aFileName, S3D_CACHE_ENTRY** aCachePtr = NULL );
/**
* Calculate the SHA1 hash of the given file.
*
* @param aFileName file name (full path).
* @param aSHA1Sum a 20 byte character array to hold the SHA1 hash.
* @return true on success, otherwise false.
*/
bool getSHA1( const wxString& aFileName, unsigned char* aSHA1Sum );
// load scene data from a cache file
bool loadCacheData( S3D_CACHE_ENTRY* aCacheItem );
// save scene data to a cache file
bool saveCacheData( S3D_CACHE_ENTRY* aCacheItem );
// the real load function (can supply a cache entry pointer to member functions)
SCENEGRAPH* load( const wxString& aModelFile, S3D_CACHE_ENTRY** aCachePtr = NULL );
/// cache entries /// cache entries
std::list< S3D_CACHE_ENTRY* > m_CacheList; std::list< S3D_CACHE_ENTRY* > m_CacheList;
@ -67,132 +179,6 @@ private:
PROJECT* m_project; PROJECT* m_project;
wxString m_CacheDir; wxString m_CacheDir;
wxString m_ConfigDir; /// base configuration path for 3D items wxString m_ConfigDir; /// base configuration path for 3D items
/** Find or create cache entry for file name
*
* Searches the cache list for the given filename and retrieves
* the cache data; a cache entry is created if one does not
* already exist.
*
* @param[in] aFileName file name (full or partial path)
* @param[out] aCachePtr optional return address for cache entry pointer
* @return SCENEGRAPH object associated with file name
* @retval NULL on error
*/
SCENEGRAPH* checkCache( const wxString& aFileName, S3D_CACHE_ENTRY** aCachePtr = NULL );
/**
* Function getSHA1
* calculates the SHA1 hash of the given file
*
* @param[in] aFileName file name (full path)
* @param[out] aSHA1Sum a 20 byte character array to hold the SHA1 hash
* @retval true success
* @retval false failure
*/
bool getSHA1( const wxString& aFileName, unsigned char* aSHA1Sum );
// load scene data from a cache file
bool loadCacheData( S3D_CACHE_ENTRY* aCacheItem );
// save scene data to a cache file
bool saveCacheData( S3D_CACHE_ENTRY* aCacheItem );
// the real load function (can supply a cache entry pointer to member functions)
SCENEGRAPH* load( const wxString& aModelFile, S3D_CACHE_ENTRY** aCachePtr = NULL );
public:
S3D_CACHE();
virtual ~S3D_CACHE();
KICAD_T Type() noexcept override
{
return S3D_CACHE_T;
}
/**
* Function Set3DConfigDir
* Sets the configuration directory to be used by the
* model manager for storing 3D model manager configuration
* data and the model cache. The config directory may only be
* set once in the lifetime of the object.
*
* @param aConfigDir is the configuration directory to use
* for 3D model manager data
* @return true on success
*/
bool Set3DConfigDir( const wxString& aConfigDir );
/**
* Function SetProjectDir
* sets the current project's working directory; this
* affects the model search path
*/
bool SetProject( PROJECT* aProject );
/**
* Function SetProgramBase
* sets the filename resolver's pointer to the application's
* PGM_BASE instance; the pointer is used to extract the
* local env vars.
*/
void SetProgramBase( PGM_BASE* aBase );
/**
* Function Load
* attempts to load the scene data for a model; it will consult the
* internal cache list and load from cache if possible before invoking
* the load() function of the available plugins.
*
* @param aModelFile [in] is the partial or full path to the model to be loaded
* @return true if the model was successfully loaded, otherwise false.
* The model may fail to load if, for example, the plugin does not
* support rendering of the 3D model.
*/
SCENEGRAPH* Load( const wxString& aModelFile );
FILENAME_RESOLVER* GetResolver() noexcept;
/**
* Function GetFileFilters
* returns the list of file filters retrieved from the plugins;
* this will contain at least the default "All Files (*.*)|*.*"
*
* @return a pointer to the filter list
*/
std::list< wxString > const* GetFileFilters() const;
/**
* Function FlushCache
* frees all data in the cache and by default closes all plugins
*/
void FlushCache( bool closePlugins = true );
/**
* Function ClosePlugins
* unloads plugins to free memory
*/
void ClosePlugins();
/**
* Function GetModel
* attempts to load the scene data for a model and to translate it
* into an S3D_MODEL structure for display by a renderer
*
* @param aModelFileName is the full path to the model to be loaded
* @return is a pointer to the render data or NULL if not available
*/
S3DMODEL* GetModel( const wxString& aModelFileName );
/**
* Function Delete up old cache files in cache directory
*
* Deletes ".3dc" files in the cache directory that are older than
* "aNumDaysOld".
*
* @param aNumDaysOld is age threshold to delete ".3dc" cache files
*/
void CleanCacheDir( int aNumDaysOld );
}; };
#endif // CACHE_3D_H #endif // CACHE_3D_H

View File

@ -2,6 +2,7 @@
* This program source code file is part of KiCad, a free EDA CAD application. * 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) 2015-2016 Cirilo Bernardo <cirilo.bernardo@gmail.com>
* Copyright (C) 2020 KiCad Developers, see AUTHORS.txt for contributors.
* *
* This program is free software; you can redistribute it and/or * This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License * modify it under the terms of the GNU General Public License
@ -41,6 +42,14 @@
#include "3d_cache/sg/scenegraph.h" #include "3d_cache/sg/scenegraph.h"
#include "plugins/ldr/3d/pluginldr3D.h" #include "plugins/ldr/3d/pluginldr3D.h"
/**
* Flag to enable 3D plugin manager debug tracing.
*
* Use "KI_TRACE_EDA_3D_VIEWER" to enable.
*
* @ingroup trace_env_vars
*/
#define MASK_3D_PLUGINMGR "3D_PLUGIN_MANAGER" #define MASK_3D_PLUGINMGR "3D_PLUGIN_MANAGER"
@ -62,7 +71,7 @@ S3D_PLUGIN_MANAGER::S3D_PLUGIN_MANAGER()
while( sM != eM ) while( sM != eM )
{ {
wxLogTrace( MASK_3D_PLUGINMGR, " + '%s' [%s]\n", sM->first.GetData(), wxLogTrace( MASK_3D_PLUGINMGR, " + '%s' [%s]\n", sM->first.GetData(),
sM->second->GetKicadPluginName() ); sM->second->GetKicadPluginName() );
++sM; ++sM;
} }
@ -91,8 +100,6 @@ S3D_PLUGIN_MANAGER::S3D_PLUGIN_MANAGER()
wxLogTrace( MASK_3D_PLUGINMGR, " * No file filters available\n" ); wxLogTrace( MASK_3D_PLUGINMGR, " * No file filters available\n" );
} }
#endif // DEBUG #endif // DEBUG
return;
} }
@ -109,7 +116,6 @@ S3D_PLUGIN_MANAGER::~S3D_PLUGIN_MANAGER()
} }
m_Plugins.clear(); m_Plugins.clear();
return;
} }
@ -121,12 +127,12 @@ void S3D_PLUGIN_MANAGER::loadPlugins( void )
#ifndef __WXMAC__ #ifndef __WXMAC__
#ifdef DEBUG #ifdef DEBUG
// set up to work from the build directory // set up to work from the build directory
fn.Assign( wxStandardPaths::Get().GetExecutablePath() ); fn.Assign( wxStandardPaths::Get().GetExecutablePath() );
fn.AppendDir( wxT("..") ); fn.AppendDir( wxT( ".." ) );
fn.AppendDir( wxT("plugins") ); fn.AppendDir( wxT( "plugins" ) );
fn.AppendDir( wxT("3d") ); fn.AppendDir( wxT( "3d" ) );
std::string testpath = std::string( fn.GetPathWithSep().ToUTF8() ); std::string testpath = std::string( fn.GetPathWithSep().ToUTF8() );
checkPluginPath( testpath, searchpaths ); checkPluginPath( testpath, searchpaths );
@ -137,27 +143,25 @@ void S3D_PLUGIN_MANAGER::loadPlugins( void )
debugPluginDir.Open( testpath ); debugPluginDir.Open( testpath );
if( debugPluginDir.IsOpened() && if( debugPluginDir.IsOpened() && debugPluginDir.GetFirst( &subdir, wxEmptyString, wxDIR_DIRS ) )
debugPluginDir.GetFirst( &subdir, wxEmptyString, wxDIR_DIRS ) )
{ {
checkPluginPath( testpath + subdir, searchpaths ); checkPluginPath( testpath + subdir, searchpaths );
while( debugPluginDir.GetNext( &subdir ) ) while( debugPluginDir.GetNext( &subdir ) )
checkPluginPath( testpath + subdir, searchpaths ); checkPluginPath( testpath + subdir, searchpaths );
} }
#endif #endif
#ifndef _WIN32 #ifndef _WIN32
// PLUGINDIR = CMAKE_INSTALL_FULL_LIBDIR path is the absolute path // PLUGINDIR = CMAKE_INSTALL_FULL_LIBDIR path is the absolute path
// corresponding to the install path used for constructing KICAD_USER_PLUGIN // corresponding to the install path used for constructing KICAD_USER_PLUGIN
wxString tfname = wxString::FromUTF8Unchecked( PLUGINDIR ); wxString tfname = wxString::FromUTF8Unchecked( PLUGINDIR );
fn.Assign( tfname, ""); fn.Assign( tfname, "" );
fn.AppendDir( "kicad" ); fn.AppendDir( "kicad" );
#else #else
// on windows the plugins directory is within the executable's directory // on windows the plugins directory is within the executable's directory
fn.Assign( wxStandardPaths::Get().GetExecutablePath() ); fn.Assign( wxStandardPaths::Get().GetExecutablePath() );
#endif #endif
fn.AppendDir( wxT( "plugins" ) ); fn.AppendDir( wxT( "plugins" ) );
fn.AppendDir( wxT( "3d" ) ); fn.AppendDir( wxT( "3d" ) );
@ -169,22 +173,23 @@ void S3D_PLUGIN_MANAGER::loadPlugins( void )
// note: GetUserDataDir() gives '.pcbnew' rather than '.kicad' since it uses the exe name; // note: GetUserDataDir() gives '.pcbnew' rather than '.kicad' since it uses the exe name;
fn.Assign( wxStandardPaths::Get().GetUserDataDir(), "" ); fn.Assign( wxStandardPaths::Get().GetUserDataDir(), "" );
fn.RemoveLastDir(); fn.RemoveLastDir();
#ifdef _WIN32 #ifdef _WIN32
fn.AppendDir( wxT( "kicad" ) ); fn.AppendDir( wxT( "kicad" ) );
#else #else
fn.AppendDir( wxT( ".kicad" ) ); fn.AppendDir( wxT( ".kicad" ) );
#endif #endif
fn.AppendDir( wxT( "plugins" ) ); fn.AppendDir( wxT( "plugins" ) );
fn.AppendDir( wxT( "3d" ) ); fn.AppendDir( wxT( "3d" ) );
checkPluginPath( fn.GetPathWithSep(), searchpaths ); checkPluginPath( fn.GetPathWithSep(), searchpaths );
#else #else
// Search path on OS X is // Search path on OS X is
// (1) User ~/Library/Application Support/kicad/PlugIns/3d // (1) User ~/Library/Application Support/kicad/PlugIns/3d
checkPluginPath( GetOSXKicadUserDataDir() + wxT( "/PlugIns/3d" ), searchpaths ); checkPluginPath( GetOSXKicadUserDataDir() + wxT( "/PlugIns/3d" ), searchpaths );
// (2) Machine /Library/Application Support/kicad/PlugIns/3d // (2) Machine /Library/Application Support/kicad/PlugIns/3d
checkPluginPath( GetOSXKicadMachineDataDir() + wxT( "/PlugIns/3d" ), searchpaths ); checkPluginPath( GetOSXKicadMachineDataDir() + wxT( "/PlugIns/3d" ), searchpaths );
// (3) Bundle kicad.app/Contents/PlugIns/3d // (3) Bundle kicad.app/Contents/PlugIns/3d
fn.Assign( Pgm().GetExecutablePath() ); fn.Assign( Pgm().GetExecutablePath() );
fn.AppendDir( wxT( "Contents" ) ); fn.AppendDir( wxT( "Contents" ) );
@ -199,14 +204,9 @@ void S3D_PLUGIN_MANAGER::loadPlugins( void )
while( sPL != ePL ) while( sPL != ePL )
{ {
#ifdef DEBUG wxLogTrace( MASK_3D_PLUGINMGR, "%s:%s:%d * [DEBUG] searching path: '%s'",
do { __FILE__, __FUNCTION__, __LINE__, (*sPL).ToUTF8() );
std::ostringstream ostr;
ostr << __FILE__ << ":" << __FUNCTION__ << ":" << __LINE__ << ":\n";
ostr << " * [DEBUG] searching path: '" << (*sPL).ToUTF8() << "'";
wxLogTrace( MASK_3D_PLUGINMGR, "%s\n", ostr.str().c_str() );
} while( 0 );
#endif
listPlugins( *sPL, pluginlist ); listPlugins( *sPL, pluginlist );
++sPL; ++sPL;
} }
@ -223,25 +223,14 @@ void S3D_PLUGIN_MANAGER::loadPlugins( void )
if( pp->Open( sPL->ToUTF8() ) ) if( pp->Open( sPL->ToUTF8() ) )
{ {
#ifdef DEBUG wxLogTrace( MASK_3D_PLUGINMGR, "%s:%s:%d * [DEBUG] adding plugin",
do { __FILE__, __FUNCTION__, __LINE__ );
std::ostringstream ostr;
ostr << __FILE__ << ":" << __FUNCTION__ << ":" << __LINE__ << ":\n";
ostr << "* [DEBUG] adding plugin";
wxLogTrace( MASK_3D_PLUGINMGR, "%s\n", ostr.str().c_str() );
} while( 0 );
#endif
m_Plugins.push_back( pp ); m_Plugins.push_back( pp );
int nf = pp->GetNFilters(); int nf = pp->GetNFilters();
#ifdef DEBUG wxLogTrace( MASK_3D_PLUGINMGR, "%s:%s:%d * [DEBUG] adding %d filters",
do { __FILE__, __FUNCTION__, __LINE__, nf );
std::ostringstream ostr;
ostr << __FILE__ << ": " << __FUNCTION__ << ": " << __LINE__ << "\n";
ostr << " * [INFO] adding " << nf << " filters";
wxLogTrace( MASK_3D_PLUGINMGR, "%s\n", ostr.str().c_str() );
} while( 0 );
#endif
for( int i = 0; i < nf; ++i ) for( int i = 0; i < nf; ++i )
{ {
@ -258,38 +247,23 @@ void S3D_PLUGIN_MANAGER::loadPlugins( void )
} }
else else
{ {
#ifdef DEBUG wxLogTrace( MASK_3D_PLUGINMGR, "%s:%s:%d * [DEBUG] deleting plugin",
do { __FILE__, __FUNCTION__, __LINE__ );
std::ostringstream ostr;
ostr << __FILE__ << ":" << __FUNCTION__ << ":" << __LINE__ << ":\n";
ostr << "* [DEBUG] deleting plugin";
wxLogTrace( MASK_3D_PLUGINMGR, "%s\n", ostr.str().c_str() );
} while( 0 );
#endif
delete pp; delete pp;
} }
++sPL; ++sPL;
} }
#ifdef DEBUG wxLogTrace( MASK_3D_PLUGINMGR, "%s:%s:%d * [DEBUG] plugins loaded",
do { __FILE__, __FUNCTION__, __LINE__ );
std::ostringstream ostr;
ostr << __FILE__ << ":" << __FUNCTION__ << ":" << __LINE__ << ":\n";
ostr << "* [DEBUG] plugins loaded";
wxLogTrace( MASK_3D_PLUGINMGR, "%s\n", ostr.str().c_str() );
} while( 0 );
#endif
return;
} }
void S3D_PLUGIN_MANAGER::listPlugins( const wxString& aPath, void S3D_PLUGIN_MANAGER::listPlugins( const wxString& aPath, std::list< wxString >& aPluginList )
std::list< wxString >& aPluginList )
{ {
// list potential plugins given a search path // list potential plugins given a search path
wxString nameFilter; // filter for user-loadable libraries (aka footprints) wxString nameFilter; // filter for user-loadable libraries (aka footprints)
wxString lName; // stores name of enumerated files wxString lName; // stores name of enumerated files
wxString fName; // full name of file wxString fName; // full name of file
@ -327,13 +301,11 @@ void S3D_PLUGIN_MANAGER::listPlugins( const wxString& aPath,
} }
wd.Close(); wd.Close();
return;
} }
void S3D_PLUGIN_MANAGER::checkPluginName( const wxString& aPath, void S3D_PLUGIN_MANAGER::checkPluginName( const wxString& aPath,
std::list< wxString >& aPluginList ) std::list< wxString >& aPluginList )
{ {
// check the existence of a plugin name and add it to the list // check the existence of a plugin name and add it to the list
@ -359,12 +331,7 @@ void S3D_PLUGIN_MANAGER::checkPluginName( const wxString& aPath,
aPluginList.push_back( wxpath ); aPluginList.push_back( wxpath );
#ifdef DEBUG wxLogTrace( MASK_3D_PLUGINMGR, " * [INFO] found 3D plugin '%s'\n", wxpath.GetData() );
wxLogTrace( MASK_3D_PLUGINMGR, " * [INFO] found 3D plugin '%s'\n",
wxpath.GetData() );
#endif
return;
} }
@ -375,10 +342,7 @@ void S3D_PLUGIN_MANAGER::checkPluginPath( const wxString& aPath,
if( aPath.empty() ) if( aPath.empty() )
return; return;
#ifdef DEBUG wxLogTrace( MASK_3D_PLUGINMGR, " * [INFO] checking for 3D plugins in '%s'\n", aPath.GetData() );
wxLogTrace( MASK_3D_PLUGINMGR, " * [INFO] checking for 3D plugins in '%s'\n",
aPath.GetData() );
#endif
wxFileName path; wxFileName path;
@ -406,8 +370,6 @@ void S3D_PLUGIN_MANAGER::checkPluginPath( const wxString& aPath,
} }
aSearchList.push_back( wxpath ); aSearchList.push_back( wxpath );
return;
} }
@ -436,19 +398,13 @@ void S3D_PLUGIN_MANAGER::addFilterString( const wxString& aFilterString )
void S3D_PLUGIN_MANAGER::addExtensionMap( KICAD_PLUGIN_LDR_3D* aPlugin ) void S3D_PLUGIN_MANAGER::addExtensionMap( KICAD_PLUGIN_LDR_3D* aPlugin )
{ {
// add entries to the extension map // add entries to the extension map
if( NULL == aPlugin ) if( nullptr == aPlugin )
return; return;
int nExt = aPlugin->GetNExtensions(); int nExt = aPlugin->GetNExtensions();
#ifdef DEBUG wxLogTrace( MASK_3D_PLUGINMGR, "%s:%s:%d * [INFO] adding %d extensions",
do { __FILE__, __FUNCTION__, __LINE__, nExt );
std::ostringstream ostr;
ostr << __FILE__ << ": " << __FUNCTION__ << ": " << __LINE__ << "\n";
ostr << " * [INFO] adding " << nExt << " extensions";
wxLogTrace( MASK_3D_PLUGINMGR, "%s\n", ostr.str().c_str() );
} while( 0 );
#endif
for( int i = 0; i < nExt; ++i ) for( int i = 0; i < nExt; ++i )
{ {
@ -464,8 +420,6 @@ void S3D_PLUGIN_MANAGER::addExtensionMap( KICAD_PLUGIN_LDR_3D* aPlugin )
} }
} }
return;
} }
@ -480,11 +434,11 @@ SCENEGRAPH* S3D_PLUGIN_MANAGER::Load3DModel( const wxString& aFileName, std::str
wxFileName raw( aFileName ); wxFileName raw( aFileName );
wxString ext = raw.GetExt(); wxString ext = raw.GetExt();
#ifdef _WIN32 #ifdef _WIN32
// note: plugins only have a lowercase filter within Windows; including an uppercase // note: plugins only have a lowercase filter within Windows; including an uppercase
// filter will result in duplicate file entries and should be avoided. // filter will result in duplicate file entries and should be avoided.
ext.LowerCase(); ext.LowerCase();
#endif #endif
std::pair < std::multimap< const wxString, KICAD_PLUGIN_LDR_3D* >::iterator, std::pair < std::multimap< const wxString, KICAD_PLUGIN_LDR_3D* >::iterator,
std::multimap< const wxString, KICAD_PLUGIN_LDR_3D* >::iterator > items; std::multimap< const wxString, KICAD_PLUGIN_LDR_3D* >::iterator > items;
@ -498,7 +452,7 @@ SCENEGRAPH* S3D_PLUGIN_MANAGER::Load3DModel( const wxString& aFileName, std::str
{ {
SCENEGRAPH* sp = sL->second->Load( aFileName.ToUTF8() ); SCENEGRAPH* sp = sL->second->Load( aFileName.ToUTF8() );
if( NULL != sp ) if( nullptr != sp )
{ {
sL->second->GetPluginInfo( aPluginInfo ); sL->second->GetPluginInfo( aPluginInfo );
return sp; return sp;
@ -508,7 +462,7 @@ SCENEGRAPH* S3D_PLUGIN_MANAGER::Load3DModel( const wxString& aFileName, std::str
++sL; ++sL;
} }
return NULL; return nullptr;
} }
@ -517,28 +471,20 @@ void S3D_PLUGIN_MANAGER::ClosePlugins( void )
std::list< KICAD_PLUGIN_LDR_3D* >::iterator sP = m_Plugins.begin(); std::list< KICAD_PLUGIN_LDR_3D* >::iterator sP = m_Plugins.begin();
std::list< KICAD_PLUGIN_LDR_3D* >::iterator eP = m_Plugins.end(); std::list< KICAD_PLUGIN_LDR_3D* >::iterator eP = m_Plugins.end();
#ifdef DEBUG wxLogTrace( MASK_3D_PLUGINMGR, "%s:%s:%d * [INFO] closing %d extensions",
do { __FILE__, __FUNCTION__, __LINE__, static_cast<int>( m_Plugins.size() ) );
std::ostringstream ostr;
ostr << __FILE__ << ": " << __FUNCTION__ << ": " << __LINE__ << "\n";
ostr << " * [INFO] closing " << m_Plugins.size() << " plugins";
wxLogTrace( MASK_3D_PLUGINMGR, "%s\n", ostr.str().c_str() );
} while( 0 );
#endif
while( sP != eP ) while( sP != eP )
{ {
(*sP)->Close(); (*sP)->Close();
++sP; ++sP;
} }
return;
} }
bool S3D_PLUGIN_MANAGER::CheckTag( const char* aTag ) bool S3D_PLUGIN_MANAGER::CheckTag( const char* aTag )
{ {
if( NULL == aTag || aTag[0] == 0 || m_Plugins.empty() ) if( nullptr == aTag || aTag[0] == 0 || m_Plugins.empty() )
return false; return false;
std::string tname = aTag; std::string tname = aTag;

View File

@ -2,6 +2,7 @@
* This program source code file is part of KiCad, a free EDA CAD application. * This program source code file is part of KiCad, a free EDA CAD application.
* *
* Copyright (C) 2016 Cirilo Bernardo <cirilo.bernardo@gmail.com> * Copyright (C) 2016 Cirilo Bernardo <cirilo.bernardo@gmail.com>
* Copyright (C) 2020 KiCad Developers, see AUTHORS.txt for contributors.
* *
* This program is free software; you can redistribute it and/or * This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License * modify it under the terms of the GNU General Public License
@ -40,16 +41,35 @@ class SCENEGRAPH;
class S3D_PLUGIN_MANAGER class S3D_PLUGIN_MANAGER
{ {
public:
S3D_PLUGIN_MANAGER();
virtual ~S3D_PLUGIN_MANAGER();
/**
* Return the list of file filters; this will contain at least the default
* "All Files (*.*)|*.*" and the file filters supported by any available plugins.
*
* @return a pointer to the internal filter list.
*/
std::list< wxString > const* GetFileFilters( void ) const noexcept;
SCENEGRAPH* Load3DModel( const wxString& aFileName, std::string& aPluginInfo );
/**
* Iterate through all discovered plugins and closes them to reclaim memory.
*
* The individual plugins will be automatically reloaded as calls are made to load
* specific models.
*/
void ClosePlugins( void );
/**
* Check the given tag and returns true if the plugin named in the tag is not loaded
* or the plugin is loaded and the version matches.
*/
bool CheckTag( const char* aTag );
private: private:
/// list of discovered plugins
std::list< KICAD_PLUGIN_LDR_3D* > m_Plugins;
/// mapping of extensions to available plugins
std::multimap< const wxString, KICAD_PLUGIN_LDR_3D* > m_ExtMap;
/// list of file filters
std::list< wxString > m_FileFilters;
/// load plugins /// load plugins
void loadPlugins( void ); void loadPlugins( void );
@ -68,36 +88,14 @@ private:
/// add entries to the extension map /// add entries to the extension map
void addExtensionMap( KICAD_PLUGIN_LDR_3D* aPlugin ); void addExtensionMap( KICAD_PLUGIN_LDR_3D* aPlugin );
public: /// list of discovered plugins
S3D_PLUGIN_MANAGER(); std::list< KICAD_PLUGIN_LDR_3D* > m_Plugins;
virtual ~S3D_PLUGIN_MANAGER();
/** /// mapping of extensions to available plugins
* Function GetFileFilters std::multimap< const wxString, KICAD_PLUGIN_LDR_3D* > m_ExtMap;
* returns the list of file filters; this will contain at least
* the default "All Files (*.*)|*.*" and the file filters supported
* by any available plugins
*
* @return a pointer to the internal filter list
*/
std::list< wxString > const* GetFileFilters( void ) const noexcept;
SCENEGRAPH* Load3DModel( const wxString& aFileName, std::string& aPluginInfo ); /// list of file filters
std::list< wxString > m_FileFilters;
/**
* Function ClosePlugins
* iterates through all discovered plugins and closes them to
* reclaim memory. The individual plugins will be automatically
* reloaded as calls are made to load specific models.
*/
void ClosePlugins( void );
/**
* Function CheckTag
* checks the given tag and returns true if the plugin named in the tag
* is not loaded or the plugin is loaded and the version matches
*/
bool CheckTag( const char* aTag );
}; };
#endif // PLUGIN_MANAGER_3D_H #endif // PLUGIN_MANAGER_3D_H

View File

@ -130,7 +130,7 @@ PANEL_PREV_3D::PANEL_PREV_3D( wxWindow* aParent, PCB_BASE_FRAME* aFrame, FOOTPRI
// The rounded-button style used has a small border on the left/right sides. // The rounded-button style used has a small border on the left/right sides.
// This is automatically fixed in wx for buttons with a bitmap < 20, but not // This is automatically fixed in wx for buttons with a bitmap < 20, but not
// when the bitmap is set to be 26x26. // when the bitmap is set to be 26x26.
wxSize borderFix = wxSize(4, 4); wxSize borderFix = wxSize( 4, 4 );
m_bpvTop->SetMinSize( m_bpvTop->GetSize() + borderFix ); m_bpvTop->SetMinSize( m_bpvTop->GetSize() + borderFix );
m_bpvFront->SetMinSize( m_bpvFront->GetSize() + borderFix ); m_bpvFront->SetMinSize( m_bpvFront->GetSize() + borderFix );
@ -175,9 +175,9 @@ void PANEL_PREV_3D::loadCommonSettings()
/** /**
* @brief rotationFromString * Ensure -MAX_ROTATION <= rotation <= MAX_ROTATION.
* Ensure -MAX_ROTATION <= rotation <= MAX_ROTATION *
* aRotation will be normalized between -MAX_ROTATION and MAX_ROTATION * @param \a aRotation will be normalized between -MAX_ROTATION and MAX_ROTATION.
*/ */
static double rotationFromString( const wxString& aValue ) static double rotationFromString( const wxString& aValue )
{ {
@ -229,7 +229,6 @@ void PANEL_PREV_3D::SetSelectedModel( int idx )
// Use ChangeValue() instead of SetValue(). It's not the user making the change, so we // 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. // don't want to generate wxEVT_GRID_CELL_CHANGED events.
xscale->ChangeValue( formatScaleValue( modelInfo.m_Scale.x ) ); xscale->ChangeValue( formatScaleValue( modelInfo.m_Scale.x ) );
yscale->ChangeValue( formatScaleValue( modelInfo.m_Scale.y ) ); yscale->ChangeValue( formatScaleValue( modelInfo.m_Scale.y ) );
zscale->ChangeValue( formatScaleValue( modelInfo.m_Scale.z ) ); zscale->ChangeValue( formatScaleValue( modelInfo.m_Scale.z ) );

View File

@ -3,7 +3,7 @@
* *
* Copyright (C) 2016 Mario Luzeiro <mrluzeiro@ua.pt> * Copyright (C) 2016 Mario Luzeiro <mrluzeiro@ua.pt>
* Copyright (C) 2015 Cirilo Bernardo <cirilo.bernardo@gmail.com> * Copyright (C) 2015 Cirilo Bernardo <cirilo.bernardo@gmail.com>
* Copyright (C) 2015-2016 KiCad Developers, see AUTHORS.txt for contributors. * Copyright (C) 2015-2020 KiCad Developers, see AUTHORS.txt for contributors.
* *
* This program is free software; you can redistribute it and/or * This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License * modify it under the terms of the GNU General Public License
@ -79,22 +79,29 @@ public:
~PANEL_PREV_3D(); ~PANEL_PREV_3D();
private: /**
EDA_3D_CANVAS* m_previewPane; * The TOOL_DISPATCHER needs these to work around some issues in wxWidgets where the menu
WX_INFOBAR* m_infobar; * events aren't captured by the menus themselves.
BOARD_ADAPTER m_boardAdapter; */
CCAMERA& m_currentCamera; void OnMenuEvent( wxMenuEvent& aEvent );
CTRACK_BALL m_trackBallCamera;
BOARD* m_dummyBoard; wxWindow* GetToolCanvas() const override { return m_previewPane; }
FOOTPRINT* m_dummyFootprint;
std::vector<FP_3DMODEL>* m_parentModelList; BOARD_ADAPTER& GetAdapter() override { return m_boardAdapter; }
int m_selected; /// Index into m_parentInfoList CCAMERA& GetCurrentCamera() override { return m_currentCamera; }
EDA_UNITS m_userUnits; /**
* Set the currently selected index in the model list so that the scale/rotation/offset
* controls can be updated.
*/
void SetSelectedModel( int idx );
/**
* Copy shapes from the current shape list which are flagged for preview to the copy of
* footprint that is on the preview dummy board.
*/
void UpdateDummyFootprint( bool aRelaodRequired = true );
// Methods of the class
private: private:
/** /**
* Load 3D relevant settings from the user configuration * Load 3D relevant settings from the user configuration
@ -102,8 +109,7 @@ private:
void loadCommonSettings(); void loadCommonSettings();
/** /**
* @brief updateOrientation - it will receive the events from editing the fields * It will receive the events from editing the fields.
* @param event
*/ */
void updateOrientation( wxCommandEvent &event ) override; void updateOrientation( wxCommandEvent &event ) override;
@ -188,29 +194,20 @@ private:
m_previewPane->SetView3D( ID_VIEW3D_BOTTOM ); m_previewPane->SetView3D( ID_VIEW3D_BOTTOM );
} }
public: private:
/** EDA_3D_CANVAS* m_previewPane;
* The TOOL_DISPATCHER needs these to work around some issues in wxWidgets where the menu WX_INFOBAR* m_infobar;
* events aren't captured by the menus themselves. BOARD_ADAPTER m_boardAdapter;
*/ CCAMERA& m_currentCamera;
void OnMenuEvent( wxMenuEvent& aEvent ); CTRACK_BALL m_trackBallCamera;
wxWindow* GetToolCanvas() const override { return m_previewPane; } BOARD* m_dummyBoard;
FOOTPRINT* m_dummyFootprint;
BOARD_ADAPTER& GetAdapter() override { return m_boardAdapter; } std::vector<FP_3DMODEL>* m_parentModelList;
CCAMERA& GetCurrentCamera() override { return m_currentCamera; } int m_selected; /// Index into m_parentInfoList
/** EDA_UNITS m_userUnits;
* @brief SetSelectedModel - Sets the currently selected index in the model list so that
* the scale/rotation/offset controls can be updated.
*/
void SetSelectedModel( int idx );
/**
* @brief UpdateDummyFootprint - copy shapes from the current shape list which are flagged
* for preview to the copy of footprint that is on the preview dummy board
*/
void UpdateDummyFootprint( bool aRelaodRequired = true );
}; };
#endif // PANEL_PREV_MODEL_H #endif // PANEL_PREV_MODEL_H

View File

@ -2,6 +2,7 @@
* This program source code file is part of KiCad, a free EDA CAD application. * This program source code file is part of KiCad, a free EDA CAD application.
* *
* Copyright (C) 2015-2017 Cirilo Bernardo <cirilo.bernardo@gmail.com> * Copyright (C) 2015-2017 Cirilo Bernardo <cirilo.bernardo@gmail.com>
* Copyright (C) 2020 KiCad Developers, see AUTHORS.txt for contributors.
* *
* This program is free software; you can redistribute it and/or * This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License * modify it under the terms of the GNU General Public License
@ -36,10 +37,6 @@
#include "3d_cache/sg/sg_helpers.h" #include "3d_cache/sg/sg_helpers.h"
#ifdef DEBUG
static char BadNode[] = " * [BUG] NULL pointer passed for aNode\n";
#endif
// version format of the cache file // version format of the cache file
#define SG_VERSION_TAG "VERSION:2" #define SG_VERSION_TAG "VERSION:2"
@ -73,15 +70,13 @@ static void formatMaterial( SMATERIAL& mat, SGAPPEARANCE const* app )
mat.m_Shininess = app->shininess; mat.m_Shininess = app->shininess;
mat.m_Transparency = app->transparency; mat.m_Transparency = app->transparency;
return;
} }
bool S3D::WriteVRML( const char* filename, bool overwrite, SGNODE* aTopNode, bool S3D::WriteVRML( const char* filename, bool overwrite, SGNODE* aTopNode,
bool reuse, bool renameNodes ) bool reuse, bool renameNodes )
{ {
if( NULL == filename || filename[0] == 0 ) if( nullptr == filename || filename[0] == 0 )
return false; return false;
wxString ofile = wxString::FromUTF8Unchecked( filename ); wxString ofile = wxString::FromUTF8Unchecked( filename );
@ -96,42 +91,15 @@ bool S3D::WriteVRML( const char* filename, bool overwrite, SGNODE* aTopNode,
return false; return false;
} }
if( NULL == aTopNode ) wxCHECK( aTopNode && aTopNode->GetNodeType() == S3D::SGTYPE_TRANSFORM, false );
{
#ifdef DEBUG
do {
std::ostringstream ostr;
ostr << __FILE__ << ": " << __FUNCTION__ << ": " << __LINE__ << "\n";
ostr << " * [BUG] NULL pointer passed for aTopNode";
wxLogTrace( MASK_3D_SG, "%s\n", ostr.str().c_str() );
} while( 0 );
#endif
return false;
}
if( S3D::SGTYPE_TRANSFORM != aTopNode->GetNodeType() )
{
#ifdef DEBUG
do {
std::ostringstream ostr;
ostr << __FILE__ << ": " << __FUNCTION__ << ": " << __LINE__ << "\n";
ostr << " * [BUG] aTopNode is not a SCENEGRAPH object";
wxLogTrace( MASK_3D_SG, "%s\n", ostr.str().c_str() );
} while( 0 );
#endif
return false;
}
OPEN_OSTREAM( op, filename ); OPEN_OSTREAM( op, filename );
if( op.fail() ) if( op.fail() )
{ {
wxString errmsg; wxLogTrace( MASK_3D_SG, "%s:%s:%d * [INFO] failed to open file '%s'",
errmsg << __FILE__ << ": " << __FUNCTION__ << ": " << __LINE__ << "\n"; __FILE__, __FUNCTION__, __LINE__, filename );
errmsg << " * [INFO] " << "failed to open file" << " '" << filename << "'";
wxLogTrace( MASK_3D_SG, errmsg );
return false; return false;
} }
@ -154,10 +122,8 @@ bool S3D::WriteVRML( const char* filename, bool overwrite, SGNODE* aTopNode,
CLOSE_STREAM( op ); CLOSE_STREAM( op );
wxString errmsg; wxLogTrace( MASK_3D_SG, "%s:%s:%d * [INFO] problems encountered writing file '%s'",
errmsg << __FILE__ << ": " << __FUNCTION__ << ": " << __LINE__ << "\n"; __FILE__, __FUNCTION__, __LINE__, filename );
errmsg << " * [INFO] " << "problems encountered writing file" << " '" << filename << "'";
wxLogTrace( MASK_3D_SG, errmsg );
return false; return false;
} }
@ -165,102 +131,44 @@ bool S3D::WriteVRML( const char* filename, bool overwrite, SGNODE* aTopNode,
void S3D::ResetNodeIndex( SGNODE* aNode ) void S3D::ResetNodeIndex( SGNODE* aNode )
{ {
if( NULL == aNode ) wxCHECK( aNode, /* void */ );
{
#ifdef DEBUG
do {
std::ostringstream ostr;
ostr << __FILE__ << ": " << __FUNCTION__ << ": " << __LINE__ << "\n";
ostr << BadNode;
wxLogTrace( MASK_3D_SG, "%s", ostr.str().c_str() );
} while( 0 );
#endif
return;
}
aNode->ResetNodeIndex(); aNode->ResetNodeIndex();
return;
} }
void S3D::RenameNodes( SGNODE* aNode ) void S3D::RenameNodes( SGNODE* aNode )
{ {
if( NULL == aNode ) wxCHECK( aNode, /* void */ );
{
#ifdef DEBUG
do {
std::ostringstream ostr;
ostr << __FILE__ << ": " << __FUNCTION__ << ": " << __LINE__ << "\n";
ostr << BadNode;
wxLogTrace( MASK_3D_SG, "%s", ostr.str().c_str() );
} while( 0 );
#endif
return;
}
aNode->ReNameNodes(); aNode->ReNameNodes();
return;
} }
void S3D::DestroyNode( SGNODE* aNode ) noexcept void S3D::DestroyNode( SGNODE* aNode ) noexcept
{ {
if( NULL == aNode ) wxCHECK( aNode, /* void */ );
{
#ifdef DEBUG
do {
std::ostringstream ostr;
ostr << __FILE__ << ": " << __FUNCTION__ << ": " << __LINE__ << "\n";
ostr << BadNode;
wxLogTrace( MASK_3D_SG, "%s", ostr.str().c_str() );
} while( 0 );
#endif
return;
}
delete aNode; delete aNode;
return;
} }
bool S3D::WriteCache( const char* aFileName, bool overwrite, SGNODE* aNode, bool S3D::WriteCache( const char* aFileName, bool overwrite, SGNODE* aNode,
const char* aPluginInfo ) const char* aPluginInfo )
{ {
if( NULL == aFileName || aFileName[0] == 0 ) if( nullptr == aFileName || aFileName[0] == 0 )
return false; return false;
wxString ofile = wxString::FromUTF8Unchecked( aFileName ); wxString ofile = wxString::FromUTF8Unchecked( aFileName );
if( NULL == aNode ) wxCHECK( aNode, false );
{
#ifdef DEBUG
do {
std::ostringstream ostr;
ostr << __FILE__ << ": " << __FUNCTION__ << ": " << __LINE__ << "\n";
ostr << BadNode;
wxLogTrace( MASK_3D_SG, "%s", ostr.str().c_str() );
} while( 0 );
#endif
return false;
}
if( wxFileName::Exists( ofile ) ) if( wxFileName::Exists( ofile ) )
{ {
if( !overwrite ) if( !overwrite )
{ {
wxString errmsg; wxLogTrace( MASK_3D_SG, "%s:%s:%d * [INFO] file exists not overwriting '%s'",
errmsg << __FILE__ << ": " << __FUNCTION__ << ": " << __LINE__ << "\n"; __FILE__, __FUNCTION__, __LINE__, aFileName );
errmsg << " * [INFO] " << "file exists; not overwriting" << " '";
errmsg << aFileName << "'";
wxLogTrace( MASK_3D_SG, errmsg );
return false; return false;
} }
@ -268,11 +176,9 @@ bool S3D::WriteCache( const char* aFileName, bool overwrite, SGNODE* aNode,
// make sure we make no attempt to write a directory // make sure we make no attempt to write a directory
if( !wxFileName::FileExists( aFileName ) ) if( !wxFileName::FileExists( aFileName ) )
{ {
wxString errmsg; wxLogTrace( MASK_3D_SG, "%s:%s:%d * [INFO] specified path is a directory '%s'",
errmsg << __FILE__ << ": " << __FUNCTION__ << ": " << __LINE__ << "\n"; __FILE__, __FUNCTION__, __LINE__, aFileName );
errmsg << " * [INFO] " << "specified path is a directory" << " '";
errmsg << aFileName << "'";
wxLogTrace( MASK_3D_SG, errmsg );
return false; return false;
} }
} }
@ -281,34 +187,26 @@ bool S3D::WriteCache( const char* aFileName, bool overwrite, SGNODE* aNode,
if( output.fail() ) if( output.fail() )
{ {
wxString errmsg; wxLogTrace( MASK_3D_SG, "%s:%s:%d * [INFO] failed to open file '%s'",
errmsg << __FILE__ << ": " << __FUNCTION__ << ": " << __LINE__ << "\n"; __FILE__, __FUNCTION__, __LINE__, aFileName );
errmsg << " * [INFO] " << "failed to open file" << " '" << aFileName << "'";
wxLogTrace( MASK_3D_SG, errmsg );
return false; return false;
} }
output << "(" << SG_VERSION_TAG << ")"; output << "(" << SG_VERSION_TAG << ")";
if( NULL != aPluginInfo && aPluginInfo[0] != 0 ) if( nullptr != aPluginInfo && aPluginInfo[0] != 0 )
output << "(" << aPluginInfo << ")"; output << "(" << aPluginInfo << ")";
else else
output << "(INTERNAL:0.0.0.0)"; output << "(INTERNAL:0.0.0.0)";
bool rval = aNode->WriteCache( output, NULL ); bool rval = aNode->WriteCache( output, nullptr );
CLOSE_STREAM( output ); CLOSE_STREAM( output );
if( !rval ) if( !rval )
{ {
#ifdef DEBUG wxLogTrace( MASK_3D_SG, "%s:%s:%d * [INFO] problems encountered writing cache file '%s'",
do { __FILE__, __FUNCTION__, __LINE__, aFileName );
std::ostringstream ostr;
ostr << __FILE__ << ": " << __FUNCTION__ << ": " << __LINE__ << "\n";
ostr << " * [INFO] problems encountered writing cache file '";
ostr << aFileName << "'";
wxLogTrace( MASK_3D_SG, "%s\n", ostr.str().c_str() );
} while( 0 );
#endif
// delete the defective file // delete the defective file
wxRemoveFile( ofile ); wxRemoveFile( ofile );
@ -319,39 +217,29 @@ bool S3D::WriteCache( const char* aFileName, bool overwrite, SGNODE* aNode,
SGNODE* S3D::ReadCache( const char* aFileName, void* aPluginMgr, SGNODE* S3D::ReadCache( const char* aFileName, void* aPluginMgr,
bool (*aTagCheck)( const char*, void* ) ) bool (*aTagCheck)( const char*, void* ) )
{ {
if( NULL == aFileName || aFileName[0] == 0 ) if( nullptr == aFileName || aFileName[0] == 0 )
return NULL; return nullptr;
wxString ofile = wxString::FromUTF8Unchecked( aFileName ); wxString ofile = wxString::FromUTF8Unchecked( aFileName );
if( !wxFileName::FileExists( aFileName ) ) if( !wxFileName::FileExists( aFileName ) )
{ {
std::ostringstream ostr; wxLogTrace( MASK_3D_SG, "%s:%s:%d * [INFO] no such file '%s'",
ostr << __FILE__ << ": " << __FUNCTION__ << ": " << __LINE__ << "\n"; __FILE__, __FUNCTION__, __LINE__, aFileName );
wxString errmsg = _( "no such file" );
ostr << " * [INFO] " << errmsg.ToUTF8() << " '";
ostr << aFileName << "'";
wxLogTrace( MASK_3D_SG, "%s\n", ostr.str().c_str() );
return NULL; return nullptr;
} }
SGNODE* np = new SCENEGRAPH( NULL ); SGNODE* np = new SCENEGRAPH( nullptr );
if( NULL == np ) if( nullptr == np )
{ {
#ifdef DEBUG wxLogTrace( MASK_3D_SG, "%s:%s:%d * [INFO] failed to instantiate SCENEGRAPH",
do { __FILE__, __FUNCTION__, __LINE__ );
std::ostringstream ostr;
ostr << __FILE__ << ": " << __FUNCTION__ << ": " << __LINE__ << "\n";
ostr << " * [INFO] failed to instantiate SCENEGRAPH";
wxLogTrace( MASK_3D_SG, "%s\n", ostr.str().c_str() );
} while( 0 );
#endif
return NULL; return nullptr;
} }
OPEN_ISTREAM( file, aFileName ); OPEN_ISTREAM( file, aFileName );
@ -359,13 +247,11 @@ SGNODE* S3D::ReadCache( const char* aFileName, void* aPluginMgr,
if( file.fail() ) if( file.fail() )
{ {
delete np; delete np;
std::ostringstream ostr;
ostr << __FILE__ << ": " << __FUNCTION__ << ": " << __LINE__ << "\n"; wxLogTrace( MASK_3D_SG, "%s:%s:%d * [INFO] failed to open file '%s'",
wxString errmsg = _( "failed to open file" ); __FILE__, __FUNCTION__, __LINE__, aFileName );
ostr << " * [INFO] " << errmsg.ToUTF8() << " '";
ostr << aFileName << "'"; return nullptr;
wxLogTrace( MASK_3D_SG, "%s\n", ostr.str().c_str() );
return NULL;
} }
// from SG_VERSION_TAG 1, read the version tag; if it's not the expected tag // from SG_VERSION_TAG 1, read the version tag; if it's not the expected tag
@ -378,18 +264,12 @@ SGNODE* S3D::ReadCache( const char* aFileName, void* aPluginMgr,
if( '(' != schar ) if( '(' != schar )
{ {
#ifdef DEBUG wxLogTrace( MASK_3D_SG,
do { "%s:%s:%d * [INFO] corrupt data; missing left parenthesis at position '%d'",
std::ostringstream ostr; __FILE__, __FUNCTION__, __LINE__, static_cast<int>( file.tellg() ) );
ostr << __FILE__ << ": " << __FUNCTION__ << ": " << __LINE__ << "\n";
ostr << " * [INFO] corrupt data; missing left parenthesis at position ";
ostr << file.tellg();
wxLogTrace( MASK_3D_SG, "%s\n", ostr.str().c_str() );
} while( 0 );
#endif
CLOSE_STREAM( file ); CLOSE_STREAM( file );
return NULL; return nullptr;
} }
file.get( schar ); file.get( schar );
@ -403,7 +283,7 @@ SGNODE* S3D::ReadCache( const char* aFileName, void* aPluginMgr,
if( name.compare( SG_VERSION_TAG ) ) if( name.compare( SG_VERSION_TAG ) )
{ {
CLOSE_STREAM( file ); CLOSE_STREAM( file );
return NULL; return nullptr;
} }
} while( 0 ); } while( 0 );
@ -418,18 +298,12 @@ SGNODE* S3D::ReadCache( const char* aFileName, void* aPluginMgr,
if( '(' != schar ) if( '(' != schar )
{ {
#ifdef DEBUG wxLogTrace( MASK_3D_SG,
do { "%s:%s:%d * [INFO] corrupt data; missing left parenthesis at position '%d'",
std::ostringstream ostr; __FILE__, __FUNCTION__, __LINE__, static_cast<int>( file.tellg() ) );
ostr << __FILE__ << ": " << __FUNCTION__ << ": " << __LINE__ << "\n";
ostr << " * [INFO] corrupt data; missing left parenthesis at position ";
ostr << file.tellg();
wxLogTrace( MASK_3D_SG, "%s\n", ostr.str().c_str() );
} while( 0 );
#endif
CLOSE_STREAM( file ); CLOSE_STREAM( file );
return NULL; return nullptr;
} }
file.get( schar ); file.get( schar );
@ -441,27 +315,26 @@ SGNODE* S3D::ReadCache( const char* aFileName, void* aPluginMgr,
} }
// check the plugin tag // check the plugin tag
if( NULL != aTagCheck && NULL != aPluginMgr && !aTagCheck( name.c_str(), aPluginMgr ) ) if( nullptr != aTagCheck && nullptr != aPluginMgr
&& !aTagCheck( name.c_str(), aPluginMgr ) )
{ {
CLOSE_STREAM( file ); CLOSE_STREAM( file );
return NULL; return nullptr;
} }
} while( 0 ); } while( 0 );
bool rval = np->ReadCache( file, NULL ); bool rval = np->ReadCache( file, nullptr );
CLOSE_STREAM( file ); CLOSE_STREAM( file );
if( !rval ) if( !rval )
{ {
delete np; delete np;
std::ostringstream ostr;
ostr << __FILE__ << ": " << __FUNCTION__ << ": " << __LINE__ << "\n"; wxLogTrace( MASK_3D_SG, "%s:%s:%d * [INFO] problems encountered reading cache file '%s'",
wxString errmsg = "problems encountered reading cache file"; __FILE__, __FUNCTION__, __LINE__, aFileName );
ostr << " * [INFO] " << errmsg.ToUTF8() << " '";
ostr << aFileName << "'"; return nullptr;
wxLogTrace( MASK_3D_SG, "%s\n", ostr.str().c_str() );
return NULL;
} }
return np; return np;
@ -470,11 +343,11 @@ SGNODE* S3D::ReadCache( const char* aFileName, void* aPluginMgr,
S3DMODEL* S3D::GetModel( SCENEGRAPH* aNode ) S3DMODEL* S3D::GetModel( SCENEGRAPH* aNode )
{ {
if( NULL == aNode ) if( nullptr == aNode )
return NULL; return nullptr;
if( aNode->GetNodeType() != S3D::SGTYPE_TRANSFORM ) if( aNode->GetNodeType() != S3D::SGTYPE_TRANSFORM )
return NULL; return nullptr;
S3D::MATLIST materials; S3D::MATLIST materials;
std::vector< SMESH > meshes; std::vector< SMESH > meshes;
@ -484,7 +357,7 @@ S3DMODEL* S3D::GetModel( SCENEGRAPH* aNode )
// gray in hopes that it may help highlight faulty models; this color is // gray in hopes that it may help highlight faulty models; this color is
// also typical of MCAD applications. When a model has no associated // also typical of MCAD applications. When a model has no associated
// material color it shall be assigned the index 0. // material color it shall be assigned the index 0.
SGAPPEARANCE app( NULL ); SGAPPEARANCE app( nullptr );
app.ambient = SGCOLOR( 0.6f, 0.6f, 0.6f ); app.ambient = SGCOLOR( 0.6f, 0.6f, 0.6f );
app.diffuse = SGCOLOR( 0.6f, 0.6f, 0.6f ); app.diffuse = SGCOLOR( 0.6f, 0.6f, 0.6f );
app.specular = app.diffuse; app.specular = app.diffuse;
@ -494,10 +367,10 @@ S3DMODEL* S3D::GetModel( SCENEGRAPH* aNode )
materials.matorder.push_back( &app ); materials.matorder.push_back( &app );
materials.matmap.insert( std::pair< SGAPPEARANCE const*, int >( &app, 0 ) ); materials.matmap.insert( std::pair< SGAPPEARANCE const*, int >( &app, 0 ) );
if( aNode->Prepare( NULL, materials, meshes ) ) if( aNode->Prepare( nullptr, materials, meshes ) )
{ {
if( meshes.empty() ) if( meshes.empty() )
return NULL; return nullptr;
S3DMODEL* model = S3D::New3DModel(); S3DMODEL* model = S3D::New3DModel();
@ -529,35 +402,31 @@ S3DMODEL* S3D::GetModel( SCENEGRAPH* aNode )
for( size_t i = 0; i < j; ++i ) for( size_t i = 0; i < j; ++i )
S3D::Free3DMesh( meshes[i] ); S3D::Free3DMesh( meshes[i] );
return NULL; return nullptr;
} }
void S3D::Destroy3DModel( S3DMODEL** aModel ) void S3D::Destroy3DModel( S3DMODEL** aModel )
{ {
if( NULL == aModel || NULL == *aModel ) if( nullptr == aModel || nullptr == *aModel )
return; return;
S3DMODEL* m = *aModel; S3DMODEL* m = *aModel;
S3D::FREE_S3DMODEL( *m ); S3D::FREE_S3DMODEL( *m );
delete m; delete m;
*aModel = NULL; *aModel = nullptr;
return;
} }
void Free3DModel( S3DMODEL& aModel ) void Free3DModel( S3DMODEL& aModel )
{ {
S3D::FREE_S3DMODEL( aModel ); S3D::FREE_S3DMODEL( aModel );
return;
} }
void S3D::Free3DMesh( SMESH& aMesh ) void S3D::Free3DMesh( SMESH& aMesh )
{ {
S3D::FREE_SMESH( aMesh ); S3D::FREE_SMESH( aMesh );
return;
} }
@ -572,20 +441,17 @@ S3DMODEL* S3D::New3DModel( void )
void S3D::Init3DMaterial( SMATERIAL& aMat ) void S3D::Init3DMaterial( SMATERIAL& aMat )
{ {
S3D::INIT_SMATERIAL( aMat ); S3D::INIT_SMATERIAL( aMat );
return;
} }
void S3D::Init3DMesh( SMESH& aMesh ) void S3D::Init3DMesh( SMESH& aMesh )
{ {
S3D::INIT_SMESH( aMesh ); S3D::INIT_SMESH( aMesh );
return;
} }
void S3D::GetLibVersion( unsigned char* Major, unsigned char* Minor, void S3D::GetLibVersion( unsigned char* Major, unsigned char* Minor, unsigned char* Patch,
unsigned char* Patch, unsigned char* Revision ) noexcept unsigned char* Revision ) noexcept
{ {
if( Major ) if( Major )
*Major = KICADSG_VERSION_MAJOR; *Major = KICADSG_VERSION_MAJOR;
@ -598,8 +464,6 @@ void S3D::GetLibVersion( unsigned char* Major, unsigned char* Minor,
if( Patch ) if( Patch )
*Patch = KICADSG_VERSION_PATCH; *Patch = KICADSG_VERSION_PATCH;
return;
} }
@ -626,7 +490,7 @@ SGVECTOR S3D::CalcTriNorm( const SGPOINT& p1, const SGPOINT& p2, const SGPOINT&
S3D::SGTYPES S3D::GetSGNodeType( SGNODE* aNode ) S3D::SGTYPES S3D::GetSGNodeType( SGNODE* aNode )
{ {
if( NULL == aNode ) if( nullptr == aNode )
return SGTYPE_END; return SGTYPE_END;
return aNode->GetNodeType(); return aNode->GetNodeType();
@ -635,8 +499,8 @@ S3D::SGTYPES S3D::GetSGNodeType( SGNODE* aNode )
SGNODE* S3D::GetSGNodeParent( SGNODE* aNode ) SGNODE* S3D::GetSGNodeParent( SGNODE* aNode )
{ {
if( NULL == aNode ) if( nullptr == aNode )
return NULL; return nullptr;
return aNode->GetParent(); return aNode->GetParent();
} }
@ -644,7 +508,7 @@ SGNODE* S3D::GetSGNodeParent( SGNODE* aNode )
bool S3D::AddSGNodeRef( SGNODE* aParent, SGNODE* aChild ) bool S3D::AddSGNodeRef( SGNODE* aParent, SGNODE* aChild )
{ {
if( NULL == aParent || NULL == aChild ) if( nullptr == aParent || nullptr == aChild )
return false; return false;
return aParent->AddRefNode( aChild ); return aParent->AddRefNode( aChild );
@ -653,7 +517,7 @@ bool S3D::AddSGNodeRef( SGNODE* aParent, SGNODE* aChild )
bool S3D::AddSGNodeChild( SGNODE* aParent, SGNODE* aChild ) bool S3D::AddSGNodeChild( SGNODE* aParent, SGNODE* aChild )
{ {
if( NULL == aParent || NULL == aChild ) if( nullptr == aParent || nullptr == aChild )
return false; return false;
return aParent->AddChildNode( aChild ); return aParent->AddChildNode( aChild );
@ -662,10 +526,8 @@ bool S3D::AddSGNodeChild( SGNODE* aParent, SGNODE* aChild )
void S3D::AssociateSGNodeWrapper( SGNODE* aObject, SGNODE** aRefPtr ) void S3D::AssociateSGNodeWrapper( SGNODE* aObject, SGNODE** aRefPtr )
{ {
if( NULL == aObject || NULL == aRefPtr || aObject != *aRefPtr ) if( nullptr == aObject || nullptr == aRefPtr || aObject != *aRefPtr )
return; return;
aObject->AssociateWrapper( aRefPtr ); aObject->AssociateWrapper( aRefPtr );
return;
} }

View File

@ -2,6 +2,7 @@
* This program source code file is part of KiCad, a free EDA CAD application. * This program source code file is part of KiCad, a free EDA CAD application.
* *
* Copyright (C) 2015 Cirilo Bernardo <cirilo.bernardo@gmail.com> * Copyright (C) 2015 Cirilo Bernardo <cirilo.bernardo@gmail.com>
* Copyright (C) 2020 KiCad Developers, see AUTHORS.txt for contributors.
* *
* This program is free software; you can redistribute it and/or * This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License * modify it under the terms of the GNU General Public License
@ -29,55 +30,42 @@
#include "3d_cache/sg/sg_appearance.h" #include "3d_cache/sg/sg_appearance.h"
extern char BadObject[];
extern char BadOperand[];
extern char BadParent[]; extern char BadParent[];
extern char WrongParent[]; extern char WrongParent[];
IFSG_APPEARANCE::IFSG_APPEARANCE( bool create ) IFSG_APPEARANCE::IFSG_APPEARANCE( bool create )
{ {
m_node = NULL; m_node = nullptr;
if( !create ) if( !create )
return ; return ;
m_node = new SGAPPEARANCE( NULL ); m_node = new SGAPPEARANCE( nullptr );
if( m_node ) if( m_node )
m_node->AssociateWrapper( &m_node ); m_node->AssociateWrapper( &m_node );
return;
} }
IFSG_APPEARANCE::IFSG_APPEARANCE( SGNODE* aParent ) IFSG_APPEARANCE::IFSG_APPEARANCE( SGNODE* aParent )
{ {
m_node = new SGAPPEARANCE( NULL ); m_node = new SGAPPEARANCE( nullptr );
if( m_node ) if( m_node )
{ {
if( !m_node->SetParent( aParent ) ) if( !m_node->SetParent( aParent ) )
{ {
delete m_node; delete m_node;
m_node = NULL; m_node = nullptr;
#ifdef DEBUG wxLogTrace( MASK_3D_SG, "%s:%s:%d %s", __FILE__, __FUNCTION__, __LINE__, WrongParent );
do {
std::ostringstream ostr;
ostr << __FILE__ << ": " << __FUNCTION__ << ": " << __LINE__ << "\n";
ostr << WrongParent;
wxLogTrace( MASK_3D_SG, "%s\n", ostr.str().c_str() );
} while( 0 );
#endif
return; return;
} }
m_node->AssociateWrapper( &m_node ); m_node->AssociateWrapper( &m_node );
} }
return;
} }
@ -85,39 +73,29 @@ IFSG_APPEARANCE::IFSG_APPEARANCE( IFSG_NODE& aParent )
{ {
SGNODE* pp = aParent.GetRawPtr(); SGNODE* pp = aParent.GetRawPtr();
#ifdef DEBUG #ifdef DEBUG
if( ! pp ) if( ! pp )
{ {
std::ostringstream ostr; wxLogTrace( MASK_3D_SG, "%s:%s:%d %s", __FILE__, __FUNCTION__, __LINE__, BadParent );
ostr << __FILE__ << ": " << __FUNCTION__ << ": " << __LINE__ << "\n";
ostr << BadParent;
wxLogTrace( MASK_3D_SG, "%s\n", ostr.str().c_str() );
} }
#endif #endif
m_node = new SGAPPEARANCE( NULL ); m_node = new SGAPPEARANCE( nullptr );
if( m_node ) if( m_node )
{ {
if( !m_node->SetParent( pp ) ) if( !m_node->SetParent( pp ) )
{ {
delete m_node; delete m_node;
m_node = NULL; m_node = nullptr;
#ifdef DEBUG wxLogTrace( MASK_3D_SG, "%s:%s:%d %s", __FILE__, __FUNCTION__, __LINE__, WrongParent );
std::ostringstream ostr;
ostr << __FILE__ << ": " << __FUNCTION__ << ": " << __LINE__ << "\n";
ostr << WrongParent;
wxLogTrace( MASK_3D_SG, "%s\n", ostr.str().c_str() );
#endif
return; return;
} }
m_node->AssociateWrapper( &m_node ); m_node->AssociateWrapper( &m_node );
} }
return;
} }
@ -126,7 +104,7 @@ bool IFSG_APPEARANCE::Attach( SGNODE* aNode )
if( m_node ) if( m_node )
m_node->DisassociateWrapper( &m_node ); m_node->DisassociateWrapper( &m_node );
m_node = NULL; m_node = nullptr;
if( !aNode ) if( !aNode )
return false; return false;
@ -152,17 +130,12 @@ bool IFSG_APPEARANCE::NewNode( SGNODE* aParent )
if( aParent != m_node->GetParent() ) if( aParent != m_node->GetParent() )
{ {
#ifdef DEBUG wxLogTrace( MASK_3D_SG, "%s:%s:%d * [BUG] invalid SGNODE parent (%s) to SGAPPEARANCE",
std::ostringstream ostr; __FILE__, __FUNCTION__, __LINE__,
ostr << __FILE__ << ": " << __FUNCTION__ << ": " << __LINE__ << "\n"; aParent->GetNodeTypeName( aParent->GetNodeType() ) );
ostr << " * [BUG] invalid SGNODE parent (";
ostr << aParent->GetNodeTypeName( aParent->GetNodeType() );
ostr << ") to SGAPPEARANCE";
wxLogTrace( MASK_3D_SG, "%s\n", ostr.str().c_str() );
#endif
delete m_node; delete m_node;
m_node = NULL; m_node = nullptr;
return false; return false;
} }
@ -176,17 +149,7 @@ bool IFSG_APPEARANCE::NewNode( IFSG_NODE& aParent )
{ {
SGNODE* np = aParent.GetRawPtr(); SGNODE* np = aParent.GetRawPtr();
if( NULL == np ) wxCHECK( np, false );
{
#ifdef DEBUG
std::ostringstream ostr;
ostr << __FILE__ << ": " << __FUNCTION__ << ": " << __LINE__ << "\n";
ostr << BadParent;
wxLogTrace( MASK_3D_SG, "%s\n", ostr.str().c_str() );
#endif
return false;
}
return NewNode( np ); return NewNode( np );
} }
@ -194,247 +157,113 @@ bool IFSG_APPEARANCE::NewNode( IFSG_NODE& aParent )
bool IFSG_APPEARANCE::SetEmissive( float aRVal, float aGVal, float aBVal ) bool IFSG_APPEARANCE::SetEmissive( float aRVal, float aGVal, float aBVal )
{ {
if( NULL == m_node ) wxCHECK( m_node, false );
{
#ifdef DEBUG
std::ostringstream ostr;
ostr << __FILE__ << ": " << __FUNCTION__ << ": " << __LINE__ << "\n";
ostr << BadObject << "\n";
wxLogTrace( MASK_3D_SG, "%s\n", ostr.str().c_str() );
#endif
return false; return ( (SGAPPEARANCE*) m_node )->SetEmissive( aRVal, aGVal, aBVal );
}
return ((SGAPPEARANCE*)m_node)->SetEmissive( aRVal, aGVal, aBVal );
} }
bool IFSG_APPEARANCE::SetEmissive( const SGCOLOR* aRGBColor ) bool IFSG_APPEARANCE::SetEmissive( const SGCOLOR* aRGBColor )
{ {
if( NULL == m_node ) wxCHECK( m_node, false );
{
#ifdef DEBUG
std::ostringstream ostr;
ostr << __FILE__ << ": " << __FUNCTION__ << ": " << __LINE__ << "\n";
ostr << BadObject << "\n";
wxLogTrace( MASK_3D_SG, "%s\n", ostr.str().c_str() );
#endif
return false; return ( (SGAPPEARANCE*) m_node )->SetEmissive( aRGBColor );
}
return ((SGAPPEARANCE*)m_node)->SetEmissive( aRGBColor );
} }
bool IFSG_APPEARANCE::SetEmissive( const SGCOLOR& aRGBColor ) bool IFSG_APPEARANCE::SetEmissive( const SGCOLOR& aRGBColor )
{ {
if( NULL == m_node ) wxCHECK( m_node, false );
{
#ifdef DEBUG
std::ostringstream ostr;
ostr << __FILE__ << ": " << __FUNCTION__ << ": " << __LINE__ << "\n";
ostr << BadObject;
wxLogTrace( MASK_3D_SG, "%s\n", ostr.str().c_str() );
#endif
return false; return ( (SGAPPEARANCE*) m_node )->SetEmissive( aRGBColor );
}
return ((SGAPPEARANCE*)m_node)->SetEmissive( aRGBColor );
} }
bool IFSG_APPEARANCE::SetDiffuse( float aRVal, float aGVal, float aBVal ) bool IFSG_APPEARANCE::SetDiffuse( float aRVal, float aGVal, float aBVal )
{ {
if( NULL == m_node ) wxCHECK( m_node, false );
{
#ifdef DEBUG
std::ostringstream ostr;
ostr << __FILE__ << ": " << __FUNCTION__ << ": " << __LINE__ << "\n";
ostr << BadObject;
wxLogTrace( MASK_3D_SG, "%s\n", ostr.str().c_str() );
#endif
return false; return ( (SGAPPEARANCE*) m_node )->SetDiffuse( aRVal, aGVal, aBVal );
}
return ((SGAPPEARANCE*)m_node)->SetDiffuse( aRVal, aGVal, aBVal );
} }
bool IFSG_APPEARANCE::SetDiffuse( const SGCOLOR* aRGBColor ) bool IFSG_APPEARANCE::SetDiffuse( const SGCOLOR* aRGBColor )
{ {
if( NULL == m_node ) wxCHECK( m_node, false );
{
#ifdef DEBUG
std::ostringstream ostr;
ostr << __FILE__ << ": " << __FUNCTION__ << ": " << __LINE__ << "\n";
ostr << BadObject;
wxLogTrace( MASK_3D_SG, "%s\n", ostr.str().c_str() );
#endif
return false; return ( (SGAPPEARANCE*) m_node )->SetDiffuse( aRGBColor );
}
return ((SGAPPEARANCE*)m_node)->SetDiffuse( aRGBColor );
} }
bool IFSG_APPEARANCE::SetDiffuse( const SGCOLOR& aRGBColor ) bool IFSG_APPEARANCE::SetDiffuse( const SGCOLOR& aRGBColor )
{ {
if( NULL == m_node ) wxCHECK( m_node, false );
{
#ifdef DEBUG
std::ostringstream ostr;
ostr << __FILE__ << ": " << __FUNCTION__ << ": " << __LINE__ << "\n";
ostr << BadObject;
wxLogTrace( MASK_3D_SG, "%s\n", ostr.str().c_str() );
#endif
return false; return ( (SGAPPEARANCE*) m_node )->SetDiffuse( aRGBColor );
}
return ((SGAPPEARANCE*)m_node)->SetDiffuse( aRGBColor );
} }
bool IFSG_APPEARANCE::SetSpecular( float aRVal, float aGVal, float aBVal ) bool IFSG_APPEARANCE::SetSpecular( float aRVal, float aGVal, float aBVal )
{ {
if( NULL == m_node ) wxCHECK( m_node, false );
{
#ifdef DEBUG
std::ostringstream ostr;
ostr << __FILE__ << ": " << __FUNCTION__ << ": " << __LINE__ << "\n";
ostr << BadObject;
wxLogTrace( MASK_3D_SG, "%s\n", ostr.str().c_str() );
#endif
return false; return ( (SGAPPEARANCE*) m_node )->SetSpecular( aRVal, aGVal, aBVal );
}
return ((SGAPPEARANCE*)m_node)->SetSpecular( aRVal, aGVal, aBVal );
} }
bool IFSG_APPEARANCE::SetSpecular( const SGCOLOR* aRGBColor ) bool IFSG_APPEARANCE::SetSpecular( const SGCOLOR* aRGBColor )
{ {
if( NULL == m_node ) wxCHECK( m_node, false );
{
#ifdef DEBUG
std::ostringstream ostr;
ostr << __FILE__ << ": " << __FUNCTION__ << ": " << __LINE__ << "\n";
ostr << BadObject;
wxLogTrace( MASK_3D_SG, "%s\n", ostr.str().c_str() );
#endif
return false; return ( (SGAPPEARANCE*) m_node )->SetSpecular( aRGBColor );
}
return ((SGAPPEARANCE*)m_node)->SetSpecular( aRGBColor );
} }
bool IFSG_APPEARANCE::SetSpecular( const SGCOLOR& aRGBColor ) bool IFSG_APPEARANCE::SetSpecular( const SGCOLOR& aRGBColor )
{ {
if( NULL == m_node ) wxCHECK( m_node, false );
{
#ifdef DEBUG
std::ostringstream ostr;
ostr << __FILE__ << ": " << __FUNCTION__ << ": " << __LINE__ << "\n";
ostr << BadObject;
wxLogTrace( MASK_3D_SG, "%s\n", ostr.str().c_str() );
#endif
return false; return ( (SGAPPEARANCE*) m_node )->SetSpecular( aRGBColor );
}
return ((SGAPPEARANCE*)m_node)->SetSpecular( aRGBColor );
} }
bool IFSG_APPEARANCE::SetAmbient( float aRVal, float aGVal, float aBVal ) bool IFSG_APPEARANCE::SetAmbient( float aRVal, float aGVal, float aBVal )
{ {
if( NULL == m_node ) wxCHECK( m_node, false );
{
#ifdef DEBUG
std::ostringstream ostr;
ostr << __FILE__ << ": " << __FUNCTION__ << ": " << __LINE__ << "\n";
ostr << BadObject;
wxLogTrace( MASK_3D_SG, "%s\n", ostr.str().c_str() );
#endif
return false; return ( (SGAPPEARANCE*) m_node )->SetAmbient( aRVal, aGVal, aBVal );
}
return ((SGAPPEARANCE*)m_node)->SetAmbient( aRVal, aGVal, aBVal );
} }
bool IFSG_APPEARANCE::SetAmbient( const SGCOLOR* aRGBColor ) bool IFSG_APPEARANCE::SetAmbient( const SGCOLOR* aRGBColor )
{ {
if( NULL == m_node ) wxCHECK( m_node, false );
{
#ifdef DEBUG
std::ostringstream ostr;
ostr << __FILE__ << ": " << __FUNCTION__ << ": " << __LINE__ << "\n";
ostr << BadObject;
wxLogTrace( MASK_3D_SG, "%s\n", ostr.str().c_str() );
#endif
return false; return ( (SGAPPEARANCE*) m_node )->SetAmbient( aRGBColor );
}
return ((SGAPPEARANCE*)m_node)->SetAmbient( aRGBColor );
} }
bool IFSG_APPEARANCE::SetAmbient( const SGCOLOR& aRGBColor ) bool IFSG_APPEARANCE::SetAmbient( const SGCOLOR& aRGBColor )
{ {
if( NULL == m_node ) wxCHECK( m_node, false );
{
#ifdef DEBUG
std::ostringstream ostr;
ostr << __FILE__ << ": " << __FUNCTION__ << ": " << __LINE__ << "\n";
ostr << BadObject;
wxLogTrace( MASK_3D_SG, "%s\n", ostr.str().c_str() );
#endif
return false; return ( (SGAPPEARANCE*) m_node )->SetAmbient( aRGBColor );
}
return ((SGAPPEARANCE*)m_node)->SetAmbient( aRGBColor );
} }
bool IFSG_APPEARANCE::SetShininess( float aShininess ) noexcept bool IFSG_APPEARANCE::SetShininess( float aShininess ) noexcept
{ {
if( NULL == m_node ) wxCHECK( m_node, false );
{
#ifdef DEBUG
std::ostringstream ostr;
ostr << __FILE__ << ": " << __FUNCTION__ << ": " << __LINE__ << "\n";
ostr << BadObject;
wxLogTrace( MASK_3D_SG, "%s\n", ostr.str().c_str() );
#endif
return false;
}
if( aShininess < 0 || aShininess > 1.0 ) if( aShininess < 0 || aShininess > 1.0 )
{ {
#ifdef DEBUG wxLogTrace( MASK_3D_SG, "%s:%s:%d * [BUG] shininess out of range [0..1]",
std::ostringstream ostr; __FILE__, __FUNCTION__, __LINE__ );
ostr << __FILE__ << ": " << __FUNCTION__ << ": " << __LINE__ << "\n";
ostr << " * [BUG] shininess out of range [0..1]";
wxLogTrace( MASK_3D_SG, "%s\n", ostr.str().c_str() );
#endif
return false; return false;
} }
((SGAPPEARANCE*)m_node)->shininess = aShininess; ( (SGAPPEARANCE*) m_node )->shininess = aShininess;
return true; return true;
} }
@ -442,31 +271,17 @@ bool IFSG_APPEARANCE::SetShininess( float aShininess ) noexcept
bool IFSG_APPEARANCE::SetTransparency( float aTransparency ) noexcept bool IFSG_APPEARANCE::SetTransparency( float aTransparency ) noexcept
{ {
if( NULL == m_node ) wxCHECK( m_node, false );
{
#ifdef DEBUG
std::ostringstream ostr;
ostr << __FILE__ << ": " << __FUNCTION__ << ": " << __LINE__ << "\n";
ostr << BadObject;
wxLogTrace( MASK_3D_SG, "%s\n", ostr.str().c_str() );
#endif
return false;
}
if( aTransparency < 0 || aTransparency > 1.0 ) if( aTransparency < 0 || aTransparency > 1.0 )
{ {
#ifdef DEBUG wxLogTrace( MASK_3D_SG, "%s:%s:%d * [BUG] transparency out of range [0..1]",
std::ostringstream ostr; __FILE__, __FUNCTION__, __LINE__ );
ostr << __FILE__ << ": " << __FUNCTION__ << ": " << __LINE__ << "\n";
ostr << " * [BUG] transparency out of range [0..1]";
wxLogTrace( MASK_3D_SG, "%s\n", ostr.str().c_str() );
#endif
return false; return false;
} }
((SGAPPEARANCE*)m_node)->transparency = aTransparency; ( (SGAPPEARANCE*) m_node )->transparency = aTransparency;
return true; return true;
} }

View File

@ -2,6 +2,7 @@
* This program source code file is part of KiCad, a free EDA CAD application. * This program source code file is part of KiCad, a free EDA CAD application.
* *
* Copyright (C) 2015 Cirilo Bernardo <cirilo.bernardo@gmail.com> * Copyright (C) 2015 Cirilo Bernardo <cirilo.bernardo@gmail.com>
* Copyright (C) 2020 KiCad Developers, see AUTHORS.txt for contributors.
* *
* This program is free software; you can redistribute it and/or * This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License * modify it under the terms of the GNU General Public License
@ -29,52 +30,42 @@
#include "3d_cache/sg/sg_colors.h" #include "3d_cache/sg/sg_colors.h"
extern char BadObject[];
extern char BadParent[]; extern char BadParent[];
extern char WrongParent[]; extern char WrongParent[];
IFSG_COLORS::IFSG_COLORS( bool create ) IFSG_COLORS::IFSG_COLORS( bool create )
{ {
m_node = NULL; m_node = nullptr;
if( !create ) if( !create )
return ; return;
m_node = new SGCOLORS( NULL ); m_node = new SGCOLORS( nullptr );
if( m_node ) if( m_node )
m_node->AssociateWrapper( &m_node ); m_node->AssociateWrapper( &m_node );
return;
} }
IFSG_COLORS::IFSG_COLORS( SGNODE* aParent ) IFSG_COLORS::IFSG_COLORS( SGNODE* aParent )
{ {
m_node = new SGCOLORS( NULL ); m_node = new SGCOLORS( nullptr );
if( m_node ) if( m_node )
{ {
if( !m_node->SetParent( aParent ) ) if( !m_node->SetParent( aParent ) )
{ {
delete m_node; delete m_node;
m_node = NULL; m_node = nullptr;
#ifdef DEBUG wxLogTrace( MASK_3D_SG, "%s:%s:%d", __FILE__, __FUNCTION__, __LINE__ );
std::ostringstream ostr;
ostr << __FILE__ << ": " << __FUNCTION__ << ": " << __LINE__ << "\n";
ostr << WrongParent;
wxLogTrace( MASK_3D_SG, "%s\n", ostr.str().c_str() );
#endif
return; return;
} }
m_node->AssociateWrapper( &m_node ); m_node->AssociateWrapper( &m_node );
} }
return;
} }
@ -82,39 +73,28 @@ IFSG_COLORS::IFSG_COLORS( IFSG_NODE& aParent )
{ {
SGNODE* pp = aParent.GetRawPtr(); SGNODE* pp = aParent.GetRawPtr();
#ifdef DEBUG #ifdef DEBUG
if( ! pp ) if( !pp )
{ wxLogTrace( MASK_3D_SG, "%s:%s:%d %s", __FILE__, __FUNCTION__, __LINE__, BadParent );
std::ostringstream ostr; #endif
ostr << __FILE__ << ": " << __FUNCTION__ << ": " << __LINE__ << "\n";
ostr << BadParent;
wxLogTrace( MASK_3D_SG, "%s\n", ostr.str().c_str() );
}
#endif
m_node = new SGCOLORS( NULL ); m_node = new SGCOLORS( nullptr );
if( m_node ) if( m_node )
{ {
if( !m_node->SetParent( pp ) ) if( !m_node->SetParent( pp ) )
{ {
delete m_node; delete m_node;
m_node = NULL; m_node = nullptr;
#ifdef DEBUG wxLogTrace( MASK_3D_SG, "%s:%s:%d %s", __FILE__, __FUNCTION__, __LINE__,
std::ostringstream ostr; WrongParent );
ostr << __FILE__ << ": " << __FUNCTION__ << ": " << __LINE__ << "\n";
ostr << WrongParent;
wxLogTrace( MASK_3D_SG, "%s\n", ostr.str().c_str() );
#endif
return; return;
} }
m_node->AssociateWrapper( &m_node ); m_node->AssociateWrapper( &m_node );
} }
return;
} }
@ -123,7 +103,7 @@ bool IFSG_COLORS::Attach( SGNODE* aNode )
if( m_node ) if( m_node )
m_node->DisassociateWrapper( &m_node ); m_node->DisassociateWrapper( &m_node );
m_node = NULL; m_node = nullptr;
if( !aNode ) if( !aNode )
return false; return false;
@ -149,17 +129,12 @@ bool IFSG_COLORS::NewNode( SGNODE* aParent )
if( aParent != m_node->GetParent() ) if( aParent != m_node->GetParent() )
{ {
#ifdef DEBUG wxLogTrace( MASK_3D_SG, "%s:%s:%d * [BUG] invalid SGNODE parent (%s) to SGCOLORS",
std::ostringstream ostr; __FILE__, __FUNCTION__, __LINE__,
ostr << __FILE__ << ": " << __FUNCTION__ << ": " << __LINE__ << "\n"; aParent->GetNodeTypeName( aParent->GetNodeType() ) );
ostr << " * [BUG] invalid SGNODE parent (";
ostr << aParent->GetNodeTypeName( aParent->GetNodeType() );
ostr << ") to SGCOLORS";
wxLogTrace( MASK_3D_SG, "%s\n", ostr.str().c_str() );
#endif
delete m_node; delete m_node;
m_node = NULL; m_node = nullptr;
return false; return false;
} }
@ -173,17 +148,7 @@ bool IFSG_COLORS::NewNode( IFSG_NODE& aParent )
{ {
SGNODE* np = aParent.GetRawPtr(); SGNODE* np = aParent.GetRawPtr();
if( NULL == np ) wxCHECK( np, false );
{
#ifdef DEBUG
std::ostringstream ostr;
ostr << __FILE__ << ": " << __FUNCTION__ << ": " << __LINE__ << "\n";
ostr << BadParent;
wxLogTrace( MASK_3D_SG, "%s\n", ostr.str().c_str() );
#endif
return false;
}
return NewNode( np ); return NewNode( np );
} }
@ -191,37 +156,17 @@ bool IFSG_COLORS::NewNode( IFSG_NODE& aParent )
bool IFSG_COLORS::GetColorList( size_t& aListSize, SGCOLOR*& aColorList ) bool IFSG_COLORS::GetColorList( size_t& aListSize, SGCOLOR*& aColorList )
{ {
if( NULL == m_node ) wxCHECK( m_node, false );
{
#ifdef DEBUG
std::ostringstream ostr;
ostr << __FILE__ << ": " << __FUNCTION__ << ": " << __LINE__ << "\n";
ostr << BadObject;
wxLogTrace( MASK_3D_SG, "%s\n", ostr.str().c_str() );
#endif
return false; return ( (SGCOLORS*) m_node )->GetColorList( aListSize, aColorList );
}
return ((SGCOLORS*)m_node)->GetColorList( aListSize, aColorList );
} }
bool IFSG_COLORS::SetColorList( size_t aListSize, const SGCOLOR* aColorList ) bool IFSG_COLORS::SetColorList( size_t aListSize, const SGCOLOR* aColorList )
{ {
if( NULL == m_node ) wxCHECK( m_node, false );
{
#ifdef DEBUG
std::ostringstream ostr;
ostr << __FILE__ << ": " << __FUNCTION__ << ": " << __LINE__ << "\n";
ostr << BadObject;
wxLogTrace( MASK_3D_SG, "%s\n", ostr.str().c_str() );
#endif
return false; ( (SGCOLORS*) m_node )->SetColorList( aListSize, aColorList );
}
((SGCOLORS*)m_node)->SetColorList( aListSize, aColorList );
return true; return true;
} }
@ -229,19 +174,9 @@ bool IFSG_COLORS::SetColorList( size_t aListSize, const SGCOLOR* aColorList )
bool IFSG_COLORS::AddColor( double aRedValue, double aGreenValue, double aBlueValue ) bool IFSG_COLORS::AddColor( double aRedValue, double aGreenValue, double aBlueValue )
{ {
if( NULL == m_node ) wxCHECK( m_node, false );
{
#ifdef DEBUG
std::ostringstream ostr;
ostr << __FILE__ << ": " << __FUNCTION__ << ": " << __LINE__ << "\n";
ostr << BadObject;
wxLogTrace( MASK_3D_SG, "%s\n", ostr.str().c_str() );
#endif
return false; ( (SGCOLORS*) m_node )->AddColor( aRedValue, aGreenValue, aBlueValue );
}
((SGCOLORS*)m_node)->AddColor( aRedValue, aGreenValue, aBlueValue );
return true; return true;
} }
@ -249,19 +184,9 @@ bool IFSG_COLORS::AddColor( double aRedValue, double aGreenValue, double aBlueVa
bool IFSG_COLORS::AddColor( const SGCOLOR& aColor ) bool IFSG_COLORS::AddColor( const SGCOLOR& aColor )
{ {
if( NULL == m_node ) wxCHECK( m_node, false );
{
#ifdef DEBUG
std::ostringstream ostr;
ostr << __FILE__ << ": " << __FUNCTION__ << ": " << __LINE__ << "\n";
ostr << BadObject;
wxLogTrace( MASK_3D_SG, "%s\n", ostr.str().c_str() );
#endif
return false; ( (SGCOLORS*) m_node )->AddColor( aColor );
}
((SGCOLORS*)m_node)->AddColor( aColor );
return true; return true;
} }

View File

@ -2,6 +2,7 @@
* This program source code file is part of KiCad, a free EDA CAD application. * This program source code file is part of KiCad, a free EDA CAD application.
* *
* Copyright (C) 2015 Cirilo Bernardo <cirilo.bernardo@gmail.com> * Copyright (C) 2015 Cirilo Bernardo <cirilo.bernardo@gmail.com>
* Copyright (C) 2020 KiCad Developers, see AUTHORS.txt for contributors.
* *
* This program is free software; you can redistribute it and/or * This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License * modify it under the terms of the GNU General Public License
@ -30,50 +31,39 @@
#include "3d_cache/sg/sg_coordindex.h" #include "3d_cache/sg/sg_coordindex.h"
extern char BadObject[];
extern char BadOperand[];
extern char BadParent[]; extern char BadParent[];
extern char WrongParent[]; extern char WrongParent[];
IFSG_COORDINDEX::IFSG_COORDINDEX( bool create ) IFSG_COORDINDEX::IFSG_COORDINDEX( bool create )
{ {
m_node = NULL; m_node = nullptr;
if( !create ) if( !create )
return; return;
m_node = new SGCOORDINDEX( NULL ); m_node = new SGCOORDINDEX( nullptr );
if( m_node ) if( m_node )
m_node->AssociateWrapper( &m_node ); m_node->AssociateWrapper( &m_node );
return;
} }
IFSG_COORDINDEX::IFSG_COORDINDEX( SGNODE* aParent ) IFSG_COORDINDEX::IFSG_COORDINDEX( SGNODE* aParent )
{ {
m_node = new SGCOORDINDEX( NULL ); m_node = new SGCOORDINDEX( nullptr );
if( !m_node->SetParent( aParent ) ) if( !m_node->SetParent( aParent ) )
{ {
delete m_node; delete m_node;
m_node = NULL; m_node = nullptr;
#ifdef DEBUG wxLogTrace( MASK_3D_SG, "%s:%s:%d %s", __FILE__, __FUNCTION__, __LINE__, WrongParent );
std::ostringstream ostr;
ostr << __FILE__ << ": " << __FUNCTION__ << ": " << __LINE__ << "\n";
ostr << WrongParent;
wxLogTrace( MASK_3D_SG, "%s\n", ostr.str().c_str() );
#endif
return; return;
} }
m_node->AssociateWrapper( &m_node ); m_node->AssociateWrapper( &m_node );
return;
} }
@ -83,35 +73,23 @@ IFSG_COORDINDEX::IFSG_COORDINDEX( IFSG_NODE& aParent )
if( !pp ) if( !pp )
{ {
#ifdef DEBUG wxLogTrace( MASK_3D_SG, "%s:%s:%d %s", __FILE__, __FUNCTION__, __LINE__, BadParent );
std::ostringstream ostr;
ostr << __FILE__ << ": " << __FUNCTION__ << ": " << __LINE__ << "\n";
ostr << BadParent;
wxLogTrace( MASK_3D_SG, "%s\n", ostr.str().c_str() );
#endif
return; return;
} }
m_node = new SGCOORDINDEX( NULL ); m_node = new SGCOORDINDEX( nullptr );
if( !m_node->SetParent( pp ) ) if( !m_node->SetParent( pp ) )
{ {
#ifdef DEBUG wxLogTrace( MASK_3D_SG, "%s:%s:%d %s", __FILE__, __FUNCTION__, __LINE__, WrongParent );
std::ostringstream ostr;
ostr << __FILE__ << ": " << __FUNCTION__ << ": " << __LINE__ << "\n";
ostr << WrongParent;
wxLogTrace( MASK_3D_SG, "%s\n", ostr.str().c_str() );
#endif
delete m_node; delete m_node;
m_node = NULL; m_node = nullptr;
return; return;
} }
m_node->AssociateWrapper( &m_node ); m_node->AssociateWrapper( &m_node );
return;
} }
@ -120,7 +98,7 @@ bool IFSG_COORDINDEX::Attach( SGNODE* aNode )
if( m_node ) if( m_node )
m_node->DisassociateWrapper( &m_node ); m_node->DisassociateWrapper( &m_node );
m_node = NULL; m_node = nullptr;
if( !aNode ) if( !aNode )
return false; return false;
@ -146,17 +124,12 @@ bool IFSG_COORDINDEX::NewNode( SGNODE* aParent )
if( aParent != m_node->GetParent() ) if( aParent != m_node->GetParent() )
{ {
#ifdef DEBUG wxLogTrace( MASK_3D_SG, "%s:%s:%d * [BUG] invalid SGNODE parent (%s) to SGCOORDINDEX",
std::ostringstream ostr; __FILE__, __FUNCTION__, __LINE__,
ostr << __FILE__ << ": " << __FUNCTION__ << ": " << __LINE__ << "\n"; aParent->GetNodeTypeName( aParent->GetNodeType() ) );
ostr << " * [BUG] invalid SGNODE parent (";
ostr << aParent->GetNodeTypeName( aParent->GetNodeType() );
ostr << ") to SGCOORDINDEX";
wxLogTrace( MASK_3D_SG, "%s\n", ostr.str().c_str() );
#endif
delete m_node; delete m_node;
m_node = NULL; m_node = nullptr;
return false; return false;
} }
@ -170,17 +143,7 @@ bool IFSG_COORDINDEX::NewNode( IFSG_NODE& aParent )
{ {
SGNODE* np = aParent.GetRawPtr(); SGNODE* np = aParent.GetRawPtr();
if( NULL == np ) wxCHECK( np, false );
{
#ifdef DEBUG
std::ostringstream ostr;
ostr << __FILE__ << ": " << __FUNCTION__ << ": " << __LINE__ << "\n";
ostr << BadParent;
wxLogTrace( MASK_3D_SG, "%s\n", ostr.str().c_str() );
#endif
return false;
}
return NewNode( np ); return NewNode( np );
} }

View File

@ -2,6 +2,7 @@
* This program source code file is part of KiCad, a free EDA CAD application. * This program source code file is part of KiCad, a free EDA CAD application.
* *
* Copyright (C) 2015 Cirilo Bernardo <cirilo.bernardo@gmail.com> * Copyright (C) 2015 Cirilo Bernardo <cirilo.bernardo@gmail.com>
* Copyright (C) 2020 KiCad Developers, see AUTHORS.txt for contributors.
* *
* This program is free software; you can redistribute it and/or * This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License * modify it under the terms of the GNU General Public License
@ -29,52 +30,42 @@
#include "3d_cache/sg/sg_coords.h" #include "3d_cache/sg/sg_coords.h"
extern char BadObject[];
extern char BadParent[]; extern char BadParent[];
extern char WrongParent[]; extern char WrongParent[];
IFSG_COORDS::IFSG_COORDS( bool create ) IFSG_COORDS::IFSG_COORDS( bool create )
{ {
m_node = NULL; m_node = nullptr;
if( !create ) if( !create )
return ; return ;
m_node = new SGCOORDS( NULL ); m_node = new SGCOORDS( nullptr );
if( m_node ) if( m_node )
m_node->AssociateWrapper( &m_node ); m_node->AssociateWrapper( &m_node );
return;
} }
IFSG_COORDS::IFSG_COORDS( SGNODE* aParent ) IFSG_COORDS::IFSG_COORDS( SGNODE* aParent )
{ {
m_node = new SGCOORDS( NULL ); m_node = new SGCOORDS( nullptr );
if( m_node ) if( m_node )
{ {
if( !m_node->SetParent( aParent ) ) if( !m_node->SetParent( aParent ) )
{ {
delete m_node; delete m_node;
m_node = NULL; m_node = nullptr;
#ifdef DEBUG wxLogTrace( MASK_3D_SG, "%s:%s:%d %s", __FILE__, __FUNCTION__, __LINE__, WrongParent );
std::ostringstream ostr;
ostr << __FILE__ << ": " << __FUNCTION__ << ": " << __LINE__ << "\n";
ostr << WrongParent;
wxLogTrace( MASK_3D_SG, "%s\n", ostr.str().c_str() );
#endif
return; return;
} }
m_node->AssociateWrapper( &m_node ); m_node->AssociateWrapper( &m_node );
} }
return;
} }
@ -82,39 +73,29 @@ IFSG_COORDS::IFSG_COORDS( IFSG_NODE& aParent )
{ {
SGNODE* pp = aParent.GetRawPtr(); SGNODE* pp = aParent.GetRawPtr();
#ifdef DEBUG #ifdef DEBUG
if( ! pp ) if( !pp )
{ {
std::ostringstream ostr; wxLogTrace( MASK_3D_SG, "%s:%s:%d %s", __FILE__, __FUNCTION__, __LINE__, BadParent );
ostr << __FILE__ << ": " << __FUNCTION__ << ": " << __LINE__ << "\n";
ostr << BadParent;
wxLogTrace( MASK_3D_SG, "%s\n", ostr.str().c_str() );
} }
#endif #endif
m_node = new SGCOORDS( NULL ); m_node = new SGCOORDS( nullptr );
if( m_node ) if( m_node )
{ {
if( !m_node->SetParent( pp ) ) if( !m_node->SetParent( pp ) )
{ {
delete m_node; delete m_node;
m_node = NULL; m_node = nullptr;
#ifdef DEBUG wxLogTrace( MASK_3D_SG, "%s:%s:%d %s", __FILE__, __FUNCTION__, __LINE__, WrongParent );
std::ostringstream ostr;
ostr << __FILE__ << ": " << __FUNCTION__ << ": " << __LINE__ << "\n";
ostr << WrongParent;
wxLogTrace( MASK_3D_SG, "%s\n", ostr.str().c_str() );
#endif
return; return;
} }
m_node->AssociateWrapper( &m_node ); m_node->AssociateWrapper( &m_node );
} }
return;
} }
@ -123,7 +104,7 @@ bool IFSG_COORDS::Attach( SGNODE* aNode )
if( m_node ) if( m_node )
m_node->DisassociateWrapper( &m_node ); m_node->DisassociateWrapper( &m_node );
m_node = NULL; m_node = nullptr;
if( !aNode ) if( !aNode )
return false; return false;
@ -149,17 +130,12 @@ bool IFSG_COORDS::NewNode( SGNODE* aParent )
if( aParent != m_node->GetParent() ) if( aParent != m_node->GetParent() )
{ {
#ifdef DEBUG wxLogTrace( MASK_3D_SG, "%s:%s:%d * [BUG] invalid SGNODE parent (%s) to SGCOORDS",
std::ostringstream ostr; __FILE__, __FUNCTION__, __LINE__,
ostr << __FILE__ << ": " << __FUNCTION__ << ": " << __LINE__ << "\n"; aParent->GetNodeTypeName( aParent->GetNodeType() ) );
ostr << " * [BUG] invalid SGNODE parent (";
ostr << aParent->GetNodeTypeName( aParent->GetNodeType() );
ostr << ") to SGCOORDS";
wxLogTrace( MASK_3D_SG, "%s\n", ostr.str().c_str() );
#endif
delete m_node; delete m_node;
m_node = NULL; m_node = nullptr;
return false; return false;
} }
@ -173,17 +149,7 @@ bool IFSG_COORDS::NewNode( IFSG_NODE& aParent )
{ {
SGNODE* np = aParent.GetRawPtr(); SGNODE* np = aParent.GetRawPtr();
if( NULL == np ) wxCHECK( np, false );
{
#ifdef DEBUG
std::ostringstream ostr;
ostr << __FILE__ << ": " << __FUNCTION__ << ": " << __LINE__ << "\n";
ostr << BadParent;
wxLogTrace( MASK_3D_SG, "%s\n", ostr.str().c_str() );
#endif
return false;
}
return NewNode( np ); return NewNode( np );
} }
@ -191,37 +157,17 @@ bool IFSG_COORDS::NewNode( IFSG_NODE& aParent )
bool IFSG_COORDS::GetCoordsList( size_t& aListSize, SGPOINT*& aCoordsList ) bool IFSG_COORDS::GetCoordsList( size_t& aListSize, SGPOINT*& aCoordsList )
{ {
if( NULL == m_node ) wxCHECK( m_node, false );
{
#ifdef DEBUG
std::ostringstream ostr;
ostr << __FILE__ << ": " << __FUNCTION__ << ": " << __LINE__ << "\n";
ostr << BadObject;
wxLogTrace( MASK_3D_SG, "%s\n", ostr.str().c_str() );
#endif
return false; return ( (SGCOORDS*) m_node )->GetCoordsList( aListSize, aCoordsList );
}
return ((SGCOORDS*)m_node)->GetCoordsList( aListSize, aCoordsList );
} }
bool IFSG_COORDS::SetCoordsList( size_t aListSize, const SGPOINT* aCoordsList ) bool IFSG_COORDS::SetCoordsList( size_t aListSize, const SGPOINT* aCoordsList )
{ {
if( NULL == m_node ) wxCHECK( m_node, false );
{
#ifdef DEBUG
std::ostringstream ostr;
ostr << __FILE__ << ": " << __FUNCTION__ << ": " << __LINE__ << "\n";
ostr << BadObject;
wxLogTrace( MASK_3D_SG, "%s\n", ostr.str().c_str() );
#endif
return false; ( (SGCOORDS*) m_node )->SetCoordsList( aListSize, aCoordsList );
}
((SGCOORDS*)m_node)->SetCoordsList( aListSize, aCoordsList );
return true; return true;
} }
@ -229,19 +175,9 @@ bool IFSG_COORDS::SetCoordsList( size_t aListSize, const SGPOINT* aCoordsList )
bool IFSG_COORDS::AddCoord( double aXValue, double aYValue, double aZValue ) bool IFSG_COORDS::AddCoord( double aXValue, double aYValue, double aZValue )
{ {
if( NULL == m_node ) wxCHECK( m_node, false );
{
#ifdef DEBUG
std::ostringstream ostr;
ostr << __FILE__ << ": " << __FUNCTION__ << ": " << __LINE__ << "\n";
ostr << BadObject;
wxLogTrace( MASK_3D_SG, "%s\n", ostr.str().c_str() );
#endif
return false; ( (SGCOORDS*) m_node )->AddCoord( aXValue, aYValue, aZValue );
}
((SGCOORDS*)m_node)->AddCoord( aXValue, aYValue, aZValue );
return true; return true;
} }
@ -249,19 +185,9 @@ bool IFSG_COORDS::AddCoord( double aXValue, double aYValue, double aZValue )
bool IFSG_COORDS::AddCoord( const SGPOINT& aPoint ) bool IFSG_COORDS::AddCoord( const SGPOINT& aPoint )
{ {
if( NULL == m_node ) wxCHECK( m_node, false );
{
#ifdef DEBUG
std::ostringstream ostr;
ostr << __FILE__ << ": " << __FUNCTION__ << ": " << __LINE__ << "\n";
ostr << BadObject;
wxLogTrace( MASK_3D_SG, "%s\n", ostr.str().c_str() );
#endif
return false; ( (SGCOORDS*) m_node )->AddCoord( aPoint );
}
((SGCOORDS*)m_node)->AddCoord( aPoint );
return true; return true;
} }

View File

@ -2,6 +2,7 @@
* This program source code file is part of KiCad, a free EDA CAD application. * This program source code file is part of KiCad, a free EDA CAD application.
* *
* Copyright (C) 2015 Cirilo Bernardo <cirilo.bernardo@gmail.com> * Copyright (C) 2015 Cirilo Bernardo <cirilo.bernardo@gmail.com>
* Copyright (C) 2020 KiCad Developers, see AUTHORS.txt for contributors.
* *
* This program is free software; you can redistribute it and/or * This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License * modify it under the terms of the GNU General Public License
@ -30,52 +31,42 @@
#include "3d_cache/sg/sg_faceset.h" #include "3d_cache/sg/sg_faceset.h"
extern char BadObject[];
extern char BadParent[]; extern char BadParent[];
extern char WrongParent[]; extern char WrongParent[];
IFSG_FACESET::IFSG_FACESET( bool create ) IFSG_FACESET::IFSG_FACESET( bool create )
{ {
m_node = NULL; m_node = nullptr;
if( !create ) if( !create )
return ; return ;
m_node = new SGFACESET( NULL ); m_node = new SGFACESET( nullptr );
if( m_node ) if( m_node )
m_node->AssociateWrapper( &m_node ); m_node->AssociateWrapper( &m_node );
return;
} }
IFSG_FACESET::IFSG_FACESET( SGNODE* aParent ) IFSG_FACESET::IFSG_FACESET( SGNODE* aParent )
{ {
m_node = new SGFACESET( NULL ); m_node = new SGFACESET( nullptr );
if( m_node ) if( m_node )
{ {
if( !m_node->SetParent( aParent ) ) if( !m_node->SetParent( aParent ) )
{ {
delete m_node; delete m_node;
m_node = NULL; m_node = nullptr;
#ifdef DEBUG wxLogTrace( MASK_3D_SG, "%s:%s:%d %s", __FILE__, __FUNCTION__, __LINE__, WrongParent );
std::ostringstream ostr;
ostr << __FILE__ << ": " << __FUNCTION__ << ": " << __LINE__ << "\n";
ostr << WrongParent;
wxLogTrace( MASK_3D_SG, "%s\n", ostr.str().c_str() );
#endif
return; return;
} }
m_node->AssociateWrapper( &m_node ); m_node->AssociateWrapper( &m_node );
} }
return;
} }
@ -83,39 +74,29 @@ IFSG_FACESET::IFSG_FACESET( IFSG_NODE& aParent )
{ {
SGNODE* pp = aParent.GetRawPtr(); SGNODE* pp = aParent.GetRawPtr();
#ifdef DEBUG #ifdef DEBUG
if( ! pp ) if( ! pp )
{ {
std::ostringstream ostr; wxLogTrace( MASK_3D_SG, "%s:%s:%d %s", __FILE__, __FUNCTION__, __LINE__, BadParent );
ostr << __FILE__ << ": " << __FUNCTION__ << ": " << __LINE__ << "\n";
ostr << BadParent;
wxLogTrace( MASK_3D_SG, "%s\n", ostr.str().c_str() );
} }
#endif #endif
m_node = new SGFACESET( NULL ); m_node = new SGFACESET( nullptr );
if( m_node ) if( m_node )
{ {
if( !m_node->SetParent( pp ) ) if( !m_node->SetParent( pp ) )
{ {
delete m_node; delete m_node;
m_node = NULL; m_node = nullptr;
#ifdef DEBUG wxLogTrace( MASK_3D_SG, "%s:%s:%d %s", __FILE__, __FUNCTION__, __LINE__, WrongParent );
std::ostringstream ostr;
ostr << __FILE__ << ": " << __FUNCTION__ << ": " << __LINE__ << "\n";
ostr << WrongParent;
wxLogTrace( MASK_3D_SG, "%s\n", ostr.str().c_str() );
#endif
return; return;
} }
m_node->AssociateWrapper( &m_node ); m_node->AssociateWrapper( &m_node );
} }
return;
} }
@ -124,7 +105,7 @@ bool IFSG_FACESET::Attach( SGNODE* aNode )
if( m_node ) if( m_node )
m_node->DisassociateWrapper( &m_node ); m_node->DisassociateWrapper( &m_node );
m_node = NULL; m_node = nullptr;
if( !aNode ) if( !aNode )
return false; return false;
@ -150,17 +131,12 @@ bool IFSG_FACESET::NewNode( SGNODE* aParent )
if( aParent != m_node->GetParent() ) if( aParent != m_node->GetParent() )
{ {
#ifdef DEBUG wxLogTrace( MASK_3D_SG, "%s:%s:%d * [BUG] invalid SGNODE parent (%s) to SGFACESET",
std::ostringstream ostr; __FILE__, __FUNCTION__, __LINE__,
ostr << __FILE__ << ": " << __FUNCTION__ << ": " << __LINE__ << "\n"; aParent->GetNodeTypeName( aParent->GetNodeType() ) );
ostr << " * [BUG] invalid SGNODE parent (";
ostr << aParent->GetNodeTypeName( aParent->GetNodeType() );
ostr << ") to SGFACESET";
wxLogTrace( MASK_3D_SG, "%s\n", ostr.str().c_str() );
#endif
delete m_node; delete m_node;
m_node = NULL; m_node = nullptr;
return false; return false;
} }
@ -174,17 +150,7 @@ bool IFSG_FACESET::NewNode( IFSG_NODE& aParent )
{ {
SGNODE* np = aParent.GetRawPtr(); SGNODE* np = aParent.GetRawPtr();
if( NULL == np ) wxCHECK( np, false );
{
#ifdef DEBUG
std::ostringstream ostr;
ostr << __FILE__ << ": " << __FUNCTION__ << ": " << __LINE__ << "\n";
ostr << BadParent;
wxLogTrace( MASK_3D_SG, "%s\n", ostr.str().c_str() );
#endif
return false;
}
return NewNode( np ); return NewNode( np );
} }
@ -193,7 +159,7 @@ bool IFSG_FACESET::NewNode( IFSG_NODE& aParent )
bool IFSG_FACESET::CalcNormals( SGNODE** aPtr ) bool IFSG_FACESET::CalcNormals( SGNODE** aPtr )
{ {
if( m_node ) if( m_node )
return ((SGFACESET*)m_node)->CalcNormals( aPtr ); return ( (SGFACESET*) m_node )->CalcNormals( aPtr );
return false; return false;
} }

View File

@ -2,6 +2,7 @@
* This program source code file is part of KiCad, a free EDA CAD application. * This program source code file is part of KiCad, a free EDA CAD application.
* *
* Copyright (C) 2015 Cirilo Bernardo <cirilo.bernardo@gmail.com> * Copyright (C) 2015 Cirilo Bernardo <cirilo.bernardo@gmail.com>
* Copyright (C) 2020 KiCad Developers, see AUTHORS.txt for contributors.
* *
* This program is free software; you can redistribute it and/or * This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License * modify it under the terms of the GNU General Public License
@ -30,51 +31,24 @@
#include "3d_cache/sg/sg_coordindex.h" #include "3d_cache/sg/sg_coordindex.h"
extern char BadObject[];
extern char BadOperand[];
extern char BadParent[];
extern char WrongParent[];
IFSG_INDEX::IFSG_INDEX() : IFSG_NODE() IFSG_INDEX::IFSG_INDEX() : IFSG_NODE()
{ {
return;
} }
bool IFSG_INDEX::GetIndices( size_t& nIndices, int*& aIndexList ) bool IFSG_INDEX::GetIndices( size_t& nIndices, int*& aIndexList )
{ {
if( NULL == m_node ) wxCHECK( m_node, false );
{
#ifdef DEBUG
std::ostringstream ostr;
ostr << __FILE__ << ": " << __FUNCTION__ << ": " << __LINE__ << "\n";
ostr << BadObject;
wxLogTrace( MASK_3D_SG, "%s\n", ostr.str().c_str() );
#endif
return false; return ( (SGINDEX*) m_node )->GetIndices( nIndices, aIndexList );
}
return ((SGINDEX*)m_node)->GetIndices( nIndices, aIndexList );
} }
bool IFSG_INDEX::SetIndices( size_t nIndices, int* aIndexList ) bool IFSG_INDEX::SetIndices( size_t nIndices, int* aIndexList )
{ {
if( NULL == m_node ) wxCHECK( m_node, false );
{
#ifdef DEBUG
std::ostringstream ostr;
ostr << __FILE__ << ": " << __FUNCTION__ << ": " << __LINE__ << "\n";
ostr << BadObject;
wxLogTrace( MASK_3D_SG, "%s\n", ostr.str().c_str() );
#endif
return false; ( (SGINDEX*) m_node )->SetIndices( nIndices, aIndexList );
}
((SGINDEX*)m_node)->SetIndices( nIndices, aIndexList );
return true; return true;
} }
@ -82,19 +56,9 @@ bool IFSG_INDEX::SetIndices( size_t nIndices, int* aIndexList )
bool IFSG_INDEX::AddIndex( int aIndex ) bool IFSG_INDEX::AddIndex( int aIndex )
{ {
if( NULL == m_node ) wxCHECK( m_node, false );
{
#ifdef DEBUG
std::ostringstream ostr;
ostr << __FILE__ << ": " << __FUNCTION__ << ": " << __LINE__ << "\n";
ostr << BadObject;
wxLogTrace( MASK_3D_SG, "%s\n", ostr.str().c_str() );
#endif
return false; ( (SGINDEX*) m_node )->AddIndex( aIndex );
}
((SGINDEX*)m_node)->AddIndex( aIndex );
return true; return true;
} }

View File

@ -2,6 +2,7 @@
* This program source code file is part of KiCad, a free EDA CAD application. * This program source code file is part of KiCad, a free EDA CAD application.
* *
* Copyright (C) 2015 Cirilo Bernardo <cirilo.bernardo@gmail.com> * Copyright (C) 2015 Cirilo Bernardo <cirilo.bernardo@gmail.com>
* Copyright (C) 2020 KiCad Developers, see AUTHORS.txt for contributors.
* *
* This program is free software; you can redistribute it and/or * This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License * modify it under the terms of the GNU General Public License
@ -30,15 +31,17 @@
#include "3d_cache/sg/sg_node.h" #include "3d_cache/sg/sg_node.h"
#include "plugins/3dapi/ifsg_api.h" #include "plugins/3dapi/ifsg_api.h"
// collection of common error strings used by the wrappers // collection of common error strings used by the wrappers
char BadObject[] = " * [BUG] operating on an invalid wrapper (object may have been deleted)"; char BadObject[] = " * [BUG] operating on an invalid wrapper (object may have been deleted)";
char BadOperand[] = " * [BUG] parameter aNode is an invalid wrapper; its data may have been deleted"; char BadOperand[] = " * [BUG] parameter aNode is an invalid wrapper; its data may have been deleted";
char BadParent[] = " * [BUG] invalid parent node (data may have been deleted)"; char BadParent[] = " * [BUG] invalid parent node (data may have been deleted)";
char WrongParent[] = " * [BUG] parent node type is incompatible"; char WrongParent[] = " * [BUG] parent node type is incompatible";
IFSG_NODE::IFSG_NODE() IFSG_NODE::IFSG_NODE()
{ {
m_node = NULL; m_node = nullptr;
} }
@ -46,8 +49,6 @@ IFSG_NODE::~IFSG_NODE()
{ {
if( m_node ) if( m_node )
m_node->DisassociateWrapper( &m_node ); m_node->DisassociateWrapper( &m_node );
return;
} }
@ -57,9 +58,7 @@ void IFSG_NODE::Destroy( void )
m_node->DisassociateWrapper( &m_node ); m_node->DisassociateWrapper( &m_node );
delete m_node; delete m_node;
m_node = NULL; m_node = nullptr;
return;
} }
@ -71,17 +70,7 @@ SGNODE* IFSG_NODE::GetRawPtr( void ) noexcept
S3D::SGTYPES IFSG_NODE::GetNodeType( void ) const S3D::SGTYPES IFSG_NODE::GetNodeType( void ) const
{ {
if( NULL == m_node ) wxCHECK( m_node, S3D::SGTYPE_END );
{
#ifdef DEBUG
std::ostringstream ostr;
ostr << __FILE__ << ": " << __FUNCTION__ << ": " << __LINE__ << "\n";
ostr << BadObject;
wxLogTrace( MASK_3D_SG, "%s\n", ostr.str().c_str() );
#endif
return S3D::SGTYPE_END;
}
return m_node->GetNodeType(); return m_node->GetNodeType();
} }
@ -89,17 +78,7 @@ S3D::SGTYPES IFSG_NODE::GetNodeType( void ) const
SGNODE* IFSG_NODE::GetParent( void ) const SGNODE* IFSG_NODE::GetParent( void ) const
{ {
if( NULL == m_node ) wxCHECK( m_node, nullptr );
{
#ifdef DEBUG
std::ostringstream ostr;
ostr << __FILE__ << ": " << __FUNCTION__ << ": " << __LINE__ << "\n";
ostr << BadObject;
wxLogTrace( MASK_3D_SG, "%s\n", ostr.str().c_str() );
#endif
return NULL;
}
return m_node->GetParent(); return m_node->GetParent();
} }
@ -107,17 +86,7 @@ SGNODE* IFSG_NODE::GetParent( void ) const
bool IFSG_NODE::SetParent( SGNODE* aParent ) bool IFSG_NODE::SetParent( SGNODE* aParent )
{ {
if( NULL == m_node ) wxCHECK( m_node, false );
{
#ifdef DEBUG
std::ostringstream ostr;
ostr << __FILE__ << ": " << __FUNCTION__ << ": " << __LINE__ << "\n";
ostr << BadObject;
wxLogTrace( MASK_3D_SG, "%s\n", ostr.str().c_str() );
#endif
return false;
}
return m_node->SetParent( aParent ); return m_node->SetParent( aParent );
} }
@ -125,90 +94,40 @@ bool IFSG_NODE::SetParent( SGNODE* aParent )
const char* IFSG_NODE::GetName( void ) const char* IFSG_NODE::GetName( void )
{ {
if( NULL == m_node ) wxCHECK( m_node, nullptr );
{
#ifdef DEBUG
std::ostringstream ostr;
ostr << __FILE__ << ": " << __FUNCTION__ << ": " << __LINE__ << "\n";
ostr << BadObject;
wxLogTrace( MASK_3D_SG, "%s\n", ostr.str().c_str() );
#endif
return NULL;
}
return m_node->GetName(); return m_node->GetName();
} }
bool IFSG_NODE::SetName( const char *aName ) bool IFSG_NODE::SetName( const char* aName )
{ {
if( NULL == m_node ) wxCHECK( m_node, false );
{
#ifdef DEBUG
std::ostringstream ostr;
ostr << __FILE__ << ": " << __FUNCTION__ << ": " << __LINE__ << "\n";
ostr << BadObject;
wxLogTrace( MASK_3D_SG, "%s\n", ostr.str().c_str() );
#endif
return false;
}
m_node->SetName( aName ); m_node->SetName( aName );
return true; return true;
} }
const char * IFSG_NODE::GetNodeTypeName( S3D::SGTYPES aNodeType ) const const char* IFSG_NODE::GetNodeTypeName( S3D::SGTYPES aNodeType ) const
{ {
if( NULL == m_node ) wxCHECK( m_node, nullptr );
{
#ifdef DEBUG
std::ostringstream ostr;
ostr << __FILE__ << ": " << __FUNCTION__ << ": " << __LINE__ << "\n";
ostr << BadObject;
wxLogTrace( MASK_3D_SG, "%s\n", ostr.str().c_str() );
#endif
return NULL;
}
return m_node->GetNodeTypeName( aNodeType ); return m_node->GetNodeTypeName( aNodeType );
} }
SGNODE* IFSG_NODE::FindNode( const char *aNodeName ) SGNODE* IFSG_NODE::FindNode( const char* aNodeName )
{ {
if( NULL == m_node ) wxCHECK( m_node, nullptr );
{
#ifdef DEBUG
std::ostringstream ostr;
ostr << __FILE__ << ": " << __FUNCTION__ << ": " << __LINE__ << "\n";
ostr << BadObject;
wxLogTrace( MASK_3D_SG, "%s\n", ostr.str().c_str() );
#endif
return NULL; return m_node->FindNode( aNodeName, nullptr );
}
return m_node->FindNode( aNodeName, NULL );
} }
bool IFSG_NODE::AddRefNode( SGNODE* aNode ) bool IFSG_NODE::AddRefNode( SGNODE* aNode )
{ {
if( NULL == m_node ) wxCHECK( m_node, false );
{
#ifdef DEBUG
std::ostringstream ostr;
ostr << __FILE__ << ": " << __FUNCTION__ << ": " << __LINE__ << "\n";
ostr << BadObject;
wxLogTrace( MASK_3D_SG, "%s\n", ostr.str().c_str() );
#endif
return false;
}
return m_node->AddRefNode( aNode ); return m_node->AddRefNode( aNode );
} }
@ -216,31 +135,11 @@ bool IFSG_NODE::AddRefNode( SGNODE* aNode )
bool IFSG_NODE::AddRefNode( IFSG_NODE& aNode ) bool IFSG_NODE::AddRefNode( IFSG_NODE& aNode )
{ {
if( NULL == m_node ) wxCHECK( m_node, false );
{
#ifdef DEBUG
std::ostringstream ostr;
ostr << __FILE__ << ": " << __FUNCTION__ << ": " << __LINE__ << "\n";
ostr << BadObject;
wxLogTrace( MASK_3D_SG, "%s\n", ostr.str().c_str() );
#endif
return false;
}
SGNODE* np = aNode.GetRawPtr(); SGNODE* np = aNode.GetRawPtr();
if( NULL == np ) wxCHECK( np, false );
{
#ifdef DEBUG
std::ostringstream ostr;
ostr << __FILE__ << ": " << __FUNCTION__ << ": " << __LINE__ << "\n";
ostr << BadOperand;
wxLogTrace( MASK_3D_SG, "%s\n", ostr.str().c_str() );
#endif
return false;
}
return m_node->AddRefNode( np ); return m_node->AddRefNode( np );
} }
@ -248,17 +147,7 @@ bool IFSG_NODE::AddRefNode( IFSG_NODE& aNode )
bool IFSG_NODE::AddChildNode( SGNODE* aNode ) bool IFSG_NODE::AddChildNode( SGNODE* aNode )
{ {
if( NULL == m_node ) wxCHECK( m_node, false );
{
#ifdef DEBUG
std::ostringstream ostr;
ostr << __FILE__ << ": " << __FUNCTION__ << ": " << __LINE__ << "\n";
ostr << BadObject;
wxLogTrace( MASK_3D_SG, "%s\n", ostr.str().c_str() );
#endif
return false;
}
return m_node->AddChildNode( aNode ); return m_node->AddChildNode( aNode );
} }
@ -266,31 +155,11 @@ bool IFSG_NODE::AddChildNode( SGNODE* aNode )
bool IFSG_NODE::AddChildNode( IFSG_NODE& aNode ) bool IFSG_NODE::AddChildNode( IFSG_NODE& aNode )
{ {
if( NULL == m_node ) wxCHECK( m_node, false );
{
#ifdef DEBUG
std::ostringstream ostr;
ostr << __FILE__ << ": " << __FUNCTION__ << ": " << __LINE__ << "\n";
ostr << BadObject;
wxLogTrace( MASK_3D_SG, "%s\n", ostr.str().c_str() );
#endif
return false;
}
SGNODE* np = aNode.GetRawPtr(); SGNODE* np = aNode.GetRawPtr();
if( NULL == np ) wxCHECK( np, false );
{
#ifdef DEBUG
std::ostringstream ostr;
ostr << __FILE__ << ": " << __FUNCTION__ << ": " << __LINE__ << "\n";
ostr << BadOperand;
wxLogTrace( MASK_3D_SG, "%s\n", ostr.str().c_str() );
#endif
return false;
}
return m_node->AddChildNode( np ); return m_node->AddChildNode( np );
} }

View File

@ -2,6 +2,7 @@
* This program source code file is part of KiCad, a free EDA CAD application. * This program source code file is part of KiCad, a free EDA CAD application.
* *
* Copyright (C) 2015 Cirilo Bernardo <cirilo.bernardo@gmail.com> * Copyright (C) 2015 Cirilo Bernardo <cirilo.bernardo@gmail.com>
* Copyright (C) 2020 KiCad Developers, see AUTHORS.txt for contributors.
* *
* This program is free software; you can redistribute it and/or * This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License * modify it under the terms of the GNU General Public License
@ -30,53 +31,42 @@
#include "3d_cache/sg/sg_normals.h" #include "3d_cache/sg/sg_normals.h"
extern char BadObject[];
extern char BadOperand[];
extern char BadParent[]; extern char BadParent[];
extern char WrongParent[]; extern char WrongParent[];
IFSG_NORMALS::IFSG_NORMALS( bool create ) IFSG_NORMALS::IFSG_NORMALS( bool create )
{ {
m_node = NULL; m_node = nullptr;
if( !create ) if( !create )
return; return;
m_node = new SGNORMALS( NULL ); m_node = new SGNORMALS( nullptr );
if( m_node ) if( m_node )
m_node->AssociateWrapper( &m_node ); m_node->AssociateWrapper( &m_node );
return;
} }
IFSG_NORMALS::IFSG_NORMALS( SGNODE* aParent ) IFSG_NORMALS::IFSG_NORMALS( SGNODE* aParent )
{ {
m_node = new SGNORMALS( NULL ); m_node = new SGNORMALS( nullptr );
if( m_node ) if( m_node )
{ {
if( !m_node->SetParent( aParent ) ) if( !m_node->SetParent( aParent ) )
{ {
delete m_node; delete m_node;
m_node = NULL; m_node = nullptr;
#ifdef DEBUG wxLogTrace( MASK_3D_SG, "%s:%s:%d %s", __FILE__, __FUNCTION__, __LINE__, WrongParent );
std::ostringstream ostr;
ostr << __FILE__ << ": " << __FUNCTION__ << ": " << __LINE__ << "\n";
ostr << WrongParent;
wxLogTrace( MASK_3D_SG, "%s\n", ostr.str().c_str() );
#endif
return; return;
} }
m_node->AssociateWrapper( &m_node ); m_node->AssociateWrapper( &m_node );
} }
return;
} }
@ -84,39 +74,29 @@ IFSG_NORMALS::IFSG_NORMALS( IFSG_NODE& aParent )
{ {
SGNODE* pp = aParent.GetRawPtr(); SGNODE* pp = aParent.GetRawPtr();
#ifdef DEBUG #ifdef DEBUG
if( ! pp ) if( ! pp )
{ {
std::ostringstream ostr; wxLogTrace( MASK_3D_SG, "%s:%s:%d %s", __FILE__, __FUNCTION__, __LINE__, BadParent );
ostr << __FILE__ << ": " << __FUNCTION__ << ": " << __LINE__ << "\n";
ostr << BadParent;
wxLogTrace( MASK_3D_SG, "%s\n", ostr.str().c_str() );
} }
#endif #endif
m_node = new SGNORMALS( NULL ); m_node = new SGNORMALS( nullptr );
if( m_node ) if( m_node )
{ {
if( !m_node->SetParent( pp ) ) if( !m_node->SetParent( pp ) )
{ {
delete m_node; delete m_node;
m_node = NULL; m_node = nullptr;
#ifdef DEBUG wxLogTrace( MASK_3D_SG, "%s:%s:%d %s", __FILE__, __FUNCTION__, __LINE__, WrongParent );
std::ostringstream ostr;
ostr << __FILE__ << ": " << __FUNCTION__ << ": " << __LINE__ << "\n";
ostr << WrongParent;
wxLogTrace( MASK_3D_SG, "%s\n", ostr.str().c_str() );
#endif
return; return;
} }
m_node->AssociateWrapper( &m_node ); m_node->AssociateWrapper( &m_node );
} }
return;
} }
@ -125,7 +105,7 @@ bool IFSG_NORMALS::Attach( SGNODE* aNode )
if( m_node ) if( m_node )
m_node->DisassociateWrapper( &m_node ); m_node->DisassociateWrapper( &m_node );
m_node = NULL; m_node = nullptr;
if( !aNode ) if( !aNode )
return false; return false;
@ -151,17 +131,12 @@ bool IFSG_NORMALS::NewNode( SGNODE* aParent )
if( aParent != m_node->GetParent() ) if( aParent != m_node->GetParent() )
{ {
#ifdef DEBUG wxLogTrace( MASK_3D_SG, "%s:%s:%d * [BUG] invalid SGNODE parent (%s) to SGNORMALS",
std::ostringstream ostr; __FILE__, __FUNCTION__, __LINE__,
ostr << __FILE__ << ": " << __FUNCTION__ << ": " << __LINE__ << "\n"; aParent->GetNodeTypeName( aParent->GetNodeType() ) );
ostr << " * [BUG] invalid SGNODE parent (";
ostr << aParent->GetNodeTypeName( aParent->GetNodeType() );
ostr << ") to SGNORMALS";
wxLogTrace( MASK_3D_SG, "%s\n", ostr.str().c_str() );
#endif
delete m_node; delete m_node;
m_node = NULL; m_node = nullptr;
return false; return false;
} }
@ -175,17 +150,7 @@ bool IFSG_NORMALS::NewNode( IFSG_NODE& aParent )
{ {
SGNODE* np = aParent.GetRawPtr(); SGNODE* np = aParent.GetRawPtr();
if( NULL == np ) wxCHECK( np, false );
{
#ifdef DEBUG
std::ostringstream ostr;
ostr << __FILE__ << ": " << __FUNCTION__ << ": " << __LINE__ << "\n";
ostr << BadParent;
wxLogTrace( MASK_3D_SG, "%s\n", ostr.str().c_str() );
#endif
return false;
}
return NewNode( np ); return NewNode( np );
} }
@ -193,74 +158,34 @@ bool IFSG_NORMALS::NewNode( IFSG_NODE& aParent )
bool IFSG_NORMALS::GetNormalList( size_t& aListSize, SGVECTOR*& aNormalList ) bool IFSG_NORMALS::GetNormalList( size_t& aListSize, SGVECTOR*& aNormalList )
{ {
if( NULL == m_node ) wxCHECK( m_node, false );
{
#ifdef DEBUG
std::ostringstream ostr;
ostr << __FILE__ << ": " << __FUNCTION__ << ": " << __LINE__ << "\n";
ostr << BadObject;
wxLogTrace( MASK_3D_SG, "%s\n", ostr.str().c_str() );
#endif
return false; return ( (SGNORMALS*) m_node )->GetNormalList( aListSize, aNormalList );
}
return ((SGNORMALS*)m_node)->GetNormalList( aListSize, aNormalList );
} }
bool IFSG_NORMALS::SetNormalList( size_t aListSize, const SGVECTOR* aNormalList ) bool IFSG_NORMALS::SetNormalList( size_t aListSize, const SGVECTOR* aNormalList )
{ {
if( NULL == m_node ) wxCHECK( m_node, false );
{
#ifdef DEBUG
std::ostringstream ostr;
ostr << __FILE__ << ": " << __FUNCTION__ << ": " << __LINE__ << "\n";
ostr << BadObject;
wxLogTrace( MASK_3D_SG, "%s\n", ostr.str().c_str() );
#endif
return false; ( (SGNORMALS*) m_node )->SetNormalList( aListSize, aNormalList );
}
((SGNORMALS*)m_node)->SetNormalList( aListSize, aNormalList );
return true; return true;
} }
bool IFSG_NORMALS::AddNormal( double aXValue, double aYValue, double aZValue ) bool IFSG_NORMALS::AddNormal( double aXValue, double aYValue, double aZValue )
{ {
if( NULL == m_node ) wxCHECK( m_node, false );
{
#ifdef DEBUG
std::ostringstream ostr;
ostr << __FILE__ << ": " << __FUNCTION__ << ": " << __LINE__ << "\n";
ostr << BadObject;
wxLogTrace( MASK_3D_SG, "%s\n", ostr.str().c_str() );
#endif
return false; ( (SGNORMALS*) m_node )->AddNormal( aXValue, aYValue, aZValue );
}
((SGNORMALS*)m_node)->AddNormal( aXValue, aYValue, aZValue );
return true; return true;
} }
bool IFSG_NORMALS::AddNormal( const SGVECTOR& aNormal ) bool IFSG_NORMALS::AddNormal( const SGVECTOR& aNormal )
{ {
if( NULL == m_node ) wxCHECK( m_node, false );
{
#ifdef DEBUG
std::ostringstream ostr;
ostr << __FILE__ << ": " << __FUNCTION__ << ": " << __LINE__ << "\n";
ostr << BadObject;
wxLogTrace( MASK_3D_SG, "%s\n", ostr.str().c_str() );
#endif
return false; ( (SGNORMALS*) m_node )->AddNormal( aNormal );
}
((SGNORMALS*)m_node)->AddNormal( aNormal );
return true; return true;
} }

View File

@ -2,6 +2,7 @@
* This program source code file is part of KiCad, a free EDA CAD application. * This program source code file is part of KiCad, a free EDA CAD application.
* *
* Copyright (C) 2015 Cirilo Bernardo <cirilo.bernardo@gmail.com> * Copyright (C) 2015 Cirilo Bernardo <cirilo.bernardo@gmail.com>
* Copyright (C) 2020 KiCad Developers, see AUTHORS.txt for contributors.
* *
* This program is free software; you can redistribute it and/or * This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License * modify it under the terms of the GNU General Public License
@ -30,53 +31,42 @@
#include "3d_cache/sg/sg_shape.h" #include "3d_cache/sg/sg_shape.h"
extern char BadObject[];
extern char BadOperand[];
extern char BadParent[]; extern char BadParent[];
extern char WrongParent[]; extern char WrongParent[];
IFSG_SHAPE::IFSG_SHAPE( bool create ) IFSG_SHAPE::IFSG_SHAPE( bool create )
{ {
m_node = NULL; m_node = nullptr;
if( !create ) if( !create )
return ; return ;
m_node = new SGSHAPE( NULL ); m_node = new SGSHAPE( nullptr );
if( m_node ) if( m_node )
m_node->AssociateWrapper( &m_node ); m_node->AssociateWrapper( &m_node );
return;
} }
IFSG_SHAPE::IFSG_SHAPE( SGNODE* aParent ) IFSG_SHAPE::IFSG_SHAPE( SGNODE* aParent )
{ {
m_node = new SGSHAPE( NULL ); m_node = new SGSHAPE( nullptr );
if( m_node ) if( m_node )
{ {
if( !m_node->SetParent( aParent ) ) if( !m_node->SetParent( aParent ) )
{ {
delete m_node; delete m_node;
m_node = NULL; m_node = nullptr;
#ifdef DEBUG wxLogTrace( MASK_3D_SG, "%s:%s:%d %s", __FILE__, __FUNCTION__, __LINE__, WrongParent );
std::ostringstream ostr;
ostr << __FILE__ << ": " << __FUNCTION__ << ": " << __LINE__ << "\n";
ostr << WrongParent;
wxLogTrace( MASK_3D_SG, "%s\n", ostr.str().c_str() );
#endif
return; return;
} }
m_node->AssociateWrapper( &m_node ); m_node->AssociateWrapper( &m_node );
} }
return;
} }
@ -84,39 +74,29 @@ IFSG_SHAPE::IFSG_SHAPE( IFSG_NODE& aParent )
{ {
SGNODE* pp = aParent.GetRawPtr(); SGNODE* pp = aParent.GetRawPtr();
#ifdef DEBUG #ifdef DEBUG
if( ! pp ) if( !pp )
{ {
std::ostringstream ostr; wxLogTrace( MASK_3D_SG, "%s:%s:%d %s", __FILE__, __FUNCTION__, __LINE__, BadParent );
ostr << __FILE__ << ": " << __FUNCTION__ << ": " << __LINE__ << "\n";
ostr << BadParent;
wxLogTrace( MASK_3D_SG, "%s\n", ostr.str().c_str() );
} }
#endif #endif
m_node = new SGSHAPE( NULL ); m_node = new SGSHAPE( nullptr );
if( m_node ) if( m_node )
{ {
if( !m_node->SetParent( pp ) ) if( !m_node->SetParent( pp ) )
{ {
delete m_node; delete m_node;
m_node = NULL; m_node = nullptr;
#ifdef DEBUG wxLogTrace( MASK_3D_SG, "%s:%s:%d %s", __FILE__, __FUNCTION__, __LINE__, WrongParent );
std::ostringstream ostr;
ostr << __FILE__ << ": " << __FUNCTION__ << ": " << __LINE__ << "\n";
ostr << WrongParent;
wxLogTrace( MASK_3D_SG, "%s\n", ostr.str().c_str() );
#endif
return; return;
} }
m_node->AssociateWrapper( &m_node ); m_node->AssociateWrapper( &m_node );
} }
return;
} }
@ -125,7 +105,7 @@ bool IFSG_SHAPE::Attach( SGNODE* aNode )
if( m_node ) if( m_node )
m_node->DisassociateWrapper( &m_node ); m_node->DisassociateWrapper( &m_node );
m_node = NULL; m_node = nullptr;
if( !aNode ) if( !aNode )
return false; return false;
@ -151,17 +131,12 @@ bool IFSG_SHAPE::NewNode( SGNODE* aParent )
if( aParent != m_node->GetParent() ) if( aParent != m_node->GetParent() )
{ {
#ifdef DEBUG wxLogTrace( MASK_3D_SG, "%s:%s:%d * [BUG] invalid SGNODE parent (%s) to SGSHAPE",
std::ostringstream ostr; __FILE__, __FUNCTION__, __LINE__,
ostr << __FILE__ << ": " << __FUNCTION__ << ": " << __LINE__ << "\n"; aParent->GetNodeTypeName( aParent->GetNodeType() ) );
ostr << " * [BUG] invalid SGNODE parent (";
ostr << aParent->GetNodeTypeName( aParent->GetNodeType() );
ostr << ") to SGSHAPE";
wxLogTrace( MASK_3D_SG, "%s\n", ostr.str().c_str() );
#endif
delete m_node; delete m_node;
m_node = NULL; m_node = nullptr;
return false; return false;
} }
@ -175,17 +150,7 @@ bool IFSG_SHAPE::NewNode( IFSG_NODE& aParent )
{ {
SGNODE* np = aParent.GetRawPtr(); SGNODE* np = aParent.GetRawPtr();
if( NULL == np ) wxCHECK( np, false );
{
#ifdef DEBUG
std::ostringstream ostr;
ostr << __FILE__ << ": " << __FUNCTION__ << ": " << __LINE__ << "\n";
ostr << BadParent;
wxLogTrace( MASK_3D_SG, "%s\n", ostr.str().c_str() );
#endif
return false;
}
return NewNode( np ); return NewNode( np );
} }

View File

@ -2,6 +2,7 @@
* This program source code file is part of KiCad, a free EDA CAD application. * This program source code file is part of KiCad, a free EDA CAD application.
* *
* Copyright (C) 2015 Cirilo Bernardo <cirilo.bernardo@gmail.com> * Copyright (C) 2015 Cirilo Bernardo <cirilo.bernardo@gmail.com>
* Copyright (C) 2020 KiCad Developers, see AUTHORS.txt for contributors.
* *
* This program is free software; you can redistribute it and/or * This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License * modify it under the terms of the GNU General Public License
@ -30,52 +31,41 @@
#include "3d_cache/sg/scenegraph.h" #include "3d_cache/sg/scenegraph.h"
extern char BadObject[];
extern char BadOperand[];
extern char BadParent[];
extern char WrongParent[]; extern char WrongParent[];
IFSG_TRANSFORM::IFSG_TRANSFORM( bool create ) IFSG_TRANSFORM::IFSG_TRANSFORM( bool create )
{ {
m_node = NULL; m_node = nullptr;
if( !create ) if( !create )
return; return;
m_node = new SCENEGRAPH( NULL ); m_node = new SCENEGRAPH( nullptr );
if( m_node ) if( m_node )
m_node->AssociateWrapper( &m_node ); m_node->AssociateWrapper( &m_node );
return;
} }
IFSG_TRANSFORM::IFSG_TRANSFORM( SGNODE* aParent ) IFSG_TRANSFORM::IFSG_TRANSFORM( SGNODE* aParent )
{ {
m_node = new SCENEGRAPH( NULL ); m_node = new SCENEGRAPH( nullptr );
if( m_node ) if( m_node )
{ {
if( !m_node->SetParent( aParent ) ) if( !m_node->SetParent( aParent ) )
{ {
delete m_node; delete m_node;
m_node = NULL; m_node = nullptr;
#ifdef DEBUG wxLogTrace( MASK_3D_SG, "%s:%s:%d %s", __FILE__, __FUNCTION__, __LINE__, WrongParent );
std::ostringstream ostr;
ostr << __FILE__ << ": " << __FUNCTION__ << ": " << __LINE__ << "\n";
ostr << WrongParent;
wxLogTrace( MASK_3D_SG, "%s\n", ostr.str().c_str() );
#endif
return; return;
} }
m_node->AssociateWrapper( &m_node ); m_node->AssociateWrapper( &m_node );
} }
return;
} }
@ -84,7 +74,7 @@ bool IFSG_TRANSFORM::Attach( SGNODE* aNode )
if( m_node ) if( m_node )
m_node->DisassociateWrapper( &m_node ); m_node->DisassociateWrapper( &m_node );
m_node = NULL; m_node = nullptr;
if( !aNode ) if( !aNode )
return false; return false;
@ -110,17 +100,12 @@ bool IFSG_TRANSFORM::NewNode( SGNODE* aParent )
if( aParent != m_node->GetParent() ) if( aParent != m_node->GetParent() )
{ {
#ifdef DEBUG wxLogTrace( MASK_3D_SG, "%s:%s:%d * [BUG] invalid SGNODE parent (%s) to SCENEGRAPH",
std::ostringstream ostr; __FILE__, __FUNCTION__, __LINE__,
ostr << __FILE__ << ": " << __FUNCTION__ << ": " << __LINE__ << "\n"; aParent->GetNodeTypeName( aParent->GetNodeType() ) );
ostr << " * [BUG] invalid SGNODE parent (";
ostr << aParent->GetNodeTypeName( aParent->GetNodeType() );
ostr << ") to SCENEGRAPH";
wxLogTrace( MASK_3D_SG, "%s\n", ostr.str().c_str() );
#endif
delete m_node; delete m_node;
m_node = NULL; m_node = nullptr;
return false; return false;
} }
@ -134,17 +119,7 @@ bool IFSG_TRANSFORM::NewNode( IFSG_NODE& aParent )
{ {
SGNODE* np = aParent.GetRawPtr(); SGNODE* np = aParent.GetRawPtr();
if( NULL == np ) wxCHECK( np, false );
{
#ifdef DEBUG
std::ostringstream ostr;
ostr << __FILE__ << ": " << __FUNCTION__ << ": " << __LINE__ << "\n";
ostr << BadParent;
wxLogTrace( MASK_3D_SG, "%s\n", ostr.str().c_str() );
#endif
return false;
}
return NewNode( np ); return NewNode( np );
} }
@ -152,20 +127,10 @@ bool IFSG_TRANSFORM::NewNode( IFSG_NODE& aParent )
bool IFSG_TRANSFORM::SetRotation( const SGVECTOR& aRotationAxis, double aAngle ) bool IFSG_TRANSFORM::SetRotation( const SGVECTOR& aRotationAxis, double aAngle )
{ {
if( NULL == m_node ) wxCHECK( m_node, false );
{
#ifdef DEBUG
std::ostringstream ostr;
ostr << __FILE__ << ": " << __FUNCTION__ << ": " << __LINE__ << "\n";
ostr << BadObject;
wxLogTrace( MASK_3D_SG, "%s\n", ostr.str().c_str() );
#endif
return false; ( (SCENEGRAPH*) m_node )->rotation_axis = aRotationAxis;
} ( (SCENEGRAPH*) m_node )->rotation_angle = aAngle;
((SCENEGRAPH*)m_node)->rotation_axis = aRotationAxis;
((SCENEGRAPH*)m_node)->rotation_angle = aAngle;
return true; return true;
} }
@ -173,19 +138,9 @@ bool IFSG_TRANSFORM::SetRotation( const SGVECTOR& aRotationAxis, double aAngle )
bool IFSG_TRANSFORM::SetScale( const SGPOINT& aScale ) noexcept bool IFSG_TRANSFORM::SetScale( const SGPOINT& aScale ) noexcept
{ {
if( NULL == m_node ) wxCHECK( m_node, false );
{
#ifdef DEBUG
std::ostringstream ostr;
ostr << __FILE__ << ": " << __FUNCTION__ << ": " << __LINE__ << "\n";
ostr << BadObject;
wxLogTrace( MASK_3D_SG, "%s\n", ostr.str().c_str() );
#endif
return false; ( (SCENEGRAPH*) m_node )->scale = aScale;
}
((SCENEGRAPH*)m_node)->scale = aScale;
return true; return true;
} }
@ -193,31 +148,17 @@ bool IFSG_TRANSFORM::SetScale( const SGPOINT& aScale ) noexcept
bool IFSG_TRANSFORM::SetScale( double aScale ) bool IFSG_TRANSFORM::SetScale( double aScale )
{ {
if( NULL == m_node ) wxCHECK( m_node, false );
{
#ifdef DEBUG
std::ostringstream ostr;
ostr << __FILE__ << ": " << __FUNCTION__ << ": " << __LINE__ << "\n";
ostr << BadObject;
wxLogTrace( MASK_3D_SG, "%s\n", ostr.str().c_str() );
#endif
return false;
}
if( aScale < 1e-8 && aScale > -1e-8 ) if( aScale < 1e-8 && aScale > -1e-8 )
{ {
#ifdef DEBUG wxLogTrace( MASK_3D_SG, "%s:%s:%d * [BUG] |scale| is < 1e-8 - this seems strange",
std::ostringstream ostr; __FILE__, __FUNCTION__, __LINE__ );
ostr << __FILE__ << ": " << __FUNCTION__ << ": " << __LINE__ << "\n";
ostr << " * [BUG] |scale| is < 1e-8 - this seems strange";
wxLogTrace( MASK_3D_SG, "%s\n", ostr.str().c_str() );
#endif
return false; return false;
} }
((SCENEGRAPH*)m_node)->scale = SGPOINT( aScale, aScale, aScale ); ( (SCENEGRAPH*) m_node )->scale = SGPOINT( aScale, aScale, aScale );
return true; return true;
} }
@ -225,19 +166,9 @@ bool IFSG_TRANSFORM::SetScale( double aScale )
bool IFSG_TRANSFORM::SetTranslation( const SGPOINT& aTranslation ) noexcept bool IFSG_TRANSFORM::SetTranslation( const SGPOINT& aTranslation ) noexcept
{ {
if( NULL == m_node ) wxCHECK( m_node, false );
{
#ifdef DEBUG
std::ostringstream ostr;
ostr << __FILE__ << ": " << __FUNCTION__ << ": " << __LINE__ << "\n";
ostr << BadObject;
wxLogTrace( MASK_3D_SG, "%s\n", ostr.str().c_str() );
#endif
return false; ( (SCENEGRAPH*) m_node )->translation = aTranslation;
}
((SCENEGRAPH*)m_node)->translation = aTranslation;
return true; return true;
} }
@ -245,20 +176,10 @@ bool IFSG_TRANSFORM::SetTranslation( const SGPOINT& aTranslation ) noexcept
bool IFSG_TRANSFORM::SetScaleOrientation( const SGVECTOR& aScaleAxis, double aAngle ) bool IFSG_TRANSFORM::SetScaleOrientation( const SGVECTOR& aScaleAxis, double aAngle )
{ {
if( NULL == m_node ) wxCHECK( m_node, false );
{
#ifdef DEBUG
std::ostringstream ostr;
ostr << __FILE__ << ": " << __FUNCTION__ << ": " << __LINE__ << "\n";
ostr << BadObject;
wxLogTrace( MASK_3D_SG, "%s\n", ostr.str().c_str() );
#endif
return false; ( (SCENEGRAPH*) m_node )->scale_axis = aScaleAxis;
} ( (SCENEGRAPH*) m_node )->scale_angle = aAngle;
((SCENEGRAPH*)m_node)->scale_axis = aScaleAxis;
((SCENEGRAPH*)m_node)->scale_angle = aAngle;
return true; return true;
} }
@ -266,19 +187,9 @@ bool IFSG_TRANSFORM::SetScaleOrientation( const SGVECTOR& aScaleAxis, double aAn
bool IFSG_TRANSFORM::SetCenter( const SGPOINT& aCenter ) noexcept bool IFSG_TRANSFORM::SetCenter( const SGPOINT& aCenter ) noexcept
{ {
if( NULL == m_node ) wxCHECK( m_node, false );
{
#ifdef DEBUG
std::ostringstream ostr;
ostr << __FILE__ << ": " << __FUNCTION__ << ": " << __LINE__ << "\n";
ostr << BadObject;
wxLogTrace( MASK_3D_SG, "%s\n", ostr.str().c_str() );
#endif
return false; ( (SCENEGRAPH*) m_node )->center = aCenter;
}
((SCENEGRAPH*)m_node)->center = aCenter;
return true; return true;
} }

View File

@ -2,6 +2,7 @@
* This program source code file is part of KiCad, a free EDA CAD application. * This program source code file is part of KiCad, a free EDA CAD application.
* *
* Copyright (C) 2015 Cirilo Bernardo <cirilo.bernardo@gmail.com> * Copyright (C) 2015 Cirilo Bernardo <cirilo.bernardo@gmail.com>
* Copyright (C) 2020 KiCad Developers, see AUTHORS.txt for contributors.
* *
* This program is free software; you can redistribute it and/or * This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License * modify it under the terms of the GNU General Public License
@ -44,24 +45,17 @@ SCENEGRAPH::SCENEGRAPH( SGNODE* aParent ) : SGNODE( aParent )
scale.y = 1.0; scale.y = 1.0;
scale.z = 1.0; scale.z = 1.0;
if( NULL != aParent && S3D::SGTYPE_TRANSFORM != aParent->GetNodeType() ) if( nullptr != aParent && S3D::SGTYPE_TRANSFORM != aParent->GetNodeType() )
{ {
m_Parent = NULL; m_Parent = nullptr;
#ifdef DEBUG wxLogTrace( MASK_3D_SG, "%s:%s:%d * [BUG] inappropriate parent to SCENEGRAPH (type %d)" ,
std::ostringstream ostr; __FILE__, __FUNCTION__, __LINE__, aParent->GetNodeType() );
ostr << __FILE__ << ": " << __FUNCTION__ << ": " << __LINE__ << "\n";
ostr << " * [BUG] inappropriate parent to SCENEGRAPH (type ";
ostr << aParent->GetNodeType() << ")";
wxLogTrace( MASK_3D_SG, "%s\n", ostr.str().c_str() );
#endif
} }
else if( NULL != aParent && S3D::SGTYPE_TRANSFORM == aParent->GetNodeType() ) else if( nullptr != aParent && S3D::SGTYPE_TRANSFORM == aParent->GetNodeType() )
{ {
m_Parent->AddChildNode( this ); m_Parent->AddChildNode( this );
} }
return;
} }
@ -74,14 +68,12 @@ SCENEGRAPH::~SCENEGRAPH()
// delete owned objects // delete owned objects
DEL_OBJS( SCENEGRAPH, m_Transforms ); DEL_OBJS( SCENEGRAPH, m_Transforms );
DEL_OBJS( SGSHAPE, m_Shape ); DEL_OBJS( SGSHAPE, m_Shape );
return;
} }
bool SCENEGRAPH::SetParent( SGNODE* aParent, bool notify ) bool SCENEGRAPH::SetParent( SGNODE* aParent, bool notify )
{ {
if( NULL != m_Parent ) if( nullptr != m_Parent )
{ {
if( aParent == m_Parent ) if( aParent == m_Parent )
return true; return true;
@ -90,14 +82,14 @@ bool SCENEGRAPH::SetParent( SGNODE* aParent, bool notify )
if( notify ) if( notify )
m_Parent->unlinkChildNode( this ); m_Parent->unlinkChildNode( this );
m_Parent = NULL; m_Parent = nullptr;
if( NULL == aParent ) if( nullptr == aParent )
return true; return true;
} }
// only a transform may be parent to a transform // only a transform may be parent to a transform
if( NULL != aParent && S3D::SGTYPE_TRANSFORM != aParent->GetNodeType() ) if( nullptr != aParent && S3D::SGTYPE_TRANSFORM != aParent->GetNodeType() )
return false; return false;
m_Parent = aParent; m_Parent = aParent;
@ -111,8 +103,8 @@ bool SCENEGRAPH::SetParent( SGNODE* aParent, bool notify )
SGNODE* SCENEGRAPH::FindNode(const char *aNodeName, const SGNODE *aCaller) SGNODE* SCENEGRAPH::FindNode(const char *aNodeName, const SGNODE *aCaller)
{ {
if( NULL == aNodeName || 0 == aNodeName[0] ) if( nullptr == aNodeName || 0 == aNodeName[0] )
return NULL; return nullptr;
if( !m_Name.compare( aNodeName ) ) if( !m_Name.compare( aNodeName ) )
return this; return this;
@ -121,8 +113,8 @@ SGNODE* SCENEGRAPH::FindNode(const char *aNodeName, const SGNODE *aCaller)
FIND_NODE( SGSHAPE, aNodeName, m_Shape, aCaller ); FIND_NODE( SGSHAPE, aNodeName, m_Shape, aCaller );
// query the parent if appropriate // query the parent if appropriate
if( aCaller == m_Parent || NULL == m_Parent ) if( aCaller == m_Parent || nullptr == m_Parent )
return NULL; return nullptr;
return m_Parent->FindNode( aNodeName, this ); return m_Parent->FindNode( aNodeName, this );
} }
@ -130,33 +122,26 @@ SGNODE* SCENEGRAPH::FindNode(const char *aNodeName, const SGNODE *aCaller)
void SCENEGRAPH::unlinkNode( const SGNODE* aNode, bool isChild ) void SCENEGRAPH::unlinkNode( const SGNODE* aNode, bool isChild )
{ {
if( NULL == aNode ) if( nullptr == aNode )
return; return;
switch( aNode->GetNodeType() ) switch( aNode->GetNodeType() )
{ {
case S3D::SGTYPE_TRANSFORM: case S3D::SGTYPE_TRANSFORM:
UNLINK_NODE( S3D::SGTYPE_TRANSFORM, SCENEGRAPH, aNode, m_Transforms, m_RTransforms, isChild ); UNLINK_NODE( S3D::SGTYPE_TRANSFORM, SCENEGRAPH, aNode, m_Transforms, m_RTransforms,
break; isChild );
break;
case S3D::SGTYPE_SHAPE: case S3D::SGTYPE_SHAPE:
UNLINK_NODE( S3D::SGTYPE_SHAPE, SGSHAPE, aNode, m_Shape, m_RShape, isChild ); UNLINK_NODE( S3D::SGTYPE_SHAPE, SGSHAPE, aNode, m_Shape, m_RShape, isChild );
break; break;
default: default:
break; break;
} }
#ifdef DEBUG wxLogTrace( MASK_3D_SG, "%s:%s:%d * [BUG] unlinkNode() did not find its target",
do { __FILE__, __FUNCTION__, __LINE__ );
std::ostringstream ostr;
ostr << __FILE__ << ": " << __FUNCTION__ << ": " << __LINE__ << "\n";
ostr << " * [BUG] unlinkNode() did not find its target";
wxLogTrace( MASK_3D_SG, "%s\n", ostr.str().c_str() );
} while( 0 );
#endif
return;
} }
@ -176,30 +161,13 @@ void SCENEGRAPH::unlinkRefNode( const SGNODE* aNode )
bool SCENEGRAPH::addNode( SGNODE* aNode, bool isChild ) bool SCENEGRAPH::addNode( SGNODE* aNode, bool isChild )
{ {
if( NULL == aNode ) wxCHECK( aNode, false );
{
#ifdef DEBUG
std::ostringstream ostr;
ostr << __FILE__ << ": " << __FUNCTION__ << ": " << __LINE__ << "\n";
ostr << " * [BUG] NULL pointer passed for aNode";
wxLogTrace( MASK_3D_SG, "%s\n", ostr.str().c_str() );
#endif
return false;
}
ADD_NODE( S3D::SGTYPE_TRANSFORM, SCENEGRAPH, aNode, m_Transforms, m_RTransforms, isChild ); ADD_NODE( S3D::SGTYPE_TRANSFORM, SCENEGRAPH, aNode, m_Transforms, m_RTransforms, isChild );
ADD_NODE( S3D::SGTYPE_SHAPE, SGSHAPE, aNode, m_Shape, m_RShape, isChild ); ADD_NODE( S3D::SGTYPE_SHAPE, SGSHAPE, aNode, m_Shape, m_RShape, isChild );
#ifdef DEBUG wxLogTrace( MASK_3D_SG, "%s:%s:%d * [BUG] object '%s' is not a valid type for this object (%d)",
do { __FILE__, __FUNCTION__, __LINE__, aNode->GetName(), aNode->GetNodeType() );
std::ostringstream ostr;
ostr << __FILE__ << ": " << __FUNCTION__ << ": " << __LINE__ << "\n";
ostr << " * [BUG] object '" << aNode->GetName();
ostr << "' is not a valid type for this object (" << aNode->GetNodeType() << ")";
wxLogTrace( MASK_3D_SG, "%s\n", ostr.str().c_str() );
} while( 0 );
#endif
return false; return false;
} }
@ -237,7 +205,7 @@ void SCENEGRAPH::ReNameNodes( void )
++sL; ++sL;
} }
} while(0); } while( 0 );
// rename all transforms // rename all transforms
do do
@ -251,16 +219,13 @@ void SCENEGRAPH::ReNameNodes( void )
++sL; ++sL;
} }
} while(0); } while( 0 );
return;
} }
bool SCENEGRAPH::WriteVRML( std::ostream& aFile, bool aReuseFlag ) bool SCENEGRAPH::WriteVRML( std::ostream& aFile, bool aReuseFlag )
{ {
if( m_Transforms.empty() && m_RTransforms.empty() if( m_Transforms.empty() && m_RTransforms.empty() && m_Shape.empty() && m_RShape.empty() )
&& m_Shape.empty() && m_RShape.empty() )
{ {
return false; return false;
} }
@ -366,14 +331,14 @@ bool SCENEGRAPH::WriteVRML( std::ostream& aFile, bool aReuseFlag )
bool SCENEGRAPH::WriteCache( std::ostream& aFile, SGNODE* parentNode ) bool SCENEGRAPH::WriteCache( std::ostream& aFile, SGNODE* parentNode )
{ {
if( NULL == parentNode && NULL != m_Parent ) if( nullptr == parentNode && nullptr != m_Parent )
{ {
SGNODE* np = m_Parent; SGNODE* np = m_Parent;
while( NULL != np->GetParent() ) while( nullptr != np->GetParent() )
np = np->GetParent(); np = np->GetParent();
if( np->WriteCache( aFile, NULL ) ) if( np->WriteCache( aFile, nullptr ) )
{ {
m_written = true; m_written = true;
return true; return true;
@ -382,19 +347,9 @@ bool SCENEGRAPH::WriteCache( std::ostream& aFile, SGNODE* parentNode )
return false; return false;
} }
if( parentNode != m_Parent ) wxCHECK( parentNode == m_Parent, false );
{
#ifdef DEBUG
std::ostringstream ostr;
ostr << __FILE__ << ": " << __FUNCTION__ << ": " << __LINE__ << "\n";
ostr << " * [BUG] corrupt data; parentNode != m_aParent";
wxLogTrace( MASK_3D_SG, "%s\n", ostr.str().c_str() );
#endif
return false; if( nullptr == m_Parent )
}
if( NULL == m_Parent )
{ {
// ensure unique node names // ensure unique node names
ResetNodeIndex(); ResetNodeIndex();
@ -403,12 +358,7 @@ bool SCENEGRAPH::WriteCache( std::ostream& aFile, SGNODE* parentNode )
if( aFile.fail() ) if( aFile.fail() )
{ {
#ifdef DEBUG wxLogTrace( MASK_3D_SG, "%s:%s:%d * [INFO] bad stream", __FILE__, __FUNCTION__, __LINE__ );
std::ostringstream ostr;
ostr << __FILE__ << ": " << __FUNCTION__ << ": " << __LINE__ << "\n";
ostr << " * [INFO] bad stream";
wxLogTrace( MASK_3D_SG, "%s\n", ostr.str().c_str() );
#endif
return false; return false;
} }
@ -464,12 +414,8 @@ bool SCENEGRAPH::WriteCache( std::ostream& aFile, SGNODE* parentNode )
{ {
if( !m_Transforms[i]->WriteCache( aFile, this ) ) if( !m_Transforms[i]->WriteCache( aFile, this ) )
{ {
#ifdef DEBUG wxLogTrace( MASK_3D_SG, "%s:%s:%d * [INFO] bad stream while writing child transforms",
std::ostringstream ostr; __FILE__, __FUNCTION__, __LINE__ );
ostr << __FILE__ << ": " << __FUNCTION__ << ": " << __LINE__ << "\n";
ostr << " * [INFO] bad stream while writing child transforms";
wxLogTrace( MASK_3D_SG, "%s\n", ostr.str().c_str() );
#endif
return false; return false;
} }
@ -477,21 +423,19 @@ bool SCENEGRAPH::WriteCache( std::ostream& aFile, SGNODE* parentNode )
// write referenced transform names // write referenced transform names
asize = m_RTransforms.size(); asize = m_RTransforms.size();
for( i = 0; i < asize; ++i ) for( i = 0; i < asize; ++i )
aFile << "[" << m_RTransforms[i]->GetName() << "]"; aFile << "[" << m_RTransforms[i]->GetName() << "]";
// write child shapes // write child shapes
asize = m_Shape.size(); asize = m_Shape.size();
for( i = 0; i < asize; ++i ) for( i = 0; i < asize; ++i )
{ {
if( !m_Shape[i]->WriteCache( aFile, this ) ) if( !m_Shape[i]->WriteCache( aFile, this ) )
{ {
#ifdef DEBUG wxLogTrace( MASK_3D_SG, "%s:%s:%d * [INFO] bad stream while writing child shapes",
std::ostringstream ostr; __FILE__, __FUNCTION__, __LINE__ );
ostr << __FILE__ << ": " << __FUNCTION__ << ": " << __LINE__ << "\n";
ostr << " * [INFO] bad stream while writing child shapes";
wxLogTrace( MASK_3D_SG, "%s\n", ostr.str().c_str() );
#endif
return false; return false;
} }
@ -499,6 +443,7 @@ bool SCENEGRAPH::WriteCache( std::ostream& aFile, SGNODE* parentNode )
// write referenced transform names // write referenced transform names
asize = m_RShape.size(); asize = m_RShape.size();
for( i = 0; i < asize; ++i ) for( i = 0; i < asize; ++i )
aFile << "[" << m_RShape[i]->GetName() << "]"; aFile << "[" << m_RShape[i]->GetName() << "]";
@ -512,33 +457,20 @@ bool SCENEGRAPH::WriteCache( std::ostream& aFile, SGNODE* parentNode )
bool SCENEGRAPH::ReadCache( std::istream& aFile, SGNODE* parentNode ) bool SCENEGRAPH::ReadCache( std::istream& aFile, SGNODE* parentNode )
{ {
if( !m_Transforms.empty() || !m_RTransforms.empty() wxCHECK( m_Transforms.empty() && m_RTransforms.empty() && m_Shape.empty() && m_RShape.empty(),
|| !m_Shape.empty() || !m_RShape.empty() ) false );
{
#ifdef DEBUG
std::ostringstream ostr;
ostr << __FILE__ << ": " << __FUNCTION__ << ": " << __LINE__ << "\n";
ostr << " * [BUG] non-empty node";
wxLogTrace( MASK_3D_SG, "%s\n", ostr.str().c_str() );
#endif
return false;
}
std::string name; // name of the node std::string name; // name of the node
if( NULL == parentNode ) if( nullptr == parentNode )
{ {
// we need to read the tag and verify its type // we need to read the tag and verify its type
if( S3D::SGTYPE_TRANSFORM != S3D::ReadTag( aFile, name ) ) if( S3D::SGTYPE_TRANSFORM != S3D::ReadTag( aFile, name ) )
{ {
#ifdef DEBUG wxLogTrace( MASK_3D_SG,
std::ostringstream ostr; "%s:%s:%d * [INFO] corrupt data; tag mismatch at position %ul",
ostr << __FILE__ << ": " << __FUNCTION__ << ": " << __LINE__ << "\n"; __FILE__, __FUNCTION__, __LINE__,
ostr << " * [INFO] corrupt data; tag mismatch at position "; static_cast<unsigned long>( aFile.tellg() ) );
ostr << aFile.tellg();
wxLogTrace( MASK_3D_SG, "%s\n", ostr.str().c_str() );
#endif
return false; return false;
} }
@ -572,13 +504,10 @@ bool SCENEGRAPH::ReadCache( std::istream& aFile, SGNODE* parentNode )
{ {
if( S3D::SGTYPE_TRANSFORM != S3D::ReadTag( aFile, name ) ) if( S3D::SGTYPE_TRANSFORM != S3D::ReadTag( aFile, name ) )
{ {
#ifdef DEBUG wxLogTrace( MASK_3D_SG,
std::ostringstream ostr; "%s:%s:%d * [INFO] corrupt data; bad child transform tag at position %ul",
ostr << __FILE__ << ": " << __FUNCTION__ << ": " << __LINE__ << "\n"; __FILE__, __FUNCTION__, __LINE__,
ostr << " * [INFO] corrupt data; bad child transform tag at position "; static_cast<unsigned long>( aFile.tellg() ) );
ostr << aFile.tellg();
wxLogTrace( MASK_3D_SG, "%s\n", ostr.str().c_str() );
#endif
return false; return false;
} }
@ -588,13 +517,10 @@ bool SCENEGRAPH::ReadCache( std::istream& aFile, SGNODE* parentNode )
if( !sp->ReadCache( aFile, this ) ) if( !sp->ReadCache( aFile, this ) )
{ {
#ifdef DEBUG wxLogTrace( MASK_3D_SG,
std::ostringstream ostr; "%s:%s:%d * [INFO] corrupt data while reading transform %ul",
ostr << __FILE__ << ": " << __FUNCTION__ << ": " << __LINE__ << "\n"; __FILE__, __FUNCTION__, __LINE__,
ostr << " * [INFO] corrupt data while reading transform '"; static_cast<unsigned long>( aFile.tellg() ) );
ostr << name << "' pos " << aFile.tellg();
wxLogTrace( MASK_3D_SG, "%s\n", ostr.str().c_str() );
#endif
return false; return false;
} }
@ -605,13 +531,10 @@ bool SCENEGRAPH::ReadCache( std::istream& aFile, SGNODE* parentNode )
{ {
if( S3D::SGTYPE_TRANSFORM != S3D::ReadTag( aFile, name ) ) if( S3D::SGTYPE_TRANSFORM != S3D::ReadTag( aFile, name ) )
{ {
#ifdef DEBUG wxLogTrace( MASK_3D_SG,
std::ostringstream ostr; "%s:%s:%d * [INFO] corrupt data; bad ref transform tag at position %ul",
ostr << __FILE__ << ": " << __FUNCTION__ << ": " << __LINE__ << "\n"; __FILE__, __FUNCTION__, __LINE__,
ostr << " * [INFO] corrupt data; bad ref transform tag at position "; static_cast<unsigned long>( aFile.tellg() ) );
ostr << aFile.tellg();
wxLogTrace( MASK_3D_SG, "%s\n", ostr.str().c_str() );
#endif
return false; return false;
} }
@ -620,26 +543,20 @@ bool SCENEGRAPH::ReadCache( std::istream& aFile, SGNODE* parentNode )
if( !sp ) if( !sp )
{ {
#ifdef DEBUG wxLogTrace( MASK_3D_SG,
std::ostringstream ostr; "%s:%s:%d * [INFO] corrupt data: cannot find ref transform at position %ul",
ostr << __FILE__ << ": " << __FUNCTION__ << ": " << __LINE__ << "\n"; __FILE__, __FUNCTION__, __LINE__,
ostr << " * [INFO] corrupt data: cannot find ref transform '"; static_cast<unsigned long>( aFile.tellg() ) );
ostr << name << "' pos " << aFile.tellg();
wxLogTrace( MASK_3D_SG, "%s\n", ostr.str().c_str() );
#endif
return false; return false;
} }
if( S3D::SGTYPE_TRANSFORM != sp->GetNodeType() ) if( S3D::SGTYPE_TRANSFORM != sp->GetNodeType() )
{ {
#ifdef DEBUG wxLogTrace( MASK_3D_SG,
std::ostringstream ostr; "%s:%s:%d * [INFO] corrupt data: type is not TRANSFORM at position %ul",
ostr << __FILE__ << ": " << __FUNCTION__ << ": " << __LINE__ << "\n"; __FILE__, __FUNCTION__, __LINE__,
ostr << " * [INFO] corrupt data: type is not TRANSFORM '"; static_cast<unsigned long>( aFile.tellg() ) );
ostr << name << "' pos " << aFile.tellg();
wxLogTrace( MASK_3D_SG, "%s\n", ostr.str().c_str() );
#endif
return false; return false;
} }
@ -652,13 +569,10 @@ bool SCENEGRAPH::ReadCache( std::istream& aFile, SGNODE* parentNode )
{ {
if( S3D::SGTYPE_SHAPE != S3D::ReadTag( aFile, name ) ) if( S3D::SGTYPE_SHAPE != S3D::ReadTag( aFile, name ) )
{ {
#ifdef DEBUG wxLogTrace( MASK_3D_SG,
std::ostringstream ostr; "%s:%s:%d * [INFO] corrupt data; bad child shape tag at position %ul",
ostr << __FILE__ << ": " << __FUNCTION__ << ": " << __LINE__ << "\n"; __FILE__, __FUNCTION__, __LINE__,
ostr << " * [INFO] corrupt data; bad child shape tag at position "; static_cast<unsigned long>( aFile.tellg() ) );
ostr << aFile.tellg();
wxLogTrace( MASK_3D_SG, "%s\n", ostr.str().c_str() );
#endif
return false; return false;
} }
@ -668,13 +582,10 @@ bool SCENEGRAPH::ReadCache( std::istream& aFile, SGNODE* parentNode )
if( !sp->ReadCache( aFile, this ) ) if( !sp->ReadCache( aFile, this ) )
{ {
#ifdef DEBUG wxLogTrace( MASK_3D_SG,
std::ostringstream ostr; "%s:%s:%d * [INFO] corrupt data; corrupt data while reading shape at "
ostr << __FILE__ << ": " << __FUNCTION__ << ": " << __LINE__ << "\n"; "position %ul", __FILE__, __FUNCTION__, __LINE__,
ostr << " * [INFO] corrupt data while reading shape '"; static_cast<unsigned long>( aFile.tellg() ) );
ostr << name << "' pos " << aFile.tellg();
wxLogTrace( MASK_3D_SG, "%s\n", ostr.str().c_str() );
#endif
return false; return false;
} }
@ -685,13 +596,10 @@ bool SCENEGRAPH::ReadCache( std::istream& aFile, SGNODE* parentNode )
{ {
if( S3D::SGTYPE_SHAPE != S3D::ReadTag( aFile, name ) ) if( S3D::SGTYPE_SHAPE != S3D::ReadTag( aFile, name ) )
{ {
#ifdef DEBUG wxLogTrace( MASK_3D_SG,
std::ostringstream ostr; "%s:%s:%d * [INFO] corrupt data; bad ref shape tag at position %ul",
ostr << __FILE__ << ": " << __FUNCTION__ << ": " << __LINE__ << "\n"; __FILE__, __FUNCTION__, __LINE__,
ostr << " * [INFO] corrupt data; bad ref shape tag at position "; static_cast<unsigned long>( aFile.tellg() ) );
ostr << aFile.tellg();
wxLogTrace( MASK_3D_SG, "%s\n", ostr.str().c_str() );
#endif
return false; return false;
} }
@ -700,26 +608,20 @@ bool SCENEGRAPH::ReadCache( std::istream& aFile, SGNODE* parentNode )
if( !sp ) if( !sp )
{ {
#ifdef DEBUG wxLogTrace( MASK_3D_SG,
std::ostringstream ostr; "%s:%s:%d * [INFO] corrupt data: cannot find ref shape at position %ul",
ostr << __FILE__ << ": " << __FUNCTION__ << ": " << __LINE__ << "\n"; __FILE__, __FUNCTION__, __LINE__,
ostr << " * [INFO] corrupt data: cannot find ref shape '"; static_cast<unsigned long>( aFile.tellg() ) );
ostr << name << "' pos " << aFile.tellg();
wxLogTrace( MASK_3D_SG, "%s\n", ostr.str().c_str() );
#endif
return false; return false;
} }
if( S3D::SGTYPE_SHAPE != sp->GetNodeType() ) if( S3D::SGTYPE_SHAPE != sp->GetNodeType() )
{ {
#ifdef DEBUG wxLogTrace( MASK_3D_SG,
std::ostringstream ostr; "%s:%s:%d * [INFO] corrupt data: type is not SGSHAPE at position %ul",
ostr << __FILE__ << ": " << __FUNCTION__ << ": " << __LINE__ << "\n"; __FILE__, __FUNCTION__, __LINE__,
ostr << " * [INFO] corrupt data: type is not SGSHAPE '"; static_cast<unsigned long>( aFile.tellg() ) );
ostr << name << "' pos " << aFile.tellg();
wxLogTrace( MASK_3D_SG, "%s\n", ostr.str().c_str() );
#endif
return false; return false;
} }
@ -734,21 +636,27 @@ bool SCENEGRAPH::ReadCache( std::istream& aFile, SGNODE* parentNode )
} }
bool SCENEGRAPH::Prepare( const glm::dmat4* aTransform, bool SCENEGRAPH::Prepare( const glm::dmat4* aTransform, S3D::MATLIST& materials,
S3D::MATLIST& materials, std::vector< SMESH >& meshes ) std::vector< SMESH >& meshes )
{ {
// calculate the accumulated transform // calculate the accumulated transform
double rX, rY, rZ; double rX, rY, rZ;
// rotation // rotation
rotation_axis.GetVector( rX, rY, rZ ); rotation_axis.GetVector( rX, rY, rZ );
glm::dmat4 rM = glm::rotate( glm::dmat4( 1.0 ), rotation_angle, glm::dvec3( rX, rY, rZ ) ); glm::dmat4 rM = glm::rotate( glm::dmat4( 1.0 ), rotation_angle, glm::dvec3( rX, rY, rZ ) );
// translation // translation
glm::dmat4 tM = glm::translate( glm::dmat4( 1.0 ), glm::dvec3( translation.x, translation.y, translation.z ) ); glm::dmat4 tM = glm::translate( glm::dmat4( 1.0 ), glm::dvec3( translation.x, translation.y,
translation.z ) );
// center // center
glm::dmat4 cM = glm::translate( glm::dmat4( 1.0 ), glm::dvec3( center.x, center.y, center.z ) ); glm::dmat4 cM = glm::translate( glm::dmat4( 1.0 ), glm::dvec3( center.x, center.y, center.z ) );
glm::dmat4 ncM = glm::translate( glm::dmat4( 1.0 ), glm::dvec3( -center.x, -center.y, -center.z ) ); glm::dmat4 ncM = glm::translate( glm::dmat4( 1.0 ), glm::dvec3( -center.x, -center.y,
-center.z ) );
// scale // scale
glm::dmat4 sM = glm::scale( glm::dmat4( 1.0 ), glm::dvec3( scale.x, scale.y, scale.z ) ); glm::dmat4 sM = glm::scale( glm::dmat4( 1.0 ), glm::dvec3( scale.x, scale.y, scale.z ) );
// scaleOrientation // scaleOrientation
scale_axis.GetVector( rX, rY, rZ ); scale_axis.GetVector( rX, rY, rZ );
glm::dmat4 srM = glm::rotate( glm::dmat4( 1.0 ), scale_angle, glm::dvec3( rX, rY, rZ ) ); glm::dmat4 srM = glm::rotate( glm::dmat4( 1.0 ), scale_angle, glm::dvec3( rX, rY, rZ ) );
@ -760,7 +668,7 @@ bool SCENEGRAPH::Prepare( const glm::dmat4* aTransform,
// tx0 = tM * cM * rM * srM * sM * nsrM * ncM // tx0 = tM * cM * rM * srM * sM * nsrM * ncM
glm::dmat4 tx0; glm::dmat4 tx0;
if( NULL != aTransform ) if( nullptr != aTransform )
tx0 = (*aTransform) * tM * cM * rM * srM * sM * nsrM * ncM; tx0 = (*aTransform) * tM * cM * rM * srM * sM * nsrM * ncM;
else else
tx0 = tM * cM * rM * srM * sM * nsrM * ncM; tx0 = tM * cM * rM * srM * sM * nsrM * ncM;
@ -788,7 +696,7 @@ bool SCENEGRAPH::Prepare( const glm::dmat4* aTransform,
++sL; ++sL;
} }
} while(0); } while( 0 );
// prepare all transforms // prepare all transforms
do do
@ -811,7 +719,7 @@ bool SCENEGRAPH::Prepare( const glm::dmat4* aTransform,
++sL; ++sL;
} }
} while(0); } while( 0 );
return ok; return ok;
} }

View File

@ -2,6 +2,7 @@
* This program source code file is part of KiCad, a free EDA CAD application. * This program source code file is part of KiCad, a free EDA CAD application.
* *
* Copyright (C) 2015 Cirilo Bernardo <cirilo.bernardo@gmail.com> * Copyright (C) 2015 Cirilo Bernardo <cirilo.bernardo@gmail.com>
* Copyright (C) 2020 KiCad Developers, see AUTHORS.txt for contributors.
* *
* This program is free software; you can redistribute it and/or * This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License * modify it under the terms of the GNU General Public License
@ -23,10 +24,6 @@
/** /**
* @file scenegraph.h * @file scenegraph.h
* defines the basic data set required to represent a 3D model;
* this model must remain compatible with VRML2.0 in order to
* facilitate VRML export of scene graph data created by available
* 3D plugins.
*/ */
@ -38,38 +35,18 @@
class SGSHAPE; class SGSHAPE;
/**
* Define the basic data set required to represent a 3D model.
*
* This model must remain compatible with VRML2.0 in order to facilitate VRML export of
* scene graph data created by available 3D plugins.
*/
class SCENEGRAPH : public SGNODE class SCENEGRAPH : public SGNODE
{ {
private:
// The following are items which may be defined for reuse
// in a VRML output file. They do not necessarily correspond
// to the use of DEF within a VRML input file; it is the
// responsibility of the plugin to perform any necessary
// conversions to comply with the restrictions imposed by
// this scene graph structure
std::vector< SCENEGRAPH* > m_Transforms; // local Transform nodes
std::vector< SGSHAPE* > m_Shape; // local Shape nodes
std::vector< SCENEGRAPH* > m_RTransforms; // referenced Transform nodes
std::vector< SGSHAPE* > m_RShape; // referenced Shape nodes
void unlinkNode( const SGNODE* aNode, bool isChild );
bool addNode( SGNODE* aNode, bool isChild );
public: public:
void unlinkChildNode( const SGNODE* aNode ) override; void unlinkChildNode( const SGNODE* aNode ) override;
void unlinkRefNode( const SGNODE* aNode ) override; void unlinkRefNode( const SGNODE* aNode ) override;
public:
// note: order of transformation is Translate, Rotate, Offset
SGPOINT center;
SGPOINT translation;
SGVECTOR rotation_axis;
double rotation_angle; // radians
SGPOINT scale;
SGVECTOR scale_axis;
double scale_angle; // radians
SCENEGRAPH( SGNODE* aParent ); SCENEGRAPH( SGNODE* aParent );
virtual ~SCENEGRAPH(); virtual ~SCENEGRAPH();
@ -84,8 +61,35 @@ public:
bool WriteCache( std::ostream& aFile, SGNODE* parentNode ) override; bool WriteCache( std::ostream& aFile, SGNODE* parentNode ) override;
bool ReadCache( std::istream& aFile, SGNODE* parentNode ) override; bool ReadCache( std::istream& aFile, SGNODE* parentNode ) override;
bool Prepare( const glm::dmat4* aTransform, bool Prepare( const glm::dmat4* aTransform, S3D::MATLIST& materials,
S3D::MATLIST& materials, std::vector< SMESH >& meshes ); std::vector< SMESH >& meshes );
private:
void unlinkNode( const SGNODE* aNode, bool isChild );
bool addNode( SGNODE* aNode, bool isChild );
public:
// note: order of transformation is Translate, Rotate, Offset
SGPOINT center;
SGPOINT translation;
SGVECTOR rotation_axis;
double rotation_angle; // radians
SGPOINT scale;
SGVECTOR scale_axis;
double scale_angle; // radians
private:
// The following are items which may be defined for reuse
// in a VRML output file. They do not necessarily correspond
// to the use of DEF within a VRML input file; it is the
// responsibility of the plugin to perform any necessary
// conversions to comply with the restrictions imposed by
// this scene graph structure
std::vector< SCENEGRAPH* > m_Transforms; // local Transform nodes
std::vector< SGSHAPE* > m_Shape; // local Shape nodes
std::vector< SCENEGRAPH* > m_RTransforms; // referenced Transform nodes
std::vector< SGSHAPE* > m_RShape; // referenced Shape nodes
}; };
/* /*

View File

@ -2,6 +2,7 @@
* This program source code file is part of KiCad, a free EDA CAD application. * This program source code file is part of KiCad, a free EDA CAD application.
* *
* Copyright (C) 2015-2017 Cirilo Bernardo <cirilo.bernardo@gmail.com> * Copyright (C) 2015-2017 Cirilo Bernardo <cirilo.bernardo@gmail.com>
* Copyright (C) 2020 KiCad Developers, see AUTHORS.txt for contributors.
* *
* This program is free software; you can redistribute it and/or * This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License * modify it under the terms of the GNU General Public License
@ -29,7 +30,8 @@
#include "3d_cache/sg/sg_appearance.h" #include "3d_cache/sg/sg_appearance.h"
#include "3d_cache/sg/sg_helpers.h" #include "3d_cache/sg/sg_helpers.h"
SGAPPEARANCE::SGAPPEARANCE( SGNODE* aParent ) : SGNODE( aParent)
SGAPPEARANCE::SGAPPEARANCE( SGNODE* aParent ) : SGNODE( aParent )
{ {
m_SGtype = S3D::SGTYPE_APPEARANCE; m_SGtype = S3D::SGTYPE_APPEARANCE;
@ -39,36 +41,28 @@ SGAPPEARANCE::SGAPPEARANCE( SGNODE* aParent ) : SGNODE( aParent)
transparency = 0.0f; transparency = 0.0f;
diffuse.SetColor( 0.8f, 0.8f, 0.8f ); diffuse.SetColor( 0.8f, 0.8f, 0.8f );
if( NULL != aParent && S3D::SGTYPE_SHAPE != aParent->GetNodeType() ) if( nullptr != aParent && S3D::SGTYPE_SHAPE != aParent->GetNodeType() )
{ {
m_Parent = NULL; m_Parent = nullptr;
#ifdef DEBUG wxLogTrace( MASK_3D_SG, "%s:%s:%d * [BUG] inappropriate parent to SGAPPEARANCE (type %s )",
std::ostringstream ostr; __FILE__, __FUNCTION__, __LINE__, aParent->GetNodeType() );
ostr << __FILE__ << ": " << __FUNCTION__ << ": " << __LINE__ << "\n";
ostr << " * [BUG] inappropriate parent to SGAPPEARANCE (type ";
ostr << aParent->GetNodeType() << ")";
wxLogTrace( MASK_3D_SG, "%s\n", ostr.str().c_str() );
#endif
} }
else if( NULL != aParent && S3D::SGTYPE_SHAPE == aParent->GetNodeType() ) else if( nullptr != aParent && S3D::SGTYPE_SHAPE == aParent->GetNodeType() )
{ {
m_Parent->AddChildNode( this ); m_Parent->AddChildNode( this );
} }
return;
} }
SGAPPEARANCE::~SGAPPEARANCE() SGAPPEARANCE::~SGAPPEARANCE()
{ {
return;
} }
bool SGAPPEARANCE::SetParent( SGNODE* aParent, bool notify ) bool SGAPPEARANCE::SetParent( SGNODE* aParent, bool notify )
{ {
if( NULL != m_Parent ) if( nullptr != m_Parent )
{ {
if( aParent == m_Parent ) if( aParent == m_Parent )
return true; return true;
@ -77,14 +71,14 @@ bool SGAPPEARANCE::SetParent( SGNODE* aParent, bool notify )
if( notify ) if( notify )
m_Parent->unlinkChildNode( this ); m_Parent->unlinkChildNode( this );
m_Parent = NULL; m_Parent = nullptr;
if( NULL == aParent ) if( nullptr == aParent )
return true; return true;
} }
// only a SGSHAPE may be parent to a SGAPPEARANCE // only a SGSHAPE may be parent to a SGAPPEARANCE
if( NULL != aParent && S3D::SGTYPE_SHAPE != aParent->GetNodeType() ) if( nullptr != aParent && S3D::SGTYPE_SHAPE != aParent->GetNodeType() )
return false; return false;
m_Parent = aParent; m_Parent = aParent;
@ -104,17 +98,7 @@ bool SGAPPEARANCE::SetEmissive( float aRVal, float aGVal, float aBVal )
bool SGAPPEARANCE::SetEmissive( const SGCOLOR* aRGBColor ) bool SGAPPEARANCE::SetEmissive( const SGCOLOR* aRGBColor )
{ {
if( NULL == aRGBColor ) wxCHECK_MSG( aRGBColor, false, "NULL pointer passed for aRGBColor" );
{
#ifdef DEBUG
std::ostringstream ostr;
ostr << __FILE__ << ": " << __FUNCTION__ << ": " << __LINE__ << "\n";
ostr << " * [BUG] NULL pointer passed for aRGBColor";
wxLogTrace( MASK_3D_SG, "%s\n", ostr.str().c_str() );
#endif
return false;
}
return emissive.SetColor( aRGBColor ); return emissive.SetColor( aRGBColor );
} }
@ -134,17 +118,7 @@ bool SGAPPEARANCE::SetDiffuse( float aRVal, float aGVal, float aBVal )
bool SGAPPEARANCE::SetDiffuse( const SGCOLOR* aRGBColor ) bool SGAPPEARANCE::SetDiffuse( const SGCOLOR* aRGBColor )
{ {
if( NULL == aRGBColor ) wxCHECK_MSG( aRGBColor, false, "NULL pointer passed for aRGBColor" );
{
#ifdef DEBUG
std::ostringstream ostr;
ostr << __FILE__ << ": " << __FUNCTION__ << ": " << __LINE__ << "\n";
ostr << " * [BUG] NULL pointer passed for aRGBColor";
wxLogTrace( MASK_3D_SG, "%s\n", ostr.str().c_str() );
#endif
return false;
}
return diffuse.SetColor( aRGBColor ); return diffuse.SetColor( aRGBColor );
} }
@ -164,17 +138,7 @@ bool SGAPPEARANCE::SetSpecular( float aRVal, float aGVal, float aBVal )
bool SGAPPEARANCE::SetSpecular( const SGCOLOR* aRGBColor ) bool SGAPPEARANCE::SetSpecular( const SGCOLOR* aRGBColor )
{ {
if( NULL == aRGBColor ) wxCHECK_MSG( aRGBColor, false, "NULL pointer passed for aRGBColor" );
{
#ifdef DEBUG
std::ostringstream ostr;
ostr << __FILE__ << ": " << __FUNCTION__ << ": " << __LINE__ << "\n";
ostr << " * [BUG] NULL pointer passed for aRGBColor";
wxLogTrace( MASK_3D_SG, "%s\n", ostr.str().c_str() );
#endif
return false;
}
return specular.SetColor( aRGBColor ); return specular.SetColor( aRGBColor );
} }
@ -193,17 +157,7 @@ bool SGAPPEARANCE::SetAmbient( float aRVal, float aGVal, float aBVal )
bool SGAPPEARANCE::SetAmbient( const SGCOLOR* aRGBColor ) bool SGAPPEARANCE::SetAmbient( const SGCOLOR* aRGBColor )
{ {
if( NULL == aRGBColor ) wxCHECK_MSG( aRGBColor, false, "NULL pointer passed for aRGBColor" );
{
#ifdef DEBUG
std::ostringstream ostr;
ostr << __FILE__ << ": " << __FUNCTION__ << ": " << __LINE__ << "\n";
ostr << " * [BUG] NULL pointer passed for aRGBColor";
wxLogTrace( MASK_3D_SG, "%s\n", ostr.str().c_str() );
#endif
return false;
}
return ambient.SetColor( aRGBColor ); return ambient.SetColor( aRGBColor );
} }
@ -215,66 +169,46 @@ bool SGAPPEARANCE::SetAmbient( const SGCOLOR& aRGBColor )
} }
SGNODE* SGAPPEARANCE::FindNode(const char *aNodeName, const SGNODE *aCaller) noexcept SGNODE* SGAPPEARANCE::FindNode( const char* aNodeName, const SGNODE* aCaller) noexcept
{ {
if( NULL == aNodeName || 0 == aNodeName[0] ) if( nullptr == aNodeName || 0 == aNodeName[0] )
return NULL; return nullptr;
if( !m_Name.compare( aNodeName ) ) if( !m_Name.compare( aNodeName ) )
return this; return this;
return NULL; return nullptr;
} }
void SGAPPEARANCE::unlinkChildNode( const SGNODE* aCaller ) noexcept void SGAPPEARANCE::unlinkChildNode( const SGNODE* aCaller ) noexcept
{ {
#ifdef DEBUG wxCHECK_MSG( aCaller, /* void */,
std::ostringstream ostr; "unexpected code branch; node should have no children or refs" );
ostr << __FILE__ << ": " << __FUNCTION__ << ": " << __LINE__ << "\n";
ostr << " * [BUG] unexpected code branch; node should have no children or refs";
wxLogTrace( MASK_3D_SG, "%s\n", ostr.str().c_str() );
#endif
return;
} }
void SGAPPEARANCE::unlinkRefNode( const SGNODE* aCaller ) noexcept void SGAPPEARANCE::unlinkRefNode( const SGNODE* aCaller ) noexcept
{ {
#ifdef DEBUG wxCHECK_MSG( aCaller, /* void */,
std::ostringstream ostr; "unexpected code branch; node should have no children or refs" );
ostr << __FILE__ << ": " << __FUNCTION__ << ": " << __LINE__ << "\n";
ostr << " * [BUG] unexpected code branch; node should have no children or refs";
wxLogTrace( MASK_3D_SG, "%s\n", ostr.str().c_str() );
#endif
return;
} }
bool SGAPPEARANCE::AddRefNode( SGNODE* aNode ) noexcept bool SGAPPEARANCE::AddRefNode( SGNODE* aNode ) noexcept
{ {
#ifdef DEBUG wxCHECK_MSG( aNode, false, "this node does not accept children or refs" );
std::ostringstream ostr;
ostr << __FILE__ << ": " << __FUNCTION__ << ": " << __LINE__ << "\n";
ostr << " * [BUG] this node does not accept children or refs";
wxLogTrace( MASK_3D_SG, "%s\n", ostr.str().c_str() );
#endif
// This is redundant but it keeps gcc from generating a warning on debug builds.
return false; return false;
} }
bool SGAPPEARANCE::AddChildNode( SGNODE* aNode ) noexcept bool SGAPPEARANCE::AddChildNode( SGNODE* aNode ) noexcept
{ {
#ifdef DEBUG wxCHECK_MSG( aNode, false, "this node does not accept children or refs" );
std::ostringstream ostr;
ostr << __FILE__ << ": " << __FUNCTION__ << ": " << __LINE__ << "\n";
ostr << " * [BUG] this node does not accept children or refs";
wxLogTrace( MASK_3D_SG, "%s\n", ostr.str().c_str() );
#endif
// This is redundant but it keeps gcc from generating a warning on debug builds.
return false; return false;
} }
@ -368,26 +302,16 @@ bool SGAPPEARANCE::WriteVRML( std::ostream& aFile, bool aReuseFlag )
bool SGAPPEARANCE::WriteCache( std::ostream& aFile, SGNODE* parentNode ) bool SGAPPEARANCE::WriteCache( std::ostream& aFile, SGNODE* parentNode )
{ {
if( NULL == parentNode ) if( nullptr == parentNode )
{ {
if( NULL == m_Parent ) wxCHECK_MSG( m_Parent, false, "corrupt data; m_aParent is NULL" );
{
#ifdef DEBUG
std::ostringstream ostr;
ostr << __FILE__ << ": " << __FUNCTION__ << ": " << __LINE__ << "\n";
ostr << " * [BUG] corrupt data; m_aParent is NULL";
wxLogTrace( MASK_3D_SG, "%s\n", ostr.str().c_str() );
#endif
return false;
}
SGNODE* np = m_Parent; SGNODE* np = m_Parent;
while( NULL != np->GetParent() ) while( nullptr != np->GetParent() )
np = np->GetParent(); np = np->GetParent();
if( np->WriteCache( aFile, NULL ) ) if( np->WriteCache( aFile, nullptr ) )
{ {
m_written = true; m_written = true;
return true; return true;
@ -396,34 +320,19 @@ bool SGAPPEARANCE::WriteCache( std::ostream& aFile, SGNODE* parentNode )
return false; return false;
} }
if( parentNode != m_Parent ) wxCHECK_MSG( parentNode == m_Parent, false, "corrupt data; parentNode != m_aParent" );
{
#ifdef DEBUG
std::ostringstream ostr;
ostr << __FILE__ << ": " << __FUNCTION__ << ": " << __LINE__ << "\n";
ostr << " * [BUG] corrupt data; parentNode != m_aParent";
wxLogTrace( MASK_3D_SG, "%s\n", ostr.str().c_str() );
#endif
return false;
}
if( !aFile.good() ) if( !aFile.good() )
{ {
#ifdef DEBUG wxLogTrace( MASK_3D_SG, "%s:%s:%d * [INFO] bad stream", __FILE__, __FUNCTION__, __LINE__ );
std::ostringstream ostr;
ostr << __FILE__ << ": " << __FUNCTION__ << ": " << __LINE__ << "\n";
ostr << " * [INFO] bad stream";
wxLogTrace( MASK_3D_SG, "%s\n", ostr.str().c_str() );
#endif
return false; return false;
} }
aFile << "[" << GetName() << "]"; aFile << "[" << GetName() << "]";
S3D::WriteColor( aFile, ambient ); S3D::WriteColor( aFile, ambient );
aFile.write( (char*)&shininess, sizeof(shininess) ); aFile.write( (char*) &shininess, sizeof( shininess ) );
aFile.write( (char*)&transparency, sizeof(transparency) ); aFile.write( (char*) &transparency, sizeof( transparency ) );
S3D::WriteColor( aFile, diffuse ); S3D::WriteColor( aFile, diffuse );
S3D::WriteColor( aFile, emissive ); S3D::WriteColor( aFile, emissive );
S3D::WriteColor( aFile, specular ); S3D::WriteColor( aFile, specular );
@ -439,8 +348,8 @@ bool SGAPPEARANCE::WriteCache( std::ostream& aFile, SGNODE* parentNode )
bool SGAPPEARANCE::ReadCache( std::istream& aFile, SGNODE* parentNode ) bool SGAPPEARANCE::ReadCache( std::istream& aFile, SGNODE* parentNode )
{ {
S3D::ReadColor( aFile, ambient ); S3D::ReadColor( aFile, ambient );
aFile.read( (char*)&shininess, sizeof(shininess) ); aFile.read( (char*) &shininess, sizeof( shininess ) );
aFile.read( (char*)&transparency, sizeof(transparency) ); aFile.read( (char*) &transparency, sizeof( transparency ) );
S3D::ReadColor( aFile, diffuse ); S3D::ReadColor( aFile, diffuse );
S3D::ReadColor( aFile, emissive ); S3D::ReadColor( aFile, emissive );
S3D::ReadColor( aFile, specular ); S3D::ReadColor( aFile, specular );

View File

@ -2,6 +2,7 @@
* This program source code file is part of KiCad, a free EDA CAD application. * This program source code file is part of KiCad, a free EDA CAD application.
* *
* Copyright (C) 2015-2017 Cirilo Bernardo <cirilo.bernardo@gmail.com> * Copyright (C) 2015-2017 Cirilo Bernardo <cirilo.bernardo@gmail.com>
* Copyright (C) 2020 KiCad Developers, see AUTHORS.txt for contributors.
* *
* This program is free software; you can redistribute it and/or * This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License * modify it under the terms of the GNU General Public License
@ -23,7 +24,6 @@
/** /**
* @file sg_appearance.h * @file sg_appearance.h
* defines the generic material appearance of a scenegraph object
*/ */
#ifndef SG_APPEARANCE_H #ifndef SG_APPEARANCE_H
@ -31,20 +31,15 @@
#include "3d_cache/sg/sg_node.h" #include "3d_cache/sg/sg_node.h"
/**
* Defines the generic material appearance of a scenegraph object.
*/
class SGAPPEARANCE : public SGNODE class SGAPPEARANCE : public SGNODE
{ {
public: public:
float shininess; // default 0.2
float transparency; // default 0.0
SGCOLOR ambient; // default 0.05317 0.17879 0.01804
SGCOLOR diffuse; // default 0.8 0.8 0.8
SGCOLOR emissive; // default 0.0 0.0 0.0
SGCOLOR specular; // default 0.0 0.0 0.0
void unlinkChildNode( const SGNODE* aNode ) noexcept override; void unlinkChildNode( const SGNODE* aNode ) noexcept override;
void unlinkRefNode( const SGNODE* aNode ) noexcept override; void unlinkRefNode( const SGNODE* aNode ) noexcept override;
public:
SGAPPEARANCE( SGNODE* aParent ); SGAPPEARANCE( SGNODE* aParent );
virtual ~SGAPPEARANCE(); virtual ~SGAPPEARANCE();
@ -75,6 +70,14 @@ public:
bool WriteCache( std::ostream& aFile, SGNODE* parentNode ) override; bool WriteCache( std::ostream& aFile, SGNODE* parentNode ) override;
bool ReadCache( std::istream& aFile, SGNODE* parentNode ) override; bool ReadCache( std::istream& aFile, SGNODE* parentNode ) override;
float shininess; // default 0.2
float transparency; // default 0.0
SGCOLOR ambient; // default 0.05317 0.17879 0.01804
SGCOLOR diffuse; // default 0.8 0.8 0.8
SGCOLOR emissive; // default 0.0 0.0 0.0
SGCOLOR specular; // default 0.0 0.0 0.0
}; };
#endif // SG_APPEARANCE_H #endif // SG_APPEARANCE_H

View File

@ -2,6 +2,7 @@
* This program source code file is part of KiCad, a free EDA CAD application. * This program source code file is part of KiCad, a free EDA CAD application.
* *
* Copyright (C) 2015 Cirilo Bernardo <cirilo.bernardo@gmail.com> * Copyright (C) 2015 Cirilo Bernardo <cirilo.bernardo@gmail.com>
* Copyright (C) 2020 KiCad Developers, see AUTHORS.txt for contributors.
* *
* This program is free software; you can redistribute it and/or * This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License * modify it under the terms of the GNU General Public License
@ -35,20 +36,14 @@ SGCOLOR::SGCOLOR()
red = 0.0; red = 0.0;
green = 0.0; green = 0.0;
blue = 0.0; blue = 0.0;
return;
} }
SGCOLOR::SGCOLOR( float aRVal, float aGVal, float aBVal ) SGCOLOR::SGCOLOR( float aRVal, float aGVal, float aBVal )
{ {
if( !checkRange( aRVal, aGVal, aBVal ) ) if( !checkRange( aRVal, aGVal, aBVal ) )
{ {
#ifdef DEBUG wxLogTrace( MASK_3D_SG, "%s:%s:%d * [BUG] invalid value passed to constructor",
std::ostringstream ostr; __FILE__, __FUNCTION__, __LINE__ );
ostr << __FILE__ << ": " << __FUNCTION__ << ": " << __LINE__ << "\n";
ostr << " * [BUG] invalid value passed to constructor";
wxLogTrace( MASK_3D_SG, "%s\n", ostr.str().c_str() );
#endif
red = 0.0; red = 0.0;
green = 0.0; green = 0.0;
blue = 0.0; blue = 0.0;
@ -58,7 +53,6 @@ SGCOLOR::SGCOLOR( float aRVal, float aGVal, float aBVal )
red = aRVal; red = aRVal;
green = aGVal; green = aGVal;
blue = aBVal; blue = aBVal;
return;
} }
@ -67,7 +61,6 @@ void SGCOLOR::GetColor( float& aRedVal, float& aGreenVal, float& aBlueVal ) cons
aRedVal = red; aRedVal = red;
aGreenVal = green; aGreenVal = green;
aBlueVal = blue; aBlueVal = blue;
return;
} }
@ -76,28 +69,16 @@ void SGCOLOR::GetColor( SGCOLOR& aColor ) const noexcept
aColor.red = red; aColor.red = red;
aColor.green = green; aColor.green = green;
aColor.blue = blue; aColor.blue = blue;
return;
} }
void SGCOLOR::GetColor( SGCOLOR* aColor ) const noexcept void SGCOLOR::GetColor( SGCOLOR* aColor ) const noexcept
{ {
if( NULL == aColor ) wxCHECK_MSG( aColor, /* void */, "NULL pointer passed for aRGBColor" );
{
#ifdef DEBUG
std::ostringstream ostr;
ostr << __FILE__ << ": " << __FUNCTION__ << ": " << __LINE__ << "\n";
ostr << " * [BUG] NULL pointer passed for aColor";
wxLogTrace( MASK_3D_SG, "%s\n", ostr.str().c_str() );
#endif
return;
}
aColor->red = red; aColor->red = red;
aColor->green = green; aColor->green = green;
aColor->blue = blue; aColor->blue = blue;
return;
} }
@ -125,17 +106,7 @@ bool SGCOLOR::SetColor( const SGCOLOR& aColor ) noexcept
bool SGCOLOR::SetColor( const SGCOLOR* aColor ) noexcept bool SGCOLOR::SetColor( const SGCOLOR* aColor ) noexcept
{ {
if( NULL == aColor ) wxCHECK_MSG( aColor, false, "NULL pointer passed for aRGBColor" );
{
#ifdef DEBUG
std::ostringstream ostr;
ostr << __FILE__ << ": " << __FUNCTION__ << ": " << __LINE__ << "\n";
ostr << " * [BUG] NULL pointer passed for aColor";
wxLogTrace( MASK_3D_SG, "%s\n", ostr.str().c_str() );
#endif
return false;
}
red = aColor->red; red = aColor->red;
green = aColor->green; green = aColor->green;
@ -150,36 +121,25 @@ bool SGCOLOR::checkRange( float aRedVal, float aGreenVal, float aBlueVal ) const
if( aRedVal < 0.0 || aRedVal > 1.0 ) if( aRedVal < 0.0 || aRedVal > 1.0 )
{ {
#ifdef DEBUG wxLogTrace( MASK_3D_SG, "%s:%s:%d * [BUG] invalid RED value: %g",
std::ostringstream ostr; __FILE__, __FUNCTION__, __LINE__, aRedVal );
ostr << __FILE__ << ": " << __FUNCTION__ << ": " << __LINE__ << "\n";
ostr << " * [BUG] invalid RED value: " << aRedVal;
wxLogTrace( MASK_3D_SG, "%s\n", ostr.str().c_str() );
#endif
ok = false; ok = false;
} }
if( aGreenVal < 0.0 || aGreenVal > 1.0 ) if( aGreenVal < 0.0 || aGreenVal > 1.0 )
{ {
#ifdef DEBUG wxLogTrace( MASK_3D_SG, "%s:%s:%d * [BUG] invalid GREEN value: %g",
if( ok ) __FILE__, __FUNCTION__, __LINE__, aGreenVal );
{
wxLogTrace( MASK_3D_SG, "%s:%s:%d\n", __FILE__, __FUNCTION__, __LINE__ );
}
wxLogTrace( MASK_3D_SG, " * [BUG] invalid GREEN value: %f\n", aGreenVal );
#endif
ok = false; ok = false;
} }
if( aBlueVal < 0.0 || aBlueVal > 1.0 ) if( aBlueVal < 0.0 || aBlueVal > 1.0 )
{ {
#ifdef DEBUG wxLogTrace( MASK_3D_SG, "%s:%s:%d * [BUG] invalid BLUE value: %g",
if( ok ) __FILE__, __FUNCTION__, __LINE__, aBlueVal );
{
wxLogTrace( MASK_3D_SG, "%s:%s:%d\n", __FILE__, __FUNCTION__, __LINE__ );
}
wxLogTrace( MASK_3D_SG, " * [BUG] invalid BLUE value: %f\n", aBlueVal );
#endif
ok = false; ok = false;
} }
@ -192,7 +152,6 @@ SGPOINT::SGPOINT()
x = 0.0; x = 0.0;
y = 0.0; y = 0.0;
z = 0.0; z = 0.0;
return;
} }
@ -209,7 +168,6 @@ void SGPOINT::GetPoint( double& aXVal, double& aYVal, double& aZVal ) noexcept
x = aXVal; x = aXVal;
y = aYVal; y = aYVal;
z = aZVal; z = aZVal;
return;
} }
@ -218,28 +176,16 @@ void SGPOINT::GetPoint( SGPOINT& aPoint ) noexcept
x = aPoint.x; x = aPoint.x;
y = aPoint.y; y = aPoint.y;
z = aPoint.z; z = aPoint.z;
return;
} }
void SGPOINT::GetPoint( SGPOINT* aPoint ) noexcept void SGPOINT::GetPoint( SGPOINT* aPoint ) noexcept
{ {
if( NULL == aPoint ) wxCHECK_MSG( aPoint, /* void */, "NULL pointer passed for aPoint" );
{
#ifdef DEBUG
std::ostringstream ostr;
ostr << __FILE__ << ": " << __FUNCTION__ << ": " << __LINE__ << "\n";
ostr << " * [BUG] NULL pointer passed for aPoint";
wxLogTrace( MASK_3D_SG, "%s\n", ostr.str().c_str() );
#endif
return;
}
x = aPoint->x; x = aPoint->x;
y = aPoint->y; y = aPoint->y;
z = aPoint->z; z = aPoint->z;
return;
} }
@ -248,7 +194,6 @@ void SGPOINT::SetPoint( double aXVal, double aYVal, double aZVal ) noexcept
x = aXVal; x = aXVal;
y = aYVal; y = aYVal;
z = aZVal; z = aZVal;
return;
} }
@ -257,7 +202,6 @@ void SGPOINT::SetPoint( const SGPOINT& aPoint ) noexcept
x = aPoint.x; x = aPoint.x;
y = aPoint.y; y = aPoint.y;
z = aPoint.z; z = aPoint.z;
return;
} }
@ -266,7 +210,6 @@ SGVECTOR::SGVECTOR()
vx = 0.0; vx = 0.0;
vy = 0.0; vy = 0.0;
vz = 1.0; vz = 1.0;
return;
} }
@ -276,7 +219,6 @@ SGVECTOR::SGVECTOR( double aXVal, double aYVal, double aZVal )
vy = aYVal; vy = aYVal;
vz = aZVal; vz = aZVal;
normalize(); normalize();
return;
} }
@ -285,7 +227,6 @@ void SGVECTOR::GetVector( double& aXVal, double& aYVal, double& aZVal ) const no
aXVal = vx; aXVal = vx;
aYVal = vy; aYVal = vy;
aZVal = vz; aZVal = vz;
return;
} }
@ -295,14 +236,12 @@ void SGVECTOR::SetVector( double aXVal, double aYVal, double aZVal )
vy = aYVal; vy = aYVal;
vz = aZVal; vz = aZVal;
normalize(); normalize();
return;
} }
void SGVECTOR::SetVector( const SGVECTOR& aVector ) void SGVECTOR::SetVector( const SGVECTOR& aVector )
{ {
aVector.GetVector( vx, vy, vz ); aVector.GetVector( vx, vy, vz );
return;
} }
@ -313,10 +252,9 @@ void SGVECTOR::normalize( void ) noexcept
double dz = vz * vz; double dz = vz * vz;
double dv2 = sqrt( dx + dy + dz ); double dv2 = sqrt( dx + dy + dz );
if( (dx + dy + dz) < 1e-8 ) if( ( dx + dy + dz ) < 1e-8 )
{ {
// use the default; the numbers are too small // use the default; the numbers are too small to be believable
// to be believable
vx = 0.0; vx = 0.0;
vy = 0.0; vy = 0.0;
vz = 1.0; vz = 1.0;
@ -326,8 +264,6 @@ void SGVECTOR::normalize( void ) noexcept
vx /= dv2; vx /= dv2;
vy /= dv2; vy /= dv2;
vz /= dv2; vz /= dv2;
return;
} }
@ -336,5 +272,4 @@ SGVECTOR& SGVECTOR::operator=( const SGVECTOR& source ) noexcept
vx = source.vx; vx = source.vx;
vy = source.vy; vy = source.vy;
vz = source.vz; vz = source.vz;
return *this;
} }

View File

@ -2,6 +2,7 @@
* This program source code file is part of KiCad, a free EDA CAD application. * This program source code file is part of KiCad, a free EDA CAD application.
* *
* Copyright (C) 2015-2017 Cirilo Bernardo <cirilo.bernardo@gmail.com> * Copyright (C) 2015-2017 Cirilo Bernardo <cirilo.bernardo@gmail.com>
* Copyright (C) 2020 KiCad Developers, see AUTHORS.txt for contributors.
* *
* This program is free software; you can redistribute it and/or * This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License * modify it under the terms of the GNU General Public License
@ -28,41 +29,34 @@
#include "3d_cache/sg/sg_colors.h" #include "3d_cache/sg/sg_colors.h"
#include "3d_cache/sg/sg_helpers.h" #include "3d_cache/sg/sg_helpers.h"
SGCOLORS::SGCOLORS( SGNODE* aParent ) : SGNODE( aParent ) SGCOLORS::SGCOLORS( SGNODE* aParent ) : SGNODE( aParent )
{ {
m_SGtype = S3D::SGTYPE_COLORS; m_SGtype = S3D::SGTYPE_COLORS;
if( NULL != aParent && S3D::SGTYPE_FACESET != aParent->GetNodeType() ) if( nullptr != aParent && S3D::SGTYPE_FACESET != aParent->GetNodeType() )
{ {
m_Parent = NULL; m_Parent = nullptr;
#ifdef DEBUG wxLogTrace( MASK_3D_SG, "%s:%s:%d * [BUG] inappropriate parent to SGCOLORS (type %s)",
std::ostringstream ostr; __FILE__, __FUNCTION__, __LINE__, aParent->GetNodeType() );
ostr << __FILE__ << ": " << __FUNCTION__ << ": " << __LINE__ << "\n";
ostr << " * [BUG] inappropriate parent to SGCOLORS (type ";
ostr << aParent->GetNodeType() << ")";
wxLogTrace( MASK_3D_SG, "%s\n", ostr.str().c_str() );
#endif
} }
else if( NULL != aParent && S3D::SGTYPE_FACESET == aParent->GetNodeType() ) else if( nullptr != aParent && S3D::SGTYPE_FACESET == aParent->GetNodeType() )
{ {
m_Parent->AddChildNode( this ); m_Parent->AddChildNode( this );
} }
return;
} }
SGCOLORS::~SGCOLORS() SGCOLORS::~SGCOLORS()
{ {
colors.clear(); colors.clear();
return;
} }
bool SGCOLORS::SetParent( SGNODE* aParent, bool notify ) bool SGCOLORS::SetParent( SGNODE* aParent, bool notify )
{ {
if( NULL != m_Parent ) if( nullptr != m_Parent )
{ {
if( aParent == m_Parent ) if( aParent == m_Parent )
return true; return true;
@ -71,14 +65,14 @@ bool SGCOLORS::SetParent( SGNODE* aParent, bool notify )
if( notify ) if( notify )
m_Parent->unlinkChildNode( this ); m_Parent->unlinkChildNode( this );
m_Parent = NULL; m_Parent = nullptr;
if( NULL == aParent ) if( nullptr == aParent )
return true; return true;
} }
// only a SGFACESET may be parent to a SGCOLORS // only a SGFACESET may be parent to a SGCOLORS
if( NULL != aParent && S3D::SGTYPE_FACESET != aParent->GetNodeType() ) if( nullptr != aParent && S3D::SGTYPE_FACESET != aParent->GetNodeType() )
return false; return false;
m_Parent = aParent; m_Parent = aParent;
@ -90,52 +84,33 @@ bool SGCOLORS::SetParent( SGNODE* aParent, bool notify )
} }
SGNODE* SGCOLORS::FindNode(const char *aNodeName, const SGNODE *aCaller) noexcept SGNODE* SGCOLORS::FindNode(const char* aNodeName, const SGNODE *aCaller) noexcept
{ {
if( NULL == aNodeName || 0 == aNodeName[0] ) if( nullptr == aNodeName || 0 == aNodeName[0] )
return NULL; return nullptr;
if( !m_Name.compare( aNodeName ) ) if( !m_Name.compare( aNodeName ) )
return this; return this;
return NULL; return nullptr;
} }
void SGCOLORS::unlinkChildNode( const SGNODE* aCaller ) noexcept void SGCOLORS::unlinkChildNode( const SGNODE* aCaller ) noexcept
{ {
#ifdef DEBUG wxCHECK( aCaller, /* void */ );
std::ostringstream ostr;
ostr << __FILE__ << ": " << __FUNCTION__ << ": " << __LINE__ << "\n";
ostr << " * [BUG] unexpected code branch; node should have no children or refs";
wxLogTrace( MASK_3D_SG, "%s\n", ostr.str().c_str() );
#endif
return;
} }
void SGCOLORS::unlinkRefNode( const SGNODE* aCaller ) noexcept void SGCOLORS::unlinkRefNode( const SGNODE* aCaller ) noexcept
{ {
#ifdef DEBUG wxCHECK( aCaller, /* void */ );
std::ostringstream ostr;
ostr << __FILE__ << ": " << __FUNCTION__ << ": " << __LINE__ << "\n";
ostr << " * [BUG] unexpected code branch; node should have no children or refs";
wxLogTrace( MASK_3D_SG, "%s\n", ostr.str().c_str() );
#endif
return;
} }
bool SGCOLORS::AddRefNode( SGNODE* aNode ) noexcept bool SGCOLORS::AddRefNode( SGNODE* aNode ) noexcept
{ {
#ifdef DEBUG wxCHECK( aNode, false );
std::ostringstream ostr;
ostr << __FILE__ << ": " << __FUNCTION__ << ": " << __LINE__ << "\n";
ostr << " * [BUG] this node does not accept children or refs";
wxLogTrace( MASK_3D_SG, "%s\n", ostr.str().c_str() );
#endif
return false; return false;
} }
@ -143,12 +118,7 @@ bool SGCOLORS::AddRefNode( SGNODE* aNode ) noexcept
bool SGCOLORS::AddChildNode( SGNODE* aNode ) noexcept bool SGCOLORS::AddChildNode( SGNODE* aNode ) noexcept
{ {
#ifdef DEBUG wxCHECK( aNode, false );
std::ostringstream ostr;
ostr << __FILE__ << ": " << __FUNCTION__ << ": " << __LINE__ << "\n";
ostr << " * [BUG] this node does not accept children or refs";
wxLogTrace( MASK_3D_SG, "%s\n", ostr.str().c_str() );
#endif
return false; return false;
} }
@ -159,7 +129,7 @@ bool SGCOLORS::GetColorList( size_t& aListSize, SGCOLOR*& aColorList )
if( colors.empty() ) if( colors.empty() )
{ {
aListSize = 0; aListSize = 0;
aColorList = NULL; aColorList = nullptr;
return false; return false;
} }
@ -173,7 +143,7 @@ void SGCOLORS::SetColorList( size_t aListSize, const SGCOLOR* aColorList )
{ {
colors.clear(); colors.clear();
if( 0 == aListSize || NULL == aColorList ) if( 0 == aListSize || nullptr == aColorList )
return; return;
for( size_t i = 0; i < aListSize; ++i ) for( size_t i = 0; i < aListSize; ++i )
@ -267,26 +237,16 @@ bool SGCOLORS::WriteVRML( std::ostream& aFile, bool aReuseFlag )
bool SGCOLORS::WriteCache( std::ostream& aFile, SGNODE* parentNode ) bool SGCOLORS::WriteCache( std::ostream& aFile, SGNODE* parentNode )
{ {
if( NULL == parentNode ) if( nullptr == parentNode )
{ {
if( NULL == m_Parent ) wxCHECK( m_Parent, false );
{
#ifdef DEBUG
std::ostringstream ostr;
ostr << __FILE__ << ": " << __FUNCTION__ << ": " << __LINE__ << "\n";
ostr << " * [BUG] corrupt data; m_aParent is NULL";
wxLogTrace( MASK_3D_SG, "%s\n", ostr.str().c_str() );
#endif
return false;
}
SGNODE* np = m_Parent; SGNODE* np = m_Parent;
while( NULL != np->GetParent() ) while( nullptr != np->GetParent() )
np = np->GetParent(); np = np->GetParent();
if( np->WriteCache( aFile, NULL ) ) if( np->WriteCache( aFile, nullptr ) )
{ {
m_written = true; m_written = true;
return true; return true;
@ -295,26 +255,11 @@ bool SGCOLORS::WriteCache( std::ostream& aFile, SGNODE* parentNode )
return false; return false;
} }
if( parentNode != m_Parent ) wxCHECK( parentNode == m_Parent, false );
{
#ifdef DEBUG
std::ostringstream ostr;
ostr << __FILE__ << ": " << __FUNCTION__ << ": " << __LINE__ << "\n";
ostr << " * [BUG] corrupt data; parentNode != m_aParent";
wxLogTrace( MASK_3D_SG, "%s\n", ostr.str().c_str() );
#endif
return false;
}
if( !aFile.good() ) if( !aFile.good() )
{ {
#ifdef DEBUG wxLogTrace( MASK_3D_SG, "%s:%s:%d * [INFO] bad stream", __FILE__, __FUNCTION__, __LINE__ );
std::ostringstream ostr;
ostr << __FILE__ << ": " << __FUNCTION__ << ": " << __LINE__ << "\n";
ostr << " * [INFO] bad stream";
wxLogTrace( MASK_3D_SG, "%s\n", ostr.str().c_str() );
#endif
return false; return false;
} }
@ -336,20 +281,10 @@ bool SGCOLORS::WriteCache( std::ostream& aFile, SGNODE* parentNode )
bool SGCOLORS::ReadCache( std::istream& aFile, SGNODE* parentNode ) bool SGCOLORS::ReadCache( std::istream& aFile, SGNODE* parentNode )
{ {
if( !colors.empty() ) wxCHECK( colors.empty(), false );
{
#ifdef DEBUG
std::ostringstream ostr;
ostr << __FILE__ << ": " << __FUNCTION__ << ": " << __LINE__ << "\n";
ostr << " * [BUG] non-empty node";
wxLogTrace( MASK_3D_SG, "%s\n", ostr.str().c_str() );
#endif
return false;
}
size_t ncolors; size_t ncolors;
aFile.read( (char*)&ncolors, sizeof(size_t) ); aFile.read( (char*) &ncolors, sizeof( size_t ) );
SGCOLOR tmp; SGCOLOR tmp;
if( aFile.fail() ) if( aFile.fail() )

View File

@ -2,6 +2,7 @@
* This program source code file is part of KiCad, a free EDA CAD application. * This program source code file is part of KiCad, a free EDA CAD application.
* *
* Copyright (C) 2015-2017 Cirilo Bernardo <cirilo.bernardo@gmail.com> * Copyright (C) 2015-2017 Cirilo Bernardo <cirilo.bernardo@gmail.com>
* Copyright (C) 2020 KiCad Developers, see AUTHORS.txt for contributors.
* *
* This program is free software; you can redistribute it and/or * This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License * modify it under the terms of the GNU General Public License
@ -23,7 +24,6 @@
/** /**
* @file sg_colors.h * @file sg_colors.h
* defines an RGB color set for a scenegraph object
*/ */
#ifndef SG_COLORS_H #ifndef SG_COLORS_H
@ -32,20 +32,20 @@
#include <vector> #include <vector>
#include "3d_cache/sg/sg_node.h" #include "3d_cache/sg/sg_node.h"
/**
* Define an RGB color set for a scenegraph object.
*/
class SGCOLORS : public SGNODE class SGCOLORS : public SGNODE
{ {
public:
std::vector< SGCOLOR > colors;
void unlinkChildNode( const SGNODE* aNode ) noexcept override;
void unlinkRefNode( const SGNODE* aNode ) noexcept override;
public: public:
SGCOLORS( SGNODE* aParent ); SGCOLORS( SGNODE* aParent );
virtual ~SGCOLORS(); virtual ~SGCOLORS();
virtual bool SetParent( SGNODE* aParent, bool notify = true ) override; virtual bool SetParent( SGNODE* aParent, bool notify = true ) override;
void unlinkChildNode( const SGNODE* aNode ) noexcept override;
void unlinkRefNode( const SGNODE* aNode ) noexcept override;
SGNODE* FindNode(const char *aNodeName, const SGNODE *aCaller) noexcept override; SGNODE* FindNode(const char *aNodeName, const SGNODE *aCaller) noexcept override;
bool AddRefNode( SGNODE* aNode ) noexcept override; bool AddRefNode( SGNODE* aNode ) noexcept override;
bool AddChildNode( SGNODE* aNode ) noexcept override; bool AddChildNode( SGNODE* aNode ) noexcept override;
@ -60,6 +60,8 @@ public:
bool WriteCache( std::ostream& aFile, SGNODE* parentNode ) override; bool WriteCache( std::ostream& aFile, SGNODE* parentNode ) override;
bool ReadCache( std::istream& aFile, SGNODE* parentNode ) override; bool ReadCache( std::istream& aFile, SGNODE* parentNode ) override;
std::vector< SGCOLOR > colors;
}; };
#endif // SG_COLORS_H #endif // SG_COLORS_H

View File

@ -2,6 +2,7 @@
* This program source code file is part of KiCad, a free EDA CAD application. * This program source code file is part of KiCad, a free EDA CAD application.
* *
* Copyright (C) 2015 Cirilo Bernardo <cirilo.bernardo@gmail.com> * Copyright (C) 2015 Cirilo Bernardo <cirilo.bernardo@gmail.com>
* Copyright (C) 2020 KiCad Developers, see AUTHORS.txt for contributors.
* *
* This program is free software; you can redistribute it and/or * This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License * modify it under the terms of the GNU General Public License
@ -32,14 +33,11 @@ SGCOORDINDEX::SGCOORDINDEX( SGNODE* aParent ) : SGINDEX( aParent )
{ {
m_Parent->AddChildNode( this ); m_Parent->AddChildNode( this );
} }
return;
} }
SGCOORDINDEX::~SGCOORDINDEX() SGCOORDINDEX::~SGCOORDINDEX()
{ {
return;
} }
@ -49,6 +47,4 @@ void SGCOORDINDEX::GatherCoordIndices( std::vector< int >& aIndexList )
return; return;
aIndexList.insert( aIndexList.end(), index.begin(), index.end() ); aIndexList.insert( aIndexList.end(), index.begin(), index.end() );
return;
} }

View File

@ -2,6 +2,7 @@
* This program source code file is part of KiCad, a free EDA CAD application. * This program source code file is part of KiCad, a free EDA CAD application.
* *
* Copyright (C) 2015 Cirilo Bernardo <cirilo.bernardo@gmail.com> * Copyright (C) 2015 Cirilo Bernardo <cirilo.bernardo@gmail.com>
* Copyright (C) 2020 KiCad Developers, see AUTHORS.txt for contributors.
* *
* This program is free software; you can redistribute it and/or * This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License * modify it under the terms of the GNU General Public License
@ -23,7 +24,6 @@
/** /**
* @file sg_coordindex.h * @file sg_coordindex.h
* defines an coordinate index set for a scenegraph object
*/ */
#ifndef SG_COORDINDEX_H #ifndef SG_COORDINDEX_H
@ -32,14 +32,12 @@
#include "3d_cache/sg/sg_index.h" #include "3d_cache/sg/sg_index.h"
/** /**
* SGCOORDINDEX * An object to maintain a coordinate index list.
* is a class which maintains a coordinate index list. Users *
* must ensure that coordinate indices are specified as * Users must ensure that coordinate indices are specified as triplets (triangular faces)
* triplets (triangular faces) since no checking is performed. * since no checking is performed. In instances where it is not possible to determine which
* In instances where it is not possible to determine which * side of the triangle is to be rendered (for example IGES entities) then the user must
* side of the triangle is to be rendered (for example IGES * supply each triplet in both point orders.
* entities) then the user must supply each triplet in both
* point orders.
*/ */
class SGCOORDINDEX : public SGINDEX class SGCOORDINDEX : public SGINDEX
{ {
@ -48,9 +46,7 @@ public:
virtual ~SGCOORDINDEX(); virtual ~SGCOORDINDEX();
/** /**
* Function GatherCoordIndices * Add all coordinate indices to the given list in preparation for a normals calculation.
* adds all coordinate indices to the given list
* in preparation for a normals calculation
*/ */
void GatherCoordIndices( std::vector< int >& aIndexList ); void GatherCoordIndices( std::vector< int >& aIndexList );
}; };

View File

@ -2,6 +2,7 @@
* This program source code file is part of KiCad, a free EDA CAD application. * This program source code file is part of KiCad, a free EDA CAD application.
* *
* Copyright (C) 2015-2017 Cirilo Bernardo <cirilo.bernardo@gmail.com> * Copyright (C) 2015-2017 Cirilo Bernardo <cirilo.bernardo@gmail.com>
* Copyright (C) 2020 KiCad Developers, see AUTHORS.txt for contributors.
* *
* This program is free software; you can redistribute it and/or * This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License * modify it under the terms of the GNU General Public License
@ -35,37 +36,29 @@ SGCOORDS::SGCOORDS( SGNODE* aParent ) : SGNODE( aParent )
{ {
m_SGtype = S3D::SGTYPE_COORDS; m_SGtype = S3D::SGTYPE_COORDS;
if( NULL != aParent && S3D::SGTYPE_FACESET != aParent->GetNodeType() ) if( nullptr != aParent && S3D::SGTYPE_FACESET != aParent->GetNodeType() )
{ {
m_Parent = NULL; m_Parent = nullptr;
#ifdef DEBUG wxLogTrace( MASK_3D_SG, "%s:%s:%d * [BUG] inappropriate parent to SGCOORDS (type %s)",
std::ostringstream ostr; __FILE__, __FUNCTION__, __LINE__, aParent->GetNodeType() );
ostr << __FILE__ << ": " << __FUNCTION__ << ": " << __LINE__ << "\n";
ostr << " * [BUG] inappropriate parent to SGCOORDS (type ";
ostr << aParent->GetNodeType() << ")";
wxLogTrace( MASK_3D_SG, "%s\n", ostr.str().c_str() );
#endif
} }
else if( NULL != aParent && S3D::SGTYPE_FACESET == aParent->GetNodeType() ) else if( nullptr != aParent && S3D::SGTYPE_FACESET == aParent->GetNodeType() )
{ {
m_Parent->AddChildNode( this ); m_Parent->AddChildNode( this );
} }
return;
} }
SGCOORDS::~SGCOORDS() SGCOORDS::~SGCOORDS()
{ {
coords.clear(); coords.clear();
return;
} }
bool SGCOORDS::SetParent( SGNODE* aParent, bool notify ) bool SGCOORDS::SetParent( SGNODE* aParent, bool notify )
{ {
if( NULL != m_Parent ) if( nullptr != m_Parent )
{ {
if( aParent == m_Parent ) if( aParent == m_Parent )
return true; return true;
@ -74,14 +67,14 @@ bool SGCOORDS::SetParent( SGNODE* aParent, bool notify )
if( notify ) if( notify )
m_Parent->unlinkChildNode( this ); m_Parent->unlinkChildNode( this );
m_Parent = NULL; m_Parent = nullptr;
if( NULL == aParent ) if( nullptr == aParent )
return true; return true;
} }
// only a SGFACESET may be parent to a SGCOORDS // only a SGFACESET may be parent to a SGCOORDS
if( NULL != aParent && S3D::SGTYPE_FACESET != aParent->GetNodeType() ) if( nullptr != aParent && S3D::SGTYPE_FACESET != aParent->GetNodeType() )
return false; return false;
m_Parent = aParent; m_Parent = aParent;
@ -95,50 +88,31 @@ bool SGCOORDS::SetParent( SGNODE* aParent, bool notify )
SGNODE* SGCOORDS::FindNode(const char *aNodeName, const SGNODE *aCaller) noexcept SGNODE* SGCOORDS::FindNode(const char *aNodeName, const SGNODE *aCaller) noexcept
{ {
if( NULL == aNodeName || 0 == aNodeName[0] ) if( nullptr == aNodeName || 0 == aNodeName[0] )
return NULL; return nullptr;
if( !m_Name.compare( aNodeName ) ) if( !m_Name.compare( aNodeName ) )
return this; return this;
return NULL; return nullptr;
} }
void SGCOORDS::unlinkChildNode( const SGNODE* aCaller ) noexcept void SGCOORDS::unlinkChildNode( const SGNODE* aCaller ) noexcept
{ {
#ifdef DEBUG wxCHECK( aCaller, /* void */ );
std::ostringstream ostr;
ostr << __FILE__ << ": " << __FUNCTION__ << ": " << __LINE__ << "\n";
ostr << " * [BUG] unexpected code branch; node should have no children or refs";
wxLogTrace( MASK_3D_SG, "%s\n", ostr.str().c_str() );
#endif
return;
} }
void SGCOORDS::unlinkRefNode( const SGNODE* aCaller ) noexcept void SGCOORDS::unlinkRefNode( const SGNODE* aCaller ) noexcept
{ {
#ifdef DEBUG wxCHECK( aCaller, /* void */ );
std::ostringstream ostr;
ostr << __FILE__ << ": " << __FUNCTION__ << ": " << __LINE__ << "\n";
ostr << " * [BUG] unexpected code branch; node should have no children or refs";
wxLogTrace( MASK_3D_SG, "%s\n", ostr.str().c_str() );
#endif
return;
} }
bool SGCOORDS::AddRefNode( SGNODE* aNode ) noexcept bool SGCOORDS::AddRefNode( SGNODE* aNode ) noexcept
{ {
#ifdef DEBUG wxCHECK( aNode, false );
std::ostringstream ostr;
ostr << __FILE__ << ": " << __FUNCTION__ << ": " << __LINE__ << "\n";
ostr << " * [BUG] this node does not accept children or refs";
wxLogTrace( MASK_3D_SG, "%s\n", ostr.str().c_str() );
#endif
return false; return false;
} }
@ -146,12 +120,7 @@ bool SGCOORDS::AddRefNode( SGNODE* aNode ) noexcept
bool SGCOORDS::AddChildNode( SGNODE* aNode ) noexcept bool SGCOORDS::AddChildNode( SGNODE* aNode ) noexcept
{ {
#ifdef DEBUG wxCHECK( aNode, false );
std::ostringstream ostr;
ostr << __FILE__ << ": " << __FUNCTION__ << ": " << __LINE__ << "\n";
ostr << " * [BUG] this node does not accept children or refs";
wxLogTrace( MASK_3D_SG, "%s\n", ostr.str().c_str() );
#endif
return false; return false;
} }
@ -162,7 +131,7 @@ bool SGCOORDS::GetCoordsList( size_t& aListSize, SGPOINT*& aCoordsList )
if( coords.empty() ) if( coords.empty() )
{ {
aListSize = 0; aListSize = 0;
aCoordsList = NULL; aCoordsList = nullptr;
return false; return false;
} }
@ -176,27 +145,23 @@ void SGCOORDS::SetCoordsList( size_t aListSize, const SGPOINT* aCoordsList )
{ {
coords.clear(); coords.clear();
if( 0 == aListSize || NULL == aCoordsList ) if( 0 == aListSize || nullptr == aCoordsList )
return; return;
for( size_t i = 0; i < aListSize; ++i ) for( size_t i = 0; i < aListSize; ++i )
coords.push_back( aCoordsList[i] ); coords.push_back( aCoordsList[i] );
return;
} }
void SGCOORDS::AddCoord( double aXValue, double aYValue, double aZValue ) void SGCOORDS::AddCoord( double aXValue, double aYValue, double aZValue )
{ {
coords.emplace_back( aXValue, aYValue, aZValue ); coords.emplace_back( aXValue, aYValue, aZValue );
return;
} }
void SGCOORDS::AddCoord( const SGPOINT& aPoint ) void SGCOORDS::AddCoord( const SGPOINT& aPoint )
{ {
coords.push_back( aPoint ); coords.push_back( aPoint );
return;
} }
@ -274,26 +239,16 @@ bool SGCOORDS::WriteVRML( std::ostream& aFile, bool aReuseFlag )
bool SGCOORDS::WriteCache( std::ostream& aFile, SGNODE* parentNode ) bool SGCOORDS::WriteCache( std::ostream& aFile, SGNODE* parentNode )
{ {
if( NULL == parentNode ) if( nullptr == parentNode )
{ {
if( NULL == m_Parent ) wxCHECK( m_Parent, false );
{
#ifdef DEBUG
std::ostringstream ostr;
ostr << __FILE__ << ": " << __FUNCTION__ << ": " << __LINE__ << "\n";
ostr << " * [BUG] corrupt data; m_aParent is NULL";
wxLogTrace( MASK_3D_SG, "%s\n", ostr.str().c_str() );
#endif
return false;
}
SGNODE* np = m_Parent; SGNODE* np = m_Parent;
while( NULL != np->GetParent() ) while( nullptr != np->GetParent() )
np = np->GetParent(); np = np->GetParent();
if( np->WriteCache( aFile, NULL ) ) if( np->WriteCache( aFile, nullptr ) )
{ {
m_written = true; m_written = true;
return true; return true;
@ -302,26 +257,11 @@ bool SGCOORDS::WriteCache( std::ostream& aFile, SGNODE* parentNode )
return false; return false;
} }
if( parentNode != m_Parent ) wxCHECK( parentNode == m_Parent, false );
{
#ifdef DEBUG
std::ostringstream ostr;
ostr << __FILE__ << ": " << __FUNCTION__ << ": " << __LINE__ << "\n";
ostr << " * [BUG] corrupt data; parentNode != m_aParent";
wxLogTrace( MASK_3D_SG, "%s\n", ostr.str().c_str() );
#endif
return false;
}
if( !aFile.good() ) if( !aFile.good() )
{ {
#ifdef DEBUG wxLogTrace( MASK_3D_SG, "%s:%s:%d * [INFO] bad stream", __FILE__, __FUNCTION__, __LINE__ );
std::ostringstream ostr;
ostr << __FILE__ << ": " << __FUNCTION__ << ": " << __LINE__ << "\n";
ostr << " * [INFO] bad stream";
wxLogTrace( MASK_3D_SG, "%s\n", ostr.str().c_str() );
#endif
return false; return false;
} }
@ -343,20 +283,10 @@ bool SGCOORDS::WriteCache( std::ostream& aFile, SGNODE* parentNode )
bool SGCOORDS::ReadCache( std::istream& aFile, SGNODE* parentNode ) bool SGCOORDS::ReadCache( std::istream& aFile, SGNODE* parentNode )
{ {
if( !coords.empty() ) wxCHECK( coords.empty(), false );
{
#ifdef DEBUG
std::ostringstream ostr;
ostr << __FILE__ << ": " << __FUNCTION__ << ": " << __LINE__ << "\n";
ostr << " * [BUG] non-empty node";
wxLogTrace( MASK_3D_SG, "%s\n", ostr.str().c_str() );
#endif
return false;
}
size_t npts; size_t npts;
aFile.read( (char*)&npts, sizeof(size_t) ); aFile.read( (char*) &npts, sizeof( size_t ) );
SGPOINT tmp; SGPOINT tmp;
if( aFile.fail() ) if( aFile.fail() )
@ -377,15 +307,15 @@ bool SGCOORDS::ReadCache( std::istream& aFile, SGNODE* parentNode )
bool SGCOORDS::CalcNormals( SGFACESET* callingNode, SGNODE** aPtr ) bool SGCOORDS::CalcNormals( SGFACESET* callingNode, SGNODE** aPtr )
{ {
if( aPtr ) if( aPtr )
*aPtr = NULL; *aPtr = nullptr;
if( NULL == m_Parent || NULL == callingNode ) if( nullptr == m_Parent || nullptr == callingNode )
return false; return false;
// the parent and all references must have indices; collect all // the parent and all references must have indices; collect all
// indices into one std::vector<> // indices into one std::vector<>
std::vector< int > ilist; std::vector< int > ilist;
SGNORMALS* np = NULL; SGNORMALS* np = nullptr;
if( callingNode == m_Parent ) if( callingNode == m_Parent )
{ {
@ -401,7 +331,7 @@ bool SGCOORDS::CalcNormals( SGFACESET* callingNode, SGNODE** aPtr )
++sB; ++sB;
} }
np = ((SGFACESET*)m_Parent)->m_Normals; np = ( (SGFACESET*) m_Parent )->m_Normals;
if( !np ) if( !np )
np = new SGNORMALS( m_Parent ); np = new SGNORMALS( m_Parent );

View File

@ -2,6 +2,7 @@
* This program source code file is part of KiCad, a free EDA CAD application. * This program source code file is part of KiCad, a free EDA CAD application.
* *
* Copyright (C) 2015-2017 Cirilo Bernardo <cirilo.bernardo@gmail.com> * Copyright (C) 2015-2017 Cirilo Bernardo <cirilo.bernardo@gmail.com>
* Copyright (C) 2020 KiCad Developers, see AUTHORS.txt for contributors.
* *
* This program is free software; you can redistribute it and/or * This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License * modify it under the terms of the GNU General Public License
@ -23,7 +24,6 @@
/** /**
* @file sg_coords.h * @file sg_coords.h
* defines a vertex coordinate set for a scenegraph object
*/ */
#ifndef SG_COORDS_H #ifndef SG_COORDS_H
@ -34,18 +34,18 @@
class SGFACESET; class SGFACESET;
/**
* Define a vertex coordinate set for a scenegraph object.
*/
class SGCOORDS : public SGNODE class SGCOORDS : public SGNODE
{ {
public: public:
std::vector< SGPOINT > coords; SGCOORDS( SGNODE* aParent );
virtual ~SGCOORDS();
void unlinkChildNode( const SGNODE* aNode ) noexcept override; void unlinkChildNode( const SGNODE* aNode ) noexcept override;
void unlinkRefNode( const SGNODE* aNode ) noexcept override; void unlinkRefNode( const SGNODE* aNode ) noexcept override;
public:
SGCOORDS( SGNODE* aParent );
virtual ~SGCOORDS();
virtual bool SetParent( SGNODE* aParent, bool notify = true ) override; virtual bool SetParent( SGNODE* aParent, bool notify = true ) override;
SGNODE* FindNode(const char *aNodeName, const SGNODE *aCaller) noexcept override; SGNODE* FindNode(const char *aNodeName, const SGNODE *aCaller) noexcept override;
@ -58,17 +58,18 @@ public:
void AddCoord( const SGPOINT& aPoint ); void AddCoord( const SGPOINT& aPoint );
/** /**
* Function CalcNormals * Calculate normals for this coordinate list and sets the normals list in the
* calculates normals for this coordinate list and sets the * parent #SGFACESET.
* normals list in the parent SGFACESET
*/ */
bool CalcNormals( SGFACESET* callingNode, SGNODE** aPtr = NULL ); bool CalcNormals( SGFACESET* callingNode, SGNODE** aPtr = nullptr );
void ReNameNodes( void ) override; void ReNameNodes( void ) override;
bool WriteVRML( std::ostream& aFile, bool aReuseFlag ) override; bool WriteVRML( std::ostream& aFile, bool aReuseFlag ) override;
bool WriteCache( std::ostream& aFile, SGNODE* parentNode ) override; bool WriteCache( std::ostream& aFile, SGNODE* parentNode ) override;
bool ReadCache( std::istream& aFile, SGNODE* parentNode ) override; bool ReadCache( std::istream& aFile, SGNODE* parentNode ) override;
std::vector< SGPOINT > coords;
}; };
#endif // SG_COORDS_H #endif // SG_COORDS_H

View File

@ -2,6 +2,7 @@
* This program source code file is part of KiCad, a free EDA CAD application. * This program source code file is part of KiCad, a free EDA CAD application.
* *
* Copyright (C) 2015-2017 Cirilo Bernardo <cirilo.bernardo@gmail.com> * Copyright (C) 2015-2017 Cirilo Bernardo <cirilo.bernardo@gmail.com>
* Copyright (C) 2020 KiCad Developers, see AUTHORS.txt for contributors.
* *
* This program is free software; you can redistribute it and/or * This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License * modify it under the terms of the GNU General Public License
@ -33,37 +34,31 @@
#include "3d_cache/sg/sg_coordindex.h" #include "3d_cache/sg/sg_coordindex.h"
#include "3d_cache/sg/sg_helpers.h" #include "3d_cache/sg/sg_helpers.h"
SGFACESET::SGFACESET( SGNODE* aParent ) : SGNODE( aParent ) SGFACESET::SGFACESET( SGNODE* aParent ) : SGNODE( aParent )
{ {
m_SGtype = S3D::SGTYPE_FACESET; m_SGtype = S3D::SGTYPE_FACESET;
m_Colors = NULL; m_Colors = nullptr;
m_Coords = NULL; m_Coords = nullptr;
m_CoordIndices = NULL; m_CoordIndices = nullptr;
m_Normals = NULL; m_Normals = nullptr;
m_RColors = NULL; m_RColors = nullptr;
m_RCoords = NULL; m_RCoords = nullptr;
m_RNormals = NULL; m_RNormals = nullptr;
valid = false; valid = false;
validated = false; validated = false;
if( NULL != aParent && S3D::SGTYPE_SHAPE != aParent->GetNodeType() ) if( nullptr != aParent && S3D::SGTYPE_SHAPE != aParent->GetNodeType() )
{ {
m_Parent = NULL; m_Parent = nullptr;
#ifdef DEBUG wxLogTrace( MASK_3D_SG, "%s:%s:%d * [BUG] inappropriate parent to SGFACESET (type %s)",
std::ostringstream ostr; __FILE__, __FUNCTION__, __LINE__, aParent->GetNodeType() );
ostr << __FILE__ << ": " << __FUNCTION__ << ": " << __LINE__ << "\n";
ostr << " * [BUG] inappropriate parent to SGFACESET (type ";
ostr << aParent->GetNodeType() << ")";
wxLogTrace( MASK_3D_SG, "%s\n", ostr.str().c_str() );
#endif
} }
else if( NULL != aParent && S3D::SGTYPE_SHAPE == aParent->GetNodeType() ) else if( nullptr != aParent && S3D::SGTYPE_SHAPE == aParent->GetNodeType() )
{ {
m_Parent->AddChildNode( this ); m_Parent->AddChildNode( this );
} }
return;
} }
@ -73,57 +68,55 @@ SGFACESET::~SGFACESET()
if( m_RColors ) if( m_RColors )
{ {
m_RColors->delNodeRef( this ); m_RColors->delNodeRef( this );
m_RColors = NULL; m_RColors = nullptr;
} }
if( m_RCoords ) if( m_RCoords )
{ {
m_RCoords->delNodeRef( this ); m_RCoords->delNodeRef( this );
m_RCoords = NULL; m_RCoords = nullptr;
} }
if( m_RNormals ) if( m_RNormals )
{ {
m_RNormals->delNodeRef( this ); m_RNormals->delNodeRef( this );
m_RNormals = NULL; m_RNormals = nullptr;
} }
// delete owned objects // delete owned objects
if( m_Colors ) if( m_Colors )
{ {
m_Colors->SetParent( NULL, false ); m_Colors->SetParent( nullptr, false );
delete m_Colors; delete m_Colors;
m_Colors = NULL; m_Colors = nullptr;
} }
if( m_Coords ) if( m_Coords )
{ {
m_Coords->SetParent( NULL, false ); m_Coords->SetParent( nullptr, false );
delete m_Coords; delete m_Coords;
m_Coords = NULL; m_Coords = nullptr;
} }
if( m_Normals ) if( m_Normals )
{ {
m_Normals->SetParent( NULL, false ); m_Normals->SetParent( nullptr, false );
delete m_Normals; delete m_Normals;
m_Normals = NULL; m_Normals = nullptr;
} }
if( m_CoordIndices ) if( m_CoordIndices )
{ {
m_CoordIndices->SetParent( NULL, false ); m_CoordIndices->SetParent( nullptr, false );
delete m_CoordIndices; delete m_CoordIndices;
m_CoordIndices = NULL; m_CoordIndices = nullptr;
} }
return;
} }
bool SGFACESET::SetParent( SGNODE* aParent, bool notify ) bool SGFACESET::SetParent( SGNODE* aParent, bool notify )
{ {
if( NULL != m_Parent ) if( nullptr != m_Parent )
{ {
if( aParent == m_Parent ) if( aParent == m_Parent )
return true; return true;
@ -132,14 +125,14 @@ bool SGFACESET::SetParent( SGNODE* aParent, bool notify )
if( notify ) if( notify )
m_Parent->unlinkChildNode( this ); m_Parent->unlinkChildNode( this );
m_Parent = NULL; m_Parent = nullptr;
if( NULL == aParent ) if( nullptr == aParent )
return true; return true;
} }
// only a SGSHAPE may be parent to a SGFACESET // only a SGSHAPE may be parent to a SGFACESET
if( NULL != aParent && S3D::SGTYPE_SHAPE != aParent->GetNodeType() ) if( nullptr != aParent && S3D::SGTYPE_SHAPE != aParent->GetNodeType() )
return false; return false;
m_Parent = aParent; m_Parent = aParent;
@ -153,13 +146,13 @@ bool SGFACESET::SetParent( SGNODE* aParent, bool notify )
SGNODE* SGFACESET::FindNode(const char *aNodeName, const SGNODE *aCaller) SGNODE* SGFACESET::FindNode(const char *aNodeName, const SGNODE *aCaller)
{ {
if( NULL == aNodeName || 0 == aNodeName[0] ) if( nullptr == aNodeName || 0 == aNodeName[0] )
return NULL; return nullptr;
if( !m_Name.compare( aNodeName ) ) if( !m_Name.compare( aNodeName ) )
return this; return this;
SGNODE* np = NULL; SGNODE* np = nullptr;
if( m_Colors ) if( m_Colors )
{ {
@ -194,8 +187,8 @@ SGNODE* SGFACESET::FindNode(const char *aNodeName, const SGNODE *aCaller)
} }
// query the parent if appropriate // query the parent if appropriate
if( aCaller == m_Parent || NULL == m_Parent ) if( aCaller == m_Parent || nullptr == m_Parent )
return NULL; return nullptr;
return m_Parent->FindNode( aNodeName, this ); return m_Parent->FindNode( aNodeName, this );
} }
@ -203,7 +196,7 @@ SGNODE* SGFACESET::FindNode(const char *aNodeName, const SGNODE *aCaller)
void SGFACESET::unlinkNode( const SGNODE* aNode, bool isChild ) void SGFACESET::unlinkNode( const SGNODE* aNode, bool isChild )
{ {
if( NULL == aNode ) if( nullptr == aNode )
return; return;
valid = false; valid = false;
@ -213,25 +206,25 @@ void SGFACESET::unlinkNode( const SGNODE* aNode, bool isChild )
{ {
if( aNode == m_Colors ) if( aNode == m_Colors )
{ {
m_Colors = NULL; m_Colors = nullptr;
return; return;
} }
if( aNode == m_Coords ) if( aNode == m_Coords )
{ {
m_Coords = NULL; m_Coords = nullptr;
return; return;
} }
if( aNode == m_Normals ) if( aNode == m_Normals )
{ {
m_Normals = NULL; m_Normals = nullptr;
return; return;
} }
if( aNode == m_CoordIndices ) if( aNode == m_CoordIndices )
{ {
m_CoordIndices = NULL; m_CoordIndices = nullptr;
return; return;
} }
} }
@ -240,66 +233,46 @@ void SGFACESET::unlinkNode( const SGNODE* aNode, bool isChild )
if( aNode == m_RColors ) if( aNode == m_RColors )
{ {
delNodeRef( this ); delNodeRef( this );
m_RColors = NULL; m_RColors = nullptr;
return; return;
} }
if( aNode == m_RCoords ) if( aNode == m_RCoords )
{ {
delNodeRef( this ); delNodeRef( this );
m_RCoords = NULL; m_RCoords = nullptr;
return; return;
} }
if( aNode == m_RNormals ) if( aNode == m_RNormals )
{ {
delNodeRef( this ); delNodeRef( this );
m_RNormals = NULL; m_RNormals = nullptr;
return; return;
} }
} }
#ifdef DEBUG wxLogTrace( MASK_3D_SG, "%s:%s:%d * [BUG] unlinkNode() did not find its target",
do { __FILE__, __FUNCTION__, __LINE__ );
std::ostringstream ostr;
ostr << __FILE__ << ": " << __FUNCTION__ << ": " << __LINE__ << "\n";
ostr << " * [BUG] unlinkNode() did not find its target";
wxLogTrace( MASK_3D_SG, "%s\n", ostr.str().c_str() );
} while( 0 );
#endif
return;
} }
void SGFACESET::unlinkChildNode( const SGNODE* aNode ) void SGFACESET::unlinkChildNode( const SGNODE* aNode )
{ {
unlinkNode( aNode, true ); unlinkNode( aNode, true );
return;
} }
void SGFACESET::unlinkRefNode( const SGNODE* aNode ) void SGFACESET::unlinkRefNode( const SGNODE* aNode )
{ {
unlinkNode( aNode, false ); unlinkNode( aNode, false );
return;
} }
bool SGFACESET::addNode( SGNODE* aNode, bool isChild ) bool SGFACESET::addNode( SGNODE* aNode, bool isChild )
{ {
if( NULL == aNode ) wxCHECK( aNode, false );
{
#ifdef DEBUG
std::ostringstream ostr;
ostr << __FILE__ << ": " << __FUNCTION__ << ": " << __LINE__ << "\n";
ostr << " * [BUG] NULL pointer passed for aNode";
wxLogTrace( MASK_3D_SG, "%s\n", ostr.str().c_str() );
#endif
return false;
}
valid = false; valid = false;
validated = false; validated = false;
@ -310,12 +283,8 @@ bool SGFACESET::addNode( SGNODE* aNode, bool isChild )
{ {
if( aNode != m_Colors && aNode != m_RColors ) if( aNode != m_Colors && aNode != m_RColors )
{ {
#ifdef DEBUG wxLogTrace( MASK_3D_SG, "%s:%s:%d * [BUG] assigning multiple Colors nodes",
std::ostringstream ostr; __FILE__, __FUNCTION__, __LINE__ );
ostr << __FILE__ << ": " << __FUNCTION__ << ": " << __LINE__ << "\n";
ostr << " * [BUG] assigning multiple Colors nodes";
wxLogTrace( MASK_3D_SG, "%s\n", ostr.str().c_str() );
#endif
return false; return false;
} }
@ -343,12 +312,8 @@ bool SGFACESET::addNode( SGNODE* aNode, bool isChild )
{ {
if( aNode != m_Coords && aNode != m_RCoords ) if( aNode != m_Coords && aNode != m_RCoords )
{ {
#ifdef DEBUG wxLogTrace( MASK_3D_SG, "%s:%s:%d * [BUG] assigning multiple Colors nodes",
std::ostringstream ostr; __FILE__, __FUNCTION__, __LINE__ );
ostr << __FILE__ << ": " << __FUNCTION__ << ": " << __LINE__ << "\n";
ostr << " * [BUG] assigning multiple Coords nodes";
wxLogTrace( MASK_3D_SG, "%s\n", ostr.str().c_str() );
#endif
return false; return false;
} }
@ -376,12 +341,8 @@ bool SGFACESET::addNode( SGNODE* aNode, bool isChild )
{ {
if( aNode != m_Normals && aNode != m_RNormals ) if( aNode != m_Normals && aNode != m_RNormals )
{ {
#ifdef DEBUG wxLogTrace( MASK_3D_SG, "%s:%s:%d * [BUG] assigning multiple Normals nodes",
std::ostringstream ostr; __FILE__, __FUNCTION__, __LINE__ );
ostr << __FILE__ << ": " << __FUNCTION__ << ": " << __LINE__ << "\n";
ostr << " * [BUG] assigning multiple Normals nodes";
wxLogTrace( MASK_3D_SG, "%s\n", ostr.str().c_str() );
#endif
return false; return false;
} }
@ -409,12 +370,8 @@ bool SGFACESET::addNode( SGNODE* aNode, bool isChild )
{ {
if( aNode != m_CoordIndices ) if( aNode != m_CoordIndices )
{ {
#ifdef DEBUG wxLogTrace( MASK_3D_SG, "%s:%s:%d * [BUG] assigning multiple CoordIndex nodes",
std::ostringstream ostr; __FILE__, __FUNCTION__, __LINE__ );
ostr << __FILE__ << ": " << __FUNCTION__ << ": " << __LINE__ << "\n";
ostr << " * [BUG] assigning multiple CoordIndex nodes";
wxLogTrace( MASK_3D_SG, "%s\n", ostr.str().c_str() );
#endif
return false; return false;
} }
@ -428,16 +385,9 @@ bool SGFACESET::addNode( SGNODE* aNode, bool isChild )
return true; return true;
} }
#ifdef DEBUG wxLogTrace( MASK_3D_SG, "%s:%s:%d * [BUG] object type '%s' is not a valid type for "
do { "this object '%d'", __FILE__, __FUNCTION__, __LINE__, aNode->GetName(),
std::ostringstream ostr; aNode->GetNodeType() );
ostr << __FILE__ << ": " << __FUNCTION__ << ": " << __LINE__ << "\n";
ostr << " * [BUG] object '" << aNode->GetName();
ostr << "' (type " << aNode->GetNodeType();
ostr << ") is not a valid type for this object (" << aNode->GetNodeType() << ")";
wxLogTrace( MASK_3D_SG, "%s\n", ostr.str().c_str() );
} while( 0 );
#endif
return false; return false;
} }
@ -477,15 +427,12 @@ void SGFACESET::ReNameNodes( void )
// rename all Normals and Indices // rename all Normals and Indices
if( m_Normals ) if( m_Normals )
m_Normals->ReNameNodes(); m_Normals->ReNameNodes();
return;
} }
bool SGFACESET::WriteVRML( std::ostream& aFile, bool aReuseFlag ) bool SGFACESET::WriteVRML( std::ostream& aFile, bool aReuseFlag )
{ {
if( ( NULL == m_Coords && NULL == m_RCoords ) if( ( nullptr == m_Coords && nullptr == m_RCoords ) || ( nullptr == m_CoordIndices ) )
|| ( NULL == m_CoordIndices ) )
{ {
return false; return false;
} }
@ -540,26 +487,16 @@ bool SGFACESET::WriteVRML( std::ostream& aFile, bool aReuseFlag )
bool SGFACESET::WriteCache( std::ostream& aFile, SGNODE* parentNode ) bool SGFACESET::WriteCache( std::ostream& aFile, SGNODE* parentNode )
{ {
if( NULL == parentNode ) if( nullptr == parentNode )
{ {
if( NULL == m_Parent ) wxCHECK( m_Parent, false );
{
#ifdef DEBUG
std::ostringstream ostr;
ostr << __FILE__ << ": " << __FUNCTION__ << ": " << __LINE__ << "\n";
ostr << " * [BUG] corrupt data; m_aParent is NULL";
wxLogTrace( MASK_3D_SG, "%s\n", ostr.str().c_str() );
#endif
return false;
}
SGNODE* np = m_Parent; SGNODE* np = m_Parent;
while( NULL != np->GetParent() ) while( nullptr != np->GetParent() )
np = np->GetParent(); np = np->GetParent();
if( np->WriteCache( aFile, NULL ) ) if( np->WriteCache( aFile, nullptr ) )
{ {
m_written = true; m_written = true;
return true; return true;
@ -568,38 +505,23 @@ bool SGFACESET::WriteCache( std::ostream& aFile, SGNODE* parentNode )
return false; return false;
} }
if( parentNode != m_Parent ) wxCHECK( parentNode == m_Parent, false );
{
#ifdef DEBUG
std::ostringstream ostr;
ostr << __FILE__ << ": " << __FUNCTION__ << ": " << __LINE__ << "\n";
ostr << " * [BUG] corrupt data; parentNode != m_aParent";
wxLogTrace( MASK_3D_SG, "%s\n", ostr.str().c_str() );
#endif
return false;
}
if( !aFile.good() ) if( !aFile.good() )
{ {
#ifdef DEBUG wxLogTrace( MASK_3D_SG, "%s:%s:%d * [INFO] bad stream", __FILE__, __FUNCTION__, __LINE__ );
std::ostringstream ostr;
ostr << __FILE__ << ": " << __FUNCTION__ << ": " << __LINE__ << "\n";
ostr << " * [INFO] bad stream";
wxLogTrace( MASK_3D_SG, "%s\n", ostr.str().c_str() );
#endif
return false; return false;
} }
// check if any references are unwritten and swap parents if so // check if any references are unwritten and swap parents if so
if( NULL != m_RCoords && !m_RCoords->isWritten() ) if( nullptr != m_RCoords && !m_RCoords->isWritten() )
m_RCoords->SwapParent( this ); m_RCoords->SwapParent( this );
if( NULL != m_RNormals && !m_RNormals->isWritten() ) if( nullptr != m_RNormals && !m_RNormals->isWritten() )
m_RNormals->SwapParent( this ); m_RNormals->SwapParent( this );
if( NULL != m_RColors && !m_RColors->isWritten() ) if( nullptr != m_RColors && !m_RColors->isWritten() )
m_RColors->SwapParent( this ); m_RColors->SwapParent( this );
aFile << "[" << GetName() << "]"; aFile << "[" << GetName() << "]";
@ -611,35 +533,35 @@ bool SGFACESET::WriteCache( std::ostream& aFile, SGNODE* parentNode )
items[i] = 0; items[i] = 0;
i = 0; i = 0;
if( NULL != m_Coords ) if( nullptr != m_Coords )
items[i] = true; items[i] = true;
++i; ++i;
if( NULL != m_RCoords ) if( nullptr != m_RCoords )
items[i] = true; items[i] = true;
++i; ++i;
if( NULL != m_CoordIndices ) if( nullptr != m_CoordIndices )
items[i] = true; items[i] = true;
++i; ++i;
if( NULL != m_Normals ) if( nullptr != m_Normals )
items[i] = true; items[i] = true;
++i; ++i;
if( NULL != m_RNormals ) if( nullptr != m_RNormals )
items[i] = true; items[i] = true;
++i; ++i;
if( NULL != m_Colors ) if( nullptr != m_Colors )
items[i] = true; items[i] = true;
++i; ++i;
if( NULL != m_RColors ) if( nullptr != m_RColors )
items[i] = true; items[i] = true;
for( int jj = 0; jj < NITEMS; ++jj ) for( int jj = 0; jj < NITEMS; ++jj )
aFile.write( (char*)&items[jj], sizeof(bool) ); aFile.write( (char*) &items[jj], sizeof( bool ) );
if( items[0] ) if( items[0] )
m_Coords->WriteCache( aFile, this ); m_Coords->WriteCache( aFile, this );
@ -672,16 +594,11 @@ bool SGFACESET::WriteCache( std::ostream& aFile, SGNODE* parentNode )
bool SGFACESET::ReadCache( std::istream& aFile, SGNODE* parentNode ) bool SGFACESET::ReadCache( std::istream& aFile, SGNODE* parentNode )
{ {
if( m_Coords || m_RCoords || m_CoordIndices if( m_Coords || m_RCoords || m_CoordIndices || m_Colors || m_RColors || m_Normals
|| m_Colors || m_RColors || m_RNormals )
|| m_Normals || m_RNormals )
{ {
#ifdef DEBUG wxLogTrace( MASK_3D_SG, "%s:%s:%d * [BUG] non-empty node",
std::ostringstream ostr; __FILE__, __FUNCTION__, __LINE__ );
ostr << __FILE__ << ": " << __FUNCTION__ << ": " << __LINE__ << "\n";
ostr << " * [BUG] non-empty node";
wxLogTrace( MASK_3D_SG, "%s\n", ostr.str().c_str() );
#endif
return false; return false;
} }
@ -690,18 +607,13 @@ bool SGFACESET::ReadCache( std::istream& aFile, SGNODE* parentNode )
bool items[NITEMS]; bool items[NITEMS];
for( int i = 0; i < NITEMS; ++i ) for( int i = 0; i < NITEMS; ++i )
aFile.read( (char*)&items[i], sizeof(bool) ); aFile.read( (char*) &items[i], sizeof( bool ) );
if( ( items[0] && items[1] ) || ( items[3] && items[4] ) if( ( items[0] && items[1] ) || ( items[3] && items[4] ) || ( items[5] && items[6] ) )
|| ( items[5] && items[6] ) )
{ {
#ifdef DEBUG wxLogTrace( MASK_3D_SG,
std::ostringstream ostr; "%s:%s:%d * [INFO] corrupt data; multiple item definitions at position %d",
ostr << __FILE__ << ": " << __FUNCTION__ << ": " << __LINE__ << "\n"; __FILE__, __FUNCTION__, __LINE__, static_cast<int>( aFile.tellg() ) );
ostr << " * [INFO] corrupt data; multiple item definitions at position ";
ostr << aFile.tellg();
wxLogTrace( MASK_3D_SG, "%s\n", ostr.str().c_str() );
#endif
return false; return false;
} }
@ -712,13 +624,9 @@ bool SGFACESET::ReadCache( std::istream& aFile, SGNODE* parentNode )
{ {
if( S3D::SGTYPE_COORDS != S3D::ReadTag( aFile, name ) ) if( S3D::SGTYPE_COORDS != S3D::ReadTag( aFile, name ) )
{ {
#ifdef DEBUG wxLogTrace( MASK_3D_SG,
std::ostringstream ostr; "%s:%s:%d * [INFO] corrupt data; bad child coords tag at position %d",
ostr << __FILE__ << ": " << __FUNCTION__ << ": " << __LINE__ << "\n"; __FILE__, __FUNCTION__, __LINE__, static_cast<int>( aFile.tellg() ) );
ostr << " * [INFO] corrupt data; bad child coords tag at position ";
ostr << aFile.tellg();
wxLogTrace( MASK_3D_SG, "%s\n", ostr.str().c_str() );
#endif
return false; return false;
} }
@ -728,13 +636,9 @@ bool SGFACESET::ReadCache( std::istream& aFile, SGNODE* parentNode )
if( !m_Coords->ReadCache( aFile, this ) ) if( !m_Coords->ReadCache( aFile, this ) )
{ {
#ifdef DEBUG wxLogTrace( MASK_3D_SG,
std::ostringstream ostr; "%s:%s:%d * [INFO] corrupt data; corrupt data while reading coords '%s'",
ostr << __FILE__ << ": " << __FUNCTION__ << ": " << __LINE__ << "\n"; __FILE__, __FUNCTION__, __LINE__, name );
ostr << " * [INFO] corrupt data while reading coords '";
ostr << name << "'";
wxLogTrace( MASK_3D_SG, "%s\n", ostr.str().c_str() );
#endif
return false; return false;
} }
@ -744,13 +648,9 @@ bool SGFACESET::ReadCache( std::istream& aFile, SGNODE* parentNode )
{ {
if( S3D::SGTYPE_COORDS != S3D::ReadTag( aFile, name ) ) if( S3D::SGTYPE_COORDS != S3D::ReadTag( aFile, name ) )
{ {
#ifdef DEBUG wxLogTrace( MASK_3D_SG,
std::ostringstream ostr; "%s:%s:%d * [INFO] corrupt data; bad ref coords tag at position %d",
ostr << __FILE__ << ": " << __FUNCTION__ << ": " << __LINE__ << "\n"; __FILE__, __FUNCTION__, __LINE__, static_cast<int>( aFile.tellg() ) );
ostr << " * [INFO] corrupt data; bad ref coords tag at position ";
ostr << aFile.tellg();
wxLogTrace( MASK_3D_SG, "%s\n", ostr.str().c_str() );
#endif
return false; return false;
} }
@ -759,26 +659,18 @@ bool SGFACESET::ReadCache( std::istream& aFile, SGNODE* parentNode )
if( !np ) if( !np )
{ {
#ifdef DEBUG wxLogTrace( MASK_3D_SG,
std::ostringstream ostr; "%s:%s:%d * [INFO] corrupt data; cannot find ref coords '%s'",
ostr << __FILE__ << ": " << __FUNCTION__ << ": " << __LINE__ << "\n"; __FILE__, __FUNCTION__, __LINE__, name );
ostr << " * [INFO] corrupt data: cannot find ref coords '";
ostr << name << "'";
wxLogTrace( MASK_3D_SG, "%s\n", ostr.str().c_str() );
#endif
return false; return false;
} }
if( S3D::SGTYPE_COORDS != np->GetNodeType() ) if( S3D::SGTYPE_COORDS != np->GetNodeType() )
{ {
#ifdef DEBUG wxLogTrace( MASK_3D_SG,
std::ostringstream ostr; "%s:%s:%d * [INFO] corrupt data; type is not SGCOORDS '%s'",
ostr << __FILE__ << ": " << __FUNCTION__ << ": " << __LINE__ << "\n"; __FILE__, __FUNCTION__, __LINE__, name );
ostr << " * [INFO] corrupt data: type is not SGCOORDS '";
ostr << name << "'";
wxLogTrace( MASK_3D_SG, "%s\n", ostr.str().c_str() );
#endif
return false; return false;
} }
@ -791,13 +683,9 @@ bool SGFACESET::ReadCache( std::istream& aFile, SGNODE* parentNode )
{ {
if( S3D::SGTYPE_COORDINDEX != S3D::ReadTag( aFile, name ) ) if( S3D::SGTYPE_COORDINDEX != S3D::ReadTag( aFile, name ) )
{ {
#ifdef DEBUG wxLogTrace( MASK_3D_SG,
std::ostringstream ostr; "%s:%s:%d * [INFO] corrupt data; bad coord index tag at position %d",
ostr << __FILE__ << ": " << __FUNCTION__ << ": " << __LINE__ << "\n"; __FILE__, __FUNCTION__, __LINE__, static_cast<int>( aFile.tellg() ) );
ostr << " * [INFO] corrupt data; bad coord index tag at position ";
ostr << aFile.tellg();
wxLogTrace( MASK_3D_SG, "%s\n", ostr.str().c_str() );
#endif
return false; return false;
} }
@ -807,13 +695,9 @@ bool SGFACESET::ReadCache( std::istream& aFile, SGNODE* parentNode )
if( !m_CoordIndices->ReadCache( aFile, this ) ) if( !m_CoordIndices->ReadCache( aFile, this ) )
{ {
#ifdef DEBUG wxLogTrace( MASK_3D_SG,
std::ostringstream ostr; "%s:%s:%d * [INFO] corrupt data while reading coord index '%s'",
ostr << __FILE__ << ": " << __FUNCTION__ << ": " << __LINE__ << "\n"; __FILE__, __FUNCTION__, __LINE__, name );
ostr << " * [INFO] corrupt data while reading coord index '";
ostr << name << "'";
wxLogTrace( MASK_3D_SG, "%s\n", ostr.str().c_str() );
#endif
return false; return false;
} }
@ -823,13 +707,9 @@ bool SGFACESET::ReadCache( std::istream& aFile, SGNODE* parentNode )
{ {
if( S3D::SGTYPE_NORMALS != S3D::ReadTag( aFile, name ) ) if( S3D::SGTYPE_NORMALS != S3D::ReadTag( aFile, name ) )
{ {
#ifdef DEBUG wxLogTrace( MASK_3D_SG,
std::ostringstream ostr; "%s:%s:%d * [INFO] corrupt data; bad child normals tag at position %d",
ostr << __FILE__ << ": " << __FUNCTION__ << ": " << __LINE__ << "\n"; __FILE__, __FUNCTION__, __LINE__, static_cast<int>( aFile.tellg() ) );
ostr << " * [INFO] corrupt data; bad child normals tag at position ";
ostr << aFile.tellg();
wxLogTrace( MASK_3D_SG, "%s\n", ostr.str().c_str() );
#endif
return false; return false;
} }
@ -839,13 +719,9 @@ bool SGFACESET::ReadCache( std::istream& aFile, SGNODE* parentNode )
if( !m_Normals->ReadCache( aFile, this ) ) if( !m_Normals->ReadCache( aFile, this ) )
{ {
#ifdef DEBUG wxLogTrace( MASK_3D_SG,
std::ostringstream ostr; "%s:%s:%d * [INFO] corrupt data while reading normals '%s'",
ostr << __FILE__ << ": " << __FUNCTION__ << ": " << __LINE__ << "\n"; __FILE__, __FUNCTION__, __LINE__, name );
ostr << " * [INFO] corrupt data while reading normals '";
ostr << name << "'";
wxLogTrace( MASK_3D_SG, "%s\n", ostr.str().c_str() );
#endif
return false; return false;
} }
@ -855,13 +731,9 @@ bool SGFACESET::ReadCache( std::istream& aFile, SGNODE* parentNode )
{ {
if( S3D::SGTYPE_NORMALS != S3D::ReadTag( aFile, name ) ) if( S3D::SGTYPE_NORMALS != S3D::ReadTag( aFile, name ) )
{ {
#ifdef DEBUG wxLogTrace( MASK_3D_SG,
std::ostringstream ostr; "%s:%s:%d * [INFO] corrupt data; bad ref normals tag at position %d",
ostr << __FILE__ << ": " << __FUNCTION__ << ": " << __LINE__ << "\n"; __FILE__, __FUNCTION__, __LINE__, static_cast<int>( aFile.tellg() ) );
ostr << " * [INFO] corrupt data; bad ref normals tag at position ";
ostr << aFile.tellg();
wxLogTrace( MASK_3D_SG, "%s\n", ostr.str().c_str() );
#endif
return false; return false;
} }
@ -870,26 +742,18 @@ bool SGFACESET::ReadCache( std::istream& aFile, SGNODE* parentNode )
if( !np ) if( !np )
{ {
#ifdef DEBUG wxLogTrace( MASK_3D_SG,
std::ostringstream ostr; "%s:%s:%d * [INFO] corrupt: cannot find ref normals '%s'",
ostr << __FILE__ << ": " << __FUNCTION__ << ": " << __LINE__ << "\n"; __FILE__, __FUNCTION__, __LINE__, name );
ostr << " * [INFO] corrupt data: cannot find ref normals '";
ostr << name << "'";
wxLogTrace( MASK_3D_SG, "%s\n", ostr.str().c_str() );
#endif
return false; return false;
} }
if( S3D::SGTYPE_NORMALS != np->GetNodeType() ) if( S3D::SGTYPE_NORMALS != np->GetNodeType() )
{ {
#ifdef DEBUG wxLogTrace( MASK_3D_SG,
std::ostringstream ostr; "%s:%s:%d * [INFO] corrupt: type is not SGNORMALS '%s'",
ostr << __FILE__ << ": " << __FUNCTION__ << ": " << __LINE__ << "\n"; __FILE__, __FUNCTION__, __LINE__, name );
ostr << " * [INFO] corrupt data: type is not SGNORMALS '";
ostr << name << "'";
wxLogTrace( MASK_3D_SG, "%s\n", ostr.str().c_str() );
#endif
return false; return false;
} }
@ -902,13 +766,9 @@ bool SGFACESET::ReadCache( std::istream& aFile, SGNODE* parentNode )
{ {
if( S3D::SGTYPE_COLORS != S3D::ReadTag( aFile, name ) ) if( S3D::SGTYPE_COLORS != S3D::ReadTag( aFile, name ) )
{ {
#ifdef DEBUG wxLogTrace( MASK_3D_SG,
std::ostringstream ostr; "%s:%s:%d * [INFO] corrupt data; bad child colors tag at position %d",
ostr << __FILE__ << ": " << __FUNCTION__ << ": " << __LINE__ << "\n"; __FILE__, __FUNCTION__, __LINE__, static_cast<int>( aFile.tellg() ) );
ostr << " * [INFO] corrupt data; bad child colors tag at position ";
ostr << aFile.tellg();
wxLogTrace( MASK_3D_SG, "%s\n", ostr.str().c_str() );
#endif
return false; return false;
} }
@ -918,13 +778,9 @@ bool SGFACESET::ReadCache( std::istream& aFile, SGNODE* parentNode )
if( !m_Colors->ReadCache( aFile, this ) ) if( !m_Colors->ReadCache( aFile, this ) )
{ {
#ifdef DEBUG wxLogTrace( MASK_3D_SG,
std::ostringstream ostr; "%s:%s:%d * [INFO] corrupt data while reading colors '%s'",
ostr << __FILE__ << ": " << __FUNCTION__ << ": " << __LINE__ << "\n"; __FILE__, __FUNCTION__, __LINE__, name );
ostr << " * [INFO] corrupt data while reading colors '";
ostr << name << "'";
wxLogTrace( MASK_3D_SG, "%s\n", ostr.str().c_str() );
#endif
return false; return false;
} }
@ -934,13 +790,9 @@ bool SGFACESET::ReadCache( std::istream& aFile, SGNODE* parentNode )
{ {
if( S3D::SGTYPE_COLORS != S3D::ReadTag( aFile, name ) ) if( S3D::SGTYPE_COLORS != S3D::ReadTag( aFile, name ) )
{ {
#ifdef DEBUG wxLogTrace( MASK_3D_SG,
std::ostringstream ostr; "%s:%s:%d * [INFO] corrupt data; bad ref colors tag at position %d",
ostr << __FILE__ << ": " << __FUNCTION__ << ": " << __LINE__ << "\n"; __FILE__, __FUNCTION__, __LINE__, static_cast<int>( aFile.tellg() ) );
ostr << " * [INFO] corrupt data; bad ref colors tag at position ";
ostr << aFile.tellg();
wxLogTrace( MASK_3D_SG, "%s\n", ostr.str().c_str() );
#endif
return false; return false;
} }
@ -949,26 +801,18 @@ bool SGFACESET::ReadCache( std::istream& aFile, SGNODE* parentNode )
if( !np ) if( !np )
{ {
#ifdef DEBUG wxLogTrace( MASK_3D_SG,
std::ostringstream ostr; "%s:%s:%d * [INFO] corrupt data: cannot find ref colors '%s'",
ostr << __FILE__ << ": " << __FUNCTION__ << ": " << __LINE__ << "\n"; __FILE__, __FUNCTION__, __LINE__, name );
ostr << " * [INFO] corrupt data: cannot find ref colors '";
ostr << name << "'";
wxLogTrace( MASK_3D_SG, "%s\n", ostr.str().c_str() );
#endif
return false; return false;
} }
if( S3D::SGTYPE_COLORS != np->GetNodeType() ) if( S3D::SGTYPE_COLORS != np->GetNodeType() )
{ {
#ifdef DEBUG wxLogTrace( MASK_3D_SG,
std::ostringstream ostr; "%s:%s:%d * [INFO] corrupt data: type is not SGCOLORS '%s'",
ostr << __FILE__ << ": " << __FUNCTION__ << ": " << __LINE__ << "\n"; __FILE__, __FUNCTION__, __LINE__, name );
ostr << " * [INFO] corrupt data: type is not SGCOLORS '";
ostr << name << "'";
wxLogTrace( MASK_3D_SG, "%s\n", ostr.str().c_str() );
#endif
return false; return false;
} }
@ -991,16 +835,14 @@ bool SGFACESET::validate( void )
return valid; return valid;
// ensure we have at least coordinates and their normals // ensure we have at least coordinates and their normals
if( (NULL == m_Coords && NULL == m_RCoords) if( ( nullptr == m_Coords && nullptr == m_RCoords )
|| (NULL == m_Normals && NULL == m_RNormals) || ( nullptr == m_Normals && nullptr == m_RNormals )
|| (NULL == m_CoordIndices) ) || ( nullptr == m_CoordIndices ) )
{ {
#ifdef DEBUG wxLogTrace( MASK_3D_SG,
std::ostringstream ostr; "%s:%s:%d * [INFO] bad model; no vertices, vertex indices, or normals",
ostr << __FILE__ << ": " << __FUNCTION__ << ": " << __LINE__ << "\n"; __FILE__, __FUNCTION__, __LINE__ );
ostr << " * [INFO] bad model; no vertices, vertex indices, or normals";
wxLogTrace( MASK_3D_SG, "%s\n", ostr.str().c_str() );
#endif
validated = true; validated = true;
valid = false; valid = false;
return false; return false;
@ -1009,21 +851,18 @@ bool SGFACESET::validate( void )
// check that there are >3 vertices // check that there are >3 vertices
SGCOORDS* coords = m_Coords; SGCOORDS* coords = m_Coords;
if( NULL == coords ) if( nullptr == coords )
coords = m_RCoords; coords = m_RCoords;
size_t nCoords = 0; size_t nCoords = 0;
SGPOINT* lCoords = NULL; SGPOINT* lCoords = nullptr;
coords->GetCoordsList( nCoords, lCoords ); coords->GetCoordsList( nCoords, lCoords );
if( nCoords < 3 ) if( nCoords < 3 )
{ {
#ifdef DEBUG wxLogTrace( MASK_3D_SG, "%s:%s:%d * [INFO] bad model; fewer than 3 vertices",
std::ostringstream ostr; __FILE__, __FUNCTION__, __LINE__ );
ostr << __FILE__ << ": " << __FUNCTION__ << ": " << __LINE__ << "\n";
ostr << " * [INFO] bad model; fewer than 3 vertices";
wxLogTrace( MASK_3D_SG, "%s\n", ostr.str().c_str() );
#endif
validated = true; validated = true;
valid = false; valid = false;
return false; return false;
@ -1031,17 +870,15 @@ bool SGFACESET::validate( void )
// check that nVertices is divisible by 3 (facets are triangles) // check that nVertices is divisible by 3 (facets are triangles)
size_t nCIdx = 0; size_t nCIdx = 0;
int* lCIdx = NULL; int* lCIdx = nullptr;
m_CoordIndices->GetIndices( nCIdx, lCIdx ); m_CoordIndices->GetIndices( nCIdx, lCIdx );
if( nCIdx < 3 || ( nCIdx % 3 > 0 ) ) if( nCIdx < 3 || ( nCIdx % 3 > 0 ) )
{ {
#ifdef DEBUG wxLogTrace( MASK_3D_SG,
std::ostringstream ostr; "%s:%s:%d * [INFO] bad model; no vertex indices or not multiple of 3",
ostr << __FILE__ << ": " << __FUNCTION__ << ": " << __LINE__ << "\n"; __FILE__, __FUNCTION__, __LINE__ );
ostr << " * [INFO] bad model; no vertex indices or not multiple of 3";
wxLogTrace( MASK_3D_SG, "%s\n", ostr.str().c_str() );
#endif
validated = true; validated = true;
valid = false; valid = false;
return false; return false;
@ -1052,12 +889,9 @@ bool SGFACESET::validate( void )
{ {
if( lCIdx[i] < 0 || lCIdx[i] >= (int)nCoords ) if( lCIdx[i] < 0 || lCIdx[i] >= (int)nCoords )
{ {
#ifdef DEBUG wxLogTrace( MASK_3D_SG, "%s:%s:%d * [INFO] bad model; vertex index out of bounds",
std::ostringstream ostr; __FILE__, __FUNCTION__, __LINE__ );
ostr << __FILE__ << ": " << __FUNCTION__ << ": " << __LINE__ << "\n";
ostr << " * [INFO] bad model; vertex index out of bounds";
wxLogTrace( MASK_3D_SG, "%s\n", ostr.str().c_str() );
#endif
validated = true; validated = true;
valid = false; valid = false;
return false; return false;
@ -1066,23 +900,21 @@ bool SGFACESET::validate( void )
// check that there are as many normals as vertices // check that there are as many normals as vertices
size_t nNorms = 0; size_t nNorms = 0;
SGVECTOR* lNorms = NULL; SGVECTOR* lNorms = nullptr;
SGNORMALS* pNorms = m_Normals; SGNORMALS* pNorms = m_Normals;
if( NULL == pNorms ) if( nullptr == pNorms )
pNorms = m_RNormals; pNorms = m_RNormals;
pNorms->GetNormalList( nNorms, lNorms ); pNorms->GetNormalList( nNorms, lNorms );
if( nNorms != nCoords ) if( nNorms != nCoords )
{ {
#ifdef DEBUG wxLogTrace( MASK_3D_SG,
std::ostringstream ostr; "%s:%s:%d * [INFO] bad model; number of normals (%ul) does not match "
ostr << __FILE__ << ": " << __FUNCTION__ << ": " << __LINE__ << "\n"; "number of vertices (%ul)", __FILE__, __FUNCTION__, __LINE__,
ostr << " * [INFO] bad model; number of normals (" << nNorms; static_cast<unsigned long>( nNorms ), static_cast<unsigned long>( nCoords ) );
ostr << ") does not match number of vertices (" << nCoords << ")";
wxLogTrace( MASK_3D_SG, "%s\n", ostr.str().c_str() );
#endif
validated = true; validated = true;
valid = false; valid = false;
return false; return false;
@ -1091,14 +923,14 @@ bool SGFACESET::validate( void )
// if there are colors then ensure there are as many colors as vertices // if there are colors then ensure there are as many colors as vertices
SGCOLORS* pColors = m_Colors; SGCOLORS* pColors = m_Colors;
if( NULL == pColors ) if( nullptr == pColors )
pColors = m_RColors; pColors = m_RColors;
if( NULL != pColors ) if( nullptr != pColors )
{ {
// we must have at least as many colors as vertices // we must have at least as many colors as vertices
size_t nColor = 0; size_t nColor = 0;
SGCOLOR* pColor = NULL; SGCOLOR* pColor = nullptr;
pColors->GetColorList( nColor, pColor ); pColors->GetColorList( nColor, pColor );
} }
@ -1112,8 +944,6 @@ void SGFACESET::GatherCoordIndices( std::vector< int >& aIndexList )
{ {
if( m_CoordIndices ) if( m_CoordIndices )
m_CoordIndices->GatherCoordIndices( aIndexList ); m_CoordIndices->GatherCoordIndices( aIndexList );
return;
} }
@ -1124,7 +954,7 @@ bool SGFACESET::CalcNormals( SGNODE** aPtr )
if( m_RCoords ) if( m_RCoords )
coords = m_RCoords; coords = m_RCoords;
if( NULL == coords || coords->coords.empty() ) if( nullptr == coords || coords->coords.empty() )
return false; return false;
if( m_Normals && !m_Normals->norms.empty( ) ) if( m_Normals && !m_Normals->norms.empty( ) )

View File

@ -2,6 +2,7 @@
* This program source code file is part of KiCad, a free EDA CAD application. * This program source code file is part of KiCad, a free EDA CAD application.
* *
* Copyright (C) 2015-2017 Cirilo Bernardo <cirilo.bernardo@gmail.com> * Copyright (C) 2015-2017 Cirilo Bernardo <cirilo.bernardo@gmail.com>
* Copyright (C) 2020 KiCad Developers, see AUTHORS.txt for contributors.
* *
* This program is free software; you can redistribute it and/or * This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License * modify it under the terms of the GNU General Public License
@ -23,7 +24,6 @@
/** /**
* @file sg_faceset.h * @file sg_faceset.h
* defines an indexed face set for a scenegraph
*/ */
@ -40,38 +40,18 @@ class SGNORMALS;
class SGCOLORINDEX; class SGCOLORINDEX;
class SGCOORDINDEX; class SGCOORDINDEX;
/**
* Define an indexed face set for a scenegraph.
*/
class SGFACESET : public SGNODE class SGFACESET : public SGNODE
{ {
private:
bool valid;
bool validated;
void unlinkNode( const SGNODE* aNode, bool isChild );
bool addNode( SGNODE* aNode, bool isChild );
public:
// owned objects
SGCOLORS* m_Colors;
SGCOORDS* m_Coords;
SGCOORDINDEX* m_CoordIndices;
SGNORMALS* m_Normals;
// referenced objects
SGCOLORS* m_RColors;
SGCOORDS* m_RCoords;
SGNORMALS* m_RNormals;
void unlinkChildNode( const SGNODE* aNode ) override;
void unlinkRefNode( const SGNODE* aNode ) override;
// validate the data held by this face set
bool validate( void );
public: public:
SGFACESET( SGNODE* aParent ); SGFACESET( SGNODE* aParent );
virtual ~SGFACESET(); virtual ~SGFACESET();
virtual bool SetParent( SGNODE* aParent, bool notify = true ) override; virtual bool SetParent( SGNODE* aParent, bool notify = true ) override;
SGNODE* FindNode( const char *aNodeName, const SGNODE *aCaller ) override; SGNODE* FindNode( const char* aNodeName, const SGNODE* aCaller ) override;
bool AddRefNode( SGNODE* aNode ) override; bool AddRefNode( SGNODE* aNode ) override;
bool AddChildNode( SGNODE* aNode ) override; bool AddChildNode( SGNODE* aNode ) override;
@ -84,11 +64,34 @@ public:
bool ReadCache( std::istream& aFile, SGNODE* parentNode ) override; bool ReadCache( std::istream& aFile, SGNODE* parentNode ) override;
/** /**
* Function GatherCoordIndices * Add all internal coordinate indices to the given list in preparation for a normals
* adds all internal coordinate indices to the given list * calculation.
* in preparation for a normals calculation
*/ */
void GatherCoordIndices( std::vector< int >& aIndexList ); void GatherCoordIndices( std::vector< int >& aIndexList );
void unlinkChildNode( const SGNODE* aNode ) override;
void unlinkRefNode( const SGNODE* aNode ) override;
// validate the data held by this face set
bool validate( void );
// owned objects
SGCOLORS* m_Colors;
SGCOORDS* m_Coords;
SGCOORDINDEX* m_CoordIndices;
SGNORMALS* m_Normals;
// referenced objects
SGCOLORS* m_RColors;
SGCOORDS* m_RCoords;
SGNORMALS* m_RNormals;
private:
bool valid;
bool validated;
void unlinkNode( const SGNODE* aNode, bool isChild );
bool addNode( SGNODE* aNode, bool isChild );
}; };
/* /*

View File

@ -2,6 +2,7 @@
* This program source code file is part of KiCad, a free EDA CAD application. * This program source code file is part of KiCad, a free EDA CAD application.
* *
* Copyright (C) 2015-2017 Cirilo Bernardo <cirilo.bernardo@gmail.com> * Copyright (C) 2015-2017 Cirilo Bernardo <cirilo.bernardo@gmail.com>
* Copyright (C) 2020 KiCad Developers, see AUTHORS.txt for contributors.
* *
* This program is free software; you can redistribute it and/or * This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License * modify it under the terms of the GNU General Public License
@ -33,7 +34,6 @@
#include "3d_cache/sg/sg_node.h" #include "3d_cache/sg/sg_node.h"
// formats a floating point number for text output to a VRML file
void S3D::FormatFloat( std::string& result, double value ) void S3D::FormatFloat( std::string& result, double value )
{ {
if( value < 1e-8 && value > -1e-8 ) if( value < 1e-8 && value > -1e-8 )
@ -52,7 +52,6 @@ void S3D::FormatFloat( std::string& result, double value )
size_t p = result.find( '.' ); size_t p = result.find( '.' );
// trim trailing 0 if appropriate // trim trailing 0 if appropriate
if( std::string::npos == p ) if( std::string::npos == p )
return; return;
@ -60,28 +59,26 @@ void S3D::FormatFloat( std::string& result, double value )
if( std::string::npos == p ) if( std::string::npos == p )
{ {
while( '0' == *(result.rbegin()) ) while( '0' == *( result.rbegin() ) )
result.erase( result.size() - 1 ); result.erase( result.size() - 1 );
return; return;
} }
if( '0' != result.at( p -1 ) ) if( '0' != result.at( p - 1 ) )
return; return;
// trim all 0 to the left of 'p' // trim all 0 to the left of 'p'
std::string tmp = result.substr( p ); std::string tmp = result.substr( p );
result = result.substr( 0, p ); result = result.substr( 0, p );
while( '0' == *(result.rbegin()) ) while( '0' == *( result.rbegin() ) )
result.erase( result.size() - 1 ); result.erase( result.size() - 1 );
result.append( tmp ); result.append( tmp );
return;
} }
// format orientation data for VRML output
void S3D::FormatOrientation( std::string& result, const SGVECTOR& axis, double rotation ) void S3D::FormatOrientation( std::string& result, const SGVECTOR& axis, double rotation )
{ {
double aX; double aX;
@ -100,11 +97,9 @@ void S3D::FormatOrientation( std::string& result, const SGVECTOR& axis, double r
FormatFloat( tmp, rotation ); FormatFloat( tmp, rotation );
result.append( " " ); result.append( " " );
result.append( tmp ); result.append( tmp );
return;
} }
// format point data for VRML output
void S3D::FormatPoint( std::string& result, const SGPOINT& point ) void S3D::FormatPoint( std::string& result, const SGPOINT& point )
{ {
FormatFloat( result, point.x ); FormatFloat( result, point.x );
@ -117,12 +112,9 @@ void S3D::FormatPoint( std::string& result, const SGPOINT& point )
FormatFloat( tmp, point.z ); FormatFloat( tmp, point.z );
result.append( " " ); result.append( " " );
result.append( tmp ); result.append( tmp );
return;
} }
// format vector data for VRML output
void S3D::FormatVector( std::string& result, const SGVECTOR& aVector ) void S3D::FormatVector( std::string& result, const SGVECTOR& aVector )
{ {
double X, Y, Z; double X, Y, Z;
@ -137,12 +129,9 @@ void S3D::FormatVector( std::string& result, const SGVECTOR& aVector )
FormatFloat( tmp, Z ); FormatFloat( tmp, Z );
result.append( " " ); result.append( " " );
result.append( tmp ); result.append( tmp );
return;
} }
// format Color data for VRML output
void S3D::FormatColor( std::string& result, const SGCOLOR& aColor ) void S3D::FormatColor( std::string& result, const SGCOLOR& aColor )
{ {
float R, G, B; float R, G, B;
@ -157,16 +146,14 @@ void S3D::FormatColor( std::string& result, const SGCOLOR& aColor )
FormatFloat( tmp, B ); FormatFloat( tmp, B );
result.append( " " ); result.append( " " );
result.append( tmp ); result.append( tmp );
return;
} }
bool S3D::WritePoint( std::ostream& aFile, const SGPOINT& aPoint ) bool S3D::WritePoint( std::ostream& aFile, const SGPOINT& aPoint )
{ {
aFile.write( (char*)&aPoint.x, sizeof(aPoint.x) ); aFile.write( (char*) &aPoint.x, sizeof( aPoint.x ) );
aFile.write( (char*)&aPoint.y, sizeof(aPoint.y) ); aFile.write( (char*) &aPoint.y, sizeof( aPoint.y ) );
aFile.write( (char*)&aPoint.z, sizeof(aPoint.z) ); aFile.write( (char*) &aPoint.z, sizeof( aPoint.z ) );
if( aFile.fail() ) if( aFile.fail() )
return false; return false;
@ -179,9 +166,9 @@ bool S3D::WriteVector( std::ostream& aFile, const SGVECTOR& aVector )
{ {
double x, y, z; double x, y, z;
aVector.GetVector( x, y, z ); aVector.GetVector( x, y, z );
aFile.write( (char*)&x, sizeof(double) ); aFile.write( (char*) &x, sizeof( double ) );
aFile.write( (char*)&y, sizeof(double) ); aFile.write( (char*) &y, sizeof( double ) );
aFile.write( (char*)&z, sizeof(double) ); aFile.write( (char*) &z, sizeof( double ) );
if( aFile.fail() ) if( aFile.fail() )
return false; return false;
@ -194,9 +181,9 @@ bool S3D::WriteColor( std::ostream& aFile, const SGCOLOR& aColor )
{ {
float r, g, b; float r, g, b;
aColor.GetColor( r, g, b ); aColor.GetColor( r, g, b );
aFile.write( (char*)&r, sizeof(float) ); aFile.write( (char*) &r, sizeof( float ) );
aFile.write( (char*)&g, sizeof(float) ); aFile.write( (char*) &g, sizeof( float ) );
aFile.write( (char*)&b, sizeof(float) ); aFile.write( (char*) &b, sizeof( float ) );
if( aFile.fail() ) if( aFile.fail() )
return false; return false;
@ -212,13 +199,9 @@ S3D::SGTYPES S3D::ReadTag( std::istream& aFile, std::string& aName )
if( '[' != schar ) if( '[' != schar )
{ {
#ifdef DEBUG wxLogTrace( MASK_3D_SG,
std::ostringstream ostr; "%s:%s:%d * [INFO] corrupt data; missing left bracket at position %d",
ostr << __FILE__ << ": " << __FUNCTION__ << ": " << __LINE__ << "\n"; __FILE__, __FUNCTION__, __LINE__, static_cast<int>( aFile.tellg() ) );
ostr << " * [INFO] corrupt data; missing left bracket at position ";
ostr << aFile.tellg();
wxLogTrace( MASK_3D_SG, "%s\n", ostr.str().c_str() );
#endif
return S3D::SGTYPE_END; return S3D::SGTYPE_END;
} }
@ -234,12 +217,9 @@ S3D::SGTYPES S3D::ReadTag( std::istream& aFile, std::string& aName )
if( schar != ']' ) if( schar != ']' )
{ {
#ifdef DEBUG wxLogTrace( MASK_3D_SG,
std::ostringstream ostr; "%s:%s:%d * [INFO] corrupt data; could not find right bracket",
ostr << __FILE__ << ": " << __FUNCTION__ << ": " << __LINE__ << "\n"; __FILE__, __FUNCTION__, __LINE__ );
ostr << " * [INFO] corrupt data; could not find right bracket";
wxLogTrace( MASK_3D_SG, "%s\n", ostr.str().c_str() );
#endif
return S3D::SGTYPE_END; return S3D::SGTYPE_END;
} }
@ -249,13 +229,9 @@ S3D::SGTYPES S3D::ReadTag( std::istream& aFile, std::string& aName )
if( std::string::npos == upos ) if( std::string::npos == upos )
{ {
#ifdef DEBUG wxLogTrace( MASK_3D_SG,
std::ostringstream ostr; "%s:%s:%d * [INFO] corrupt data; no underscore in name '%s'",
ostr << __FILE__ << ": " << __FUNCTION__ << ": " << __LINE__ << "\n"; __FILE__, __FUNCTION__, __LINE__, name );
ostr << " * [INFO] corrupt data; no underscore in name '";
ostr << name << "'";
wxLogTrace( MASK_3D_SG, "%s\n", ostr.str().c_str() );
#endif
return S3D::SGTYPE_END; return S3D::SGTYPE_END;
} }
@ -279,15 +255,9 @@ S3D::SGTYPES S3D::ReadTag( std::istream& aFile, std::string& aName )
return types[i]; return types[i];
} }
#ifdef DEBUG wxLogTrace( MASK_3D_SG,
do { "%s:%s:%d * [INFO] corrupt data; no node type matching '%s'",
std::ostringstream ostr; __FILE__, __FUNCTION__, __LINE__, name );
ostr << __FILE__ << ": " << __FUNCTION__ << ": " << __LINE__ << "\n";
ostr << " * [INFO] corrupt data; no node type matching '";
ostr << name << "'";
wxLogTrace( MASK_3D_SG, "%s\n", ostr.str().c_str() );
} while( 0 );
#endif
return S3D::SGTYPE_END; return S3D::SGTYPE_END;
} }
@ -295,9 +265,9 @@ S3D::SGTYPES S3D::ReadTag( std::istream& aFile, std::string& aName )
bool S3D::ReadPoint( std::istream& aFile, SGPOINT& aPoint ) bool S3D::ReadPoint( std::istream& aFile, SGPOINT& aPoint )
{ {
aFile.read( (char*)&aPoint.x, sizeof( aPoint.x ) ); aFile.read( (char*) &aPoint.x, sizeof( aPoint.x ) );
aFile.read( (char*)&aPoint.y, sizeof( aPoint.y ) ); aFile.read( (char*) &aPoint.y, sizeof( aPoint.y ) );
aFile.read( (char*)&aPoint.z, sizeof( aPoint.z ) ); aFile.read( (char*) &aPoint.z, sizeof( aPoint.z ) );
if( aFile.fail() ) if( aFile.fail() )
return false; return false;
@ -309,9 +279,9 @@ bool S3D::ReadPoint( std::istream& aFile, SGPOINT& aPoint )
bool S3D::ReadVector( std::istream& aFile, SGVECTOR& aVector ) bool S3D::ReadVector( std::istream& aFile, SGVECTOR& aVector )
{ {
double x, y, z; double x, y, z;
aFile.read( (char*)&x, sizeof(double) ); aFile.read( (char*) &x, sizeof( double ) );
aFile.read( (char*)&y, sizeof(double) ); aFile.read( (char*) &y, sizeof( double ) );
aFile.read( (char*)&z, sizeof(double) ); aFile.read( (char*) &z, sizeof( double ) );
aVector.SetVector( x, y, z ); aVector.SetVector( x, y, z );
if( aFile.fail() ) if( aFile.fail() )
@ -324,9 +294,9 @@ bool S3D::ReadVector( std::istream& aFile, SGVECTOR& aVector )
bool S3D::ReadColor( std::istream& aFile, SGCOLOR& aColor ) bool S3D::ReadColor( std::istream& aFile, SGCOLOR& aColor )
{ {
float r, g, b; float r, g, b;
aFile.read( (char*)&r, sizeof(float) ); aFile.read( (char*) &r, sizeof( float ) );
aFile.read( (char*)&g, sizeof(float) ); aFile.read( (char*) &g, sizeof( float ) );
aFile.read( (char*)&b, sizeof(float) ); aFile.read( (char*) &b, sizeof( float ) );
aColor.SetColor( r, g, b ); aColor.SetColor( r, g, b );
if( aFile.fail() ) if( aFile.fail() )
@ -376,24 +346,19 @@ static void calcTriad( glm::dvec3* pts, glm::dvec3& tri )
// normal * 2 * area // normal * 2 * area
tri = glm::cross( pts[1] - pts[0], pts[2] - pts[0] ); tri = glm::cross( pts[1] - pts[0], pts[2] - pts[0] );
return;
} }
bool S3D::CalcTriangleNormals( std::vector< SGPOINT > coords, bool S3D::CalcTriangleNormals( std::vector< SGPOINT > coords, std::vector< int >& index,
std::vector< int >& index, std::vector< SGVECTOR >& norms ) std::vector< SGVECTOR >& norms )
{ {
size_t vsize = coords.size(); size_t vsize = coords.size();
if( vsize < 3 ) if( vsize < 3 )
{ {
#ifdef DEBUG wxLogTrace( MASK_3D_SG,
std::ostringstream ostr; "%s:%s:%d * [INFO] invalid vertex set (fewer than 3 vertices)",
ostr << __FILE__ << ": " << __FUNCTION__ << ": " << __LINE__ << "\n"; __FILE__, __FUNCTION__, __LINE__ );
ostr << " * [INFO] invalid vertex set (fewer than 3 vertices)";
wxLogTrace( MASK_3D_SG, "%s\n", ostr.str().c_str() );
#endif
return false; return false;
} }
@ -402,24 +367,16 @@ bool S3D::CalcTriangleNormals( std::vector< SGPOINT > coords,
if( 0 != isize % 3 || index.empty() ) if( 0 != isize % 3 || index.empty() )
{ {
#ifdef DEBUG wxLogTrace( MASK_3D_SG, "%s:%s:%d * [INFO] invalid index set (not multiple of 3)",
std::ostringstream ostr; __FILE__, __FUNCTION__, __LINE__ );
ostr << __FILE__ << ": " << __FUNCTION__ << ": " << __LINE__ << "\n";
ostr << " * [INFO] invalid index set (not multiple of 3)";
wxLogTrace( MASK_3D_SG, "%s\n", ostr.str().c_str() );
#endif
return false; return false;
} }
if( !norms.empty() ) if( !norms.empty() )
{ {
#ifdef DEBUG wxLogTrace( MASK_3D_SG, "%s:%s:%d * [INFO] normals set is not empty",
std::ostringstream ostr; __FILE__, __FUNCTION__, __LINE__ );
ostr << __FILE__ << ": " << __FUNCTION__ << ": " << __LINE__ << "\n";
ostr << " * [INFO] normals set is not empty";
wxLogTrace( MASK_3D_SG, "%s\n", ostr.str().c_str() );
#endif
return false; return false;
} }
@ -435,15 +392,14 @@ bool S3D::CalcTriangleNormals( std::vector< SGPOINT > coords,
p2 = index[i++]; p2 = index[i++];
p3 = index[i++]; p3 = index[i++];
if( p1 < 0 || p1 >= (int)vsize || p2 < 0 || p2 >= (int)vsize || if( p1 < 0 || p1 >= (int)vsize || p2 < 0 || p2 >= (int)vsize || p3 < 0 || p3 >= (int)vsize )
p3 < 0 || p3 >= (int)vsize )
{ {
#ifdef DEBUG #ifdef DEBUG
std::ostringstream ostr; std::ostringstream ostr;
ostr << __FILE__ << ": " << __FUNCTION__ << ": " << __LINE__ << "\n"; ostr << __FILE__ << ": " << __FUNCTION__ << ": " << __LINE__ << "\n";
ostr << " * [INFO] invalid index set; index out of bounds"; ostr << " * [INFO] invalid index set; index out of bounds";
wxLogTrace( MASK_3D_SG, "%s\n", ostr.str().c_str() ); wxLogTrace( MASK_3D_SG, "%s\n", ostr.str().c_str() );
#endif #endif
return false; return false;
} }
@ -525,12 +481,9 @@ bool S3D::CalcTriangleNormals( std::vector< SGPOINT > coords,
if( norms.size() != coords.size() ) if( norms.size() != coords.size() )
{ {
#ifdef DEBUG wxLogTrace( MASK_3D_SG,
std::ostringstream ostr; "%s:%s:%d * [BUG] number of normals does not equal number of vertices",
ostr << __FILE__ << ": " << __FUNCTION__ << ": " << __LINE__ << "\n"; __FILE__, __FUNCTION__, __LINE__ );
ostr << " * [BUG] number of normals does not equal number of vertices";
wxLogTrace( MASK_3D_SG, "%s\n", ostr.str().c_str() );
#endif
return false; return false;
} }

View File

@ -2,6 +2,7 @@
* This program source code file is part of KiCad, a free EDA CAD application. * This program source code file is part of KiCad, a free EDA CAD application.
* *
* Copyright (C) 2015-2017 Cirilo Bernardo <cirilo.bernardo@gmail.com> * Copyright (C) 2015-2017 Cirilo Bernardo <cirilo.bernardo@gmail.com>
* Copyright (C) 2020 KiCad Developers, see AUTHORS.txt for contributors.
* *
* This program is free software; you can redistribute it and/or * This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License * modify it under the terms of the GNU General Public License
@ -23,10 +24,10 @@
/** /**
* @file sg_helpers.h * @file sg_helpers.h
* defines a number of macro functions to aid in repetitious code which *
* is probably best expressed as a preprocessor macro rather than as * Define a number of macros to aid in repetitious code which is probably best expressed
* a template. This header also declares a number of functions which are * as a preprocessor macro rather than as a template. This header also declares a number
* only of use within the sg_* classes. * of functions which are only of use within the sg_* classes.
*/ */
#ifndef SG_HELPERS_H #ifndef SG_HELPERS_H
@ -44,120 +45,155 @@ class SGNORMALS;
class SGCOORDS; class SGCOORDS;
class SGCOORDINDEX; class SGCOORDINDEX;
// Function to drop references within an SGNODE // Function to drop references within an SGNODE
// The node being destroyed must remove itself from the object reference's // The node being destroyed must remove itself from the object reference's
// backpointer list in order to avoid a segfault. // backpointer list in order to avoid a segfault.
#define DROP_REFS( aType, aList ) do { \ #define DROP_REFS( aType, aList ) \
std::vector< aType* >::iterator sL = aList.begin(); \ do \
std::vector< aType* >::iterator eL = aList.end(); \ { \
while( sL != eL ) { \ std::vector<aType*>::iterator sL = aList.begin(); \
((SGNODE*)*sL)->delNodeRef( this ); \ std::vector<aType*>::iterator eL = aList.end(); \
++sL; \ while( sL != eL ) \
} \ { \
aList.clear(); \ ( (SGNODE*) *sL )->delNodeRef( this ); \
++sL; \
} \
aList.clear(); \
} while( 0 ) } while( 0 )
// Function to delete owned objects within an SGNODE // Function to delete owned objects within an SGNODE
// The owned object's parent is set to NULL before // The owned object's parent is set to NULL before
// deletion to avoid a redundant 'unlinkChildNode' call. // deletion to avoid a redundant 'unlinkChildNode' call.
#define DEL_OBJS( aType, aList ) do { \ #define DEL_OBJS( aType, aList ) \
std::vector< aType* >::iterator sL = aList.begin(); \ do \
std::vector< aType* >::iterator eL = aList.end(); \ { \
while( sL != eL ) { \ std::vector<aType*>::iterator sL = aList.begin(); \
((SGNODE*)*sL)->SetParent( NULL, false ); \ std::vector<aType*>::iterator eL = aList.end(); \
delete *sL; \ while( sL != eL ) \
++sL; \ { \
} \ ( (SGNODE*) *sL )->SetParent( nullptr, false ); \
aList.clear(); \ delete *sL; \
++sL; \
} \
aList.clear(); \
} while( 0 ) } while( 0 )
// Function to unlink a child or reference node when that child or // Function to unlink a child or reference node when that child or
// reference node is being destroyed. // reference node is being destroyed.
#define UNLINK_NODE( aNodeID, aType, aNode, aOwnedList, aRefList, isChild ) do { \ #define UNLINK_NODE( aNodeID, aType, aNode, aOwnedList, aRefList, isChild ) \
if( aNodeID == aNode->GetNodeType() ) { \ do \
std::vector< aType* >* oSL; \ { \
std::vector< aType* >::iterator sL; \ if( aNodeID == aNode->GetNodeType() ) \
std::vector< aType* >::iterator eL; \ { \
if( isChild ) { \ std::vector<aType*>* oSL; \
oSL = &aOwnedList; \ std::vector<aType*>::iterator sL; \
sL = oSL->begin(); \ std::vector<aType*>::iterator eL; \
eL = oSL->end(); \ if( isChild ) \
while( sL != eL ) { \ { \
if( (SGNODE*)*sL == aNode ) { \ oSL = &aOwnedList; \
oSL->erase( sL ); \ sL = oSL->begin(); \
return; \ eL = oSL->end(); \
} \ while( sL != eL ) \
++sL; \ { \
} \ if( (SGNODE*) *sL == aNode ) \
} else { \ { \
oSL = &aRefList; \ oSL->erase( sL ); \
sL = oSL->begin(); \ return; \
eL = oSL->end(); \ } \
while( sL != eL ) { \ ++sL; \
if( (SGNODE*)*sL == aNode ) { \ } \
delNodeRef( this ); \ } \
oSL->erase( sL ); \ else \
return; \ { \
} \ oSL = &aRefList; \
++sL; \ sL = oSL->begin(); \
} \ eL = oSL->end(); \
} \ while( sL != eL ) \
return; \ { \
} } while( 0 ) if( (SGNODE*) *sL == aNode ) \
{ \
delNodeRef( this ); \
oSL->erase( sL ); \
return; \
} \
++sL; \
} \
} \
return; \
} \
} while( 0 )
// Function to check a node type, check for an existing reference, // Function to check a node type, check for an existing reference,
// and add the node type to the reference list if applicable // and add the node type to the reference list if applicable
#define ADD_NODE( aNodeID, aType, aNode, aOwnedList, aRefList, isChild ) do { \ #define ADD_NODE( aNodeID, aType, aNode, aOwnedList, aRefList, isChild ) \
if( aNodeID == aNode->GetNodeType() ) { \ do \
std::vector< aType* >::iterator sL; \ { \
sL = std::find( aOwnedList.begin(), aOwnedList.end(), aNode ); \ if( aNodeID == aNode->GetNodeType() ) \
if( sL != aOwnedList.end() ) return true; \ { \
sL = std::find( aRefList.begin(), aRefList.end(), aNode ); \ std::vector<aType*>::iterator sL; \
if( sL != aRefList.end() ) return true; \ sL = std::find( aOwnedList.begin(), aOwnedList.end(), aNode ); \
if( isChild ) { \ if( sL != aOwnedList.end() ) \
SGNODE* ppn = (SGNODE*)aNode->GetParent(); \ return true; \
if( NULL != ppn ) { \ sL = std::find( aRefList.begin(), aRefList.end(), aNode ); \
if( this != ppn ) { \ if( sL != aRefList.end() ) \
std::cerr << __FILE__ << ": " << __FUNCTION__ << ": " << __LINE__ << "\n"; \ return true; \
std::cerr << " * [BUG] object '" << aNode->GetName(); \ if( isChild ) \
std::cerr << "' has multiple parents '" << ppn->GetName() << "', '"; \ { \
std::cerr << m_Name << "'\n"; \ SGNODE* ppn = (SGNODE*) aNode->GetParent(); \
return false; \ if( nullptr != ppn ) \
} \ { \
} \ if( this != ppn ) \
aOwnedList.push_back( (aType*)aNode ); \ { \
aNode->SetParent( this, false ); \ std::cerr << __FILE__ << ": " << __FUNCTION__ << ": " << __LINE__ << "\n"; \
} else { \ std::cerr << " * [BUG] object '" << aNode->GetName(); \
/*if( NULL == aNode->GetParent() ) { \ std::cerr << "' has multiple parents '" << ppn->GetName() << "', '"; \
std::cerr << m_Name << "'\n"; \
return false; \
} \
} \
aOwnedList.push_back( (aType*) aNode ); \
aNode->SetParent( this, false ); \
} \
else \
{ \
/*if( nullptr == aNode->GetParent() ) { \
std::cerr << __FILE__ << ": " << __FUNCTION__ << ": " << __LINE__ << "\n"; \ std::cerr << __FILE__ << ": " << __FUNCTION__ << ": " << __LINE__ << "\n"; \
std::cerr << " * [BUG] object '" << aNode->GetName(); \ std::cerr << " * [BUG] object '" << aNode->GetName(); \
std::cerr << "' has no parent\n"; \ std::cerr << "' has no parent\n"; \
std::cerr << " * [INFO] possible copy assignment or copy constructor bug\n"; \ std::cerr << " * [INFO] possible copy assignment or copy constructor bug\n"; \
return false; \ return false; \
} */ \ } */ \
aRefList.push_back( (aType*)aNode ); \ aRefList.push_back( (aType*) aNode ); \
aNode->addNodeRef( this ); \ aNode->addNodeRef( this ); \
} \ } \
return true; \ return true; \
} } while( 0 ) } \
} while( 0 )
// Function to find a node object given a (non-unique) node name // Function to find a node object given a (non-unique) node name
#define FIND_NODE( aType, aName, aNodeList, aCallingNode ) do { \ #define FIND_NODE( aType, aName, aNodeList, aCallingNode ) \
std::vector< aType* >::iterator sLA = aNodeList.begin(); \ do \
std::vector< aType* >::iterator eLA = aNodeList.end(); \ { \
SGNODE* psg = NULL; \ std::vector<aType*>::iterator sLA = aNodeList.begin(); \
while( sLA != eLA ) { \ std::vector<aType*>::iterator eLA = aNodeList.end(); \
if( (SGNODE*)*sLA != aCallingNode ) { \ SGNODE* psg = nullptr; \
psg = (SGNODE*) (*sLA)->FindNode( aName, this ); \ while( sLA != eLA ) \
if( NULL != psg) \ { \
return psg; \ if( (SGNODE*) *sLA != aCallingNode ) \
} \ { \
++sLA; \ psg = (SGNODE*) ( *sLA )->FindNode( aName, this ); \
} } while ( 0 ) if( nullptr != psg ) \
return psg; \
} \
++sLA; \
} \
} while( 0 )
namespace S3D namespace S3D
{ {
@ -168,27 +204,23 @@ namespace S3D
// //
/* /*
* Function CalcTriangleNormals * Take an array of 3D coordinates and its corresponding index set and calculates
* takes an array of 3D coordinates and its corresponding index set and calculates * the normals assuming that indices are given in CCW order.
* the normals assuming that indices are given in CCW order. Care must be taken in
* using this function to ensure that:
* (a) all coordinates are indexed; unindexed coordinates are assigned normal(0,0,1);
* when dealing with VRML models which may list and reuse one large coordinate set it
* is necessary to gather all index sets and perform this operation only once.
* (b) index sets must represent triangles (multiple of 3 indices) and must not be
* degenerate - that is all indices and coordinates in a triad must be unique.
* *
* @param coords is the array of 3D vertices * Care must be taken in using this function to ensure that:
* @param index is the array of 3x vertex indices (triads) * -# All coordinates are indexed; unindexed coordinates are assigned normal(0,0,1);
* @param norms is an empty array which holds the normals corresponding to each vector * when dealing with VRML models which may list and reuse one large coordinate set it
* is necessary to gather all index sets and perform this operation only once.
* -# Index sets must represent triangles (multiple of 3 indices) and must not be
* degenerate, that is all indices and coordinates in a triad must be unique.
*
* @param coords is the array of 3D vertices.
* @param index is the array of 3x vertex indices (triads).
* @param norms is an empty array which holds the normals corresponding to each vector.
* @return true on success; otherwise false. * @return true on success; otherwise false.
*/ */
bool CalcTriangleNormals( std::vector< SGPOINT > coords, std::vector< int >& index, bool CalcTriangleNormals( std::vector< SGPOINT > coords, std::vector< int >& index,
std::vector< SGVECTOR >& norms ); std::vector< SGVECTOR >& norms );
//
// VRML related functions
//
// formats a floating point number for text output to a VRML file // formats a floating point number for text output to a VRML file
void FormatFloat( std::string& result, double value ); void FormatFloat( std::string& result, double value );
@ -218,19 +250,13 @@ namespace S3D
// write out an RGB color // write out an RGB color
bool WriteColor( std::ostream& aFile, const SGCOLOR& aColor ); bool WriteColor( std::ostream& aFile, const SGCOLOR& aColor );
//
// Cache related READ functions
//
/** /**
* Function ReadTag * Read the text tag of a binary cache file which is the NodeTag and unique ID number combined.
* reads the text tag of a binary cache file which is the
* NodeTag and unique ID number combined
* *
* @param aFile is a binary file open for reading * @param aFile is a binary file open for reading.
* @param aName will hold the tag name on successful return * @param aName will hold the tag name on successful return.
* @return will be the NodeType which the tag represents or * @return will be the NodeType which the tag represents or S3D::SGTYPES::SGTYPE_END on
* S3D::SGTYPES::SGTYPE_END on failure * failure.
*/ */
S3D::SGTYPES ReadTag( std::istream& aFile, std::string& aName ); S3D::SGTYPES ReadTag( std::istream& aFile, std::string& aName );

View File

@ -2,6 +2,7 @@
* This program source code file is part of KiCad, a free EDA CAD application. * This program source code file is part of KiCad, a free EDA CAD application.
* *
* Copyright (C) 2015-2017 Cirilo Bernardo <cirilo.bernardo@gmail.com> * Copyright (C) 2015-2017 Cirilo Bernardo <cirilo.bernardo@gmail.com>
* Copyright (C) 2020 KiCad Developers, see AUTHORS.txt for contributors.
* *
* This program is free software; you can redistribute it and/or * This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License * modify it under the terms of the GNU General Public License
@ -30,33 +31,25 @@
SGINDEX::SGINDEX( SGNODE* aParent ) : SGNODE( aParent ) SGINDEX::SGINDEX( SGNODE* aParent ) : SGNODE( aParent )
{ {
if( NULL != aParent && S3D::SGTYPE_FACESET != aParent->GetNodeType() ) if( nullptr != aParent && S3D::SGTYPE_FACESET != aParent->GetNodeType() )
{ {
m_Parent = NULL; m_Parent = nullptr;
#ifdef DEBUG wxLogTrace( MASK_3D_SG, "%s:%s:%d * [BUG] inappropriate parent to SGINDEX (type '%d')",
std::ostringstream ostr; __FILE__, __FUNCTION__, __LINE__, aParent->GetNodeType() );
ostr << __FILE__ << ": " << __FUNCTION__ << ": " << __LINE__ << "\n";
ostr << " * [BUG] inappropriate parent to SGINDEX (type ";
ostr << aParent->GetNodeType() << ")";
wxLogTrace( MASK_3D_SG, "%s\n", ostr.str().c_str() );
#endif
} }
return;
} }
SGINDEX::~SGINDEX() SGINDEX::~SGINDEX()
{ {
index.clear(); index.clear();
return;
} }
bool SGINDEX::SetParent( SGNODE* aParent, bool notify ) bool SGINDEX::SetParent( SGNODE* aParent, bool notify )
{ {
if( NULL != m_Parent ) if( nullptr != m_Parent )
{ {
if( aParent == m_Parent ) if( aParent == m_Parent )
return true; return true;
@ -65,14 +58,14 @@ bool SGINDEX::SetParent( SGNODE* aParent, bool notify )
if( notify ) if( notify )
m_Parent->unlinkChildNode( this ); m_Parent->unlinkChildNode( this );
m_Parent = NULL; m_Parent = nullptr;
if( NULL == aParent ) if( nullptr == aParent )
return true; return true;
} }
// only a SGFACESET may be parent to a SGINDEX and derived types // only a SGFACESET may be parent to a SGINDEX and derived types
if( NULL != aParent && S3D::SGTYPE_FACESET != aParent->GetNodeType() ) if( nullptr != aParent && S3D::SGTYPE_FACESET != aParent->GetNodeType() )
return false; return false;
m_Parent = aParent; m_Parent = aParent;
@ -86,50 +79,34 @@ bool SGINDEX::SetParent( SGNODE* aParent, bool notify )
SGNODE* SGINDEX::FindNode(const char *aNodeName, const SGNODE *aCaller) noexcept SGNODE* SGINDEX::FindNode(const char *aNodeName, const SGNODE *aCaller) noexcept
{ {
if( NULL == aNodeName || 0 == aNodeName[0] ) if( nullptr == aNodeName || 0 == aNodeName[0] )
return NULL; return nullptr;
if( !m_Name.compare( aNodeName ) ) if( !m_Name.compare( aNodeName ) )
return this; return this;
return NULL; return nullptr;
} }
void SGINDEX::unlinkChildNode( const SGNODE* aCaller ) noexcept void SGINDEX::unlinkChildNode( const SGNODE* aCaller ) noexcept
{ {
#ifdef DEBUG // Node should have no children or refs.
std::ostringstream ostr; wxCHECK( false, /* void */ );
ostr << __FILE__ << ": " << __FUNCTION__ << ": " << __LINE__ << "\n";
ostr << " * [BUG] unexpected code branch; node should have no children or refs";
wxLogTrace( MASK_3D_SG, "%s\n", ostr.str().c_str() );
#endif
return;
} }
void SGINDEX::unlinkRefNode( const SGNODE* aCaller ) noexcept void SGINDEX::unlinkRefNode( const SGNODE* aCaller ) noexcept
{ {
#ifdef DEBUG // Node should have no children or refs.
std::ostringstream ostr; wxCHECK( false, /* void */ );
ostr << __FILE__ << ": " << __FUNCTION__ << ": " << __LINE__ << "\n";
ostr << " * [BUG] unexpected code branch; node should have no children or refs";
wxLogTrace( MASK_3D_SG, "%s\n", ostr.str().c_str() );
#endif
return;
} }
bool SGINDEX::AddRefNode( SGNODE* aNode ) noexcept bool SGINDEX::AddRefNode( SGNODE* aNode ) noexcept
{ {
#ifdef DEBUG // Node should have no children or refs.
std::ostringstream ostr; wxCHECK( false, false );
ostr << __FILE__ << ": " << __FUNCTION__ << ": " << __LINE__ << "\n";
ostr << " * [BUG] this node does not accept children or refs";
wxLogTrace( MASK_3D_SG, "%s\n", ostr.str().c_str() );
#endif
return false; return false;
} }
@ -137,12 +114,8 @@ bool SGINDEX::AddRefNode( SGNODE* aNode ) noexcept
bool SGINDEX::AddChildNode( SGNODE* aNode ) noexcept bool SGINDEX::AddChildNode( SGNODE* aNode ) noexcept
{ {
#ifdef DEBUG // Node should have no children or refs.
std::ostringstream ostr; wxCHECK( false, false );
ostr << __FILE__ << ": " << __FUNCTION__ << ": " << __LINE__ << "\n";
ostr << " * [BUG] this node does not accept children or refs";
wxLogTrace( MASK_3D_SG, "%s\n", ostr.str().c_str() );
#endif
return false; return false;
} }
@ -153,7 +126,7 @@ bool SGINDEX::GetIndices( size_t& nIndices, int*& aIndexList )
if( index.empty() ) if( index.empty() )
{ {
nIndices = 0; nIndices = 0;
aIndexList = NULL; aIndexList = nullptr;
return false; return false;
} }
@ -167,7 +140,7 @@ void SGINDEX::SetIndices( size_t nIndices, int* aIndexList )
{ {
index.clear(); index.clear();
if( 0 == nIndices || NULL == aIndexList ) if( 0 == nIndices || nullptr == aIndexList )
return; return;
for( size_t i = 0; i < nIndices; ++i ) for( size_t i = 0; i < nIndices; ++i )
@ -180,7 +153,6 @@ void SGINDEX::SetIndices( size_t nIndices, int* aIndexList )
void SGINDEX::AddIndex( int aIndex ) void SGINDEX::AddIndex( int aIndex )
{ {
index.push_back( aIndex ); index.push_back( aIndex );
return;
} }
@ -210,17 +182,8 @@ bool SGINDEX::writeCoordIndex( std::ostream& aFile )
{ {
size_t n = index.size(); size_t n = index.size();
if( n % 3 ) wxCHECK_MSG( n % 3 == 0, false,
{ "Coordinate index is not divisible by three (violates triangle constraint)" );
#ifdef DEBUG
std::ostringstream ostr;
ostr << __FILE__ << ": " << __FUNCTION__ << ": " << __LINE__ << "\n";
ostr << " * [BUG] coord index is not divisible by three (violates triangle constraint)";
wxLogTrace( MASK_3D_SG, "%s\n", ostr.str().c_str() );
#endif
return false;
}
aFile << " coordIndex [\n "; aFile << " coordIndex [\n ";
@ -296,26 +259,16 @@ bool SGINDEX::writeIndexList( std::ostream& aFile )
bool SGINDEX::WriteCache( std::ostream& aFile, SGNODE* parentNode ) bool SGINDEX::WriteCache( std::ostream& aFile, SGNODE* parentNode )
{ {
if( NULL == parentNode ) if( nullptr == parentNode )
{ {
if( NULL == m_Parent ) wxCHECK( m_Parent, false );
{
#ifdef DEBUG
std::ostringstream ostr;
ostr << __FILE__ << ": " << __FUNCTION__ << ": " << __LINE__ << "\n";
ostr << " * [BUG] corrupt data; m_aParent is NULL";
wxLogTrace( MASK_3D_SG, "%s\n", ostr.str().c_str() );
#endif
return false;
}
SGNODE* np = m_Parent; SGNODE* np = m_Parent;
while( NULL != np->GetParent() ) while( nullptr != np->GetParent() )
np = np->GetParent(); np = np->GetParent();
if( np->WriteCache( aFile, NULL ) ) if( np->WriteCache( aFile, nullptr ) )
{ {
m_written = true; m_written = true;
return true; return true;
@ -324,26 +277,12 @@ bool SGINDEX::WriteCache( std::ostream& aFile, SGNODE* parentNode )
return false; return false;
} }
if( parentNode != m_Parent ) wxCHECK( parentNode == m_Parent, false );
{
#ifdef DEBUG
std::ostringstream ostr;
ostr << __FILE__ << ": " << __FUNCTION__ << ": " << __LINE__ << "\n";
ostr << " * [BUG] corrupt data; parentNode != m_aParent";
wxLogTrace( MASK_3D_SG, "%s\n", ostr.str().c_str() );
#endif
return false;
}
if( !aFile.good() ) if( !aFile.good() )
{ {
#ifdef DEBUG wxLogTrace( MASK_3D_SG, "%s:%s:%d * [INFO] bad stream",
std::ostringstream ostr; __FILE__, __FUNCTION__, __LINE__ );
ostr << __FILE__ << ": " << __FUNCTION__ << ": " << __LINE__ << "\n";
ostr << " * [INFO] bad stream";
wxLogTrace( MASK_3D_SG, "%s\n", ostr.str().c_str() );
#endif
return false; return false;
} }
@ -365,17 +304,7 @@ bool SGINDEX::WriteCache( std::ostream& aFile, SGNODE* parentNode )
bool SGINDEX::ReadCache( std::istream& aFile, SGNODE* parentNode ) bool SGINDEX::ReadCache( std::istream& aFile, SGNODE* parentNode )
{ {
if( !index.empty() ) wxCHECK( index.empty(), false );
{
#ifdef DEBUG
std::ostringstream ostr;
ostr << __FILE__ << ": " << __FUNCTION__ << ": " << __LINE__ << "\n";
ostr << " * [BUG] non-empty node";
wxLogTrace( MASK_3D_SG, "%s\n", ostr.str().c_str() );
#endif
return false;
}
size_t npts; size_t npts;
aFile.read( (char*)&npts, sizeof(size_t) ); aFile.read( (char*)&npts, sizeof(size_t) );
@ -386,7 +315,7 @@ bool SGINDEX::ReadCache( std::istream& aFile, SGNODE* parentNode )
for( size_t i = 0; i < npts; ++i ) for( size_t i = 0; i < npts; ++i )
{ {
aFile.read( (char*)&tmp, sizeof(int) ); aFile.read( (char*) &tmp, sizeof( int ) );
if( aFile.fail() ) if( aFile.fail() )
return false; return false;

View File

@ -2,6 +2,7 @@
* This program source code file is part of KiCad, a free EDA CAD application. * This program source code file is part of KiCad, a free EDA CAD application.
* *
* Copyright (C) 2015-2017 Cirilo Bernardo <cirilo.bernardo@gmail.com> * Copyright (C) 2015-2017 Cirilo Bernardo <cirilo.bernardo@gmail.com>
* Copyright (C) 2020 KiCad Developers, see AUTHORS.txt for contributors.
* *
* This program is free software; you can redistribute it and/or * This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License * modify it under the terms of the GNU General Public License
@ -23,7 +24,6 @@
/** /**
* @file sg_index.h * @file sg_index.h
* defines a generic Index interface for a scenegraph object
*/ */
#ifndef SG_INDEX_H #ifndef SG_INDEX_H
@ -32,58 +32,50 @@
#include <vector> #include <vector>
#include "3d_cache/sg/sg_node.h" #include "3d_cache/sg/sg_node.h"
/**
* Define a generic index interface for a scenegraph object.
*/
class SGINDEX : public SGNODE class SGINDEX : public SGNODE
{ {
protected:
bool writeCoordIndex( std::ostream& aFile );
bool writeColorIndex( std::ostream& aFile );
bool writeIndexList( std::ostream& aFile );
public:
// for internal SG consumption only
std::vector< int > index;
void unlinkChildNode( const SGNODE* aCaller ) noexcept override;
void unlinkRefNode( const SGNODE* aCaller ) noexcept override;
public: public:
SGINDEX( SGNODE* aParent ); SGINDEX( SGNODE* aParent );
virtual ~SGINDEX(); virtual ~SGINDEX();
virtual bool SetParent( SGNODE* aParent, bool notify = true ) override; virtual bool SetParent( SGNODE* aParent, bool notify = true ) override;
SGNODE* FindNode(const char *aNodeName, const SGNODE *aCaller) noexcept override; SGNODE* FindNode(const char* aNodeName, const SGNODE* aCaller) noexcept override;
bool AddRefNode( SGNODE* aNode ) noexcept override; bool AddRefNode( SGNODE* aNode ) noexcept override;
bool AddChildNode( SGNODE* aNode ) noexcept override; bool AddChildNode( SGNODE* aNode ) noexcept override;
void unlinkChildNode( const SGNODE* aCaller ) noexcept override;
void unlinkRefNode( const SGNODE* aCaller ) noexcept override;
/** /**
* Function GetIndices * Retrieve the number of indices and a pointer to the list.
* retrieves the number of indices and a pointer to
* the list. Note: the returned pointer may be invalidated
* by future operations on the SGNODE; the caller must make
* immediate use of the data and must not rely on the pointer's
* validity in the future.
* *
* @param nIndices [out] will hold the number of indices in the list * @note The returned pointer may be invalidated by future operations on the SGNODE. The
* @param aIndexList [out] will store a pointer to the data * caller must make immediate use of the data and must not rely on the pointer's
* @return true if there was available data (nIndices > 0) otherwise false * validity in the future.
*
* @param nIndices will hold the number of indices in the list.
* @param aIndexList will store a pointer to the data.
* @return true if there was available data (nIndices > 0) otherwise false.
*/ */
bool GetIndices( size_t& nIndices, int*& aIndexList ); bool GetIndices( size_t& nIndices, int*& aIndexList );
/** /**
* Function SetIndices * Set the number of indices and creates a copy of the given index data.
* sets the number of indices and creates a copy of the given index data.
* *
* @param nIndices [in] the number of indices to be stored * @param nIndices the number of indices to be stored.
* @param aIndexList [in] the index data * @param aIndexList the index data.
*/ */
void SetIndices( size_t nIndices, int* aIndexList ); void SetIndices( size_t nIndices, int* aIndexList );
/** /**
* Function AddIndex * Add a single index to the list.
* adds a single index to the list
* *
* @param aIndex is the index to add * @param aIndex is the index to add.
*/ */
void AddIndex( int aIndex ); void AddIndex( int aIndex );
@ -92,6 +84,15 @@ public:
bool WriteCache( std::ostream& aFile, SGNODE* parentNode ) override; bool WriteCache( std::ostream& aFile, SGNODE* parentNode ) override;
bool ReadCache( std::istream& aFile, SGNODE* parentNode ) override; bool ReadCache( std::istream& aFile, SGNODE* parentNode ) override;
protected:
bool writeCoordIndex( std::ostream& aFile );
bool writeColorIndex( std::ostream& aFile );
bool writeIndexList( std::ostream& aFile );
public:
// for internal SG consumption only
std::vector< int > index;
}; };
#endif // SG_INDEX_H #endif // SG_INDEX_H

View File

@ -2,6 +2,7 @@
* This program source code file is part of KiCad, a free EDA CAD application. * This program source code file is part of KiCad, a free EDA CAD application.
* *
* Copyright (C) 2015 Cirilo Bernardo <cirilo.bernardo@gmail.com> * Copyright (C) 2015 Cirilo Bernardo <cirilo.bernardo@gmail.com>
* Copyright (C) 2020 KiCad Developers, see AUTHORS.txt for contributors.
* *
* This program is free software; you can redistribute it and/or * This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License * modify it under the terms of the GNU General Public License
@ -31,6 +32,7 @@
#include "3d_cache/sg/sg_node.h" #include "3d_cache/sg/sg_node.h"
#include "plugins/3dapi/c3dmodel.h" #include "plugins/3dapi/c3dmodel.h"
static const std::string node_names[S3D::SGTYPE_END + 1] = { static const std::string node_names[S3D::SGTYPE_END + 1] = {
"TXFM", "TXFM",
"APP", "APP",
@ -68,19 +70,15 @@ static void getNodeName( S3D::SGTYPES nodeType, std::string& aName )
std::ostringstream ostr; std::ostringstream ostr;
ostr << node_names[nodeType] << "_" << seqNum; ostr << node_names[nodeType] << "_" << seqNum;
aName = ostr.str(); aName = ostr.str();
return;
} }
SGNODE::SGNODE( SGNODE* aParent ) SGNODE::SGNODE( SGNODE* aParent )
{ {
m_Parent = aParent; m_Parent = aParent;
m_Association = NULL; m_Association = nullptr;
m_written = false; m_written = false;
m_SGtype = S3D::SGTYPE_END; m_SGtype = S3D::SGTYPE_END;
return;
} }
@ -90,7 +88,7 @@ SGNODE::~SGNODE()
m_Parent->unlinkChildNode( this ); m_Parent->unlinkChildNode( this );
if( m_Association ) if( m_Association )
*m_Association = NULL; *m_Association = nullptr;
std::list< SGNODE* >::iterator sBP = m_BackPointers.begin(); std::list< SGNODE* >::iterator sBP = m_BackPointers.begin();
std::list< SGNODE* >::iterator eBP = m_BackPointers.end(); std::list< SGNODE* >::iterator eBP = m_BackPointers.end();
@ -100,8 +98,6 @@ SGNODE::~SGNODE()
(*sBP)->unlinkRefNode( this ); (*sBP)->unlinkRefNode( this );
++sBP; ++sBP;
} }
return;
} }
@ -122,10 +118,10 @@ bool SGNODE::SwapParent( SGNODE* aNewParent )
if( aNewParent == m_Parent ) if( aNewParent == m_Parent )
return true; return true;
if( NULL == aNewParent ) if( nullptr == aNewParent )
return false; return false;
if( NULL == m_Parent ) if( nullptr == m_Parent )
{ {
if( aNewParent->AddChildNode( this ) ) if( aNewParent->AddChildNode( this ) )
return true; return true;
@ -138,7 +134,7 @@ bool SGNODE::SwapParent( SGNODE* aNewParent )
SGNODE* oldParent = m_Parent; SGNODE* oldParent = m_Parent;
m_Parent->unlinkChildNode( this ); m_Parent->unlinkChildNode( this );
m_Parent = NULL; m_Parent = nullptr;
aNewParent->unlinkRefNode( this ); aNewParent->unlinkRefNode( this );
aNewParent->AddChildNode( this ); aNewParent->AddChildNode( this );
oldParent->AddRefNode( this ); oldParent->AddRefNode( this );
@ -156,18 +152,16 @@ const char* SGNODE::GetName( void )
} }
void SGNODE::SetName( const char *aName ) void SGNODE::SetName( const char* aName )
{ {
if( NULL == aName || 0 == aName[0] ) if( nullptr == aName || 0 == aName[0] )
getNodeName( m_SGtype, m_Name ); getNodeName( m_SGtype, m_Name );
else else
m_Name = aName; m_Name = aName;
return;
} }
const char * SGNODE::GetNodeTypeName( S3D::SGTYPES aNodeType ) const noexcept const char* SGNODE::GetNodeTypeName( S3D::SGTYPES aNodeType ) const noexcept
{ {
return node_names[aNodeType].c_str(); return node_names[aNodeType].c_str();
} }
@ -175,7 +169,7 @@ const char * SGNODE::GetNodeTypeName( S3D::SGTYPES aNodeType ) const noexcept
void SGNODE::addNodeRef( SGNODE* aNode ) void SGNODE::addNodeRef( SGNODE* aNode )
{ {
if( NULL == aNode ) if( nullptr == aNode )
return; return;
std::list< SGNODE* >::iterator np = std::list< SGNODE* >::iterator np =
@ -185,13 +179,12 @@ void SGNODE::addNodeRef( SGNODE* aNode )
return; return;
m_BackPointers.push_back( aNode ); m_BackPointers.push_back( aNode );
return;
} }
void SGNODE::delNodeRef( const SGNODE* aNode ) void SGNODE::delNodeRef( const SGNODE* aNode )
{ {
if( NULL == aNode ) if( nullptr == aNode )
return; return;
std::list< SGNODE* >::iterator np = std::list< SGNODE* >::iterator np =
@ -203,62 +196,28 @@ void SGNODE::delNodeRef( const SGNODE* aNode )
return; return;
} }
#ifdef DEBUG wxLogTrace( MASK_3D_SG, "%s:%s:%d * [BUG] delNodeRef() did not find its target, "
std::ostringstream ostr; "this node type %d, referenced node type %d", __FILE__, __FUNCTION__, __LINE__,
ostr << __FILE__ << ": " << __FUNCTION__ << ": " << __LINE__ << "\n"; m_SGtype, aNode->GetNodeType() );
ostr << " * [BUG] delNodeRef() did not find its target\n";
ostr << " * This Node Type: " << m_SGtype << ", Referenced node type: ";
ostr << aNode->GetNodeType() << "\n";
wxLogTrace( MASK_3D_SG, "%s\n", ostr.str().c_str() );
#endif
return;
} }
void SGNODE::AssociateWrapper( SGNODE** aWrapperRef ) noexcept void SGNODE::AssociateWrapper( SGNODE** aWrapperRef ) noexcept
{ {
if( NULL == aWrapperRef ) wxCHECK( aWrapperRef && *aWrapperRef == this, /* void */ );
{
#ifdef DEBUG
std::ostringstream ostr;
ostr << __FILE__ << ": " << __FUNCTION__ << ": " << __LINE__ << "\n";
ostr << " * [BUG] NULL handle";
wxLogTrace( MASK_3D_SG, "%s\n", ostr.str().c_str() );
#endif
return;
}
if( *aWrapperRef != this )
{
#ifdef DEBUG
std::ostringstream ostr;
ostr << __FILE__ << ": " << __FUNCTION__ << ": " << __LINE__ << "\n";
ostr << " * [BUG] handle value does not match this object's pointer";
wxLogTrace( MASK_3D_SG, "%s\n", ostr.str().c_str() );
#endif
return;
}
// if there is an existing association then break it and emit a warning // if there is an existing association then break it and emit a warning
// just in case the behavior is undesired // just in case the behavior is undesired
if( m_Association ) if( m_Association )
{ {
*m_Association = NULL; *m_Association = nullptr;
#ifdef DEBUG wxLogTrace( MASK_3D_SG,
std::ostringstream ostr; "%s:%s:%d * [WARNING] association being broken with previous wrapper",
ostr << __FILE__ << ": " << __FUNCTION__ << ": " << __LINE__ << "\n"; __FILE__, __FUNCTION__, __LINE__ );
ostr << " * [WARNING] association being broken with previous wrapper";
wxLogTrace( MASK_3D_SG, "%s\n", ostr.str().c_str() );
#endif
} }
m_Association = aWrapperRef; m_Association = aWrapperRef;
return;
} }
void SGNODE::DisassociateWrapper( SGNODE** aWrapperRef ) noexcept void SGNODE::DisassociateWrapper( SGNODE** aWrapperRef ) noexcept
@ -266,38 +225,11 @@ void SGNODE::DisassociateWrapper( SGNODE** aWrapperRef ) noexcept
if( !m_Association ) if( !m_Association )
return; return;
if( !aWrapperRef ) wxCHECK( aWrapperRef, /* void */ );
{
#ifdef DEBUG
std::ostringstream ostr;
ostr << __FILE__ << ": " << __FUNCTION__ << ": " << __LINE__ << "\n";
ostr << " * [BUG] invalid handle value aWrapperRef";
wxLogTrace( MASK_3D_SG, "%s\n", ostr.str().c_str() );
#endif
return; wxCHECK( *aWrapperRef == *m_Association && aWrapperRef == m_Association, /* void */ );
}
if( *aWrapperRef != *m_Association || aWrapperRef != m_Association ) m_Association = nullptr;
{
#ifdef DEBUG
std::ostringstream ostr;
ostr << __FILE__ << ": " << __FUNCTION__ << ": " << __LINE__ << "\n";
ostr << " * [BUG] *aWrapperRef (" << *aWrapperRef;
ostr << ") does not match *m_Association (" << *m_Association << ") in type ";
ostr << node_names[ m_SGtype] << "\n";
ostr << " * [INFO] OR aWrapperRef(" << aWrapperRef << ") != m_Association(";
ostr << m_Association << ")\n";
ostr << " * [INFO] node name: " << GetName();
wxLogTrace( MASK_3D_SG, "%s\n", ostr.str().c_str() );
#endif
return;
}
m_Association = NULL;
return;
} }
@ -305,8 +237,6 @@ void SGNODE::ResetNodeIndex( void ) noexcept
{ {
for( int i = 0; i < (int)S3D::SGTYPE_END; ++i ) for( int i = 0; i < (int)S3D::SGTYPE_END; ++i )
node_counts[i] = 1; node_counts[i] = 1;
return;
} }
@ -314,28 +244,7 @@ bool S3D::GetMatIndex( MATLIST& aList, SGNODE* aNode, int& aIndex )
{ {
aIndex = 0; aIndex = 0;
if( NULL == aNode || S3D::SGTYPE_APPEARANCE != aNode->GetNodeType() ) wxCHECK( aNode && S3D::SGTYPE_APPEARANCE == aNode->GetNodeType(), false );
{
#ifdef DEBUG
std::ostringstream ostr;
ostr << __FILE__ << ": " << __FUNCTION__ << ": " << __LINE__;
wxLogTrace( MASK_3D_SG, "%s\n", ostr.str().c_str() );
ostr.str( "" );
if( NULL == aNode )
{
wxLogTrace( MASK_3D_SG, " * [BUG] aNode is NULL\n" );
}
else
{
ostr << " * [BUG] invalid node type (" << aNode->GetNodeType();
ostr << "), expected " << S3D::SGTYPE_APPEARANCE;
wxLogTrace( MASK_3D_SG, "%s\n", ostr.str().c_str() );
}
#endif
return false;
}
SGAPPEARANCE* node = (SGAPPEARANCE*)aNode; SGAPPEARANCE* node = (SGAPPEARANCE*)aNode;
@ -374,66 +283,62 @@ void S3D::INIT_S3DMODEL( S3DMODEL& aModel ) noexcept
} }
void S3D::FREE_SMESH( SMESH& aMesh) noexcept void S3D::FREE_SMESH( SMESH& aMesh ) noexcept
{ {
if( NULL != aMesh.m_Positions ) if( nullptr != aMesh.m_Positions )
{ {
delete [] aMesh.m_Positions; delete [] aMesh.m_Positions;
aMesh.m_Positions = NULL; aMesh.m_Positions = nullptr;
} }
if( NULL != aMesh.m_Normals ) if( nullptr != aMesh.m_Normals )
{ {
delete [] aMesh.m_Normals; delete [] aMesh.m_Normals;
aMesh.m_Normals = NULL; aMesh.m_Normals = nullptr;
} }
if( NULL != aMesh.m_Texcoords ) if( nullptr != aMesh.m_Texcoords )
{ {
delete [] aMesh.m_Texcoords; delete [] aMesh.m_Texcoords;
aMesh.m_Texcoords = NULL; aMesh.m_Texcoords = nullptr;
} }
if( NULL != aMesh.m_Color ) if( nullptr != aMesh.m_Color )
{ {
delete [] aMesh.m_Color; delete [] aMesh.m_Color;
aMesh.m_Color = NULL; aMesh.m_Color = nullptr;
} }
if( NULL != aMesh.m_FaceIdx ) if( nullptr != aMesh.m_FaceIdx )
{ {
delete [] aMesh.m_FaceIdx; delete [] aMesh.m_FaceIdx;
aMesh.m_FaceIdx = NULL; aMesh.m_FaceIdx = nullptr;
} }
aMesh.m_VertexSize = 0; aMesh.m_VertexSize = 0;
aMesh.m_FaceIdxSize = 0; aMesh.m_FaceIdxSize = 0;
aMesh.m_MaterialIdx = 0; aMesh.m_MaterialIdx = 0;
return;
} }
void S3D::FREE_S3DMODEL( S3DMODEL& aModel ) void S3D::FREE_S3DMODEL( S3DMODEL& aModel )
{ {
if( NULL != aModel.m_Materials ) if( nullptr != aModel.m_Materials )
{ {
delete [] aModel.m_Materials; delete [] aModel.m_Materials;
aModel.m_Materials = NULL; aModel.m_Materials = nullptr;
} }
aModel.m_MaterialsSize = 0; aModel.m_MaterialsSize = 0;
if( NULL != aModel.m_Meshes ) if( nullptr != aModel.m_Meshes )
{ {
for( unsigned int i = 0; i < aModel.m_MeshesSize; ++i ) for( unsigned int i = 0; i < aModel.m_MeshesSize; ++i )
FREE_SMESH( aModel.m_Meshes[i] ); FREE_SMESH( aModel.m_Meshes[i] );
delete [] aModel.m_Meshes; delete [] aModel.m_Meshes;
aModel.m_Meshes = NULL; aModel.m_Meshes = nullptr;
} }
aModel.m_MeshesSize = 0; aModel.m_MeshesSize = 0;
return;
} }

View File

@ -2,6 +2,7 @@
* This program source code file is part of KiCad, a free EDA CAD application. * This program source code file is part of KiCad, a free EDA CAD application.
* *
* Copyright (C) 2015-2017 Cirilo Bernardo <cirilo.bernardo@gmail.com> * Copyright (C) 2015-2017 Cirilo Bernardo <cirilo.bernardo@gmail.com>
* Copyright (C) 2020 KiCad Developers, see AUTHORS.txt for contributors.
* *
* This program is free software; you can redistribute it and/or * This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License * modify it under the terms of the GNU General Public License
@ -23,7 +24,6 @@
/** /**
* @file sg_node.h * @file sg_node.h
* defines the base class of the intermediate scene graph NODE
*/ */
@ -47,8 +47,7 @@ class SGAPPEARANCE;
namespace S3D namespace S3D
{ {
/** /**
* Function GetNodeTypeName * Return the name of the given type of node
* returns the name of the given type of node
*/ */
char const* GetNodeTypeName( S3D::SGTYPES aType ) noexcept; char const* GetNodeTypeName( S3D::SGTYPES aType ) noexcept;
@ -70,104 +69,41 @@ namespace S3D
/** /**
* SGNODE * The base class of all Scene Graph nodes.
* represents the base class of all Scene Graph nodes
*/ */
class SGNODE class SGNODE
{ {
private:
SGNODE** m_Association; // handle to the instance held by a wrapper
protected:
std::list< SGNODE* > m_BackPointers; // nodes which hold a reference to this
SGNODE* m_Parent; // pointer to parent node; may be NULL for top level transform
S3D::SGTYPES m_SGtype; // type of SG node
std::string m_Name; // name to use for referencing the entity by name
bool m_written; // set true when the object has been written after a ReNameNodes()
public:
/**
* Function unlinkChild
* removes references to an owned child; it is invoked by the child upon destruction
* to ensure that the parent has no invalid references.
*
* @param aNode is the child which is being deleted
*/
virtual void unlinkChildNode( const SGNODE* aNode ) = 0;
/**
* Function unlinkRef
* removes pointers to a referenced node; it is invoked by the referenced node
* upon destruction to ensure that the referring node has no invalid references.
*
* @param aNode is the node which is being deleted
*/
virtual void unlinkRefNode( const SGNODE* aNode ) = 0;
/**
* Function addNodeRef
* adds a pointer to a node which references, but does not own, this node.
* Such back-pointers are required to ensure that invalidated references
* are removed when a node is deleted
*
* @param aNode is the node holding a reference to this object
*/
void addNodeRef( SGNODE* aNode );
/**
* Function delNodeRef
* removes a pointer to a node which references, but does not own, this node.
*
* @param aNode is the node holding a reference to this object
*/
void delNodeRef( const SGNODE* aNode );
/**
* Function IsWritten
* returns true if the object had already been written to a
* cache file or VRML file; for internal use only.
*/
bool isWritten( void ) noexcept
{
return m_written;
}
public: public:
SGNODE( SGNODE* aParent ); SGNODE( SGNODE* aParent );
virtual ~SGNODE(); virtual ~SGNODE();
/** /**
* Function GetNodeType * Return the type of this node instance.
* returns the type of this node instance
*/ */
S3D::SGTYPES GetNodeType( void ) const noexcept; S3D::SGTYPES GetNodeType( void ) const noexcept;
/** /**
* Function GetParent * Returns a pointer to the parent SGNODE of this object or NULL if the object has
* returns a pointer to the parent SGNODE of this object * no parent (ie. top level transform).
* or NULL if the object has no parent (ie. top level transform)
*/ */
SGNODE* GetParent( void ) const noexcept; SGNODE* GetParent( void ) const noexcept;
/** /**
* Function SetParent * Set the parent #SGNODE of this object.
* sets the parent SGNODE of this object.
* *
* @param aParent [in] is the desired parent node * @param aParent [in] is the desired parent node
* @return true if the operation succeeds; false if * @return true if the operation succeeds; false if the given node is not allowed to
* the given node is not allowed to be a parent to * be a parent to the derived object.
* the derived object.
*/ */
virtual bool SetParent( SGNODE* aParent, bool notify = true ) = 0; virtual bool SetParent( SGNODE* aParent, bool notify = true ) = 0;
/** /**
* Function SwapParent * Swap the ownership with the given parent.
* swaps the ownership with the given parent. This operation
* may be required when reordering nodes for optimization.
* *
* @param aNewParent [in] will become the new parent to the * This operation may be required when reordering nodes for optimization.
* object; it must be the same type as the parent of this *
* instance. * @param aNewParent will become the new parent to the object; it must be the same type
* as the parent of this instance.
*/ */
bool SwapParent( SGNODE* aNewParent ); bool SwapParent( SGNODE* aNewParent );
@ -177,13 +113,14 @@ public:
const char * GetNodeTypeName( S3D::SGTYPES aNodeType ) const noexcept; const char * GetNodeTypeName( S3D::SGTYPES aNodeType ) const noexcept;
/** /**
* Function FindNode searches the tree of linked nodes and returns a * Search the tree of linked nodes and return a reference to the first node found with
* reference to the first node found with the given name. The reference * the given name.
* is then typically added to another node via AddRefNode().
* *
* @param aNodeName is the name of the node to search for * The reference is then typically added to another node via AddRefNode().
* @param aCaller is a pointer to the node invoking this function *
* @return is a valid node pointer on success, otherwise NULL * @param aNodeName is the name of the node to search for.
* @param aCaller is a pointer to the node invoking this function.
* @return is a valid node pointer on success, otherwise NULL.
*/ */
virtual SGNODE* FindNode( const char *aNodeName, const SGNODE *aCaller ) = 0; virtual SGNODE* FindNode( const char *aNodeName, const SGNODE *aCaller ) = 0;
@ -192,59 +129,108 @@ public:
virtual bool AddChildNode( SGNODE* aNode ) = 0; virtual bool AddChildNode( SGNODE* aNode ) = 0;
/** /**
* Function AssociateWrapper * Associate this object with a handle to itself.
* associates this object with a handle to itself; this handle *
* is typically held by an IFSG* wrapper and the pointer which * The handle is typically held by an IFSG* wrapper and the pointer which it refers to
* it refers to is set to NULL upon destruction of this object. * is set to NULL upon destruction of this object. This mechanism provides a scheme
* This mechanism provides a scheme by which a wrapper can be * by which a wrapper can be notified of the destruction of the object which it wraps.
* notified of the destruction of the object which it wraps.
*/ */
void AssociateWrapper( SGNODE** aWrapperRef ) noexcept; void AssociateWrapper( SGNODE** aWrapperRef ) noexcept;
/** /**
* Function DisassociateWrapper * Remove the association between an IFSG* wrapper object and this object.
* removes the association between an IFSG* wrapper
* object and this object.
*/ */
void DisassociateWrapper( SGNODE** aWrapperRef ) noexcept; void DisassociateWrapper( SGNODE** aWrapperRef ) noexcept;
/** /**
* Function ResetNodeIndex * Reset the global SG* node indices in preparation for write operations.
* resets the global SG* node indices in preparation for
* Write() operations
*/ */
void ResetNodeIndex( void ) noexcept; void ResetNodeIndex( void ) noexcept;
/** /**
* Function ReNameNodes * Rename a node and all its child nodes in preparation for write operations.
* renames a node and all its child nodes in preparation for
* Write() operations
*/ */
virtual void ReNameNodes( void ) = 0; virtual void ReNameNodes( void ) = 0;
/** /**
* Function WriteVRML * Writes this node's data to a VRML file.
* writes this node's data to a VRML file; this includes *
* all data of child and referenced nodes. * This includes all data of child and referenced nodes.
*/ */
virtual bool WriteVRML( std::ostream& aFile, bool aReuseFlag ) = 0; virtual bool WriteVRML( std::ostream& aFile, bool aReuseFlag ) = 0;
/** /**
* Function WriteCache * Write this node's data to a binary cache file.
* write's this node's data to a binary cache file; the data *
* includes all data of children and references to children. * The data includes all data of children and references to children. If this function
* If this function is invoked by the user, parentNode must be * is invoked by the user, parentNode must be set to NULL in order to ensure coherent data.
* set to NULL in order to ensure coherent data.
*/ */
virtual bool WriteCache( std::ostream& aFile, SGNODE* parentNode ) = 0; virtual bool WriteCache( std::ostream& aFile, SGNODE* parentNode ) = 0;
/** /**
* Function ReadCache * Reads binary format data from a cache file.
* Reads binary format data from a cache file. To read a cache file, *
* open the file for reading and invoke this function from a new * To read a cache file, open the file for reading and invoke this function from a new
* SCENEGRAPH node. * #SCENEGRAPH node.
*/ */
virtual bool ReadCache( std::istream& aFile, SGNODE* parentNode ) = 0; virtual bool ReadCache( std::istream& aFile, SGNODE* parentNode ) = 0;
/**
* Remove references to an owned child.
*
* This is invoked by the child upon destruction to ensure that the parent has no
* invalid references.
*
* @param aNode is the child which is being deleted.
*/
virtual void unlinkChildNode( const SGNODE* aNode ) = 0;
/**
* Remove pointers to a referenced node.
*
* This is invoked by the referenced node upon destruction to ensure that the referring
* node has no invalid references.
*
* @param aNode is the node which is being deleted.
*/
virtual void unlinkRefNode( const SGNODE* aNode ) = 0;
/**
* Add a pointer to a node which references this node, but does not own.
*
* Such back-pointers are required to ensure that invalidated references are removed
* when a node is deleted.
*
* @param aNode is the node holding a reference to this object.
*/
void addNodeRef( SGNODE* aNode );
/**
* Remove a pointer to a node which references this node, but does not own.
*
* @param aNode is the node holding a reference to this object.
*/
void delNodeRef( const SGNODE* aNode );
/**
* Return true if the object had already been written to a cache file or VRML file
*
* For internal use only.
*/
bool isWritten( void ) noexcept
{
return m_written;
}
protected:
std::list< SGNODE* > m_BackPointers; ///< nodes which hold a reference to this.
SGNODE* m_Parent; ///< Pointer to parent node; may be NULL for top level transform.
S3D::SGTYPES m_SGtype; ///< Type of Scene Graph node.
std::string m_Name; ///< name to use for referencing the entity by name.
bool m_written; ///< Set to true when the object has been written after a ReNameNodes().
private:
SGNODE** m_Association; ///< Handle to the instance held by a wrapper.
}; };
#endif // SG_NODE_H #endif // SG_NODE_H

View File

@ -2,6 +2,7 @@
* This program source code file is part of KiCad, a free EDA CAD application. * This program source code file is part of KiCad, a free EDA CAD application.
* *
* Copyright (C) 2015-2017 Cirilo Bernardo <cirilo.bernardo@gmail.com> * Copyright (C) 2015-2017 Cirilo Bernardo <cirilo.bernardo@gmail.com>
* Copyright (C) 2020 KiCad Developers, see AUTHORS.txt for contributors.
* *
* This program is free software; you can redistribute it and/or * This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License * modify it under the terms of the GNU General Public License
@ -33,37 +34,29 @@ SGNORMALS::SGNORMALS( SGNODE* aParent ) : SGNODE( aParent )
{ {
m_SGtype = S3D::SGTYPE_NORMALS; m_SGtype = S3D::SGTYPE_NORMALS;
if( NULL != aParent && S3D::SGTYPE_FACESET != aParent->GetNodeType() ) if( nullptr != aParent && S3D::SGTYPE_FACESET != aParent->GetNodeType() )
{ {
m_Parent = NULL; m_Parent = nullptr;
#ifdef DEBUG wxLogTrace( MASK_3D_SG, "%s:%s:%d * [BUG] inappropriate parent to SGNORMALS (type %d)",
std::ostringstream ostr; __FILE__, __FUNCTION__, __LINE__, aParent->GetNodeType() );
ostr << __FILE__ << ": " << __FUNCTION__ << ": " << __LINE__ << "\n";
ostr << " * [BUG] inappropriate parent to SGNORMALS (type ";
ostr << aParent->GetNodeType() << ")";
wxLogTrace( MASK_3D_SG, "%s\n", ostr.str().c_str() );
#endif
} }
else if( NULL != aParent && S3D::SGTYPE_FACESET == aParent->GetNodeType() ) else if( nullptr != aParent && S3D::SGTYPE_FACESET == aParent->GetNodeType() )
{ {
m_Parent->AddChildNode( this ); m_Parent->AddChildNode( this );
} }
return;
} }
SGNORMALS::~SGNORMALS() SGNORMALS::~SGNORMALS()
{ {
norms.clear(); norms.clear();
return;
} }
bool SGNORMALS::SetParent( SGNODE* aParent, bool notify ) bool SGNORMALS::SetParent( SGNODE* aParent, bool notify )
{ {
if( NULL != m_Parent ) if( nullptr != m_Parent )
{ {
if( aParent == m_Parent ) if( aParent == m_Parent )
return true; return true;
@ -72,14 +65,14 @@ bool SGNORMALS::SetParent( SGNODE* aParent, bool notify )
if( notify ) if( notify )
m_Parent->unlinkChildNode( this ); m_Parent->unlinkChildNode( this );
m_Parent = NULL; m_Parent = nullptr;
if( NULL == aParent ) if( nullptr == aParent )
return true; return true;
} }
// only a SGFACESET may be parent to a SGNORMALS // only a SGFACESET may be parent to a SGNORMALS
if( NULL != aParent && S3D::SGTYPE_FACESET != aParent->GetNodeType() ) if( nullptr != aParent && S3D::SGTYPE_FACESET != aParent->GetNodeType() )
return false; return false;
m_Parent = aParent; m_Parent = aParent;
@ -91,52 +84,33 @@ bool SGNORMALS::SetParent( SGNODE* aParent, bool notify )
} }
SGNODE* SGNORMALS::FindNode(const char *aNodeName, const SGNODE *aCaller) noexcept SGNODE* SGNORMALS::FindNode( const char* aNodeName, const SGNODE* aCaller ) noexcept
{ {
if( NULL == aNodeName || 0 == aNodeName[0] ) if( nullptr == aNodeName || 0 == aNodeName[0] )
return NULL; return nullptr;
if( !m_Name.compare( aNodeName ) ) if( !m_Name.compare( aNodeName ) )
return this; return this;
return NULL; return nullptr;
} }
void SGNORMALS::unlinkChildNode( const SGNODE* aCaller ) noexcept void SGNORMALS::unlinkChildNode( const SGNODE* aCaller ) noexcept
{ {
#ifdef DEBUG wxCHECK( false, /* void */ );
std::ostringstream ostr;
ostr << __FILE__ << ": " << __FUNCTION__ << ": " << __LINE__ << "\n";
ostr << " * [BUG] unexpected code branch; node should have no children or refs";
wxLogTrace( MASK_3D_SG, "%s\n", ostr.str().c_str() );
#endif
return;
} }
void SGNORMALS::unlinkRefNode( const SGNODE* aCaller ) noexcept void SGNORMALS::unlinkRefNode( const SGNODE* aCaller ) noexcept
{ {
#ifdef DEBUG wxCHECK( false, /* void */ );
std::ostringstream ostr;
ostr << __FILE__ << ": " << __FUNCTION__ << ": " << __LINE__ << "\n";
ostr << " * [BUG] unexpected code branch; node should have no children or refs";
wxLogTrace( MASK_3D_SG, "%s\n", ostr.str().c_str() );
#endif
return;
} }
bool SGNORMALS::AddRefNode( SGNODE* aNode ) noexcept bool SGNORMALS::AddRefNode( SGNODE* aNode ) noexcept
{ {
#ifdef DEBUG wxCHECK( false, false );
std::ostringstream ostr;
ostr << __FILE__ << ": " << __FUNCTION__ << ": " << __LINE__ << "\n";
ostr << " * [BUG] this node does not accept children or refs";
wxLogTrace( MASK_3D_SG, "%s\n", ostr.str().c_str() );
#endif
return false; return false;
} }
@ -144,12 +118,7 @@ bool SGNORMALS::AddRefNode( SGNODE* aNode ) noexcept
bool SGNORMALS::AddChildNode( SGNODE* aNode ) noexcept bool SGNORMALS::AddChildNode( SGNODE* aNode ) noexcept
{ {
#ifdef DEBUG wxCHECK( false, false );
std::ostringstream ostr;
ostr << __FILE__ << ": " << __FUNCTION__ << ": " << __LINE__ << "\n";
ostr << " * [BUG] this node does not accept children or refs";
wxLogTrace( MASK_3D_SG, "%s\n", ostr.str().c_str() );
#endif
return false; return false;
} }
@ -160,7 +129,7 @@ bool SGNORMALS::GetNormalList( size_t& aListSize, SGVECTOR*& aNormalList )
if( norms.empty() ) if( norms.empty() )
{ {
aListSize = 0; aListSize = 0;
aNormalList = NULL; aNormalList = nullptr;
return false; return false;
} }
@ -174,27 +143,23 @@ void SGNORMALS::SetNormalList( size_t aListSize, const SGVECTOR* aNormalList )
{ {
norms.clear(); norms.clear();
if( 0 == aListSize || NULL == aNormalList ) if( 0 == aListSize || nullptr == aNormalList )
return; return;
for( int i = 0; i < (int)aListSize; ++i ) for( int i = 0; i < (int)aListSize; ++i )
norms.push_back( aNormalList[i] ); norms.push_back( aNormalList[i] );
return;
} }
void SGNORMALS::AddNormal( double aXValue, double aYValue, double aZValue ) void SGNORMALS::AddNormal( double aXValue, double aYValue, double aZValue )
{ {
norms.emplace_back( aXValue, aYValue, aZValue ); norms.emplace_back( aXValue, aYValue, aZValue );
return;
} }
void SGNORMALS::AddNormal( const SGVECTOR& aNormal ) void SGNORMALS::AddNormal( const SGVECTOR& aNormal )
{ {
norms.push_back( aNormal ); norms.push_back( aNormal );
return;
} }
@ -266,26 +231,16 @@ bool SGNORMALS::WriteVRML( std::ostream& aFile, bool aReuseFlag )
bool SGNORMALS::WriteCache( std::ostream& aFile, SGNODE* parentNode ) bool SGNORMALS::WriteCache( std::ostream& aFile, SGNODE* parentNode )
{ {
if( NULL == parentNode ) if( nullptr == parentNode )
{ {
if( NULL == m_Parent ) wxCHECK( m_Parent, false );
{
#ifdef DEBUG
std::ostringstream ostr;
ostr << __FILE__ << ": " << __FUNCTION__ << ": " << __LINE__ << "\n";
ostr << " * [BUG] corrupt data; m_aParent is NULL";
wxLogTrace( MASK_3D_SG, "%s\n", ostr.str().c_str() );
#endif
return false;
}
SGNODE* np = m_Parent; SGNODE* np = m_Parent;
while( NULL != np->GetParent() ) while( nullptr != np->GetParent() )
np = np->GetParent(); np = np->GetParent();
if( np->WriteCache( aFile, NULL ) ) if( np->WriteCache( aFile, nullptr ) )
{ {
m_written = true; m_written = true;
return true; return true;
@ -294,26 +249,12 @@ bool SGNORMALS::WriteCache( std::ostream& aFile, SGNODE* parentNode )
return false; return false;
} }
if( parentNode != m_Parent ) wxCHECK( parentNode == m_Parent, false );
{
#ifdef DEBUG
std::ostringstream ostr;
ostr << __FILE__ << ": " << __FUNCTION__ << ": " << __LINE__ << "\n";
ostr << " * [BUG] corrupt data; parentNode != m_aParent";
wxLogTrace( MASK_3D_SG, "%s\n", ostr.str().c_str() );
#endif
return false;
}
if( !aFile.good() ) if( !aFile.good() )
{ {
#ifdef DEBUG wxLogTrace( MASK_3D_SG, "%s:%s:%d * [INFO] bad stream",
std::ostringstream ostr; __FILE__, __FUNCTION__, __LINE__ );
ostr << __FILE__ << ": " << __FUNCTION__ << ": " << __LINE__ << "\n";
ostr << " * [INFO] bad stream";
wxLogTrace( MASK_3D_SG, "%s\n", ostr.str().c_str() );
#endif
return false; return false;
} }
@ -335,20 +276,10 @@ bool SGNORMALS::WriteCache( std::ostream& aFile, SGNODE* parentNode )
bool SGNORMALS::ReadCache( std::istream& aFile, SGNODE* parentNode ) bool SGNORMALS::ReadCache( std::istream& aFile, SGNODE* parentNode )
{ {
if( !norms.empty() ) wxCHECK( norms.empty(), false );
{
#ifdef DEBUG
std::ostringstream ostr;
ostr << __FILE__ << ": " << __FUNCTION__ << ": " << __LINE__ << "\n";
ostr << " * [BUG] non-empty node";
wxLogTrace( MASK_3D_SG, "%s\n", ostr.str().c_str() );
#endif
return false;
}
size_t npts; size_t npts;
aFile.read( (char*)&npts, sizeof(size_t) ); aFile.read( (char*) &npts, sizeof( size_t ) );
SGVECTOR tmp; SGVECTOR tmp;
if( aFile.fail() ) if( aFile.fail() )

View File

@ -2,6 +2,7 @@
* This program source code file is part of KiCad, a free EDA CAD application. * This program source code file is part of KiCad, a free EDA CAD application.
* *
* Copyright (C) 2015-2017 Cirilo Bernardo <cirilo.bernardo@gmail.com> * Copyright (C) 2015-2017 Cirilo Bernardo <cirilo.bernardo@gmail.com>
* Copyright (C) 2020 KiCad Developers, see AUTHORS.txt for contributors.
* *
* This program is free software; you can redistribute it and/or * This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License * modify it under the terms of the GNU General Public License
@ -23,7 +24,6 @@
/** /**
* @file sg_normals.h * @file sg_normals.h
* defines a set of vertex normals for a scene graph object
*/ */
#ifndef SG_NORMALS_H #ifndef SG_NORMALS_H
@ -32,21 +32,18 @@
#include <vector> #include <vector>
#include "3d_cache/sg/sg_node.h" #include "3d_cache/sg/sg_node.h"
/**
* Define a set of vertex normals for a scene graph object
*/
class SGNORMALS : public SGNODE class SGNORMALS : public SGNODE
{ {
public:
std::vector< SGVECTOR > norms;
void unlinkChildNode( const SGNODE* aNode ) noexcept override;
void unlinkRefNode( const SGNODE* aNode ) noexcept override;
public: public:
SGNORMALS( SGNODE* aParent ); SGNORMALS( SGNODE* aParent );
virtual ~SGNORMALS(); virtual ~SGNORMALS();
virtual bool SetParent( SGNODE* aParent, bool notify = true ) override; virtual bool SetParent( SGNODE* aParent, bool notify = true ) override;
SGNODE* FindNode(const char *aNodeName, const SGNODE *aCaller) noexcept override; SGNODE* FindNode( const char* aNodeName, const SGNODE* aCaller ) noexcept override;
bool AddRefNode( SGNODE* aNode ) noexcept override; bool AddRefNode( SGNODE* aNode ) noexcept override;
bool AddChildNode( SGNODE* aNode ) noexcept override; bool AddChildNode( SGNODE* aNode ) noexcept override;
@ -60,6 +57,11 @@ public:
bool WriteCache( std::ostream& aFile, SGNODE* parentNode ) override; bool WriteCache( std::ostream& aFile, SGNODE* parentNode ) override;
bool ReadCache( std::istream& aFile, SGNODE* parentNode ) override; bool ReadCache( std::istream& aFile, SGNODE* parentNode ) override;
void unlinkChildNode( const SGNODE* aNode ) noexcept override;
void unlinkRefNode( const SGNODE* aNode ) noexcept override;
std::vector< SGVECTOR > norms;
}; };
#endif // SG_NORMALS_H #endif // SG_NORMALS_H

View File

@ -2,6 +2,7 @@
* This program source code file is part of KiCad, a free EDA CAD application. * This program source code file is part of KiCad, a free EDA CAD application.
* *
* Copyright (C) 2015-2017 Cirilo Bernardo <cirilo.bernardo@gmail.com> * Copyright (C) 2015-2017 Cirilo Bernardo <cirilo.bernardo@gmail.com>
* Copyright (C) 2020 KiCad Developers, see AUTHORS.txt for contributors.
* *
* This program is free software; you can redistribute it and/or * This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License * modify it under the terms of the GNU General Public License
@ -39,29 +40,22 @@
SGSHAPE::SGSHAPE( SGNODE* aParent ) : SGNODE( aParent ) SGSHAPE::SGSHAPE( SGNODE* aParent ) : SGNODE( aParent )
{ {
m_SGtype = S3D::SGTYPE_SHAPE; m_SGtype = S3D::SGTYPE_SHAPE;
m_Appearance = NULL; m_Appearance = nullptr;
m_RAppearance = NULL; m_RAppearance = nullptr;
m_FaceSet = NULL; m_FaceSet = nullptr;
m_RFaceSet = NULL; m_RFaceSet = nullptr;
if( NULL != aParent && S3D::SGTYPE_TRANSFORM != aParent->GetNodeType() ) if( nullptr != aParent && S3D::SGTYPE_TRANSFORM != aParent->GetNodeType() )
{ {
m_Parent = NULL; m_Parent = nullptr;
#ifdef DEBUG wxLogTrace( MASK_3D_SG, "%s:%s:%d * [BUG] inappropriate parent to SGSHAPE (type %d)",
std::ostringstream ostr; __FILE__, __FUNCTION__, __LINE__, aParent->GetNodeType() );
ostr << __FILE__ << ": " << __FUNCTION__ << ": " << __LINE__ << "\n";
ostr << " * [BUG] inappropriate parent to SGSHAPE (type ";
ostr << aParent->GetNodeType() << ")";
wxLogTrace( MASK_3D_SG, "%s\n", ostr.str().c_str() );
#endif
} }
else if( NULL != aParent && S3D::SGTYPE_TRANSFORM == aParent->GetNodeType() ) else if( nullptr != aParent && S3D::SGTYPE_TRANSFORM == aParent->GetNodeType() )
{ {
m_Parent->AddChildNode( this ); m_Parent->AddChildNode( this );
} }
return;
} }
@ -71,37 +65,35 @@ SGSHAPE::~SGSHAPE()
if( m_RAppearance ) if( m_RAppearance )
{ {
m_RAppearance->delNodeRef( this ); m_RAppearance->delNodeRef( this );
m_RAppearance = NULL; m_RAppearance = nullptr;
} }
if( m_RFaceSet ) if( m_RFaceSet )
{ {
m_RFaceSet->delNodeRef( this ); m_RFaceSet->delNodeRef( this );
m_RFaceSet = NULL; m_RFaceSet = nullptr;
} }
// delete objects // delete objects
if( m_Appearance ) if( m_Appearance )
{ {
m_Appearance->SetParent( NULL, false ); m_Appearance->SetParent( nullptr, false );
delete m_Appearance; delete m_Appearance;
m_Appearance = NULL; m_Appearance = nullptr;
} }
if( m_FaceSet ) if( m_FaceSet )
{ {
m_FaceSet->SetParent( NULL, false ); m_FaceSet->SetParent( nullptr, false );
delete m_FaceSet; delete m_FaceSet;
m_FaceSet = NULL; m_FaceSet = nullptr;
} }
return;
} }
bool SGSHAPE::SetParent( SGNODE* aParent, bool notify ) bool SGSHAPE::SetParent( SGNODE* aParent, bool notify )
{ {
if( NULL != m_Parent ) if( nullptr != m_Parent )
{ {
if( aParent == m_Parent ) if( aParent == m_Parent )
return true; return true;
@ -110,14 +102,14 @@ bool SGSHAPE::SetParent( SGNODE* aParent, bool notify )
if( notify ) if( notify )
m_Parent->unlinkChildNode( this ); m_Parent->unlinkChildNode( this );
m_Parent = NULL; m_Parent = nullptr;
if( NULL == aParent ) if( nullptr == aParent )
return true; return true;
} }
// only a SGTRANSFORM may be parent to a SGSHAPE // only a SGTRANSFORM may be parent to a SGSHAPE
if( NULL != aParent && S3D::SGTYPE_TRANSFORM != aParent->GetNodeType() ) if( nullptr != aParent && S3D::SGTYPE_TRANSFORM != aParent->GetNodeType() )
return false; return false;
m_Parent = aParent; m_Parent = aParent;
@ -129,17 +121,17 @@ bool SGSHAPE::SetParent( SGNODE* aParent, bool notify )
} }
SGNODE* SGSHAPE::FindNode(const char *aNodeName, const SGNODE *aCaller) SGNODE* SGSHAPE::FindNode( const char* aNodeName, const SGNODE* aCaller )
{ {
if( NULL == aNodeName || 0 == aNodeName[0] ) if( nullptr == aNodeName || 0 == aNodeName[0] )
return NULL; return nullptr;
if( !m_Name.compare( aNodeName ) ) if( !m_Name.compare( aNodeName ) )
return this; return this;
SGNODE* tmp = NULL; SGNODE* tmp = nullptr;
if( NULL != m_Appearance ) if( nullptr != m_Appearance )
{ {
tmp = m_Appearance->FindNode( aNodeName, this ); tmp = m_Appearance->FindNode( aNodeName, this );
@ -149,7 +141,7 @@ SGNODE* SGSHAPE::FindNode(const char *aNodeName, const SGNODE *aCaller)
} }
} }
if( NULL != m_FaceSet ) if( nullptr != m_FaceSet )
{ {
tmp = m_FaceSet->FindNode( aNodeName, this ); tmp = m_FaceSet->FindNode( aNodeName, this );
@ -160,8 +152,8 @@ SGNODE* SGSHAPE::FindNode(const char *aNodeName, const SGNODE *aCaller)
} }
// query the parent if appropriate // query the parent if appropriate
if( aCaller == m_Parent || NULL == m_Parent ) if( aCaller == m_Parent || nullptr == m_Parent )
return NULL; return nullptr;
return m_Parent->FindNode( aNodeName, this ); return m_Parent->FindNode( aNodeName, this );
} }
@ -169,20 +161,20 @@ SGNODE* SGSHAPE::FindNode(const char *aNodeName, const SGNODE *aCaller)
void SGSHAPE::unlinkNode( const SGNODE* aNode, bool isChild ) void SGSHAPE::unlinkNode( const SGNODE* aNode, bool isChild )
{ {
if( NULL == aNode ) if( nullptr == aNode )
return; return;
if( isChild ) if( isChild )
{ {
if( aNode == m_Appearance ) if( aNode == m_Appearance )
{ {
m_Appearance = NULL; m_Appearance = nullptr;
return; return;
} }
if( aNode == m_FaceSet ) if( aNode == m_FaceSet )
{ {
m_FaceSet = NULL; m_FaceSet = nullptr;
return; return;
} }
} }
@ -191,58 +183,38 @@ void SGSHAPE::unlinkNode( const SGNODE* aNode, bool isChild )
if( aNode == m_RAppearance ) if( aNode == m_RAppearance )
{ {
delNodeRef( this ); delNodeRef( this );
m_RAppearance = NULL; m_RAppearance = nullptr;
return; return;
} }
if( aNode == m_RFaceSet ) if( aNode == m_RFaceSet )
{ {
delNodeRef( this ); delNodeRef( this );
m_RFaceSet = NULL; m_RFaceSet = nullptr;
return; return;
} }
} }
#ifdef DEBUG wxLogTrace( MASK_3D_SG, "%s:%s:%d * [BUG] unlinkNode() did not find its target",
do { __FILE__, __FUNCTION__, __LINE__ );
std::ostringstream ostr;
ostr << __FILE__ << ": " << __FUNCTION__ << ": " << __LINE__ << "\n";
ostr << " * [BUG] unlinkNode() did not find its target";
wxLogTrace( MASK_3D_SG, "%s\n", ostr.str().c_str() );
} while( 0 );
#endif
return;
} }
void SGSHAPE::unlinkChildNode( const SGNODE* aNode ) void SGSHAPE::unlinkChildNode( const SGNODE* aNode )
{ {
unlinkNode( aNode, true ); unlinkNode( aNode, true );
return;
} }
void SGSHAPE::unlinkRefNode( const SGNODE* aNode ) void SGSHAPE::unlinkRefNode( const SGNODE* aNode )
{ {
unlinkNode( aNode, false ); unlinkNode( aNode, false );
return;
} }
bool SGSHAPE::addNode( SGNODE* aNode, bool isChild ) bool SGSHAPE::addNode( SGNODE* aNode, bool isChild )
{ {
if( NULL == aNode ) wxCHECK( aNode, false );
{
#ifdef DEBUG
std::ostringstream ostr;
ostr << __FILE__ << ": " << __FUNCTION__ << ": " << __LINE__ << "\n";
ostr << " * [BUG] NULL pointer passed for aNode";
wxLogTrace( MASK_3D_SG, "%s\n", ostr.str().c_str() );
#endif
return false;
}
if( S3D::SGTYPE_APPEARANCE == aNode->GetNodeType() ) if( S3D::SGTYPE_APPEARANCE == aNode->GetNodeType() )
{ {
@ -250,12 +222,8 @@ bool SGSHAPE::addNode( SGNODE* aNode, bool isChild )
{ {
if( aNode != m_Appearance && aNode != m_RAppearance ) if( aNode != m_Appearance && aNode != m_RAppearance )
{ {
#ifdef DEBUG wxLogTrace( MASK_3D_SG, "%s:%s:%d * [BUG] assigning multiple Appearance nodes",
std::ostringstream ostr; __FILE__, __FUNCTION__, __LINE__ );
ostr << __FILE__ << ": " << __FUNCTION__ << ": " << __LINE__ << "\n";
ostr << " * [BUG] assigning multiple Appearance nodes";
wxLogTrace( MASK_3D_SG, "%s\n", ostr.str().c_str() );
#endif
return false; return false;
} }
@ -283,12 +251,8 @@ bool SGSHAPE::addNode( SGNODE* aNode, bool isChild )
{ {
if( aNode != m_FaceSet && aNode != m_RFaceSet ) if( aNode != m_FaceSet && aNode != m_RFaceSet )
{ {
#ifdef DEBUG wxLogTrace( MASK_3D_SG, "%s:%s:%d * [BUG] assigning multiple FaceSet nodes",
std::ostringstream ostr; __FILE__, __FUNCTION__, __LINE__ );
ostr << __FILE__ << ": " << __FUNCTION__ << ": " << __LINE__ << "\n";
ostr << " * [BUG] assigning multiple FaceSet nodes";
wxLogTrace( MASK_3D_SG, "%s\n", ostr.str().c_str() );
#endif
return false; return false;
} }
@ -310,15 +274,8 @@ bool SGSHAPE::addNode( SGNODE* aNode, bool isChild )
return true; return true;
} }
#ifdef DEBUG wxLogTrace( MASK_3D_SG, "%s:%s:%d * [BUG] object %s is not a valid type for this object (%d)",
do { __FILE__, __FUNCTION__, __LINE__, aNode->GetName(), aNode->GetNodeType() );
std::ostringstream ostr;
ostr << __FILE__ << ": " << __FUNCTION__ << ": " << __LINE__ << "\n";
ostr << " * [BUG] object '" << aNode->GetName();
ostr << "' is not a valid type for this object (" << aNode->GetNodeType() << ")";
wxLogTrace( MASK_3D_SG, "%s\n", ostr.str().c_str() );
} while( 0 );
#endif
return false; return false;
} }
@ -351,15 +308,12 @@ void SGSHAPE::ReNameNodes( void )
// rename FaceSet // rename FaceSet
if( m_FaceSet ) if( m_FaceSet )
m_FaceSet->ReNameNodes(); m_FaceSet->ReNameNodes();
return;
} }
bool SGSHAPE::WriteVRML( std::ostream& aFile, bool aReuseFlag ) bool SGSHAPE::WriteVRML( std::ostream& aFile, bool aReuseFlag )
{ {
if( !m_Appearance && !m_RAppearance if( !m_Appearance && !m_RAppearance && !m_FaceSet && !m_RFaceSet )
&& !m_FaceSet && !m_RFaceSet )
{ {
return false; return false;
} }
@ -402,26 +356,16 @@ bool SGSHAPE::WriteVRML( std::ostream& aFile, bool aReuseFlag )
bool SGSHAPE::WriteCache( std::ostream& aFile, SGNODE* parentNode ) bool SGSHAPE::WriteCache( std::ostream& aFile, SGNODE* parentNode )
{ {
if( NULL == parentNode ) if( nullptr == parentNode )
{ {
if( NULL == m_Parent ) wxCHECK( m_Parent, false );
{
#ifdef DEBUG
std::ostringstream ostr;
ostr << __FILE__ << ": " << __FUNCTION__ << ": " << __LINE__ << "\n";
ostr << " * [BUG] corrupt data; m_aParent is NULL";
wxLogTrace( MASK_3D_SG, "%s\n", ostr.str().c_str() );
#endif
return false;
}
SGNODE* np = m_Parent; SGNODE* np = m_Parent;
while( NULL != np->GetParent() ) while( nullptr != np->GetParent() )
np = np->GetParent(); np = np->GetParent();
if( np->WriteCache( aFile, NULL ) ) if( np->WriteCache( aFile, nullptr ) )
{ {
m_written = true; m_written = true;
return true; return true;
@ -430,35 +374,20 @@ bool SGSHAPE::WriteCache( std::ostream& aFile, SGNODE* parentNode )
return false; return false;
} }
if( parentNode != m_Parent ) wxCHECK( parentNode == m_Parent, false );
{
#ifdef DEBUG
std::ostringstream ostr;
ostr << __FILE__ << ": " << __FUNCTION__ << ": " << __LINE__ << "\n";
ostr << " * [BUG] corrupt data; parentNode != m_aParent";
wxLogTrace( MASK_3D_SG, "%s\n", ostr.str().c_str() );
#endif
return false;
}
if( !aFile.good() ) if( !aFile.good() )
{ {
#ifdef DEBUG wxLogTrace( MASK_3D_SG, "%s:%s:%d * [BUG] bad stream", __FILE__, __FUNCTION__, __LINE__ );
std::ostringstream ostr;
ostr << __FILE__ << ": " << __FUNCTION__ << ": " << __LINE__ << "\n";
ostr << " * [INFO] bad stream";
wxLogTrace( MASK_3D_SG, "%s\n", ostr.str().c_str() );
#endif
return false; return false;
} }
// check if any references are unwritten and swap parents if so // check if any references are unwritten and swap parents if so
if( NULL != m_RAppearance && !m_RAppearance->isWritten() ) if( nullptr != m_RAppearance && !m_RAppearance->isWritten() )
m_RAppearance->SwapParent(this); m_RAppearance->SwapParent(this);
if( NULL != m_RFaceSet && !m_RFaceSet->isWritten() ) if( nullptr != m_RFaceSet && !m_RFaceSet->isWritten() )
m_RFaceSet->SwapParent( this ); m_RFaceSet->SwapParent( this );
aFile << "[" << GetName() << "]"; aFile << "[" << GetName() << "]";
@ -470,19 +399,23 @@ bool SGSHAPE::WriteCache( std::ostream& aFile, SGNODE* parentNode )
items[i] = 0; items[i] = 0;
i = 0; i = 0;
if( NULL != m_Appearance )
if( nullptr != m_Appearance )
items[i] = true; items[i] = true;
++i; ++i;
if( NULL != m_RAppearance )
if( nullptr != m_RAppearance )
items[i] = true; items[i] = true;
++i; ++i;
if( NULL != m_FaceSet )
if( nullptr != m_FaceSet )
items[i] = true; items[i] = true;
++i; ++i;
if( NULL != m_RFaceSet )
if( nullptr != m_RFaceSet )
items[i] = true; items[i] = true;
for( int jj = 0; jj < NITEMS; ++jj ) for( int jj = 0; jj < NITEMS; ++jj )
@ -510,17 +443,8 @@ bool SGSHAPE::WriteCache( std::ostream& aFile, SGNODE* parentNode )
bool SGSHAPE::ReadCache( std::istream& aFile, SGNODE* parentNode ) bool SGSHAPE::ReadCache( std::istream& aFile, SGNODE* parentNode )
{ {
if( m_Appearance || m_RAppearance || m_FaceSet || m_RFaceSet ) wxCHECK( m_Appearance == nullptr && m_RAppearance == nullptr && m_FaceSet == nullptr &&
{ m_RFaceSet == nullptr, false );
#ifdef DEBUG
std::ostringstream ostr;
ostr << __FILE__ << ": " << __FUNCTION__ << ": " << __LINE__ << "\n";
ostr << " * [BUG] non-empty node";
wxLogTrace( MASK_3D_SG, "%s\n", ostr.str().c_str() );
#endif
return false;
}
#define NITEMS 4 #define NITEMS 4
bool items[NITEMS]; bool items[NITEMS];
@ -530,13 +454,9 @@ bool SGSHAPE::ReadCache( std::istream& aFile, SGNODE* parentNode )
if( ( items[0] && items[1] ) || ( items[2] && items[3] ) ) if( ( items[0] && items[1] ) || ( items[2] && items[3] ) )
{ {
#ifdef DEBUG wxLogTrace( MASK_3D_SG,
std::ostringstream ostr; "%s:%s:%d * [INFO] corrupt data; multiple item definitions at position %ul",
ostr << __FILE__ << ": " << __FUNCTION__ << ": " << __LINE__ << "\n"; __FILE__, __FUNCTION__, __LINE__, static_cast<unsigned long>( aFile.tellg() ) );
ostr << " * [INFO] corrupt data; multiple item definitions at position ";
ostr << aFile.tellg();
wxLogTrace( MASK_3D_SG, "%s\n", ostr.str().c_str() );
#endif
return false; return false;
} }
@ -547,13 +467,10 @@ bool SGSHAPE::ReadCache( std::istream& aFile, SGNODE* parentNode )
{ {
if( S3D::SGTYPE_APPEARANCE != S3D::ReadTag( aFile, name ) ) if( S3D::SGTYPE_APPEARANCE != S3D::ReadTag( aFile, name ) )
{ {
#ifdef DEBUG wxLogTrace( MASK_3D_SG,
std::ostringstream ostr; "%s:%s:%d * [INFO] corrupt data; bad child appearance tag at position %ul",
ostr << __FILE__ << ": " << __FUNCTION__ << ": " << __LINE__ << "\n"; __FILE__, __FUNCTION__, __LINE__,
ostr << " * [INFO] corrupt data; bad child apperance tag at position "; static_cast<unsigned long>( aFile.tellg() ) );
ostr << aFile.tellg();
wxLogTrace( MASK_3D_SG, "%s\n", ostr.str().c_str() );
#endif
return false; return false;
} }
@ -563,13 +480,8 @@ bool SGSHAPE::ReadCache( std::istream& aFile, SGNODE* parentNode )
if( !m_Appearance->ReadCache( aFile, this ) ) if( !m_Appearance->ReadCache( aFile, this ) )
{ {
#ifdef DEBUG wxLogTrace( MASK_3D_SG, "%s:%s:%d * [INFO] corrupt data while reading appearance '%s'",
std::ostringstream ostr; __FILE__, __FUNCTION__, __LINE__, name );
ostr << __FILE__ << ": " << __FUNCTION__ << ": " << __LINE__ << "\n";
ostr << " * [INFO] corrupt data while reading appearance '";
ostr << name << "'";
wxLogTrace( MASK_3D_SG, "%s\n", ostr.str().c_str() );
#endif
return false; return false;
} }
@ -579,13 +491,10 @@ bool SGSHAPE::ReadCache( std::istream& aFile, SGNODE* parentNode )
{ {
if( S3D::SGTYPE_APPEARANCE != S3D::ReadTag( aFile, name ) ) if( S3D::SGTYPE_APPEARANCE != S3D::ReadTag( aFile, name ) )
{ {
#ifdef DEBUG wxLogTrace( MASK_3D_SG,
std::ostringstream ostr; "%s:%s:%d * [INFO] corrupt data; bad ref appearance tag at position %ul",
ostr << __FILE__ << ": " << __FUNCTION__ << ": " << __LINE__ << "\n"; __FILE__, __FUNCTION__, __LINE__,
ostr << " * [INFO] corrupt data; bad ref appearance tag at position "; static_cast<unsigned long>( aFile.tellg() ) );
ostr << aFile.tellg();
wxLogTrace( MASK_3D_SG, "%s\n", ostr.str().c_str() );
#endif
return false; return false;
} }
@ -594,26 +503,18 @@ bool SGSHAPE::ReadCache( std::istream& aFile, SGNODE* parentNode )
if( !np ) if( !np )
{ {
#ifdef DEBUG wxLogTrace( MASK_3D_SG,
std::ostringstream ostr; "%s:%s:%d * [INFO] corrupt data: cannot find ref appearance '%s'",
ostr << __FILE__ << ": " << __FUNCTION__ << ": " << __LINE__ << "\n"; __FILE__, __FUNCTION__, __LINE__, name );
ostr << " * [INFO] corrupt data: cannot find ref appearance '";
ostr << name << "'";
wxLogTrace( MASK_3D_SG, "%s\n", ostr.str().c_str() );
#endif
return false; return false;
} }
if( S3D::SGTYPE_APPEARANCE != np->GetNodeType() ) if( S3D::SGTYPE_APPEARANCE != np->GetNodeType() )
{ {
#ifdef DEBUG wxLogTrace( MASK_3D_SG,
std::ostringstream ostr; "%s:%s:%d * [INFO] corrupt data: type is not SGAPPEARANCE '%s'",
ostr << __FILE__ << ": " << __FUNCTION__ << ": " << __LINE__ << "\n"; __FILE__, __FUNCTION__, __LINE__, name );
ostr << " * [INFO] corrupt data: type is not SGAPPEARANCE '";
ostr << name << "'";
wxLogTrace( MASK_3D_SG, "%s\n", ostr.str().c_str() );
#endif
return false; return false;
} }
@ -626,13 +527,10 @@ bool SGSHAPE::ReadCache( std::istream& aFile, SGNODE* parentNode )
{ {
if( S3D::SGTYPE_FACESET != S3D::ReadTag( aFile, name ) ) if( S3D::SGTYPE_FACESET != S3D::ReadTag( aFile, name ) )
{ {
#ifdef DEBUG wxLogTrace( MASK_3D_SG,
std::ostringstream ostr; "%s:%s:%d * [INFO] corrupt data; bad child face set tag at position %ul",
ostr << __FILE__ << ": " << __FUNCTION__ << ": " << __LINE__ << "\n"; __FILE__, __FUNCTION__, __LINE__,
ostr << " * [INFO] corrupt data; bad child face set tag at position "; static_cast<unsigned long>( aFile.tellg() ) );
ostr << aFile.tellg();
wxLogTrace( MASK_3D_SG, "%s\n", ostr.str().c_str() );
#endif
return false; return false;
} }
@ -642,13 +540,9 @@ bool SGSHAPE::ReadCache( std::istream& aFile, SGNODE* parentNode )
if( !m_FaceSet->ReadCache( aFile, this ) ) if( !m_FaceSet->ReadCache( aFile, this ) )
{ {
#ifdef DEBUG wxLogTrace( MASK_3D_SG,
std::ostringstream ostr; "%s:%s:%d * [INFO] corrupt data while reading face set '%s'",
ostr << __FILE__ << ": " << __FUNCTION__ << ": " << __LINE__ << "\n"; __FILE__, __FUNCTION__, __LINE__, name );
ostr << " * [INFO] corrupt data while reading face set '";
ostr << name << "'";
wxLogTrace( MASK_3D_SG, "%s\n", ostr.str().c_str() );
#endif
return false; return false;
} }
@ -658,13 +552,10 @@ bool SGSHAPE::ReadCache( std::istream& aFile, SGNODE* parentNode )
{ {
if( S3D::SGTYPE_FACESET != S3D::ReadTag( aFile, name ) ) if( S3D::SGTYPE_FACESET != S3D::ReadTag( aFile, name ) )
{ {
#ifdef DEBUG wxLogTrace( MASK_3D_SG,
std::ostringstream ostr; "%s:%s:%d * [INFO] corrupt data; bad ref face set tag at position %ul",
ostr << __FILE__ << ": " << __FUNCTION__ << ": " << __LINE__ << "\n"; __FILE__, __FUNCTION__, __LINE__,
ostr << " * [INFO] corrupt data; bad ref face set tag at position "; static_cast<unsigned long>( aFile.tellg() ) );
ostr << aFile.tellg();
wxLogTrace( MASK_3D_SG, "%s\n", ostr.str().c_str() );
#endif
return false; return false;
} }
@ -673,26 +564,18 @@ bool SGSHAPE::ReadCache( std::istream& aFile, SGNODE* parentNode )
if( !np ) if( !np )
{ {
#ifdef DEBUG wxLogTrace( MASK_3D_SG,
std::ostringstream ostr; "%s:%s:%d * [INFO] corrupt data: cannot find ref face set '%s'",
ostr << __FILE__ << ": " << __FUNCTION__ << ": " << __LINE__ << "\n"; __FILE__, __FUNCTION__, __LINE__, name );
ostr << " * [INFO] corrupt data: cannot find ref face set '";
ostr << name << "'";
wxLogTrace( MASK_3D_SG, "%s\n", ostr.str().c_str() );
#endif
return false; return false;
} }
if( S3D::SGTYPE_FACESET != np->GetNodeType() ) if( S3D::SGTYPE_FACESET != np->GetNodeType() )
{ {
#ifdef DEBUG wxLogTrace( MASK_3D_SG,
std::ostringstream ostr; "%s:%s:%d * [INFO] corrupt data: type is not SGFACESET '%s'",
ostr << __FILE__ << ": " << __FUNCTION__ << ": " << __LINE__ << "\n"; __FILE__, __FUNCTION__, __LINE__, name );
ostr << " * [INFO] corrupt data: type is not SGFACESET '";
ostr << name << "'";
wxLogTrace( MASK_3D_SG, "%s\n", ostr.str().c_str() );
#endif
return false; return false;
} }
@ -708,8 +591,8 @@ bool SGSHAPE::ReadCache( std::istream& aFile, SGNODE* parentNode )
} }
bool SGSHAPE::Prepare( const glm::dmat4* aTransform, bool SGSHAPE::Prepare( const glm::dmat4* aTransform, S3D::MATLIST& materials,
S3D::MATLIST& materials, std::vector< SMESH >& meshes ) std::vector< SMESH >& meshes )
{ {
SMESH m; SMESH m;
S3D::INIT_SMESH( m ); S3D::INIT_SMESH( m );
@ -717,28 +600,25 @@ bool SGSHAPE::Prepare( const glm::dmat4* aTransform,
SGAPPEARANCE* pa = m_Appearance; SGAPPEARANCE* pa = m_Appearance;
SGFACESET* pf = m_FaceSet; SGFACESET* pf = m_FaceSet;
if( NULL == pa ) if( nullptr == pa )
pa = m_RAppearance; pa = m_RAppearance;
if( NULL == pf ) if( nullptr == pf )
pf = m_RFaceSet; pf = m_RFaceSet;
// no face sets = nothing to render, which is valid though pointless // no face sets = nothing to render, which is valid though pointless
if( NULL == pf ) if( nullptr == pf )
return true; return true;
if( !pf->validate() ) if( !pf->validate() )
{ {
#ifdef DEBUG wxLogTrace( MASK_3D_SG, "%s:%s:%d * [INFO] bad model; inconsistent data",
std::ostringstream ostr; __FILE__, __FUNCTION__, __LINE__ );
ostr << __FILE__ << ": " << __FUNCTION__ << ": " << __LINE__ << "\n";
ostr << " * [INFO] bad model; inconsistent data";
wxLogTrace( MASK_3D_SG, "%s\n", ostr.str().c_str() );
#endif
return true; return true;
} }
if( NULL == pa ) if( nullptr == pa )
{ {
m.m_MaterialIdx = 0; m.m_MaterialIdx = 0;
} }
@ -761,22 +641,22 @@ bool SGSHAPE::Prepare( const glm::dmat4* aTransform,
SGCOORDINDEX* vidx = pf->m_CoordIndices; SGCOORDINDEX* vidx = pf->m_CoordIndices;
SGNORMALS* pn = pf->m_Normals; SGNORMALS* pn = pf->m_Normals;
if( NULL == pc ) if( nullptr == pc )
pc = pf->m_RColors; pc = pf->m_RColors;
if( NULL == pv ) if( nullptr == pv )
pv = pf->m_RCoords; pv = pf->m_RCoords;
if( NULL == pn ) if( nullptr == pn )
pn = pf->m_RNormals; pn = pf->m_RNormals;
// set the vertex points and indices // set the vertex points and indices
size_t nCoords = 0; size_t nCoords = 0;
SGPOINT* pCoords = NULL; SGPOINT* pCoords = nullptr;
pv->GetCoordsList( nCoords, pCoords ); pv->GetCoordsList( nCoords, pCoords );
size_t nColors = 0; size_t nColors = 0;
SGCOLOR* pColors = NULL; SGCOLOR* pColors = nullptr;
if( pc ) if( pc )
{ {
@ -785,20 +665,18 @@ bool SGSHAPE::Prepare( const glm::dmat4* aTransform,
if( nColors < nCoords ) if( nColors < nCoords )
{ {
#ifdef DEBUG wxLogTrace( MASK_3D_SG,
std::ostringstream ostr; "%s:%s:%d * [INFO] bad model; not enough colors per vertex (%ul vs %ul)",
ostr << __FILE__ << ": " << __FUNCTION__ << ": " << __LINE__ << "\n"; __FILE__, __FUNCTION__, __LINE__, static_cast<unsigned long>( nColors ),
ostr << " * [INFO] bad model; not enough colors per vertex ("; static_cast<unsigned long>( nCoords ) );
ostr << nColors << " vs " << nCoords << ")";
wxLogTrace( MASK_3D_SG, "%s\n", ostr.str().c_str() );
#endif
return true; return true;
} }
} }
// set the vertex indices // set the vertex indices
size_t nvidx = 0; size_t nvidx = 0;
int* lv = NULL; int* lv = nullptr;
vidx->GetIndices( nvidx, lv ); vidx->GetIndices( nvidx, lv );
// note: reduce the vertex set to include only the referenced vertices // note: reduce the vertex set to include only the referenced vertices
@ -819,17 +697,14 @@ bool SGSHAPE::Prepare( const glm::dmat4* aTransform,
if( vertices.size() < 3 ) if( vertices.size() < 3 )
{ {
#ifdef DEBUG wxLogTrace( MASK_3D_SG, "%s:%s:%d * [INFO] bad model; not enough vertices",
std::ostringstream ostr; __FILE__, __FUNCTION__, __LINE__ );
ostr << __FILE__ << ": " << __FUNCTION__ << ": " << __LINE__ << "\n";
ostr << " * [INFO] bad model; not enough vertices";
wxLogTrace( MASK_3D_SG, "%s\n", ostr.str().c_str() );
#endif
return true; return true;
} }
// construct the final vertex/color list // construct the final vertex/color list
SFVEC3F* lColors = NULL; SFVEC3F* lColors = nullptr;
SFVEC3F* lCoords = new SFVEC3F[ vertices.size() ]; SFVEC3F* lCoords = new SFVEC3F[ vertices.size() ];
int ti; int ti;
@ -839,7 +714,6 @@ bool SGSHAPE::Prepare( const glm::dmat4* aTransform,
m.m_Color = lColors; m.m_Color = lColors;
} }
if( pc ) if( pc )
{ {
for( size_t i = 0; i < vertices.size(); ++i ) for( size_t i = 0; i < vertices.size(); ++i )
@ -877,7 +751,7 @@ bool SGSHAPE::Prepare( const glm::dmat4* aTransform,
// set the per-vertex normals // set the per-vertex normals
size_t nNorms = 0; size_t nNorms = 0;
SGVECTOR* pNorms = NULL; SGVECTOR* pNorms = nullptr;
double x, y, z; double x, y, z;
pn->GetNormalList( nNorms, pNorms ); pn->GetNormalList( nNorms, pNorms );

View File

@ -2,6 +2,7 @@
* This program source code file is part of KiCad, a free EDA CAD application. * This program source code file is part of KiCad, a free EDA CAD application.
* *
* Copyright (C) 2015-2017 Cirilo Bernardo <cirilo.bernardo@gmail.com> * Copyright (C) 2015-2017 Cirilo Bernardo <cirilo.bernardo@gmail.com>
* Copyright (C) 2020 KiCad Developers, see AUTHORS.txt for contributors.
* *
* This program is free software; you can redistribute it and/or * This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License * modify it under the terms of the GNU General Public License
@ -23,7 +24,6 @@
/** /**
* @file sg_shape.h * @file sg_shape.h
* defines a complex 3D shape for a scenegraph object
*/ */
@ -36,8 +36,33 @@
class SGAPPEARANCE; class SGAPPEARANCE;
class SGFACESET; class SGFACESET;
/**
* Define a complex 3D shape for a scenegraph object.
*/
class SGSHAPE : public SGNODE class SGSHAPE : public SGNODE
{ {
public:
SGSHAPE( SGNODE* aParent );
virtual ~SGSHAPE();
virtual bool SetParent( SGNODE* aParent, bool notify = true ) override;
SGNODE* FindNode(const char* aNodeName, const SGNODE* aCaller) override;
bool AddRefNode( SGNODE* aNode ) override;
bool AddChildNode( SGNODE* aNode ) override;
void ReNameNodes( void ) override;
bool WriteVRML( std::ostream& aFile, bool aReuseFlag ) override;
bool WriteCache( std::ostream& aFile, SGNODE* parentNode ) override;
bool ReadCache( std::istream& aFile, SGNODE* parentNode ) override;
bool Prepare( const glm::dmat4* aTransform, S3D::MATLIST& materials,
std::vector< SMESH >& meshes );
void unlinkChildNode( const SGNODE* aNode ) override;
void unlinkRefNode( const SGNODE* aNode ) override;
private: private:
void unlinkNode( const SGNODE* aNode, bool isChild ); void unlinkNode( const SGNODE* aNode, bool isChild );
bool addNode( SGNODE* aNode, bool isChild ); bool addNode( SGNODE* aNode, bool isChild );
@ -50,28 +75,6 @@ public:
// referenced nodes // referenced nodes
SGAPPEARANCE* m_RAppearance; SGAPPEARANCE* m_RAppearance;
SGFACESET* m_RFaceSet; SGFACESET* m_RFaceSet;
void unlinkChildNode( const SGNODE* aNode ) override;
void unlinkRefNode( const SGNODE* aNode ) override;
public:
SGSHAPE( SGNODE* aParent );
virtual ~SGSHAPE();
virtual bool SetParent( SGNODE* aParent, bool notify = true ) override;
SGNODE* FindNode(const char *aNodeName, const SGNODE *aCaller) override;
bool AddRefNode( SGNODE* aNode ) override;
bool AddChildNode( SGNODE* aNode ) override;
void ReNameNodes( void ) override;
bool WriteVRML( std::ostream& aFile, bool aReuseFlag ) override;
bool WriteCache( std::ostream& aFile, SGNODE* parentNode ) override;
bool ReadCache( std::istream& aFile, SGNODE* parentNode ) override;
bool Prepare( const glm::dmat4* aTransform,
S3D::MATLIST& materials, std::vector< SMESH >& meshes );
}; };
/* /*