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
{
for( int i = 0; i < 20; ++i )
{
if( shaA[i] != shaB[i] )
return false;
}
return true;
}
@ -123,13 +125,6 @@ static const wxString sha1ToWXString( const unsigned char* aSHA1Sum )
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:
S3D_CACHE_ENTRY();
~S3D_CACHE_ENTRY();
@ -142,6 +137,13 @@ public:
std::string pluginInfo; // PluginName:Version string
SCENEGRAPH* sceneData;
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 )
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 )
*aCachePtr = ep;
}
return NULL;
@ -377,11 +379,11 @@ bool S3D_CACHE::getSHA1( const wxString& aFileName, unsigned char* aSHA1Sum )
return false;
}
#ifdef _WIN32
#ifdef _WIN32
FILE* fp = _wfopen( aFileName.wc_str(), L"rb" );
#else
#else
FILE* fp = fopen( aFileName.ToUTF8(), "rb" );
#endif
#endif
if( NULL == fp )
return false;
@ -553,11 +555,11 @@ bool S3D_CACHE::Set3DConfigDir( const wxString& aConfigDir )
// 3. MSWin: AppData\Local\kicad\3d
wxString cacheDir;
#if defined(_WIN32)
#if defined( _WIN32 )
wxStandardPaths::Get().UseAppInfo( wxStandardPaths::AppInfo_None );
cacheDir = wxStandardPaths::Get().GetUserLocalDataDir();
cacheDir.append( "\\kicad\\3d" );
#elif defined(__APPLE)
#elif defined( __APPLE )
cacheDir = "${HOME}/Library/Caches/kicad/3d";
#else // assume Linux
cacheDir = ExpandEnvVarSubstitutions( "${XDG_CACHE_HOME}", nullptr );
@ -728,6 +730,7 @@ void S3D_CACHE::CleanCacheDir( int aNumDaysOld )
}
}
S3D_CACHE* PROJECT::Get3DCacheManager( bool aUpdateProjDir )
{
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.
*
* 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
* modify it under the terms of the GNU General Public License
@ -23,7 +24,6 @@
/**
* @file 3d_cache.h
* defines the display data cache manager for 3D models
*/
#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
* element (since it inherits from 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:
/**
* 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
std::list< S3D_CACHE_ENTRY* > m_CacheList;
@ -67,132 +179,6 @@ private:
PROJECT* m_project;
wxString m_CacheDir;
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

View File

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

View File

@ -2,6 +2,7 @@
* 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) 2020 KiCad Developers, see AUTHORS.txt for contributors.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
@ -40,16 +41,35 @@ class SCENEGRAPH;
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:
/// 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
void loadPlugins( void );
@ -68,36 +88,14 @@ private:
/// add entries to the extension map
void addExtensionMap( KICAD_PLUGIN_LDR_3D* aPlugin );
public:
S3D_PLUGIN_MANAGER();
virtual ~S3D_PLUGIN_MANAGER();
/// list of discovered plugins
std::list< KICAD_PLUGIN_LDR_3D* > m_Plugins;
/**
* Function GetFileFilters
* 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;
/// mapping of extensions to available plugins
std::multimap< const wxString, KICAD_PLUGIN_LDR_3D* > m_ExtMap;
SCENEGRAPH* Load3DModel( const wxString& aFileName, std::string& aPluginInfo );
/**
* 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 );
/// list of file filters
std::list< wxString > m_FileFilters;
};
#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.
// This is automatically fixed in wx for buttons with a bitmap < 20, but not
// 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_bpvFront->SetMinSize( m_bpvFront->GetSize() + borderFix );
@ -175,9 +175,9 @@ void PANEL_PREV_3D::loadCommonSettings()
/**
* @brief rotationFromString
* Ensure -MAX_ROTATION <= rotation <= MAX_ROTATION
* aRotation will be normalized between -MAX_ROTATION and MAX_ROTATION
* Ensure -MAX_ROTATION <= rotation <= MAX_ROTATION.
*
* @param \a aRotation will be normalized between -MAX_ROTATION and MAX_ROTATION.
*/
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
// don't want to generate wxEVT_GRID_CELL_CHANGED events.
xscale->ChangeValue( formatScaleValue( modelInfo.m_Scale.x ) );
yscale->ChangeValue( formatScaleValue( modelInfo.m_Scale.y ) );
zscale->ChangeValue( formatScaleValue( modelInfo.m_Scale.z ) );

View File

@ -3,7 +3,7 @@
*
* Copyright (C) 2016 Mario Luzeiro <mrluzeiro@ua.pt>
* 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
* modify it under the terms of the GNU General Public License
@ -79,22 +79,29 @@ public:
~PANEL_PREV_3D();
private:
EDA_3D_CANVAS* m_previewPane;
WX_INFOBAR* m_infobar;
BOARD_ADAPTER m_boardAdapter;
CCAMERA& m_currentCamera;
CTRACK_BALL m_trackBallCamera;
/**
* The TOOL_DISPATCHER needs these to work around some issues in wxWidgets where the menu
* events aren't captured by the menus themselves.
*/
void OnMenuEvent( wxMenuEvent& aEvent );
BOARD* m_dummyBoard;
FOOTPRINT* m_dummyFootprint;
wxWindow* GetToolCanvas() const override { return m_previewPane; }
std::vector<FP_3DMODEL>* m_parentModelList;
int m_selected; /// Index into m_parentInfoList
BOARD_ADAPTER& GetAdapter() override { return m_boardAdapter; }
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:
/**
* Load 3D relevant settings from the user configuration
@ -102,8 +109,7 @@ private:
void loadCommonSettings();
/**
* @brief updateOrientation - it will receive the events from editing the fields
* @param event
* It will receive the events from editing the fields.
*/
void updateOrientation( wxCommandEvent &event ) override;
@ -188,29 +194,20 @@ private:
m_previewPane->SetView3D( ID_VIEW3D_BOTTOM );
}
public:
/**
* The TOOL_DISPATCHER needs these to work around some issues in wxWidgets where the menu
* events aren't captured by the menus themselves.
*/
void OnMenuEvent( wxMenuEvent& aEvent );
private:
EDA_3D_CANVAS* m_previewPane;
WX_INFOBAR* m_infobar;
BOARD_ADAPTER m_boardAdapter;
CCAMERA& m_currentCamera;
CTRACK_BALL m_trackBallCamera;
wxWindow* GetToolCanvas() const override { return m_previewPane; }
BOARD* m_dummyBoard;
FOOTPRINT* m_dummyFootprint;
BOARD_ADAPTER& GetAdapter() override { return m_boardAdapter; }
CCAMERA& GetCurrentCamera() override { return m_currentCamera; }
std::vector<FP_3DMODEL>* m_parentModelList;
int m_selected; /// Index into m_parentInfoList
/**
* @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 );
EDA_UNITS m_userUnits;
};
#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.
*
* 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
* modify it under the terms of the GNU General Public License
@ -36,10 +37,6 @@
#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
#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_Transparency = app->transparency;
return;
}
bool S3D::WriteVRML( const char* filename, bool overwrite, SGNODE* aTopNode,
bool reuse, bool renameNodes )
{
if( NULL == filename || filename[0] == 0 )
if( nullptr == filename || filename[0] == 0 )
return false;
wxString ofile = wxString::FromUTF8Unchecked( filename );
@ -96,42 +91,15 @@ bool S3D::WriteVRML( const char* filename, bool overwrite, SGNODE* aTopNode,
return false;
}
if( NULL == aTopNode )
{
#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;
}
wxCHECK( aTopNode && aTopNode->GetNodeType() == S3D::SGTYPE_TRANSFORM, false );
OPEN_OSTREAM( op, filename );
if( op.fail() )
{
wxString errmsg;
errmsg << __FILE__ << ": " << __FUNCTION__ << ": " << __LINE__ << "\n";
errmsg << " * [INFO] " << "failed to open file" << " '" << filename << "'";
wxLogTrace( MASK_3D_SG, errmsg );
wxLogTrace( MASK_3D_SG, "%s:%s:%d * [INFO] failed to open file '%s'",
__FILE__, __FUNCTION__, __LINE__, filename );
return false;
}
@ -154,10 +122,8 @@ bool S3D::WriteVRML( const char* filename, bool overwrite, SGNODE* aTopNode,
CLOSE_STREAM( op );
wxString errmsg;
errmsg << __FILE__ << ": " << __FUNCTION__ << ": " << __LINE__ << "\n";
errmsg << " * [INFO] " << "problems encountered writing file" << " '" << filename << "'";
wxLogTrace( MASK_3D_SG, errmsg );
wxLogTrace( MASK_3D_SG, "%s:%s:%d * [INFO] problems encountered writing file '%s'",
__FILE__, __FUNCTION__, __LINE__, filename );
return false;
}
@ -165,102 +131,44 @@ bool S3D::WriteVRML( const char* filename, bool overwrite, SGNODE* aTopNode,
void S3D::ResetNodeIndex( SGNODE* aNode )
{
if( NULL == aNode )
{
#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;
}
wxCHECK( aNode, /* void */ );
aNode->ResetNodeIndex();
return;
}
void S3D::RenameNodes( SGNODE* aNode )
{
if( NULL == aNode )
{
#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;
}
wxCHECK( aNode, /* void */ );
aNode->ReNameNodes();
return;
}
void S3D::DestroyNode( SGNODE* aNode ) noexcept
{
if( NULL == aNode )
{
#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;
}
wxCHECK( aNode, /* void */ );
delete aNode;
return;
}
bool S3D::WriteCache( const char* aFileName, bool overwrite, SGNODE* aNode,
const char* aPluginInfo )
{
if( NULL == aFileName || aFileName[0] == 0 )
if( nullptr == aFileName || aFileName[0] == 0 )
return false;
wxString ofile = wxString::FromUTF8Unchecked( aFileName );
if( NULL == aNode )
{
#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;
}
wxCHECK( aNode, false );
if( wxFileName::Exists( ofile ) )
{
if( !overwrite )
{
wxString errmsg;
errmsg << __FILE__ << ": " << __FUNCTION__ << ": " << __LINE__ << "\n";
errmsg << " * [INFO] " << "file exists; not overwriting" << " '";
errmsg << aFileName << "'";
wxLogTrace( MASK_3D_SG, errmsg );
wxLogTrace( MASK_3D_SG, "%s:%s:%d * [INFO] file exists not overwriting '%s'",
__FILE__, __FUNCTION__, __LINE__, aFileName );
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
if( !wxFileName::FileExists( aFileName ) )
{
wxString errmsg;
errmsg << __FILE__ << ": " << __FUNCTION__ << ": " << __LINE__ << "\n";
errmsg << " * [INFO] " << "specified path is a directory" << " '";
errmsg << aFileName << "'";
wxLogTrace( MASK_3D_SG, errmsg );
wxLogTrace( MASK_3D_SG, "%s:%s:%d * [INFO] specified path is a directory '%s'",
__FILE__, __FUNCTION__, __LINE__, aFileName );
return false;
}
}
@ -281,34 +187,26 @@ bool S3D::WriteCache( const char* aFileName, bool overwrite, SGNODE* aNode,
if( output.fail() )
{
wxString errmsg;
errmsg << __FILE__ << ": " << __FUNCTION__ << ": " << __LINE__ << "\n";
errmsg << " * [INFO] " << "failed to open file" << " '" << aFileName << "'";
wxLogTrace( MASK_3D_SG, errmsg );
wxLogTrace( MASK_3D_SG, "%s:%s:%d * [INFO] failed to open file '%s'",
__FILE__, __FUNCTION__, __LINE__, aFileName );
return false;
}
output << "(" << SG_VERSION_TAG << ")";
if( NULL != aPluginInfo && aPluginInfo[0] != 0 )
if( nullptr != aPluginInfo && aPluginInfo[0] != 0 )
output << "(" << aPluginInfo << ")";
else
output << "(INTERNAL:0.0.0.0)";
bool rval = aNode->WriteCache( output, NULL );
bool rval = aNode->WriteCache( output, nullptr );
CLOSE_STREAM( output );
if( !rval )
{
#ifdef DEBUG
do {
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
wxLogTrace( MASK_3D_SG, "%s:%s:%d * [INFO] problems encountered writing cache file '%s'",
__FILE__, __FUNCTION__, __LINE__, aFileName );
// delete the defective file
wxRemoveFile( ofile );
@ -321,37 +219,27 @@ bool S3D::WriteCache( const char* aFileName, bool overwrite, SGNODE* aNode,
SGNODE* S3D::ReadCache( const char* aFileName, void* aPluginMgr,
bool (*aTagCheck)( const char*, void* ) )
{
if( NULL == aFileName || aFileName[0] == 0 )
return NULL;
if( nullptr == aFileName || aFileName[0] == 0 )
return nullptr;
wxString ofile = wxString::FromUTF8Unchecked( aFileName );
if( !wxFileName::FileExists( aFileName ) )
{
std::ostringstream ostr;
ostr << __FILE__ << ": " << __FUNCTION__ << ": " << __LINE__ << "\n";
wxString errmsg = _( "no such file" );
ostr << " * [INFO] " << errmsg.ToUTF8() << " '";
ostr << aFileName << "'";
wxLogTrace( MASK_3D_SG, "%s\n", ostr.str().c_str() );
wxLogTrace( MASK_3D_SG, "%s:%s:%d * [INFO] no such file '%s'",
__FILE__, __FUNCTION__, __LINE__, aFileName );
return NULL;
return nullptr;
}
SGNODE* np = new SCENEGRAPH( NULL );
SGNODE* np = new SCENEGRAPH( nullptr );
if( NULL == np )
if( nullptr == np )
{
#ifdef DEBUG
do {
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
wxLogTrace( MASK_3D_SG, "%s:%s:%d * [INFO] failed to instantiate SCENEGRAPH",
__FILE__, __FUNCTION__, __LINE__ );
return NULL;
return nullptr;
}
OPEN_ISTREAM( file, aFileName );
@ -359,13 +247,11 @@ SGNODE* S3D::ReadCache( const char* aFileName, void* aPluginMgr,
if( file.fail() )
{
delete np;
std::ostringstream ostr;
ostr << __FILE__ << ": " << __FUNCTION__ << ": " << __LINE__ << "\n";
wxString errmsg = _( "failed to open file" );
ostr << " * [INFO] " << errmsg.ToUTF8() << " '";
ostr << aFileName << "'";
wxLogTrace( MASK_3D_SG, "%s\n", ostr.str().c_str() );
return NULL;
wxLogTrace( MASK_3D_SG, "%s:%s:%d * [INFO] failed to open file '%s'",
__FILE__, __FUNCTION__, __LINE__, aFileName );
return nullptr;
}
// 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 )
{
#ifdef DEBUG
do {
std::ostringstream ostr;
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
wxLogTrace( MASK_3D_SG,
"%s:%s:%d * [INFO] corrupt data; missing left parenthesis at position '%d'",
__FILE__, __FUNCTION__, __LINE__, static_cast<int>( file.tellg() ) );
CLOSE_STREAM( file );
return NULL;
return nullptr;
}
file.get( schar );
@ -403,7 +283,7 @@ SGNODE* S3D::ReadCache( const char* aFileName, void* aPluginMgr,
if( name.compare( SG_VERSION_TAG ) )
{
CLOSE_STREAM( file );
return NULL;
return nullptr;
}
} while( 0 );
@ -418,18 +298,12 @@ SGNODE* S3D::ReadCache( const char* aFileName, void* aPluginMgr,
if( '(' != schar )
{
#ifdef DEBUG
do {
std::ostringstream ostr;
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
wxLogTrace( MASK_3D_SG,
"%s:%s:%d * [INFO] corrupt data; missing left parenthesis at position '%d'",
__FILE__, __FUNCTION__, __LINE__, static_cast<int>( file.tellg() ) );
CLOSE_STREAM( file );
return NULL;
return nullptr;
}
file.get( schar );
@ -441,27 +315,26 @@ SGNODE* S3D::ReadCache( const char* aFileName, void* aPluginMgr,
}
// 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 );
return NULL;
return nullptr;
}
} while( 0 );
bool rval = np->ReadCache( file, NULL );
bool rval = np->ReadCache( file, nullptr );
CLOSE_STREAM( file );
if( !rval )
{
delete np;
std::ostringstream ostr;
ostr << __FILE__ << ": " << __FUNCTION__ << ": " << __LINE__ << "\n";
wxString errmsg = "problems encountered reading cache file";
ostr << " * [INFO] " << errmsg.ToUTF8() << " '";
ostr << aFileName << "'";
wxLogTrace( MASK_3D_SG, "%s\n", ostr.str().c_str() );
return NULL;
wxLogTrace( MASK_3D_SG, "%s:%s:%d * [INFO] problems encountered reading cache file '%s'",
__FILE__, __FUNCTION__, __LINE__, aFileName );
return nullptr;
}
return np;
@ -470,11 +343,11 @@ SGNODE* S3D::ReadCache( const char* aFileName, void* aPluginMgr,
S3DMODEL* S3D::GetModel( SCENEGRAPH* aNode )
{
if( NULL == aNode )
return NULL;
if( nullptr == aNode )
return nullptr;
if( aNode->GetNodeType() != S3D::SGTYPE_TRANSFORM )
return NULL;
return nullptr;
S3D::MATLIST materials;
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
// also typical of MCAD applications. When a model has no associated
// 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.diffuse = SGCOLOR( 0.6f, 0.6f, 0.6f );
app.specular = app.diffuse;
@ -494,10 +367,10 @@ S3DMODEL* S3D::GetModel( SCENEGRAPH* aNode )
materials.matorder.push_back( &app );
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() )
return NULL;
return nullptr;
S3DMODEL* model = S3D::New3DModel();
@ -529,35 +402,31 @@ S3DMODEL* S3D::GetModel( SCENEGRAPH* aNode )
for( size_t i = 0; i < j; ++i )
S3D::Free3DMesh( meshes[i] );
return NULL;
return nullptr;
}
void S3D::Destroy3DModel( S3DMODEL** aModel )
{
if( NULL == aModel || NULL == *aModel )
if( nullptr == aModel || nullptr == *aModel )
return;
S3DMODEL* m = *aModel;
S3D::FREE_S3DMODEL( *m );
delete m;
*aModel = NULL;
return;
*aModel = nullptr;
}
void Free3DModel( S3DMODEL& aModel )
{
S3D::FREE_S3DMODEL( aModel );
return;
}
void S3D::Free3DMesh( SMESH& aMesh )
{
S3D::FREE_SMESH( aMesh );
return;
}
@ -572,20 +441,17 @@ S3DMODEL* S3D::New3DModel( void )
void S3D::Init3DMaterial( SMATERIAL& aMat )
{
S3D::INIT_SMATERIAL( aMat );
return;
}
void S3D::Init3DMesh( SMESH& aMesh )
{
S3D::INIT_SMESH( aMesh );
return;
}
void S3D::GetLibVersion( unsigned char* Major, unsigned char* Minor,
unsigned char* Patch, unsigned char* Revision ) noexcept
void S3D::GetLibVersion( unsigned char* Major, unsigned char* Minor, unsigned char* Patch,
unsigned char* Revision ) noexcept
{
if( Major )
*Major = KICADSG_VERSION_MAJOR;
@ -598,8 +464,6 @@ void S3D::GetLibVersion( unsigned char* Major, unsigned char* Minor,
if( 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 )
{
if( NULL == aNode )
if( nullptr == aNode )
return SGTYPE_END;
return aNode->GetNodeType();
@ -635,8 +499,8 @@ S3D::SGTYPES S3D::GetSGNodeType( SGNODE* aNode )
SGNODE* S3D::GetSGNodeParent( SGNODE* aNode )
{
if( NULL == aNode )
return NULL;
if( nullptr == aNode )
return nullptr;
return aNode->GetParent();
}
@ -644,7 +508,7 @@ SGNODE* S3D::GetSGNodeParent( SGNODE* aNode )
bool S3D::AddSGNodeRef( SGNODE* aParent, SGNODE* aChild )
{
if( NULL == aParent || NULL == aChild )
if( nullptr == aParent || nullptr == aChild )
return false;
return aParent->AddRefNode( aChild );
@ -653,7 +517,7 @@ bool S3D::AddSGNodeRef( SGNODE* aParent, SGNODE* aChild )
bool S3D::AddSGNodeChild( SGNODE* aParent, SGNODE* aChild )
{
if( NULL == aParent || NULL == aChild )
if( nullptr == aParent || nullptr == aChild )
return false;
return aParent->AddChildNode( aChild );
@ -662,10 +526,8 @@ bool S3D::AddSGNodeChild( SGNODE* aParent, SGNODE* aChild )
void S3D::AssociateSGNodeWrapper( SGNODE* aObject, SGNODE** aRefPtr )
{
if( NULL == aObject || NULL == aRefPtr || aObject != *aRefPtr )
if( nullptr == aObject || nullptr == aRefPtr || aObject != *aRefPtr )
return;
aObject->AssociateWrapper( aRefPtr );
return;
}

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -2,6 +2,7 @@
* 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) 2020 KiCad Developers, see AUTHORS.txt for contributors.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
@ -30,51 +31,24 @@
#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()
{
return;
}
bool IFSG_INDEX::GetIndices( size_t& nIndices, int*& aIndexList )
{
if( NULL == m_node )
{
#ifdef DEBUG
std::ostringstream ostr;
ostr << __FILE__ << ": " << __FUNCTION__ << ": " << __LINE__ << "\n";
ostr << BadObject;
wxLogTrace( MASK_3D_SG, "%s\n", ostr.str().c_str() );
#endif
wxCHECK( m_node, false );
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 )
{
if( NULL == m_node )
{
#ifdef DEBUG
std::ostringstream ostr;
ostr << __FILE__ << ": " << __FUNCTION__ << ": " << __LINE__ << "\n";
ostr << BadObject;
wxLogTrace( MASK_3D_SG, "%s\n", ostr.str().c_str() );
#endif
wxCHECK( m_node, false );
return false;
}
((SGINDEX*)m_node)->SetIndices( nIndices, aIndexList );
( (SGINDEX*) m_node )->SetIndices( nIndices, aIndexList );
return true;
}
@ -82,19 +56,9 @@ bool IFSG_INDEX::SetIndices( size_t nIndices, int* aIndexList )
bool IFSG_INDEX::AddIndex( int aIndex )
{
if( NULL == m_node )
{
#ifdef DEBUG
std::ostringstream ostr;
ostr << __FILE__ << ": " << __FUNCTION__ << ": " << __LINE__ << "\n";
ostr << BadObject;
wxLogTrace( MASK_3D_SG, "%s\n", ostr.str().c_str() );
#endif
wxCHECK( m_node, false );
return false;
}
((SGINDEX*)m_node)->AddIndex( aIndex );
( (SGINDEX*) m_node )->AddIndex( aIndex );
return true;
}

View File

@ -2,6 +2,7 @@
* 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) 2020 KiCad Developers, see AUTHORS.txt for contributors.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
@ -30,15 +31,17 @@
#include "3d_cache/sg/sg_node.h"
#include "plugins/3dapi/ifsg_api.h"
// collection of common error strings used by the wrappers
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 BadParent[] = " * [BUG] invalid parent node (data may have been deleted)";
char WrongParent[] = " * [BUG] parent node type is incompatible";
IFSG_NODE::IFSG_NODE()
{
m_node = NULL;
m_node = nullptr;
}
@ -46,8 +49,6 @@ IFSG_NODE::~IFSG_NODE()
{
if( m_node )
m_node->DisassociateWrapper( &m_node );
return;
}
@ -57,9 +58,7 @@ void IFSG_NODE::Destroy( void )
m_node->DisassociateWrapper( &m_node );
delete m_node;
m_node = NULL;
return;
m_node = nullptr;
}
@ -71,17 +70,7 @@ SGNODE* IFSG_NODE::GetRawPtr( void ) noexcept
S3D::SGTYPES IFSG_NODE::GetNodeType( void ) const
{
if( NULL == m_node )
{
#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;
}
wxCHECK( m_node, S3D::SGTYPE_END );
return m_node->GetNodeType();
}
@ -89,17 +78,7 @@ S3D::SGTYPES IFSG_NODE::GetNodeType( void ) const
SGNODE* IFSG_NODE::GetParent( void ) const
{
if( NULL == m_node )
{
#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;
}
wxCHECK( m_node, nullptr );
return m_node->GetParent();
}
@ -107,17 +86,7 @@ SGNODE* IFSG_NODE::GetParent( void ) const
bool IFSG_NODE::SetParent( SGNODE* aParent )
{
if( NULL == m_node )
{
#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;
}
wxCHECK( m_node, false );
return m_node->SetParent( aParent );
}
@ -125,90 +94,40 @@ bool IFSG_NODE::SetParent( SGNODE* aParent )
const char* IFSG_NODE::GetName( void )
{
if( NULL == m_node )
{
#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;
}
wxCHECK( m_node, nullptr );
return m_node->GetName();
}
bool IFSG_NODE::SetName( const char *aName )
bool IFSG_NODE::SetName( const char* aName )
{
if( NULL == m_node )
{
#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;
}
wxCHECK( m_node, false );
m_node->SetName( aName );
return true;
}
const char * IFSG_NODE::GetNodeTypeName( S3D::SGTYPES aNodeType ) const
const char* IFSG_NODE::GetNodeTypeName( S3D::SGTYPES aNodeType ) const
{
if( NULL == m_node )
{
#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;
}
wxCHECK( m_node, nullptr );
return m_node->GetNodeTypeName( aNodeType );
}
SGNODE* IFSG_NODE::FindNode( const char *aNodeName )
SGNODE* IFSG_NODE::FindNode( const char* aNodeName )
{
if( NULL == m_node )
{
#ifdef DEBUG
std::ostringstream ostr;
ostr << __FILE__ << ": " << __FUNCTION__ << ": " << __LINE__ << "\n";
ostr << BadObject;
wxLogTrace( MASK_3D_SG, "%s\n", ostr.str().c_str() );
#endif
wxCHECK( m_node, nullptr );
return NULL;
}
return m_node->FindNode( aNodeName, NULL );
return m_node->FindNode( aNodeName, nullptr );
}
bool IFSG_NODE::AddRefNode( SGNODE* aNode )
{
if( NULL == m_node )
{
#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;
}
wxCHECK( m_node, false );
return m_node->AddRefNode( aNode );
}
@ -216,31 +135,11 @@ bool IFSG_NODE::AddRefNode( SGNODE* aNode )
bool IFSG_NODE::AddRefNode( IFSG_NODE& aNode )
{
if( NULL == m_node )
{
#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;
}
wxCHECK( m_node, false );
SGNODE* np = aNode.GetRawPtr();
if( NULL == np )
{
#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;
}
wxCHECK( np, false );
return m_node->AddRefNode( np );
}
@ -248,17 +147,7 @@ bool IFSG_NODE::AddRefNode( IFSG_NODE& aNode )
bool IFSG_NODE::AddChildNode( SGNODE* aNode )
{
if( NULL == m_node )
{
#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;
}
wxCHECK( m_node, false );
return m_node->AddChildNode( aNode );
}
@ -266,31 +155,11 @@ bool IFSG_NODE::AddChildNode( SGNODE* aNode )
bool IFSG_NODE::AddChildNode( IFSG_NODE& aNode )
{
if( NULL == m_node )
{
#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;
}
wxCHECK( m_node, false );
SGNODE* np = aNode.GetRawPtr();
if( NULL == np )
{
#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;
}
wxCHECK( np, false );
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.
*
* 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
* modify it under the terms of the GNU General Public License
@ -30,53 +31,42 @@
#include "3d_cache/sg/sg_normals.h"
extern char BadObject[];
extern char BadOperand[];
extern char BadParent[];
extern char WrongParent[];
IFSG_NORMALS::IFSG_NORMALS( bool create )
{
m_node = NULL;
m_node = nullptr;
if( !create )
return;
m_node = new SGNORMALS( NULL );
m_node = new SGNORMALS( nullptr );
if( m_node )
m_node->AssociateWrapper( &m_node );
return;
}
IFSG_NORMALS::IFSG_NORMALS( SGNODE* aParent )
{
m_node = new SGNORMALS( NULL );
m_node = new SGNORMALS( nullptr );
if( m_node )
{
if( !m_node->SetParent( aParent ) )
{
delete m_node;
m_node = NULL;
m_node = nullptr;
#ifdef DEBUG
std::ostringstream ostr;
ostr << __FILE__ << ": " << __FUNCTION__ << ": " << __LINE__ << "\n";
ostr << WrongParent;
wxLogTrace( MASK_3D_SG, "%s\n", ostr.str().c_str() );
#endif
wxLogTrace( MASK_3D_SG, "%s:%s:%d %s", __FILE__, __FUNCTION__, __LINE__, WrongParent );
return;
}
m_node->AssociateWrapper( &m_node );
}
return;
}
@ -84,39 +74,29 @@ IFSG_NORMALS::IFSG_NORMALS( IFSG_NODE& aParent )
{
SGNODE* pp = aParent.GetRawPtr();
#ifdef DEBUG
#ifdef DEBUG
if( ! pp )
{
std::ostringstream ostr;
ostr << __FILE__ << ": " << __FUNCTION__ << ": " << __LINE__ << "\n";
ostr << BadParent;
wxLogTrace( MASK_3D_SG, "%s\n", ostr.str().c_str() );
wxLogTrace( MASK_3D_SG, "%s:%s:%d %s", __FILE__, __FUNCTION__, __LINE__, BadParent );
}
#endif
#endif
m_node = new SGNORMALS( NULL );
m_node = new SGNORMALS( nullptr );
if( m_node )
{
if( !m_node->SetParent( pp ) )
{
delete m_node;
m_node = NULL;
m_node = nullptr;
#ifdef DEBUG
std::ostringstream ostr;
ostr << __FILE__ << ": " << __FUNCTION__ << ": " << __LINE__ << "\n";
ostr << WrongParent;
wxLogTrace( MASK_3D_SG, "%s\n", ostr.str().c_str() );
#endif
wxLogTrace( MASK_3D_SG, "%s:%s:%d %s", __FILE__, __FUNCTION__, __LINE__, WrongParent );
return;
}
m_node->AssociateWrapper( &m_node );
}
return;
}
@ -125,7 +105,7 @@ bool IFSG_NORMALS::Attach( SGNODE* aNode )
if( m_node )
m_node->DisassociateWrapper( &m_node );
m_node = NULL;
m_node = nullptr;
if( !aNode )
return false;
@ -151,17 +131,12 @@ bool IFSG_NORMALS::NewNode( SGNODE* aParent )
if( aParent != m_node->GetParent() )
{
#ifdef DEBUG
std::ostringstream ostr;
ostr << __FILE__ << ": " << __FUNCTION__ << ": " << __LINE__ << "\n";
ostr << " * [BUG] invalid SGNODE parent (";
ostr << aParent->GetNodeTypeName( aParent->GetNodeType() );
ostr << ") to SGNORMALS";
wxLogTrace( MASK_3D_SG, "%s\n", ostr.str().c_str() );
#endif
wxLogTrace( MASK_3D_SG, "%s:%s:%d * [BUG] invalid SGNODE parent (%s) to SGNORMALS",
__FILE__, __FUNCTION__, __LINE__,
aParent->GetNodeTypeName( aParent->GetNodeType() ) );
delete m_node;
m_node = NULL;
m_node = nullptr;
return false;
}
@ -175,17 +150,7 @@ bool IFSG_NORMALS::NewNode( IFSG_NODE& aParent )
{
SGNODE* np = aParent.GetRawPtr();
if( NULL == np )
{
#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;
}
wxCHECK( np, false );
return NewNode( np );
}
@ -193,74 +158,34 @@ bool IFSG_NORMALS::NewNode( IFSG_NODE& aParent )
bool IFSG_NORMALS::GetNormalList( size_t& aListSize, SGVECTOR*& aNormalList )
{
if( NULL == m_node )
{
#ifdef DEBUG
std::ostringstream ostr;
ostr << __FILE__ << ": " << __FUNCTION__ << ": " << __LINE__ << "\n";
ostr << BadObject;
wxLogTrace( MASK_3D_SG, "%s\n", ostr.str().c_str() );
#endif
wxCHECK( m_node, false );
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 )
{
if( NULL == m_node )
{
#ifdef DEBUG
std::ostringstream ostr;
ostr << __FILE__ << ": " << __FUNCTION__ << ": " << __LINE__ << "\n";
ostr << BadObject;
wxLogTrace( MASK_3D_SG, "%s\n", ostr.str().c_str() );
#endif
wxCHECK( m_node, false );
return false;
}
((SGNORMALS*)m_node)->SetNormalList( aListSize, aNormalList );
( (SGNORMALS*) m_node )->SetNormalList( aListSize, aNormalList );
return true;
}
bool IFSG_NORMALS::AddNormal( double aXValue, double aYValue, double aZValue )
{
if( NULL == m_node )
{
#ifdef DEBUG
std::ostringstream ostr;
ostr << __FILE__ << ": " << __FUNCTION__ << ": " << __LINE__ << "\n";
ostr << BadObject;
wxLogTrace( MASK_3D_SG, "%s\n", ostr.str().c_str() );
#endif
wxCHECK( m_node, false );
return false;
}
((SGNORMALS*)m_node)->AddNormal( aXValue, aYValue, aZValue );
( (SGNORMALS*) m_node )->AddNormal( aXValue, aYValue, aZValue );
return true;
}
bool IFSG_NORMALS::AddNormal( const SGVECTOR& aNormal )
{
if( NULL == m_node )
{
#ifdef DEBUG
std::ostringstream ostr;
ostr << __FILE__ << ": " << __FUNCTION__ << ": " << __LINE__ << "\n";
ostr << BadObject;
wxLogTrace( MASK_3D_SG, "%s\n", ostr.str().c_str() );
#endif
wxCHECK( m_node, false );
return false;
}
((SGNORMALS*)m_node)->AddNormal( aNormal );
( (SGNORMALS*) m_node )->AddNormal( aNormal );
return true;
}

View File

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

View File

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

View File

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

View File

@ -2,6 +2,7 @@
* 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) 2020 KiCad Developers, see AUTHORS.txt for contributors.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
@ -23,10 +24,6 @@
/**
* @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;
/**
* 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
{
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:
void unlinkChildNode( 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 );
virtual ~SCENEGRAPH();
@ -84,8 +61,35 @@ public:
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 );
bool Prepare( const glm::dmat4* aTransform, S3D::MATLIST& materials,
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.
*
* 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
* 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_helpers.h"
SGAPPEARANCE::SGAPPEARANCE( SGNODE* aParent ) : SGNODE( aParent)
SGAPPEARANCE::SGAPPEARANCE( SGNODE* aParent ) : SGNODE( aParent )
{
m_SGtype = S3D::SGTYPE_APPEARANCE;
@ -39,36 +41,28 @@ SGAPPEARANCE::SGAPPEARANCE( SGNODE* aParent ) : SGNODE( aParent)
transparency = 0.0f;
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
std::ostringstream ostr;
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
wxLogTrace( MASK_3D_SG, "%s:%s:%d * [BUG] inappropriate parent to SGAPPEARANCE (type %s )",
__FILE__, __FUNCTION__, __LINE__, aParent->GetNodeType() );
}
else if( NULL != aParent && S3D::SGTYPE_SHAPE == aParent->GetNodeType() )
else if( nullptr != aParent && S3D::SGTYPE_SHAPE == aParent->GetNodeType() )
{
m_Parent->AddChildNode( this );
}
return;
}
SGAPPEARANCE::~SGAPPEARANCE()
{
return;
}
bool SGAPPEARANCE::SetParent( SGNODE* aParent, bool notify )
{
if( NULL != m_Parent )
if( nullptr != m_Parent )
{
if( aParent == m_Parent )
return true;
@ -77,14 +71,14 @@ bool SGAPPEARANCE::SetParent( SGNODE* aParent, bool notify )
if( notify )
m_Parent->unlinkChildNode( this );
m_Parent = NULL;
m_Parent = nullptr;
if( NULL == aParent )
if( nullptr == aParent )
return true;
}
// 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;
m_Parent = aParent;
@ -104,17 +98,7 @@ bool SGAPPEARANCE::SetEmissive( float aRVal, float aGVal, float aBVal )
bool SGAPPEARANCE::SetEmissive( const SGCOLOR* aRGBColor )
{
if( NULL == 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;
}
wxCHECK_MSG( aRGBColor, false, "NULL pointer passed for aRGBColor" );
return emissive.SetColor( aRGBColor );
}
@ -134,17 +118,7 @@ bool SGAPPEARANCE::SetDiffuse( float aRVal, float aGVal, float aBVal )
bool SGAPPEARANCE::SetDiffuse( const SGCOLOR* aRGBColor )
{
if( NULL == 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;
}
wxCHECK_MSG( aRGBColor, false, "NULL pointer passed for aRGBColor" );
return diffuse.SetColor( aRGBColor );
}
@ -164,17 +138,7 @@ bool SGAPPEARANCE::SetSpecular( float aRVal, float aGVal, float aBVal )
bool SGAPPEARANCE::SetSpecular( const SGCOLOR* aRGBColor )
{
if( NULL == 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;
}
wxCHECK_MSG( aRGBColor, false, "NULL pointer passed for aRGBColor" );
return specular.SetColor( aRGBColor );
}
@ -193,17 +157,7 @@ bool SGAPPEARANCE::SetAmbient( float aRVal, float aGVal, float aBVal )
bool SGAPPEARANCE::SetAmbient( const SGCOLOR* aRGBColor )
{
if( NULL == 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;
}
wxCHECK_MSG( aRGBColor, false, "NULL pointer passed for 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] )
return NULL;
if( nullptr == aNodeName || 0 == aNodeName[0] )
return nullptr;
if( !m_Name.compare( aNodeName ) )
return this;
return NULL;
return nullptr;
}
void SGAPPEARANCE::unlinkChildNode( const SGNODE* aCaller ) noexcept
{
#ifdef DEBUG
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;
wxCHECK_MSG( aCaller, /* void */,
"unexpected code branch; node should have no children or refs" );
}
void SGAPPEARANCE::unlinkRefNode( const SGNODE* aCaller ) noexcept
{
#ifdef DEBUG
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;
wxCHECK_MSG( aCaller, /* void */,
"unexpected code branch; node should have no children or refs" );
}
bool SGAPPEARANCE::AddRefNode( SGNODE* aNode ) noexcept
{
#ifdef DEBUG
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
wxCHECK_MSG( aNode, false, "this node does not accept children or refs" );
// This is redundant but it keeps gcc from generating a warning on debug builds.
return false;
}
bool SGAPPEARANCE::AddChildNode( SGNODE* aNode ) noexcept
{
#ifdef DEBUG
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
wxCHECK_MSG( aNode, false, "this node does not accept children or refs" );
// This is redundant but it keeps gcc from generating a warning on debug builds.
return false;
}
@ -368,26 +302,16 @@ bool SGAPPEARANCE::WriteVRML( std::ostream& aFile, bool aReuseFlag )
bool SGAPPEARANCE::WriteCache( std::ostream& aFile, SGNODE* parentNode )
{
if( NULL == parentNode )
if( nullptr == parentNode )
{
if( NULL == m_Parent )
{
#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;
}
wxCHECK_MSG( m_Parent, false, "corrupt data; m_aParent is NULL" );
SGNODE* np = m_Parent;
while( NULL != np->GetParent() )
while( nullptr != np->GetParent() )
np = np->GetParent();
if( np->WriteCache( aFile, NULL ) )
if( np->WriteCache( aFile, nullptr ) )
{
m_written = true;
return true;
@ -396,34 +320,19 @@ bool SGAPPEARANCE::WriteCache( std::ostream& aFile, SGNODE* parentNode )
return false;
}
if( parentNode != m_Parent )
{
#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;
}
wxCHECK_MSG( parentNode == m_Parent, false, "corrupt data; parentNode != m_aParent" );
if( !aFile.good() )
{
#ifdef DEBUG
std::ostringstream ostr;
ostr << __FILE__ << ": " << __FUNCTION__ << ": " << __LINE__ << "\n";
ostr << " * [INFO] bad stream";
wxLogTrace( MASK_3D_SG, "%s\n", ostr.str().c_str() );
#endif
wxLogTrace( MASK_3D_SG, "%s:%s:%d * [INFO] bad stream", __FILE__, __FUNCTION__, __LINE__ );
return false;
}
aFile << "[" << GetName() << "]";
S3D::WriteColor( aFile, ambient );
aFile.write( (char*)&shininess, sizeof(shininess) );
aFile.write( (char*)&transparency, sizeof(transparency) );
aFile.write( (char*) &shininess, sizeof( shininess ) );
aFile.write( (char*) &transparency, sizeof( transparency ) );
S3D::WriteColor( aFile, diffuse );
S3D::WriteColor( aFile, emissive );
S3D::WriteColor( aFile, specular );
@ -439,8 +348,8 @@ bool SGAPPEARANCE::WriteCache( std::ostream& aFile, SGNODE* parentNode )
bool SGAPPEARANCE::ReadCache( std::istream& aFile, SGNODE* parentNode )
{
S3D::ReadColor( aFile, ambient );
aFile.read( (char*)&shininess, sizeof(shininess) );
aFile.read( (char*)&transparency, sizeof(transparency) );
aFile.read( (char*) &shininess, sizeof( shininess ) );
aFile.read( (char*) &transparency, sizeof( transparency ) );
S3D::ReadColor( aFile, diffuse );
S3D::ReadColor( aFile, emissive );
S3D::ReadColor( aFile, specular );

View File

@ -2,6 +2,7 @@
* 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) 2020 KiCad Developers, see AUTHORS.txt for contributors.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
@ -23,7 +24,6 @@
/**
* @file sg_appearance.h
* defines the generic material appearance of a scenegraph object
*/
#ifndef SG_APPEARANCE_H
@ -31,20 +31,15 @@
#include "3d_cache/sg/sg_node.h"
/**
* Defines the generic material appearance of a scenegraph object.
*/
class SGAPPEARANCE : public SGNODE
{
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 unlinkRefNode( const SGNODE* aNode ) noexcept override;
public:
SGAPPEARANCE( SGNODE* aParent );
virtual ~SGAPPEARANCE();
@ -75,6 +70,14 @@ public:
bool WriteCache( std::ostream& 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

View File

@ -2,6 +2,7 @@
* 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) 2020 KiCad Developers, see AUTHORS.txt for contributors.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
@ -35,20 +36,14 @@ SGCOLOR::SGCOLOR()
red = 0.0;
green = 0.0;
blue = 0.0;
return;
}
SGCOLOR::SGCOLOR( float aRVal, float aGVal, float aBVal )
{
if( !checkRange( aRVal, aGVal, aBVal ) )
{
#ifdef DEBUG
std::ostringstream ostr;
ostr << __FILE__ << ": " << __FUNCTION__ << ": " << __LINE__ << "\n";
ostr << " * [BUG] invalid value passed to constructor";
wxLogTrace( MASK_3D_SG, "%s\n", ostr.str().c_str() );
#endif
wxLogTrace( MASK_3D_SG, "%s:%s:%d * [BUG] invalid value passed to constructor",
__FILE__, __FUNCTION__, __LINE__ );
red = 0.0;
green = 0.0;
blue = 0.0;
@ -58,7 +53,6 @@ SGCOLOR::SGCOLOR( float aRVal, float aGVal, float aBVal )
red = aRVal;
green = aGVal;
blue = aBVal;
return;
}
@ -67,7 +61,6 @@ void SGCOLOR::GetColor( float& aRedVal, float& aGreenVal, float& aBlueVal ) cons
aRedVal = red;
aGreenVal = green;
aBlueVal = blue;
return;
}
@ -76,28 +69,16 @@ void SGCOLOR::GetColor( SGCOLOR& aColor ) const noexcept
aColor.red = red;
aColor.green = green;
aColor.blue = blue;
return;
}
void SGCOLOR::GetColor( SGCOLOR* aColor ) const noexcept
{
if( NULL == aColor )
{
#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;
}
wxCHECK_MSG( aColor, /* void */, "NULL pointer passed for aRGBColor" );
aColor->red = red;
aColor->green = green;
aColor->blue = blue;
return;
}
@ -125,17 +106,7 @@ bool SGCOLOR::SetColor( const SGCOLOR& aColor ) noexcept
bool SGCOLOR::SetColor( const SGCOLOR* aColor ) noexcept
{
if( NULL == aColor )
{
#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;
}
wxCHECK_MSG( aColor, false, "NULL pointer passed for aRGBColor" );
red = aColor->red;
green = aColor->green;
@ -150,36 +121,25 @@ bool SGCOLOR::checkRange( float aRedVal, float aGreenVal, float aBlueVal ) const
if( aRedVal < 0.0 || aRedVal > 1.0 )
{
#ifdef DEBUG
std::ostringstream ostr;
ostr << __FILE__ << ": " << __FUNCTION__ << ": " << __LINE__ << "\n";
ostr << " * [BUG] invalid RED value: " << aRedVal;
wxLogTrace( MASK_3D_SG, "%s\n", ostr.str().c_str() );
#endif
wxLogTrace( MASK_3D_SG, "%s:%s:%d * [BUG] invalid RED value: %g",
__FILE__, __FUNCTION__, __LINE__, aRedVal );
ok = false;
}
if( aGreenVal < 0.0 || aGreenVal > 1.0 )
{
#ifdef DEBUG
if( ok )
{
wxLogTrace( MASK_3D_SG, "%s:%s:%d\n", __FILE__, __FUNCTION__, __LINE__ );
}
wxLogTrace( MASK_3D_SG, " * [BUG] invalid GREEN value: %f\n", aGreenVal );
#endif
wxLogTrace( MASK_3D_SG, "%s:%s:%d * [BUG] invalid GREEN value: %g",
__FILE__, __FUNCTION__, __LINE__, aGreenVal );
ok = false;
}
if( aBlueVal < 0.0 || aBlueVal > 1.0 )
{
#ifdef DEBUG
if( ok )
{
wxLogTrace( MASK_3D_SG, "%s:%s:%d\n", __FILE__, __FUNCTION__, __LINE__ );
}
wxLogTrace( MASK_3D_SG, " * [BUG] invalid BLUE value: %f\n", aBlueVal );
#endif
wxLogTrace( MASK_3D_SG, "%s:%s:%d * [BUG] invalid BLUE value: %g",
__FILE__, __FUNCTION__, __LINE__, aBlueVal );
ok = false;
}
@ -192,7 +152,6 @@ SGPOINT::SGPOINT()
x = 0.0;
y = 0.0;
z = 0.0;
return;
}
@ -209,7 +168,6 @@ void SGPOINT::GetPoint( double& aXVal, double& aYVal, double& aZVal ) noexcept
x = aXVal;
y = aYVal;
z = aZVal;
return;
}
@ -218,28 +176,16 @@ void SGPOINT::GetPoint( SGPOINT& aPoint ) noexcept
x = aPoint.x;
y = aPoint.y;
z = aPoint.z;
return;
}
void SGPOINT::GetPoint( SGPOINT* aPoint ) noexcept
{
if( NULL == 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;
}
wxCHECK_MSG( aPoint, /* void */, "NULL pointer passed for aPoint" );
x = aPoint->x;
y = aPoint->y;
z = aPoint->z;
return;
}
@ -248,7 +194,6 @@ void SGPOINT::SetPoint( double aXVal, double aYVal, double aZVal ) noexcept
x = aXVal;
y = aYVal;
z = aZVal;
return;
}
@ -257,7 +202,6 @@ void SGPOINT::SetPoint( const SGPOINT& aPoint ) noexcept
x = aPoint.x;
y = aPoint.y;
z = aPoint.z;
return;
}
@ -266,7 +210,6 @@ SGVECTOR::SGVECTOR()
vx = 0.0;
vy = 0.0;
vz = 1.0;
return;
}
@ -276,7 +219,6 @@ SGVECTOR::SGVECTOR( double aXVal, double aYVal, double aZVal )
vy = aYVal;
vz = aZVal;
normalize();
return;
}
@ -285,7 +227,6 @@ void SGVECTOR::GetVector( double& aXVal, double& aYVal, double& aZVal ) const no
aXVal = vx;
aYVal = vy;
aZVal = vz;
return;
}
@ -295,14 +236,12 @@ void SGVECTOR::SetVector( double aXVal, double aYVal, double aZVal )
vy = aYVal;
vz = aZVal;
normalize();
return;
}
void SGVECTOR::SetVector( const SGVECTOR& aVector )
{
aVector.GetVector( vx, vy, vz );
return;
}
@ -313,10 +252,9 @@ void SGVECTOR::normalize( void ) noexcept
double dz = vz * vz;
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
// to be believable
// use the default; the numbers are too small to be believable
vx = 0.0;
vy = 0.0;
vz = 1.0;
@ -326,8 +264,6 @@ void SGVECTOR::normalize( void ) noexcept
vx /= dv2;
vy /= dv2;
vz /= dv2;
return;
}
@ -336,5 +272,4 @@ SGVECTOR& SGVECTOR::operator=( const SGVECTOR& source ) noexcept
vx = source.vx;
vy = source.vy;
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.
*
* 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
* 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_helpers.h"
SGCOLORS::SGCOLORS( SGNODE* aParent ) : SGNODE( aParent )
{
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
std::ostringstream ostr;
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
wxLogTrace( MASK_3D_SG, "%s:%s:%d * [BUG] inappropriate parent to SGCOLORS (type %s)",
__FILE__, __FUNCTION__, __LINE__, aParent->GetNodeType() );
}
else if( NULL != aParent && S3D::SGTYPE_FACESET == aParent->GetNodeType() )
else if( nullptr != aParent && S3D::SGTYPE_FACESET == aParent->GetNodeType() )
{
m_Parent->AddChildNode( this );
}
return;
}
SGCOLORS::~SGCOLORS()
{
colors.clear();
return;
}
bool SGCOLORS::SetParent( SGNODE* aParent, bool notify )
{
if( NULL != m_Parent )
if( nullptr != m_Parent )
{
if( aParent == m_Parent )
return true;
@ -71,14 +65,14 @@ bool SGCOLORS::SetParent( SGNODE* aParent, bool notify )
if( notify )
m_Parent->unlinkChildNode( this );
m_Parent = NULL;
m_Parent = nullptr;
if( NULL == aParent )
if( nullptr == aParent )
return true;
}
// 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;
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] )
return NULL;
if( nullptr == aNodeName || 0 == aNodeName[0] )
return nullptr;
if( !m_Name.compare( aNodeName ) )
return this;
return NULL;
return nullptr;
}
void SGCOLORS::unlinkChildNode( const SGNODE* aCaller ) noexcept
{
#ifdef DEBUG
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;
wxCHECK( aCaller, /* void */ );
}
void SGCOLORS::unlinkRefNode( const SGNODE* aCaller ) noexcept
{
#ifdef DEBUG
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;
wxCHECK( aCaller, /* void */ );
}
bool SGCOLORS::AddRefNode( SGNODE* aNode ) noexcept
{
#ifdef DEBUG
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
wxCHECK( aNode, false );
return false;
}
@ -143,12 +118,7 @@ bool SGCOLORS::AddRefNode( SGNODE* aNode ) noexcept
bool SGCOLORS::AddChildNode( SGNODE* aNode ) noexcept
{
#ifdef DEBUG
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
wxCHECK( aNode, false );
return false;
}
@ -159,7 +129,7 @@ bool SGCOLORS::GetColorList( size_t& aListSize, SGCOLOR*& aColorList )
if( colors.empty() )
{
aListSize = 0;
aColorList = NULL;
aColorList = nullptr;
return false;
}
@ -173,7 +143,7 @@ void SGCOLORS::SetColorList( size_t aListSize, const SGCOLOR* aColorList )
{
colors.clear();
if( 0 == aListSize || NULL == aColorList )
if( 0 == aListSize || nullptr == aColorList )
return;
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 )
{
if( NULL == parentNode )
if( nullptr == parentNode )
{
if( NULL == m_Parent )
{
#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;
}
wxCHECK( m_Parent, false );
SGNODE* np = m_Parent;
while( NULL != np->GetParent() )
while( nullptr != np->GetParent() )
np = np->GetParent();
if( np->WriteCache( aFile, NULL ) )
if( np->WriteCache( aFile, nullptr ) )
{
m_written = true;
return true;
@ -295,26 +255,11 @@ bool SGCOLORS::WriteCache( std::ostream& aFile, SGNODE* parentNode )
return false;
}
if( parentNode != m_Parent )
{
#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;
}
wxCHECK( parentNode == m_Parent, false );
if( !aFile.good() )
{
#ifdef DEBUG
std::ostringstream ostr;
ostr << __FILE__ << ": " << __FUNCTION__ << ": " << __LINE__ << "\n";
ostr << " * [INFO] bad stream";
wxLogTrace( MASK_3D_SG, "%s\n", ostr.str().c_str() );
#endif
wxLogTrace( MASK_3D_SG, "%s:%s:%d * [INFO] bad stream", __FILE__, __FUNCTION__, __LINE__ );
return false;
}
@ -336,20 +281,10 @@ bool SGCOLORS::WriteCache( std::ostream& aFile, SGNODE* parentNode )
bool SGCOLORS::ReadCache( std::istream& aFile, SGNODE* parentNode )
{
if( !colors.empty() )
{
#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;
}
wxCHECK( colors.empty(), false );
size_t ncolors;
aFile.read( (char*)&ncolors, sizeof(size_t) );
aFile.read( (char*) &ncolors, sizeof( size_t ) );
SGCOLOR tmp;
if( aFile.fail() )

View File

@ -2,6 +2,7 @@
* 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) 2020 KiCad Developers, see AUTHORS.txt for contributors.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
@ -23,7 +24,6 @@
/**
* @file sg_colors.h
* defines an RGB color set for a scenegraph object
*/
#ifndef SG_COLORS_H
@ -32,20 +32,20 @@
#include <vector>
#include "3d_cache/sg/sg_node.h"
/**
* Define an RGB color set for a scenegraph object.
*/
class SGCOLORS : public SGNODE
{
public:
std::vector< SGCOLOR > colors;
void unlinkChildNode( const SGNODE* aNode ) noexcept override;
void unlinkRefNode( const SGNODE* aNode ) noexcept override;
public:
SGCOLORS( SGNODE* aParent );
virtual ~SGCOLORS();
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;
bool AddRefNode( SGNODE* aNode ) noexcept override;
bool AddChildNode( SGNODE* aNode ) noexcept override;
@ -60,6 +60,8 @@ public:
bool WriteCache( std::ostream& aFile, SGNODE* parentNode ) override;
bool ReadCache( std::istream& aFile, SGNODE* parentNode ) override;
std::vector< SGCOLOR > colors;
};
#endif // SG_COLORS_H

View File

@ -2,6 +2,7 @@
* 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) 2020 KiCad Developers, see AUTHORS.txt for contributors.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
@ -32,14 +33,11 @@ SGCOORDINDEX::SGCOORDINDEX( SGNODE* aParent ) : SGINDEX( aParent )
{
m_Parent->AddChildNode( this );
}
return;
}
SGCOORDINDEX::~SGCOORDINDEX()
{
return;
}
@ -49,6 +47,4 @@ void SGCOORDINDEX::GatherCoordIndices( std::vector< int >& aIndexList )
return;
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.
*
* 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
* modify it under the terms of the GNU General Public License
@ -23,7 +24,6 @@
/**
* @file sg_coordindex.h
* defines an coordinate index set for a scenegraph object
*/
#ifndef SG_COORDINDEX_H
@ -32,14 +32,12 @@
#include "3d_cache/sg/sg_index.h"
/**
* SGCOORDINDEX
* is a class which maintains a coordinate index list. Users
* must ensure that coordinate indices are specified as
* triplets (triangular faces) since no checking is performed.
* 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 supply each triplet in both
* point orders.
* An object to maintain a coordinate index list.
*
* Users must ensure that coordinate indices are specified as triplets (triangular faces)
* since no checking is performed. 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
* supply each triplet in both point orders.
*/
class SGCOORDINDEX : public SGINDEX
{
@ -48,9 +46,7 @@ public:
virtual ~SGCOORDINDEX();
/**
* Function GatherCoordIndices
* adds all coordinate indices to the given list
* in preparation for a normals calculation
* Add all coordinate indices to the given list in preparation for a normals calculation.
*/
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.
*
* 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
* 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;
if( NULL != aParent && S3D::SGTYPE_FACESET != aParent->GetNodeType() )
if( nullptr != aParent && S3D::SGTYPE_FACESET != aParent->GetNodeType() )
{
m_Parent = NULL;
m_Parent = nullptr;
#ifdef DEBUG
std::ostringstream ostr;
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
wxLogTrace( MASK_3D_SG, "%s:%s:%d * [BUG] inappropriate parent to SGCOORDS (type %s)",
__FILE__, __FUNCTION__, __LINE__, aParent->GetNodeType() );
}
else if( NULL != aParent && S3D::SGTYPE_FACESET == aParent->GetNodeType() )
else if( nullptr != aParent && S3D::SGTYPE_FACESET == aParent->GetNodeType() )
{
m_Parent->AddChildNode( this );
}
return;
}
SGCOORDS::~SGCOORDS()
{
coords.clear();
return;
}
bool SGCOORDS::SetParent( SGNODE* aParent, bool notify )
{
if( NULL != m_Parent )
if( nullptr != m_Parent )
{
if( aParent == m_Parent )
return true;
@ -74,14 +67,14 @@ bool SGCOORDS::SetParent( SGNODE* aParent, bool notify )
if( notify )
m_Parent->unlinkChildNode( this );
m_Parent = NULL;
m_Parent = nullptr;
if( NULL == aParent )
if( nullptr == aParent )
return true;
}
// 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;
m_Parent = aParent;
@ -95,50 +88,31 @@ bool SGCOORDS::SetParent( SGNODE* aParent, bool notify )
SGNODE* SGCOORDS::FindNode(const char *aNodeName, const SGNODE *aCaller) noexcept
{
if( NULL == aNodeName || 0 == aNodeName[0] )
return NULL;
if( nullptr == aNodeName || 0 == aNodeName[0] )
return nullptr;
if( !m_Name.compare( aNodeName ) )
return this;
return NULL;
return nullptr;
}
void SGCOORDS::unlinkChildNode( const SGNODE* aCaller ) noexcept
{
#ifdef DEBUG
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;
wxCHECK( aCaller, /* void */ );
}
void SGCOORDS::unlinkRefNode( const SGNODE* aCaller ) noexcept
{
#ifdef DEBUG
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;
wxCHECK( aCaller, /* void */ );
}
bool SGCOORDS::AddRefNode( SGNODE* aNode ) noexcept
{
#ifdef DEBUG
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
wxCHECK( aNode, false );
return false;
}
@ -146,12 +120,7 @@ bool SGCOORDS::AddRefNode( SGNODE* aNode ) noexcept
bool SGCOORDS::AddChildNode( SGNODE* aNode ) noexcept
{
#ifdef DEBUG
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
wxCHECK( aNode, false );
return false;
}
@ -162,7 +131,7 @@ bool SGCOORDS::GetCoordsList( size_t& aListSize, SGPOINT*& aCoordsList )
if( coords.empty() )
{
aListSize = 0;
aCoordsList = NULL;
aCoordsList = nullptr;
return false;
}
@ -176,27 +145,23 @@ void SGCOORDS::SetCoordsList( size_t aListSize, const SGPOINT* aCoordsList )
{
coords.clear();
if( 0 == aListSize || NULL == aCoordsList )
if( 0 == aListSize || nullptr == aCoordsList )
return;
for( size_t i = 0; i < aListSize; ++i )
coords.push_back( aCoordsList[i] );
return;
}
void SGCOORDS::AddCoord( double aXValue, double aYValue, double aZValue )
{
coords.emplace_back( aXValue, aYValue, aZValue );
return;
}
void SGCOORDS::AddCoord( const SGPOINT& 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 )
{
if( NULL == parentNode )
if( nullptr == parentNode )
{
if( NULL == m_Parent )
{
#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;
}
wxCHECK( m_Parent, false );
SGNODE* np = m_Parent;
while( NULL != np->GetParent() )
while( nullptr != np->GetParent() )
np = np->GetParent();
if( np->WriteCache( aFile, NULL ) )
if( np->WriteCache( aFile, nullptr ) )
{
m_written = true;
return true;
@ -302,26 +257,11 @@ bool SGCOORDS::WriteCache( std::ostream& aFile, SGNODE* parentNode )
return false;
}
if( parentNode != m_Parent )
{
#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;
}
wxCHECK( parentNode == m_Parent, false );
if( !aFile.good() )
{
#ifdef DEBUG
std::ostringstream ostr;
ostr << __FILE__ << ": " << __FUNCTION__ << ": " << __LINE__ << "\n";
ostr << " * [INFO] bad stream";
wxLogTrace( MASK_3D_SG, "%s\n", ostr.str().c_str() );
#endif
wxLogTrace( MASK_3D_SG, "%s:%s:%d * [INFO] bad stream", __FILE__, __FUNCTION__, __LINE__ );
return false;
}
@ -343,20 +283,10 @@ bool SGCOORDS::WriteCache( std::ostream& aFile, SGNODE* parentNode )
bool SGCOORDS::ReadCache( std::istream& aFile, SGNODE* parentNode )
{
if( !coords.empty() )
{
#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;
}
wxCHECK( coords.empty(), false );
size_t npts;
aFile.read( (char*)&npts, sizeof(size_t) );
aFile.read( (char*) &npts, sizeof( size_t ) );
SGPOINT tmp;
if( aFile.fail() )
@ -377,15 +307,15 @@ bool SGCOORDS::ReadCache( std::istream& aFile, SGNODE* parentNode )
bool SGCOORDS::CalcNormals( SGFACESET* callingNode, SGNODE** aPtr )
{
if( aPtr )
*aPtr = NULL;
*aPtr = nullptr;
if( NULL == m_Parent || NULL == callingNode )
if( nullptr == m_Parent || nullptr == callingNode )
return false;
// the parent and all references must have indices; collect all
// indices into one std::vector<>
std::vector< int > ilist;
SGNORMALS* np = NULL;
SGNORMALS* np = nullptr;
if( callingNode == m_Parent )
{
@ -401,7 +331,7 @@ bool SGCOORDS::CalcNormals( SGFACESET* callingNode, SGNODE** aPtr )
++sB;
}
np = ((SGFACESET*)m_Parent)->m_Normals;
np = ( (SGFACESET*) m_Parent )->m_Normals;
if( !np )
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.
*
* 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
* modify it under the terms of the GNU General Public License
@ -23,7 +24,6 @@
/**
* @file sg_coords.h
* defines a vertex coordinate set for a scenegraph object
*/
#ifndef SG_COORDS_H
@ -34,18 +34,18 @@
class SGFACESET;
/**
* Define a vertex coordinate set for a scenegraph object.
*/
class SGCOORDS : public SGNODE
{
public:
std::vector< SGPOINT > coords;
SGCOORDS( SGNODE* aParent );
virtual ~SGCOORDS();
void unlinkChildNode( 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;
SGNODE* FindNode(const char *aNodeName, const SGNODE *aCaller) noexcept override;
@ -58,17 +58,18 @@ public:
void AddCoord( const SGPOINT& aPoint );
/**
* Function CalcNormals
* calculates normals for this coordinate list and sets the
* normals list in the parent SGFACESET
* Calculate normals for this coordinate list and sets the normals list in the
* parent #SGFACESET.
*/
bool CalcNormals( SGFACESET* callingNode, SGNODE** aPtr = NULL );
bool CalcNormals( SGFACESET* callingNode, SGNODE** aPtr = nullptr );
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;
std::vector< SGPOINT > coords;
};
#endif // SG_COORDS_H

View File

@ -2,6 +2,7 @@
* 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) 2020 KiCad Developers, see AUTHORS.txt for contributors.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
@ -33,37 +34,31 @@
#include "3d_cache/sg/sg_coordindex.h"
#include "3d_cache/sg/sg_helpers.h"
SGFACESET::SGFACESET( SGNODE* aParent ) : SGNODE( aParent )
{
m_SGtype = S3D::SGTYPE_FACESET;
m_Colors = NULL;
m_Coords = NULL;
m_CoordIndices = NULL;
m_Normals = NULL;
m_RColors = NULL;
m_RCoords = NULL;
m_RNormals = NULL;
m_Colors = nullptr;
m_Coords = nullptr;
m_CoordIndices = nullptr;
m_Normals = nullptr;
m_RColors = nullptr;
m_RCoords = nullptr;
m_RNormals = nullptr;
valid = 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
std::ostringstream ostr;
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
wxLogTrace( MASK_3D_SG, "%s:%s:%d * [BUG] inappropriate parent to SGFACESET (type %s)",
__FILE__, __FUNCTION__, __LINE__, aParent->GetNodeType() );
}
else if( NULL != aParent && S3D::SGTYPE_SHAPE == aParent->GetNodeType() )
else if( nullptr != aParent && S3D::SGTYPE_SHAPE == aParent->GetNodeType() )
{
m_Parent->AddChildNode( this );
}
return;
}
@ -73,57 +68,55 @@ SGFACESET::~SGFACESET()
if( m_RColors )
{
m_RColors->delNodeRef( this );
m_RColors = NULL;
m_RColors = nullptr;
}
if( m_RCoords )
{
m_RCoords->delNodeRef( this );
m_RCoords = NULL;
m_RCoords = nullptr;
}
if( m_RNormals )
{
m_RNormals->delNodeRef( this );
m_RNormals = NULL;
m_RNormals = nullptr;
}
// delete owned objects
if( m_Colors )
{
m_Colors->SetParent( NULL, false );
m_Colors->SetParent( nullptr, false );
delete m_Colors;
m_Colors = NULL;
m_Colors = nullptr;
}
if( m_Coords )
{
m_Coords->SetParent( NULL, false );
m_Coords->SetParent( nullptr, false );
delete m_Coords;
m_Coords = NULL;
m_Coords = nullptr;
}
if( m_Normals )
{
m_Normals->SetParent( NULL, false );
m_Normals->SetParent( nullptr, false );
delete m_Normals;
m_Normals = NULL;
m_Normals = nullptr;
}
if( m_CoordIndices )
{
m_CoordIndices->SetParent( NULL, false );
m_CoordIndices->SetParent( nullptr, false );
delete m_CoordIndices;
m_CoordIndices = NULL;
m_CoordIndices = nullptr;
}
return;
}
bool SGFACESET::SetParent( SGNODE* aParent, bool notify )
{
if( NULL != m_Parent )
if( nullptr != m_Parent )
{
if( aParent == m_Parent )
return true;
@ -132,14 +125,14 @@ bool SGFACESET::SetParent( SGNODE* aParent, bool notify )
if( notify )
m_Parent->unlinkChildNode( this );
m_Parent = NULL;
m_Parent = nullptr;
if( NULL == aParent )
if( nullptr == aParent )
return true;
}
// 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;
m_Parent = aParent;
@ -153,13 +146,13 @@ bool SGFACESET::SetParent( SGNODE* aParent, bool notify )
SGNODE* SGFACESET::FindNode(const char *aNodeName, const SGNODE *aCaller)
{
if( NULL == aNodeName || 0 == aNodeName[0] )
return NULL;
if( nullptr == aNodeName || 0 == aNodeName[0] )
return nullptr;
if( !m_Name.compare( aNodeName ) )
return this;
SGNODE* np = NULL;
SGNODE* np = nullptr;
if( m_Colors )
{
@ -194,8 +187,8 @@ SGNODE* SGFACESET::FindNode(const char *aNodeName, const SGNODE *aCaller)
}
// query the parent if appropriate
if( aCaller == m_Parent || NULL == m_Parent )
return NULL;
if( aCaller == m_Parent || nullptr == m_Parent )
return nullptr;
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 )
{
if( NULL == aNode )
if( nullptr == aNode )
return;
valid = false;
@ -213,25 +206,25 @@ void SGFACESET::unlinkNode( const SGNODE* aNode, bool isChild )
{
if( aNode == m_Colors )
{
m_Colors = NULL;
m_Colors = nullptr;
return;
}
if( aNode == m_Coords )
{
m_Coords = NULL;
m_Coords = nullptr;
return;
}
if( aNode == m_Normals )
{
m_Normals = NULL;
m_Normals = nullptr;
return;
}
if( aNode == m_CoordIndices )
{
m_CoordIndices = NULL;
m_CoordIndices = nullptr;
return;
}
}
@ -240,66 +233,46 @@ void SGFACESET::unlinkNode( const SGNODE* aNode, bool isChild )
if( aNode == m_RColors )
{
delNodeRef( this );
m_RColors = NULL;
m_RColors = nullptr;
return;
}
if( aNode == m_RCoords )
{
delNodeRef( this );
m_RCoords = NULL;
m_RCoords = nullptr;
return;
}
if( aNode == m_RNormals )
{
delNodeRef( this );
m_RNormals = NULL;
m_RNormals = nullptr;
return;
}
}
#ifdef DEBUG
do {
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;
wxLogTrace( MASK_3D_SG, "%s:%s:%d * [BUG] unlinkNode() did not find its target",
__FILE__, __FUNCTION__, __LINE__ );
}
void SGFACESET::unlinkChildNode( const SGNODE* aNode )
{
unlinkNode( aNode, true );
return;
}
void SGFACESET::unlinkRefNode( const SGNODE* aNode )
{
unlinkNode( aNode, false );
return;
}
bool SGFACESET::addNode( SGNODE* aNode, bool isChild )
{
if( NULL == aNode )
{
#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;
}
wxCHECK( aNode, false );
valid = false;
validated = false;
@ -310,12 +283,8 @@ bool SGFACESET::addNode( SGNODE* aNode, bool isChild )
{
if( aNode != m_Colors && aNode != m_RColors )
{
#ifdef DEBUG
std::ostringstream ostr;
ostr << __FILE__ << ": " << __FUNCTION__ << ": " << __LINE__ << "\n";
ostr << " * [BUG] assigning multiple Colors nodes";
wxLogTrace( MASK_3D_SG, "%s\n", ostr.str().c_str() );
#endif
wxLogTrace( MASK_3D_SG, "%s:%s:%d * [BUG] assigning multiple Colors nodes",
__FILE__, __FUNCTION__, __LINE__ );
return false;
}
@ -343,12 +312,8 @@ bool SGFACESET::addNode( SGNODE* aNode, bool isChild )
{
if( aNode != m_Coords && aNode != m_RCoords )
{
#ifdef DEBUG
std::ostringstream ostr;
ostr << __FILE__ << ": " << __FUNCTION__ << ": " << __LINE__ << "\n";
ostr << " * [BUG] assigning multiple Coords nodes";
wxLogTrace( MASK_3D_SG, "%s\n", ostr.str().c_str() );
#endif
wxLogTrace( MASK_3D_SG, "%s:%s:%d * [BUG] assigning multiple Colors nodes",
__FILE__, __FUNCTION__, __LINE__ );
return false;
}
@ -376,12 +341,8 @@ bool SGFACESET::addNode( SGNODE* aNode, bool isChild )
{
if( aNode != m_Normals && aNode != m_RNormals )
{
#ifdef DEBUG
std::ostringstream ostr;
ostr << __FILE__ << ": " << __FUNCTION__ << ": " << __LINE__ << "\n";
ostr << " * [BUG] assigning multiple Normals nodes";
wxLogTrace( MASK_3D_SG, "%s\n", ostr.str().c_str() );
#endif
wxLogTrace( MASK_3D_SG, "%s:%s:%d * [BUG] assigning multiple Normals nodes",
__FILE__, __FUNCTION__, __LINE__ );
return false;
}
@ -409,12 +370,8 @@ bool SGFACESET::addNode( SGNODE* aNode, bool isChild )
{
if( aNode != m_CoordIndices )
{
#ifdef DEBUG
std::ostringstream ostr;
ostr << __FILE__ << ": " << __FUNCTION__ << ": " << __LINE__ << "\n";
ostr << " * [BUG] assigning multiple CoordIndex nodes";
wxLogTrace( MASK_3D_SG, "%s\n", ostr.str().c_str() );
#endif
wxLogTrace( MASK_3D_SG, "%s:%s:%d * [BUG] assigning multiple CoordIndex nodes",
__FILE__, __FUNCTION__, __LINE__ );
return false;
}
@ -428,16 +385,9 @@ bool SGFACESET::addNode( SGNODE* aNode, bool isChild )
return true;
}
#ifdef DEBUG
do {
std::ostringstream ostr;
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
wxLogTrace( MASK_3D_SG, "%s:%s:%d * [BUG] object type '%s' is not a valid type for "
"this object '%d'", __FILE__, __FUNCTION__, __LINE__, aNode->GetName(),
aNode->GetNodeType() );
return false;
}
@ -477,15 +427,12 @@ void SGFACESET::ReNameNodes( void )
// rename all Normals and Indices
if( m_Normals )
m_Normals->ReNameNodes();
return;
}
bool SGFACESET::WriteVRML( std::ostream& aFile, bool aReuseFlag )
{
if( ( NULL == m_Coords && NULL == m_RCoords )
|| ( NULL == m_CoordIndices ) )
if( ( nullptr == m_Coords && nullptr == m_RCoords ) || ( nullptr == m_CoordIndices ) )
{
return false;
}
@ -540,26 +487,16 @@ bool SGFACESET::WriteVRML( std::ostream& aFile, bool aReuseFlag )
bool SGFACESET::WriteCache( std::ostream& aFile, SGNODE* parentNode )
{
if( NULL == parentNode )
if( nullptr == parentNode )
{
if( NULL == m_Parent )
{
#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;
}
wxCHECK( m_Parent, false );
SGNODE* np = m_Parent;
while( NULL != np->GetParent() )
while( nullptr != np->GetParent() )
np = np->GetParent();
if( np->WriteCache( aFile, NULL ) )
if( np->WriteCache( aFile, nullptr ) )
{
m_written = true;
return true;
@ -568,38 +505,23 @@ bool SGFACESET::WriteCache( std::ostream& aFile, SGNODE* parentNode )
return false;
}
if( parentNode != m_Parent )
{
#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;
}
wxCHECK( parentNode == m_Parent, false );
if( !aFile.good() )
{
#ifdef DEBUG
std::ostringstream ostr;
ostr << __FILE__ << ": " << __FUNCTION__ << ": " << __LINE__ << "\n";
ostr << " * [INFO] bad stream";
wxLogTrace( MASK_3D_SG, "%s\n", ostr.str().c_str() );
#endif
wxLogTrace( MASK_3D_SG, "%s:%s:%d * [INFO] bad stream", __FILE__, __FUNCTION__, __LINE__ );
return false;
}
// 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 );
if( NULL != m_RNormals && !m_RNormals->isWritten() )
if( nullptr != m_RNormals && !m_RNormals->isWritten() )
m_RNormals->SwapParent( this );
if( NULL != m_RColors && !m_RColors->isWritten() )
if( nullptr != m_RColors && !m_RColors->isWritten() )
m_RColors->SwapParent( this );
aFile << "[" << GetName() << "]";
@ -611,35 +533,35 @@ bool SGFACESET::WriteCache( std::ostream& aFile, SGNODE* parentNode )
items[i] = 0;
i = 0;
if( NULL != m_Coords )
if( nullptr != m_Coords )
items[i] = true;
++i;
if( NULL != m_RCoords )
if( nullptr != m_RCoords )
items[i] = true;
++i;
if( NULL != m_CoordIndices )
if( nullptr != m_CoordIndices )
items[i] = true;
++i;
if( NULL != m_Normals )
if( nullptr != m_Normals )
items[i] = true;
++i;
if( NULL != m_RNormals )
if( nullptr != m_RNormals )
items[i] = true;
++i;
if( NULL != m_Colors )
if( nullptr != m_Colors )
items[i] = true;
++i;
if( NULL != m_RColors )
if( nullptr != m_RColors )
items[i] = true;
for( int jj = 0; jj < NITEMS; ++jj )
aFile.write( (char*)&items[jj], sizeof(bool) );
aFile.write( (char*) &items[jj], sizeof( bool ) );
if( items[0] )
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 )
{
if( m_Coords || m_RCoords || m_CoordIndices
|| m_Colors || m_RColors
|| m_Normals || m_RNormals )
if( m_Coords || m_RCoords || m_CoordIndices || m_Colors || m_RColors || m_Normals
|| m_RNormals )
{
#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
wxLogTrace( MASK_3D_SG, "%s:%s:%d * [BUG] non-empty node",
__FILE__, __FUNCTION__, __LINE__ );
return false;
}
@ -690,18 +607,13 @@ bool SGFACESET::ReadCache( std::istream& aFile, SGNODE* parentNode )
bool items[NITEMS];
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] )
|| ( items[5] && items[6] ) )
if( ( items[0] && items[1] ) || ( items[3] && items[4] ) || ( items[5] && items[6] ) )
{
#ifdef DEBUG
std::ostringstream ostr;
ostr << __FILE__ << ": " << __FUNCTION__ << ": " << __LINE__ << "\n";
ostr << " * [INFO] corrupt data; multiple item definitions at position ";
ostr << aFile.tellg();
wxLogTrace( MASK_3D_SG, "%s\n", ostr.str().c_str() );
#endif
wxLogTrace( MASK_3D_SG,
"%s:%s:%d * [INFO] corrupt data; multiple item definitions at position %d",
__FILE__, __FUNCTION__, __LINE__, static_cast<int>( aFile.tellg() ) );
return false;
}
@ -712,13 +624,9 @@ bool SGFACESET::ReadCache( std::istream& aFile, SGNODE* parentNode )
{
if( S3D::SGTYPE_COORDS != S3D::ReadTag( aFile, name ) )
{
#ifdef DEBUG
std::ostringstream ostr;
ostr << __FILE__ << ": " << __FUNCTION__ << ": " << __LINE__ << "\n";
ostr << " * [INFO] corrupt data; bad child coords tag at position ";
ostr << aFile.tellg();
wxLogTrace( MASK_3D_SG, "%s\n", ostr.str().c_str() );
#endif
wxLogTrace( MASK_3D_SG,
"%s:%s:%d * [INFO] corrupt data; bad child coords tag at position %d",
__FILE__, __FUNCTION__, __LINE__, static_cast<int>( aFile.tellg() ) );
return false;
}
@ -728,13 +636,9 @@ bool SGFACESET::ReadCache( std::istream& aFile, SGNODE* parentNode )
if( !m_Coords->ReadCache( aFile, this ) )
{
#ifdef DEBUG
std::ostringstream ostr;
ostr << __FILE__ << ": " << __FUNCTION__ << ": " << __LINE__ << "\n";
ostr << " * [INFO] corrupt data while reading coords '";
ostr << name << "'";
wxLogTrace( MASK_3D_SG, "%s\n", ostr.str().c_str() );
#endif
wxLogTrace( MASK_3D_SG,
"%s:%s:%d * [INFO] corrupt data; corrupt data while reading coords '%s'",
__FILE__, __FUNCTION__, __LINE__, name );
return false;
}
@ -744,13 +648,9 @@ bool SGFACESET::ReadCache( std::istream& aFile, SGNODE* parentNode )
{
if( S3D::SGTYPE_COORDS != S3D::ReadTag( aFile, name ) )
{
#ifdef DEBUG
std::ostringstream ostr;
ostr << __FILE__ << ": " << __FUNCTION__ << ": " << __LINE__ << "\n";
ostr << " * [INFO] corrupt data; bad ref coords tag at position ";
ostr << aFile.tellg();
wxLogTrace( MASK_3D_SG, "%s\n", ostr.str().c_str() );
#endif
wxLogTrace( MASK_3D_SG,
"%s:%s:%d * [INFO] corrupt data; bad ref coords tag at position %d",
__FILE__, __FUNCTION__, __LINE__, static_cast<int>( aFile.tellg() ) );
return false;
}
@ -759,26 +659,18 @@ bool SGFACESET::ReadCache( std::istream& aFile, SGNODE* parentNode )
if( !np )
{
#ifdef DEBUG
std::ostringstream ostr;
ostr << __FILE__ << ": " << __FUNCTION__ << ": " << __LINE__ << "\n";
ostr << " * [INFO] corrupt data: cannot find ref coords '";
ostr << name << "'";
wxLogTrace( MASK_3D_SG, "%s\n", ostr.str().c_str() );
#endif
wxLogTrace( MASK_3D_SG,
"%s:%s:%d * [INFO] corrupt data; cannot find ref coords '%s'",
__FILE__, __FUNCTION__, __LINE__, name );
return false;
}
if( S3D::SGTYPE_COORDS != np->GetNodeType() )
{
#ifdef DEBUG
std::ostringstream ostr;
ostr << __FILE__ << ": " << __FUNCTION__ << ": " << __LINE__ << "\n";
ostr << " * [INFO] corrupt data: type is not SGCOORDS '";
ostr << name << "'";
wxLogTrace( MASK_3D_SG, "%s\n", ostr.str().c_str() );
#endif
wxLogTrace( MASK_3D_SG,
"%s:%s:%d * [INFO] corrupt data; type is not SGCOORDS '%s'",
__FILE__, __FUNCTION__, __LINE__, name );
return false;
}
@ -791,13 +683,9 @@ bool SGFACESET::ReadCache( std::istream& aFile, SGNODE* parentNode )
{
if( S3D::SGTYPE_COORDINDEX != S3D::ReadTag( aFile, name ) )
{
#ifdef DEBUG
std::ostringstream ostr;
ostr << __FILE__ << ": " << __FUNCTION__ << ": " << __LINE__ << "\n";
ostr << " * [INFO] corrupt data; bad coord index tag at position ";
ostr << aFile.tellg();
wxLogTrace( MASK_3D_SG, "%s\n", ostr.str().c_str() );
#endif
wxLogTrace( MASK_3D_SG,
"%s:%s:%d * [INFO] corrupt data; bad coord index tag at position %d",
__FILE__, __FUNCTION__, __LINE__, static_cast<int>( aFile.tellg() ) );
return false;
}
@ -807,13 +695,9 @@ bool SGFACESET::ReadCache( std::istream& aFile, SGNODE* parentNode )
if( !m_CoordIndices->ReadCache( aFile, this ) )
{
#ifdef DEBUG
std::ostringstream ostr;
ostr << __FILE__ << ": " << __FUNCTION__ << ": " << __LINE__ << "\n";
ostr << " * [INFO] corrupt data while reading coord index '";
ostr << name << "'";
wxLogTrace( MASK_3D_SG, "%s\n", ostr.str().c_str() );
#endif
wxLogTrace( MASK_3D_SG,
"%s:%s:%d * [INFO] corrupt data while reading coord index '%s'",
__FILE__, __FUNCTION__, __LINE__, name );
return false;
}
@ -823,13 +707,9 @@ bool SGFACESET::ReadCache( std::istream& aFile, SGNODE* parentNode )
{
if( S3D::SGTYPE_NORMALS != S3D::ReadTag( aFile, name ) )
{
#ifdef DEBUG
std::ostringstream ostr;
ostr << __FILE__ << ": " << __FUNCTION__ << ": " << __LINE__ << "\n";
ostr << " * [INFO] corrupt data; bad child normals tag at position ";
ostr << aFile.tellg();
wxLogTrace( MASK_3D_SG, "%s\n", ostr.str().c_str() );
#endif
wxLogTrace( MASK_3D_SG,
"%s:%s:%d * [INFO] corrupt data; bad child normals tag at position %d",
__FILE__, __FUNCTION__, __LINE__, static_cast<int>( aFile.tellg() ) );
return false;
}
@ -839,13 +719,9 @@ bool SGFACESET::ReadCache( std::istream& aFile, SGNODE* parentNode )
if( !m_Normals->ReadCache( aFile, this ) )
{
#ifdef DEBUG
std::ostringstream ostr;
ostr << __FILE__ << ": " << __FUNCTION__ << ": " << __LINE__ << "\n";
ostr << " * [INFO] corrupt data while reading normals '";
ostr << name << "'";
wxLogTrace( MASK_3D_SG, "%s\n", ostr.str().c_str() );
#endif
wxLogTrace( MASK_3D_SG,
"%s:%s:%d * [INFO] corrupt data while reading normals '%s'",
__FILE__, __FUNCTION__, __LINE__, name );
return false;
}
@ -855,13 +731,9 @@ bool SGFACESET::ReadCache( std::istream& aFile, SGNODE* parentNode )
{
if( S3D::SGTYPE_NORMALS != S3D::ReadTag( aFile, name ) )
{
#ifdef DEBUG
std::ostringstream ostr;
ostr << __FILE__ << ": " << __FUNCTION__ << ": " << __LINE__ << "\n";
ostr << " * [INFO] corrupt data; bad ref normals tag at position ";
ostr << aFile.tellg();
wxLogTrace( MASK_3D_SG, "%s\n", ostr.str().c_str() );
#endif
wxLogTrace( MASK_3D_SG,
"%s:%s:%d * [INFO] corrupt data; bad ref normals tag at position %d",
__FILE__, __FUNCTION__, __LINE__, static_cast<int>( aFile.tellg() ) );
return false;
}
@ -870,26 +742,18 @@ bool SGFACESET::ReadCache( std::istream& aFile, SGNODE* parentNode )
if( !np )
{
#ifdef DEBUG
std::ostringstream ostr;
ostr << __FILE__ << ": " << __FUNCTION__ << ": " << __LINE__ << "\n";
ostr << " * [INFO] corrupt data: cannot find ref normals '";
ostr << name << "'";
wxLogTrace( MASK_3D_SG, "%s\n", ostr.str().c_str() );
#endif
wxLogTrace( MASK_3D_SG,
"%s:%s:%d * [INFO] corrupt: cannot find ref normals '%s'",
__FILE__, __FUNCTION__, __LINE__, name );
return false;
}
if( S3D::SGTYPE_NORMALS != np->GetNodeType() )
{
#ifdef DEBUG
std::ostringstream ostr;
ostr << __FILE__ << ": " << __FUNCTION__ << ": " << __LINE__ << "\n";
ostr << " * [INFO] corrupt data: type is not SGNORMALS '";
ostr << name << "'";
wxLogTrace( MASK_3D_SG, "%s\n", ostr.str().c_str() );
#endif
wxLogTrace( MASK_3D_SG,
"%s:%s:%d * [INFO] corrupt: type is not SGNORMALS '%s'",
__FILE__, __FUNCTION__, __LINE__, name );
return false;
}
@ -902,13 +766,9 @@ bool SGFACESET::ReadCache( std::istream& aFile, SGNODE* parentNode )
{
if( S3D::SGTYPE_COLORS != S3D::ReadTag( aFile, name ) )
{
#ifdef DEBUG
std::ostringstream ostr;
ostr << __FILE__ << ": " << __FUNCTION__ << ": " << __LINE__ << "\n";
ostr << " * [INFO] corrupt data; bad child colors tag at position ";
ostr << aFile.tellg();
wxLogTrace( MASK_3D_SG, "%s\n", ostr.str().c_str() );
#endif
wxLogTrace( MASK_3D_SG,
"%s:%s:%d * [INFO] corrupt data; bad child colors tag at position %d",
__FILE__, __FUNCTION__, __LINE__, static_cast<int>( aFile.tellg() ) );
return false;
}
@ -918,13 +778,9 @@ bool SGFACESET::ReadCache( std::istream& aFile, SGNODE* parentNode )
if( !m_Colors->ReadCache( aFile, this ) )
{
#ifdef DEBUG
std::ostringstream ostr;
ostr << __FILE__ << ": " << __FUNCTION__ << ": " << __LINE__ << "\n";
ostr << " * [INFO] corrupt data while reading colors '";
ostr << name << "'";
wxLogTrace( MASK_3D_SG, "%s\n", ostr.str().c_str() );
#endif
wxLogTrace( MASK_3D_SG,
"%s:%s:%d * [INFO] corrupt data while reading colors '%s'",
__FILE__, __FUNCTION__, __LINE__, name );
return false;
}
@ -934,13 +790,9 @@ bool SGFACESET::ReadCache( std::istream& aFile, SGNODE* parentNode )
{
if( S3D::SGTYPE_COLORS != S3D::ReadTag( aFile, name ) )
{
#ifdef DEBUG
std::ostringstream ostr;
ostr << __FILE__ << ": " << __FUNCTION__ << ": " << __LINE__ << "\n";
ostr << " * [INFO] corrupt data; bad ref colors tag at position ";
ostr << aFile.tellg();
wxLogTrace( MASK_3D_SG, "%s\n", ostr.str().c_str() );
#endif
wxLogTrace( MASK_3D_SG,
"%s:%s:%d * [INFO] corrupt data; bad ref colors tag at position %d",
__FILE__, __FUNCTION__, __LINE__, static_cast<int>( aFile.tellg() ) );
return false;
}
@ -949,26 +801,18 @@ bool SGFACESET::ReadCache( std::istream& aFile, SGNODE* parentNode )
if( !np )
{
#ifdef DEBUG
std::ostringstream ostr;
ostr << __FILE__ << ": " << __FUNCTION__ << ": " << __LINE__ << "\n";
ostr << " * [INFO] corrupt data: cannot find ref colors '";
ostr << name << "'";
wxLogTrace( MASK_3D_SG, "%s\n", ostr.str().c_str() );
#endif
wxLogTrace( MASK_3D_SG,
"%s:%s:%d * [INFO] corrupt data: cannot find ref colors '%s'",
__FILE__, __FUNCTION__, __LINE__, name );
return false;
}
if( S3D::SGTYPE_COLORS != np->GetNodeType() )
{
#ifdef DEBUG
std::ostringstream ostr;
ostr << __FILE__ << ": " << __FUNCTION__ << ": " << __LINE__ << "\n";
ostr << " * [INFO] corrupt data: type is not SGCOLORS '";
ostr << name << "'";
wxLogTrace( MASK_3D_SG, "%s\n", ostr.str().c_str() );
#endif
wxLogTrace( MASK_3D_SG,
"%s:%s:%d * [INFO] corrupt data: type is not SGCOLORS '%s'",
__FILE__, __FUNCTION__, __LINE__, name );
return false;
}
@ -991,16 +835,14 @@ bool SGFACESET::validate( void )
return valid;
// ensure we have at least coordinates and their normals
if( (NULL == m_Coords && NULL == m_RCoords)
|| (NULL == m_Normals && NULL == m_RNormals)
|| (NULL == m_CoordIndices) )
if( ( nullptr == m_Coords && nullptr == m_RCoords )
|| ( nullptr == m_Normals && nullptr == m_RNormals )
|| ( nullptr == m_CoordIndices ) )
{
#ifdef DEBUG
std::ostringstream ostr;
ostr << __FILE__ << ": " << __FUNCTION__ << ": " << __LINE__ << "\n";
ostr << " * [INFO] bad model; no vertices, vertex indices, or normals";
wxLogTrace( MASK_3D_SG, "%s\n", ostr.str().c_str() );
#endif
wxLogTrace( MASK_3D_SG,
"%s:%s:%d * [INFO] bad model; no vertices, vertex indices, or normals",
__FILE__, __FUNCTION__, __LINE__ );
validated = true;
valid = false;
return false;
@ -1009,21 +851,18 @@ bool SGFACESET::validate( void )
// check that there are >3 vertices
SGCOORDS* coords = m_Coords;
if( NULL == coords )
if( nullptr == coords )
coords = m_RCoords;
size_t nCoords = 0;
SGPOINT* lCoords = NULL;
SGPOINT* lCoords = nullptr;
coords->GetCoordsList( nCoords, lCoords );
if( nCoords < 3 )
{
#ifdef DEBUG
std::ostringstream ostr;
ostr << __FILE__ << ": " << __FUNCTION__ << ": " << __LINE__ << "\n";
ostr << " * [INFO] bad model; fewer than 3 vertices";
wxLogTrace( MASK_3D_SG, "%s\n", ostr.str().c_str() );
#endif
wxLogTrace( MASK_3D_SG, "%s:%s:%d * [INFO] bad model; fewer than 3 vertices",
__FILE__, __FUNCTION__, __LINE__ );
validated = true;
valid = false;
return false;
@ -1031,17 +870,15 @@ bool SGFACESET::validate( void )
// check that nVertices is divisible by 3 (facets are triangles)
size_t nCIdx = 0;
int* lCIdx = NULL;
int* lCIdx = nullptr;
m_CoordIndices->GetIndices( nCIdx, lCIdx );
if( nCIdx < 3 || ( nCIdx % 3 > 0 ) )
{
#ifdef DEBUG
std::ostringstream ostr;
ostr << __FILE__ << ": " << __FUNCTION__ << ": " << __LINE__ << "\n";
ostr << " * [INFO] bad model; no vertex indices or not multiple of 3";
wxLogTrace( MASK_3D_SG, "%s\n", ostr.str().c_str() );
#endif
wxLogTrace( MASK_3D_SG,
"%s:%s:%d * [INFO] bad model; no vertex indices or not multiple of 3",
__FILE__, __FUNCTION__, __LINE__ );
validated = true;
valid = false;
return false;
@ -1052,12 +889,9 @@ bool SGFACESET::validate( void )
{
if( lCIdx[i] < 0 || lCIdx[i] >= (int)nCoords )
{
#ifdef DEBUG
std::ostringstream ostr;
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
wxLogTrace( MASK_3D_SG, "%s:%s:%d * [INFO] bad model; vertex index out of bounds",
__FILE__, __FUNCTION__, __LINE__ );
validated = true;
valid = false;
return false;
@ -1066,23 +900,21 @@ bool SGFACESET::validate( void )
// check that there are as many normals as vertices
size_t nNorms = 0;
SGVECTOR* lNorms = NULL;
SGVECTOR* lNorms = nullptr;
SGNORMALS* pNorms = m_Normals;
if( NULL == pNorms )
if( nullptr == pNorms )
pNorms = m_RNormals;
pNorms->GetNormalList( nNorms, lNorms );
if( nNorms != nCoords )
{
#ifdef DEBUG
std::ostringstream ostr;
ostr << __FILE__ << ": " << __FUNCTION__ << ": " << __LINE__ << "\n";
ostr << " * [INFO] bad model; number of normals (" << nNorms;
ostr << ") does not match number of vertices (" << nCoords << ")";
wxLogTrace( MASK_3D_SG, "%s\n", ostr.str().c_str() );
#endif
wxLogTrace( MASK_3D_SG,
"%s:%s:%d * [INFO] bad model; number of normals (%ul) does not match "
"number of vertices (%ul)", __FILE__, __FUNCTION__, __LINE__,
static_cast<unsigned long>( nNorms ), static_cast<unsigned long>( nCoords ) );
validated = true;
valid = false;
return false;
@ -1091,14 +923,14 @@ bool SGFACESET::validate( void )
// if there are colors then ensure there are as many colors as vertices
SGCOLORS* pColors = m_Colors;
if( NULL == pColors )
if( nullptr == pColors )
pColors = m_RColors;
if( NULL != pColors )
if( nullptr != pColors )
{
// we must have at least as many colors as vertices
size_t nColor = 0;
SGCOLOR* pColor = NULL;
SGCOLOR* pColor = nullptr;
pColors->GetColorList( nColor, pColor );
}
@ -1112,8 +944,6 @@ void SGFACESET::GatherCoordIndices( std::vector< int >& aIndexList )
{
if( m_CoordIndices )
m_CoordIndices->GatherCoordIndices( aIndexList );
return;
}
@ -1124,7 +954,7 @@ bool SGFACESET::CalcNormals( SGNODE** aPtr )
if( m_RCoords )
coords = m_RCoords;
if( NULL == coords || coords->coords.empty() )
if( nullptr == coords || coords->coords.empty() )
return false;
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.
*
* 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
* modify it under the terms of the GNU General Public License
@ -23,7 +24,6 @@
/**
* @file sg_faceset.h
* defines an indexed face set for a scenegraph
*/
@ -40,38 +40,18 @@ class SGNORMALS;
class SGCOLORINDEX;
class SGCOORDINDEX;
/**
* Define an indexed face set for a scenegraph.
*/
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:
SGFACESET( SGNODE* aParent );
virtual ~SGFACESET();
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 AddChildNode( SGNODE* aNode ) override;
@ -84,11 +64,34 @@ public:
bool ReadCache( std::istream& aFile, SGNODE* parentNode ) override;
/**
* Function GatherCoordIndices
* adds all internal coordinate indices to the given list
* in preparation for a normals calculation
* Add all internal coordinate indices to the given list in preparation for a normals
* calculation.
*/
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.
*
* 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
* modify it under the terms of the GNU General Public License
@ -33,7 +34,6 @@
#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 )
{
if( value < 1e-8 && value > -1e-8 )
@ -52,7 +52,6 @@ void S3D::FormatFloat( std::string& result, double value )
size_t p = result.find( '.' );
// trim trailing 0 if appropriate
if( std::string::npos == p )
return;
@ -60,28 +59,26 @@ void S3D::FormatFloat( std::string& result, double value )
if( std::string::npos == p )
{
while( '0' == *(result.rbegin()) )
while( '0' == *( result.rbegin() ) )
result.erase( result.size() - 1 );
return;
}
if( '0' != result.at( p -1 ) )
if( '0' != result.at( p - 1 ) )
return;
// trim all 0 to the left of 'p'
std::string tmp = result.substr( p );
result = result.substr( 0, p );
while( '0' == *(result.rbegin()) )
while( '0' == *( result.rbegin() ) )
result.erase( result.size() - 1 );
result.append( tmp );
return;
}
// format orientation data for VRML output
void S3D::FormatOrientation( std::string& result, const SGVECTOR& axis, double rotation )
{
double aX;
@ -100,11 +97,9 @@ void S3D::FormatOrientation( std::string& result, const SGVECTOR& axis, double r
FormatFloat( tmp, rotation );
result.append( " " );
result.append( tmp );
return;
}
// format point data for VRML output
void S3D::FormatPoint( std::string& result, const SGPOINT& point )
{
FormatFloat( result, point.x );
@ -117,12 +112,9 @@ void S3D::FormatPoint( std::string& result, const SGPOINT& point )
FormatFloat( tmp, point.z );
result.append( " " );
result.append( tmp );
return;
}
// format vector data for VRML output
void S3D::FormatVector( std::string& result, const SGVECTOR& aVector )
{
double X, Y, Z;
@ -137,12 +129,9 @@ void S3D::FormatVector( std::string& result, const SGVECTOR& aVector )
FormatFloat( tmp, Z );
result.append( " " );
result.append( tmp );
return;
}
// format Color data for VRML output
void S3D::FormatColor( std::string& result, const SGCOLOR& aColor )
{
float R, G, B;
@ -157,16 +146,14 @@ void S3D::FormatColor( std::string& result, const SGCOLOR& aColor )
FormatFloat( tmp, B );
result.append( " " );
result.append( tmp );
return;
}
bool S3D::WritePoint( std::ostream& aFile, const SGPOINT& aPoint )
{
aFile.write( (char*)&aPoint.x, sizeof(aPoint.x) );
aFile.write( (char*)&aPoint.y, sizeof(aPoint.y) );
aFile.write( (char*)&aPoint.z, sizeof(aPoint.z) );
aFile.write( (char*) &aPoint.x, sizeof( aPoint.x ) );
aFile.write( (char*) &aPoint.y, sizeof( aPoint.y ) );
aFile.write( (char*) &aPoint.z, sizeof( aPoint.z ) );
if( aFile.fail() )
return false;
@ -179,9 +166,9 @@ bool S3D::WriteVector( std::ostream& aFile, const SGVECTOR& aVector )
{
double x, y, z;
aVector.GetVector( x, y, z );
aFile.write( (char*)&x, sizeof(double) );
aFile.write( (char*)&y, sizeof(double) );
aFile.write( (char*)&z, sizeof(double) );
aFile.write( (char*) &x, sizeof( double ) );
aFile.write( (char*) &y, sizeof( double ) );
aFile.write( (char*) &z, sizeof( double ) );
if( aFile.fail() )
return false;
@ -194,9 +181,9 @@ bool S3D::WriteColor( std::ostream& aFile, const SGCOLOR& aColor )
{
float r, g, b;
aColor.GetColor( r, g, b );
aFile.write( (char*)&r, sizeof(float) );
aFile.write( (char*)&g, sizeof(float) );
aFile.write( (char*)&b, sizeof(float) );
aFile.write( (char*) &r, sizeof( float ) );
aFile.write( (char*) &g, sizeof( float ) );
aFile.write( (char*) &b, sizeof( float ) );
if( aFile.fail() )
return false;
@ -212,13 +199,9 @@ S3D::SGTYPES S3D::ReadTag( std::istream& aFile, std::string& aName )
if( '[' != schar )
{
#ifdef DEBUG
std::ostringstream ostr;
ostr << __FILE__ << ": " << __FUNCTION__ << ": " << __LINE__ << "\n";
ostr << " * [INFO] corrupt data; missing left bracket at position ";
ostr << aFile.tellg();
wxLogTrace( MASK_3D_SG, "%s\n", ostr.str().c_str() );
#endif
wxLogTrace( MASK_3D_SG,
"%s:%s:%d * [INFO] corrupt data; missing left bracket at position %d",
__FILE__, __FUNCTION__, __LINE__, static_cast<int>( aFile.tellg() ) );
return S3D::SGTYPE_END;
}
@ -234,12 +217,9 @@ S3D::SGTYPES S3D::ReadTag( std::istream& aFile, std::string& aName )
if( schar != ']' )
{
#ifdef DEBUG
std::ostringstream ostr;
ostr << __FILE__ << ": " << __FUNCTION__ << ": " << __LINE__ << "\n";
ostr << " * [INFO] corrupt data; could not find right bracket";
wxLogTrace( MASK_3D_SG, "%s\n", ostr.str().c_str() );
#endif
wxLogTrace( MASK_3D_SG,
"%s:%s:%d * [INFO] corrupt data; could not find right bracket",
__FILE__, __FUNCTION__, __LINE__ );
return S3D::SGTYPE_END;
}
@ -249,13 +229,9 @@ S3D::SGTYPES S3D::ReadTag( std::istream& aFile, std::string& aName )
if( std::string::npos == upos )
{
#ifdef DEBUG
std::ostringstream ostr;
ostr << __FILE__ << ": " << __FUNCTION__ << ": " << __LINE__ << "\n";
ostr << " * [INFO] corrupt data; no underscore in name '";
ostr << name << "'";
wxLogTrace( MASK_3D_SG, "%s\n", ostr.str().c_str() );
#endif
wxLogTrace( MASK_3D_SG,
"%s:%s:%d * [INFO] corrupt data; no underscore in name '%s'",
__FILE__, __FUNCTION__, __LINE__, name );
return S3D::SGTYPE_END;
}
@ -279,15 +255,9 @@ S3D::SGTYPES S3D::ReadTag( std::istream& aFile, std::string& aName )
return types[i];
}
#ifdef DEBUG
do {
std::ostringstream ostr;
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
wxLogTrace( MASK_3D_SG,
"%s:%s:%d * [INFO] corrupt data; no node type matching '%s'",
__FILE__, __FUNCTION__, __LINE__, name );
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 )
{
aFile.read( (char*)&aPoint.x, sizeof( aPoint.x ) );
aFile.read( (char*)&aPoint.y, sizeof( aPoint.y ) );
aFile.read( (char*)&aPoint.z, sizeof( aPoint.z ) );
aFile.read( (char*) &aPoint.x, sizeof( aPoint.x ) );
aFile.read( (char*) &aPoint.y, sizeof( aPoint.y ) );
aFile.read( (char*) &aPoint.z, sizeof( aPoint.z ) );
if( aFile.fail() )
return false;
@ -309,9 +279,9 @@ bool S3D::ReadPoint( std::istream& aFile, SGPOINT& aPoint )
bool S3D::ReadVector( std::istream& aFile, SGVECTOR& aVector )
{
double x, y, z;
aFile.read( (char*)&x, sizeof(double) );
aFile.read( (char*)&y, sizeof(double) );
aFile.read( (char*)&z, sizeof(double) );
aFile.read( (char*) &x, sizeof( double ) );
aFile.read( (char*) &y, sizeof( double ) );
aFile.read( (char*) &z, sizeof( double ) );
aVector.SetVector( x, y, z );
if( aFile.fail() )
@ -324,9 +294,9 @@ bool S3D::ReadVector( std::istream& aFile, SGVECTOR& aVector )
bool S3D::ReadColor( std::istream& aFile, SGCOLOR& aColor )
{
float r, g, b;
aFile.read( (char*)&r, sizeof(float) );
aFile.read( (char*)&g, sizeof(float) );
aFile.read( (char*)&b, sizeof(float) );
aFile.read( (char*) &r, sizeof( float ) );
aFile.read( (char*) &g, sizeof( float ) );
aFile.read( (char*) &b, sizeof( float ) );
aColor.SetColor( r, g, b );
if( aFile.fail() )
@ -376,24 +346,19 @@ static void calcTriad( glm::dvec3* pts, glm::dvec3& tri )
// normal * 2 * area
tri = glm::cross( pts[1] - pts[0], pts[2] - pts[0] );
return;
}
bool S3D::CalcTriangleNormals( std::vector< SGPOINT > coords,
std::vector< int >& index, std::vector< SGVECTOR >& norms )
bool S3D::CalcTriangleNormals( std::vector< SGPOINT > coords, std::vector< int >& index,
std::vector< SGVECTOR >& norms )
{
size_t vsize = coords.size();
if( vsize < 3 )
{
#ifdef DEBUG
std::ostringstream ostr;
ostr << __FILE__ << ": " << __FUNCTION__ << ": " << __LINE__ << "\n";
ostr << " * [INFO] invalid vertex set (fewer than 3 vertices)";
wxLogTrace( MASK_3D_SG, "%s\n", ostr.str().c_str() );
#endif
wxLogTrace( MASK_3D_SG,
"%s:%s:%d * [INFO] invalid vertex set (fewer than 3 vertices)",
__FILE__, __FUNCTION__, __LINE__ );
return false;
}
@ -402,24 +367,16 @@ bool S3D::CalcTriangleNormals( std::vector< SGPOINT > coords,
if( 0 != isize % 3 || index.empty() )
{
#ifdef DEBUG
std::ostringstream ostr;
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
wxLogTrace( MASK_3D_SG, "%s:%s:%d * [INFO] invalid index set (not multiple of 3)",
__FILE__, __FUNCTION__, __LINE__ );
return false;
}
if( !norms.empty() )
{
#ifdef DEBUG
std::ostringstream ostr;
ostr << __FILE__ << ": " << __FUNCTION__ << ": " << __LINE__ << "\n";
ostr << " * [INFO] normals set is not empty";
wxLogTrace( MASK_3D_SG, "%s\n", ostr.str().c_str() );
#endif
wxLogTrace( MASK_3D_SG, "%s:%s:%d * [INFO] normals set is not empty",
__FILE__, __FUNCTION__, __LINE__ );
return false;
}
@ -435,15 +392,14 @@ bool S3D::CalcTriangleNormals( std::vector< SGPOINT > coords,
p2 = index[i++];
p3 = index[i++];
if( p1 < 0 || p1 >= (int)vsize || p2 < 0 || p2 >= (int)vsize ||
p3 < 0 || p3 >= (int)vsize )
if( p1 < 0 || p1 >= (int)vsize || p2 < 0 || p2 >= (int)vsize || p3 < 0 || p3 >= (int)vsize )
{
#ifdef DEBUG
#ifdef DEBUG
std::ostringstream ostr;
ostr << __FILE__ << ": " << __FUNCTION__ << ": " << __LINE__ << "\n";
ostr << " * [INFO] invalid index set; index out of bounds";
wxLogTrace( MASK_3D_SG, "%s\n", ostr.str().c_str() );
#endif
#endif
return false;
}
@ -525,12 +481,9 @@ bool S3D::CalcTriangleNormals( std::vector< SGPOINT > coords,
if( norms.size() != coords.size() )
{
#ifdef DEBUG
std::ostringstream ostr;
ostr << __FILE__ << ": " << __FUNCTION__ << ": " << __LINE__ << "\n";
ostr << " * [BUG] number of normals does not equal number of vertices";
wxLogTrace( MASK_3D_SG, "%s\n", ostr.str().c_str() );
#endif
wxLogTrace( MASK_3D_SG,
"%s:%s:%d * [BUG] number of normals does not equal number of vertices",
__FILE__, __FUNCTION__, __LINE__ );
return false;
}

View File

@ -2,6 +2,7 @@
* 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) 2020 KiCad Developers, see AUTHORS.txt for contributors.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
@ -23,10 +24,10 @@
/**
* @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
* a template. This header also declares a number of functions which are
* only of use within the sg_* classes.
*
* Define a number of macros to aid in repetitious code which is probably best expressed
* as a preprocessor macro rather than as a template. This header also declares a number
* of functions which are only of use within the sg_* classes.
*/
#ifndef SG_HELPERS_H
@ -44,14 +45,18 @@ class SGNORMALS;
class SGCOORDS;
class SGCOORDINDEX;
// Function to drop references within an SGNODE
// The node being destroyed must remove itself from the object reference's
// backpointer list in order to avoid a segfault.
#define DROP_REFS( aType, aList ) do { \
std::vector< aType* >::iterator sL = aList.begin(); \
std::vector< aType* >::iterator eL = aList.end(); \
while( sL != eL ) { \
((SGNODE*)*sL)->delNodeRef( this ); \
#define DROP_REFS( aType, aList ) \
do \
{ \
std::vector<aType*>::iterator sL = aList.begin(); \
std::vector<aType*>::iterator eL = aList.end(); \
while( sL != eL ) \
{ \
( (SGNODE*) *sL )->delNodeRef( this ); \
++sL; \
} \
aList.clear(); \
@ -61,11 +66,14 @@ class SGCOORDINDEX;
// Function to delete owned objects within an SGNODE
// The owned object's parent is set to NULL before
// deletion to avoid a redundant 'unlinkChildNode' call.
#define DEL_OBJS( aType, aList ) do { \
std::vector< aType* >::iterator sL = aList.begin(); \
std::vector< aType* >::iterator eL = aList.end(); \
while( sL != eL ) { \
((SGNODE*)*sL)->SetParent( NULL, false ); \
#define DEL_OBJS( aType, aList ) \
do \
{ \
std::vector<aType*>::iterator sL = aList.begin(); \
std::vector<aType*>::iterator eL = aList.end(); \
while( sL != eL ) \
{ \
( (SGNODE*) *sL )->SetParent( nullptr, false ); \
delete *sL; \
++sL; \
} \
@ -75,28 +83,38 @@ class SGCOORDINDEX;
// Function to unlink a child or reference node when that child or
// reference node is being destroyed.
#define UNLINK_NODE( aNodeID, aType, aNode, aOwnedList, aRefList, isChild ) do { \
if( aNodeID == aNode->GetNodeType() ) { \
std::vector< aType* >* oSL; \
std::vector< aType* >::iterator sL; \
std::vector< aType* >::iterator eL; \
if( isChild ) { \
#define UNLINK_NODE( aNodeID, aType, aNode, aOwnedList, aRefList, isChild ) \
do \
{ \
if( aNodeID == aNode->GetNodeType() ) \
{ \
std::vector<aType*>* oSL; \
std::vector<aType*>::iterator sL; \
std::vector<aType*>::iterator eL; \
if( isChild ) \
{ \
oSL = &aOwnedList; \
sL = oSL->begin(); \
eL = oSL->end(); \
while( sL != eL ) { \
if( (SGNODE*)*sL == aNode ) { \
while( sL != eL ) \
{ \
if( (SGNODE*) *sL == aNode ) \
{ \
oSL->erase( sL ); \
return; \
} \
++sL; \
} \
} else { \
} \
else \
{ \
oSL = &aRefList; \
sL = oSL->begin(); \
eL = oSL->end(); \
while( sL != eL ) { \
if( (SGNODE*)*sL == aNode ) { \
while( sL != eL ) \
{ \
if( (SGNODE*) *sL == aNode ) \
{ \
delNodeRef( this ); \
oSL->erase( sL ); \
return; \
@ -105,22 +123,31 @@ class SGCOORDINDEX;
} \
} \
return; \
} } while( 0 )
} \
} while( 0 )
// Function to check a node type, check for an existing reference,
// and add the node type to the reference list if applicable
#define ADD_NODE( aNodeID, aType, aNode, aOwnedList, aRefList, isChild ) do { \
if( aNodeID == aNode->GetNodeType() ) { \
std::vector< aType* >::iterator sL; \
#define ADD_NODE( aNodeID, aType, aNode, aOwnedList, aRefList, isChild ) \
do \
{ \
if( aNodeID == aNode->GetNodeType() ) \
{ \
std::vector<aType*>::iterator sL; \
sL = std::find( aOwnedList.begin(), aOwnedList.end(), aNode ); \
if( sL != aOwnedList.end() ) return true; \
if( sL != aOwnedList.end() ) \
return true; \
sL = std::find( aRefList.begin(), aRefList.end(), aNode ); \
if( sL != aRefList.end() ) return true; \
if( isChild ) { \
SGNODE* ppn = (SGNODE*)aNode->GetParent(); \
if( NULL != ppn ) { \
if( this != ppn ) { \
if( sL != aRefList.end() ) \
return true; \
if( isChild ) \
{ \
SGNODE* ppn = (SGNODE*) aNode->GetParent(); \
if( nullptr != ppn ) \
{ \
if( this != ppn ) \
{ \
std::cerr << __FILE__ << ": " << __FUNCTION__ << ": " << __LINE__ << "\n"; \
std::cerr << " * [BUG] object '" << aNode->GetName(); \
std::cerr << "' has multiple parents '" << ppn->GetName() << "', '"; \
@ -128,36 +155,45 @@ class SGCOORDINDEX;
return false; \
} \
} \
aOwnedList.push_back( (aType*)aNode ); \
aOwnedList.push_back( (aType*) aNode ); \
aNode->SetParent( this, false ); \
} else { \
/*if( NULL == aNode->GetParent() ) { \
} \
else \
{ \
/*if( nullptr == aNode->GetParent() ) { \
std::cerr << __FILE__ << ": " << __FUNCTION__ << ": " << __LINE__ << "\n"; \
std::cerr << " * [BUG] object '" << aNode->GetName(); \
std::cerr << "' has no parent\n"; \
std::cerr << " * [INFO] possible copy assignment or copy constructor bug\n"; \
return false; \
} */ \
aRefList.push_back( (aType*)aNode ); \
aRefList.push_back( (aType*) aNode ); \
aNode->addNodeRef( this ); \
} \
return true; \
} } while( 0 )
} \
} while( 0 )
// Function to find a node object given a (non-unique) node name
#define FIND_NODE( aType, aName, aNodeList, aCallingNode ) do { \
std::vector< aType* >::iterator sLA = aNodeList.begin(); \
std::vector< aType* >::iterator eLA = aNodeList.end(); \
SGNODE* psg = NULL; \
while( sLA != eLA ) { \
if( (SGNODE*)*sLA != aCallingNode ) { \
psg = (SGNODE*) (*sLA)->FindNode( aName, this ); \
if( NULL != psg) \
#define FIND_NODE( aType, aName, aNodeList, aCallingNode ) \
do \
{ \
std::vector<aType*>::iterator sLA = aNodeList.begin(); \
std::vector<aType*>::iterator eLA = aNodeList.end(); \
SGNODE* psg = nullptr; \
while( sLA != eLA ) \
{ \
if( (SGNODE*) *sLA != aCallingNode ) \
{ \
psg = (SGNODE*) ( *sLA )->FindNode( aName, this ); \
if( nullptr != psg ) \
return psg; \
} \
++sLA; \
} } while ( 0 )
} \
} while( 0 )
namespace S3D
{
@ -168,28 +204,24 @@ namespace S3D
//
/*
* Function CalcTriangleNormals
* takes an array of 3D coordinates and its corresponding index set and calculates
* 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);
* Take an array of 3D coordinates and its corresponding index set and calculates
* the normals assuming that indices are given in CCW order.
*
* Care must be taken in using this function to ensure that:
* -# 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.
* -# 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
* @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.
*/
bool CalcTriangleNormals( std::vector< SGPOINT > coords, std::vector< int >& index,
std::vector< SGVECTOR >& norms );
//
// VRML related functions
//
// formats a floating point number for text output to a VRML file
void FormatFloat( std::string& result, double value );
@ -218,19 +250,13 @@ namespace S3D
// write out an RGB color
bool WriteColor( std::ostream& aFile, const SGCOLOR& aColor );
//
// Cache related READ functions
//
/**
* Function ReadTag
* reads the text tag of a binary cache file which is the
* NodeTag and unique ID number combined
* Read 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 aName will hold the tag name on successful return
* @return will be the NodeType which the tag represents or
* S3D::SGTYPES::SGTYPE_END on failure
* @param aFile is a binary file open for reading.
* @param aName will hold the tag name on successful return.
* @return will be the NodeType which the tag represents or S3D::SGTYPES::SGTYPE_END on
* failure.
*/
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.
*
* 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
* modify it under the terms of the GNU General Public License
@ -30,33 +31,25 @@
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
std::ostringstream ostr;
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
wxLogTrace( MASK_3D_SG, "%s:%s:%d * [BUG] inappropriate parent to SGINDEX (type '%d')",
__FILE__, __FUNCTION__, __LINE__, aParent->GetNodeType() );
}
return;
}
SGINDEX::~SGINDEX()
{
index.clear();
return;
}
bool SGINDEX::SetParent( SGNODE* aParent, bool notify )
{
if( NULL != m_Parent )
if( nullptr != m_Parent )
{
if( aParent == m_Parent )
return true;
@ -65,14 +58,14 @@ bool SGINDEX::SetParent( SGNODE* aParent, bool notify )
if( notify )
m_Parent->unlinkChildNode( this );
m_Parent = NULL;
m_Parent = nullptr;
if( NULL == aParent )
if( nullptr == aParent )
return true;
}
// 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;
m_Parent = aParent;
@ -86,50 +79,34 @@ bool SGINDEX::SetParent( SGNODE* aParent, bool notify )
SGNODE* SGINDEX::FindNode(const char *aNodeName, const SGNODE *aCaller) noexcept
{
if( NULL == aNodeName || 0 == aNodeName[0] )
return NULL;
if( nullptr == aNodeName || 0 == aNodeName[0] )
return nullptr;
if( !m_Name.compare( aNodeName ) )
return this;
return NULL;
return nullptr;
}
void SGINDEX::unlinkChildNode( const SGNODE* aCaller ) noexcept
{
#ifdef DEBUG
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;
// Node should have no children or refs.
wxCHECK( false, /* void */ );
}
void SGINDEX::unlinkRefNode( const SGNODE* aCaller ) noexcept
{
#ifdef DEBUG
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;
// Node should have no children or refs.
wxCHECK( false, /* void */ );
}
bool SGINDEX::AddRefNode( SGNODE* aNode ) noexcept
{
#ifdef DEBUG
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
// Node should have no children or refs.
wxCHECK( false, false );
return false;
}
@ -137,12 +114,8 @@ bool SGINDEX::AddRefNode( SGNODE* aNode ) noexcept
bool SGINDEX::AddChildNode( SGNODE* aNode ) noexcept
{
#ifdef DEBUG
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
// Node should have no children or refs.
wxCHECK( false, false );
return false;
}
@ -153,7 +126,7 @@ bool SGINDEX::GetIndices( size_t& nIndices, int*& aIndexList )
if( index.empty() )
{
nIndices = 0;
aIndexList = NULL;
aIndexList = nullptr;
return false;
}
@ -167,7 +140,7 @@ void SGINDEX::SetIndices( size_t nIndices, int* aIndexList )
{
index.clear();
if( 0 == nIndices || NULL == aIndexList )
if( 0 == nIndices || nullptr == aIndexList )
return;
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 )
{
index.push_back( aIndex );
return;
}
@ -210,17 +182,8 @@ bool SGINDEX::writeCoordIndex( std::ostream& aFile )
{
size_t n = index.size();
if( n % 3 )
{
#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;
}
wxCHECK_MSG( n % 3 == 0, false,
"Coordinate index is not divisible by three (violates triangle constraint)" );
aFile << " coordIndex [\n ";
@ -296,26 +259,16 @@ bool SGINDEX::writeIndexList( std::ostream& aFile )
bool SGINDEX::WriteCache( std::ostream& aFile, SGNODE* parentNode )
{
if( NULL == parentNode )
if( nullptr == parentNode )
{
if( NULL == m_Parent )
{
#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;
}
wxCHECK( m_Parent, false );
SGNODE* np = m_Parent;
while( NULL != np->GetParent() )
while( nullptr != np->GetParent() )
np = np->GetParent();
if( np->WriteCache( aFile, NULL ) )
if( np->WriteCache( aFile, nullptr ) )
{
m_written = true;
return true;
@ -324,26 +277,12 @@ bool SGINDEX::WriteCache( std::ostream& aFile, SGNODE* parentNode )
return false;
}
if( parentNode != m_Parent )
{
#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;
}
wxCHECK( parentNode == m_Parent, false );
if( !aFile.good() )
{
#ifdef DEBUG
std::ostringstream ostr;
ostr << __FILE__ << ": " << __FUNCTION__ << ": " << __LINE__ << "\n";
ostr << " * [INFO] bad stream";
wxLogTrace( MASK_3D_SG, "%s\n", ostr.str().c_str() );
#endif
wxLogTrace( MASK_3D_SG, "%s:%s:%d * [INFO] bad stream",
__FILE__, __FUNCTION__, __LINE__ );
return false;
}
@ -365,17 +304,7 @@ bool SGINDEX::WriteCache( std::ostream& aFile, SGNODE* parentNode )
bool SGINDEX::ReadCache( std::istream& aFile, SGNODE* parentNode )
{
if( !index.empty() )
{
#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;
}
wxCHECK( index.empty(), false );
size_t npts;
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 )
{
aFile.read( (char*)&tmp, sizeof(int) );
aFile.read( (char*) &tmp, sizeof( int ) );
if( aFile.fail() )
return false;

View File

@ -2,6 +2,7 @@
* 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) 2020 KiCad Developers, see AUTHORS.txt for contributors.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
@ -23,7 +24,6 @@
/**
* @file sg_index.h
* defines a generic Index interface for a scenegraph object
*/
#ifndef SG_INDEX_H
@ -32,58 +32,50 @@
#include <vector>
#include "3d_cache/sg/sg_node.h"
/**
* Define a generic index interface for a scenegraph object.
*/
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:
SGINDEX( SGNODE* aParent );
virtual ~SGINDEX();
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 AddChildNode( SGNODE* aNode ) noexcept override;
void unlinkChildNode( const SGNODE* aCaller ) noexcept override;
void unlinkRefNode( const SGNODE* aCaller ) noexcept override;
/**
* Function GetIndices
* 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
* Retrieve 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
* @param aIndexList [out] will store a pointer to the data
* @return true if there was available data (nIndices > 0) otherwise false
* @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 );
/**
* Function SetIndices
* sets the number of indices and creates a copy of the given index data.
* Set the number of indices and creates a copy of the given index data.
*
* @param nIndices [in] the number of indices to be stored
* @param aIndexList [in] the index data
* @param nIndices the number of indices to be stored.
* @param aIndexList the index data.
*/
void SetIndices( size_t nIndices, int* aIndexList );
/**
* Function AddIndex
* adds a single index to the list
* Add a single index to the list.
*
* @param aIndex is the index to add
* @param aIndex is the index to add.
*/
void AddIndex( int aIndex );
@ -92,6 +84,15 @@ public:
bool WriteCache( std::ostream& 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

View File

@ -2,6 +2,7 @@
* 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) 2020 KiCad Developers, see AUTHORS.txt for contributors.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
@ -31,6 +32,7 @@
#include "3d_cache/sg/sg_node.h"
#include "plugins/3dapi/c3dmodel.h"
static const std::string node_names[S3D::SGTYPE_END + 1] = {
"TXFM",
"APP",
@ -68,19 +70,15 @@ static void getNodeName( S3D::SGTYPES nodeType, std::string& aName )
std::ostringstream ostr;
ostr << node_names[nodeType] << "_" << seqNum;
aName = ostr.str();
return;
}
SGNODE::SGNODE( SGNODE* aParent )
{
m_Parent = aParent;
m_Association = NULL;
m_Association = nullptr;
m_written = false;
m_SGtype = S3D::SGTYPE_END;
return;
}
@ -90,7 +88,7 @@ SGNODE::~SGNODE()
m_Parent->unlinkChildNode( this );
if( m_Association )
*m_Association = NULL;
*m_Association = nullptr;
std::list< SGNODE* >::iterator sBP = m_BackPointers.begin();
std::list< SGNODE* >::iterator eBP = m_BackPointers.end();
@ -100,8 +98,6 @@ SGNODE::~SGNODE()
(*sBP)->unlinkRefNode( this );
++sBP;
}
return;
}
@ -122,10 +118,10 @@ bool SGNODE::SwapParent( SGNODE* aNewParent )
if( aNewParent == m_Parent )
return true;
if( NULL == aNewParent )
if( nullptr == aNewParent )
return false;
if( NULL == m_Parent )
if( nullptr == m_Parent )
{
if( aNewParent->AddChildNode( this ) )
return true;
@ -138,7 +134,7 @@ bool SGNODE::SwapParent( SGNODE* aNewParent )
SGNODE* oldParent = m_Parent;
m_Parent->unlinkChildNode( this );
m_Parent = NULL;
m_Parent = nullptr;
aNewParent->unlinkRefNode( this );
aNewParent->AddChildNode( 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 );
else
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();
}
@ -175,7 +169,7 @@ const char * SGNODE::GetNodeTypeName( S3D::SGTYPES aNodeType ) const noexcept
void SGNODE::addNodeRef( SGNODE* aNode )
{
if( NULL == aNode )
if( nullptr == aNode )
return;
std::list< SGNODE* >::iterator np =
@ -185,13 +179,12 @@ void SGNODE::addNodeRef( SGNODE* aNode )
return;
m_BackPointers.push_back( aNode );
return;
}
void SGNODE::delNodeRef( const SGNODE* aNode )
{
if( NULL == aNode )
if( nullptr == aNode )
return;
std::list< SGNODE* >::iterator np =
@ -203,62 +196,28 @@ void SGNODE::delNodeRef( const SGNODE* aNode )
return;
}
#ifdef DEBUG
std::ostringstream ostr;
ostr << __FILE__ << ": " << __FUNCTION__ << ": " << __LINE__ << "\n";
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;
wxLogTrace( MASK_3D_SG, "%s:%s:%d * [BUG] delNodeRef() did not find its target, "
"this node type %d, referenced node type %d", __FILE__, __FUNCTION__, __LINE__,
m_SGtype, aNode->GetNodeType() );
}
void SGNODE::AssociateWrapper( SGNODE** aWrapperRef ) noexcept
{
if( NULL == aWrapperRef )
{
#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;
}
wxCHECK( aWrapperRef && *aWrapperRef == this, /* void */ );
// if there is an existing association then break it and emit a warning
// just in case the behavior is undesired
if( m_Association )
{
*m_Association = NULL;
*m_Association = nullptr;
#ifdef DEBUG
std::ostringstream ostr;
ostr << __FILE__ << ": " << __FUNCTION__ << ": " << __LINE__ << "\n";
ostr << " * [WARNING] association being broken with previous wrapper";
wxLogTrace( MASK_3D_SG, "%s\n", ostr.str().c_str() );
#endif
wxLogTrace( MASK_3D_SG,
"%s:%s:%d * [WARNING] association being broken with previous wrapper",
__FILE__, __FUNCTION__, __LINE__ );
}
m_Association = aWrapperRef;
return;
}
void SGNODE::DisassociateWrapper( SGNODE** aWrapperRef ) noexcept
@ -266,38 +225,11 @@ void SGNODE::DisassociateWrapper( SGNODE** aWrapperRef ) noexcept
if( !m_Association )
return;
if( !aWrapperRef )
{
#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
wxCHECK( aWrapperRef, /* void */ );
return;
}
wxCHECK( *aWrapperRef == *m_Association && aWrapperRef == m_Association, /* void */ );
if( *aWrapperRef != *m_Association || aWrapperRef != m_Association )
{
#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;
m_Association = nullptr;
}
@ -305,8 +237,6 @@ void SGNODE::ResetNodeIndex( void ) noexcept
{
for( int i = 0; i < (int)S3D::SGTYPE_END; ++i )
node_counts[i] = 1;
return;
}
@ -314,28 +244,7 @@ bool S3D::GetMatIndex( MATLIST& aList, SGNODE* aNode, int& aIndex )
{
aIndex = 0;
if( NULL == aNode || S3D::SGTYPE_APPEARANCE != aNode->GetNodeType() )
{
#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;
}
wxCHECK( aNode && S3D::SGTYPE_APPEARANCE == aNode->GetNodeType(), false );
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;
aMesh.m_Positions = NULL;
aMesh.m_Positions = nullptr;
}
if( NULL != aMesh.m_Normals )
if( nullptr != 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;
aMesh.m_Texcoords = NULL;
aMesh.m_Texcoords = nullptr;
}
if( NULL != aMesh.m_Color )
if( nullptr != 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;
aMesh.m_FaceIdx = NULL;
aMesh.m_FaceIdx = nullptr;
}
aMesh.m_VertexSize = 0;
aMesh.m_FaceIdxSize = 0;
aMesh.m_MaterialIdx = 0;
return;
}
void S3D::FREE_S3DMODEL( S3DMODEL& aModel )
{
if( NULL != aModel.m_Materials )
if( nullptr != aModel.m_Materials )
{
delete [] aModel.m_Materials;
aModel.m_Materials = NULL;
aModel.m_Materials = nullptr;
}
aModel.m_MaterialsSize = 0;
if( NULL != aModel.m_Meshes )
if( nullptr != aModel.m_Meshes )
{
for( unsigned int i = 0; i < aModel.m_MeshesSize; ++i )
FREE_SMESH( aModel.m_Meshes[i] );
delete [] aModel.m_Meshes;
aModel.m_Meshes = NULL;
aModel.m_Meshes = nullptr;
}
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.
*
* 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
* modify it under the terms of the GNU General Public License
@ -23,7 +24,6 @@
/**
* @file sg_node.h
* defines the base class of the intermediate scene graph NODE
*/
@ -47,8 +47,7 @@ class SGAPPEARANCE;
namespace S3D
{
/**
* Function GetNodeTypeName
* returns the name of the given type of node
* Return the name of the given type of node
*/
char const* GetNodeTypeName( S3D::SGTYPES aType ) noexcept;
@ -70,104 +69,41 @@ namespace S3D
/**
* SGNODE
* represents the base class of all Scene Graph nodes
* The base class of all Scene Graph nodes.
*/
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:
SGNODE( SGNODE* aParent );
virtual ~SGNODE();
/**
* Function GetNodeType
* returns the type of this node instance
* Return the type of this node instance.
*/
S3D::SGTYPES GetNodeType( void ) const noexcept;
/**
* Function GetParent
* returns a pointer to the parent SGNODE of this object
* or NULL if the object has no parent (ie. top level transform)
* Returns a pointer to the parent SGNODE of this object or NULL if the object has
* no parent (ie. top level transform).
*/
SGNODE* GetParent( void ) const noexcept;
/**
* Function SetParent
* sets the parent SGNODE of this object.
* Set the parent #SGNODE of this object.
*
* @param aParent [in] is the desired parent node
* @return true if the operation succeeds; false if
* the given node is not allowed to be a parent to
* the derived object.
* @return true if the operation succeeds; false if the given node is not allowed to
* be a parent to the derived object.
*/
virtual bool SetParent( SGNODE* aParent, bool notify = true ) = 0;
/**
* Function SwapParent
* swaps the ownership with the given parent. This operation
* may be required when reordering nodes for optimization.
* Swap the ownership with the given parent.
*
* @param aNewParent [in] will become the new parent to the
* object; it must be the same type as the parent of this
* instance.
* This operation may be required when reordering nodes for optimization.
*
* @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 );
@ -177,13 +113,14 @@ public:
const char * GetNodeTypeName( S3D::SGTYPES aNodeType ) const noexcept;
/**
* Function FindNode searches the tree of linked nodes and returns a
* reference to the first node found with the given name. The reference
* is then typically added to another node via AddRefNode().
* Search the tree of linked nodes and return a reference to the first node found with
* the given name.
*
* @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
* The reference is then typically added to another node via AddRefNode().
*
* @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;
@ -192,59 +129,108 @@ public:
virtual bool AddChildNode( SGNODE* aNode ) = 0;
/**
* Function AssociateWrapper
* associates this object with a handle to itself; this handle
* is typically held by an IFSG* wrapper and the pointer which
* it refers to is set to NULL upon destruction of this object.
* This mechanism provides a scheme by which a wrapper can be
* notified of the destruction of the object which it wraps.
* Associate this object with a handle to itself.
*
* The handle is typically held by an IFSG* wrapper and the pointer which it refers to
* is set to NULL upon destruction of this object. This mechanism provides a scheme
* by which a wrapper can be notified of the destruction of the object which it wraps.
*/
void AssociateWrapper( SGNODE** aWrapperRef ) noexcept;
/**
* Function DisassociateWrapper
* removes the association between an IFSG* wrapper
* object and this object.
* Remove the association between an IFSG* wrapper object and this object.
*/
void DisassociateWrapper( SGNODE** aWrapperRef ) noexcept;
/**
* Function ResetNodeIndex
* resets the global SG* node indices in preparation for
* Write() operations
* Reset the global SG* node indices in preparation for write operations.
*/
void ResetNodeIndex( void ) noexcept;
/**
* Function ReNameNodes
* renames a node and all its child nodes in preparation for
* Write() operations
* Rename a node and all its child nodes in preparation for write operations.
*/
virtual void ReNameNodes( void ) = 0;
/**
* Function WriteVRML
* writes this node's data to a VRML file; this includes
* all data of child and referenced nodes.
* Writes this node's data to a VRML file.
*
* This includes all data of child and referenced nodes.
*/
virtual bool WriteVRML( std::ostream& aFile, bool aReuseFlag ) = 0;
/**
* Function WriteCache
* write's this node's data to a binary cache file; the data
* includes all data of children and references to children.
* If this function is invoked by the user, parentNode must be
* set to NULL in order to ensure coherent data.
* Write this node's data to a binary cache file.
*
* The data includes all data of children and references to children. If this function
* is invoked by the user, parentNode must be set to NULL in order to ensure coherent data.
*/
virtual bool WriteCache( std::ostream& aFile, SGNODE* parentNode ) = 0;
/**
* Function ReadCache
* 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
* SCENEGRAPH node.
* 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
* #SCENEGRAPH node.
*/
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

View File

@ -2,6 +2,7 @@
* 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) 2020 KiCad Developers, see AUTHORS.txt for contributors.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
@ -33,37 +34,29 @@ SGNORMALS::SGNORMALS( SGNODE* aParent ) : SGNODE( aParent )
{
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
std::ostringstream ostr;
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
wxLogTrace( MASK_3D_SG, "%s:%s:%d * [BUG] inappropriate parent to SGNORMALS (type %d)",
__FILE__, __FUNCTION__, __LINE__, aParent->GetNodeType() );
}
else if( NULL != aParent && S3D::SGTYPE_FACESET == aParent->GetNodeType() )
else if( nullptr != aParent && S3D::SGTYPE_FACESET == aParent->GetNodeType() )
{
m_Parent->AddChildNode( this );
}
return;
}
SGNORMALS::~SGNORMALS()
{
norms.clear();
return;
}
bool SGNORMALS::SetParent( SGNODE* aParent, bool notify )
{
if( NULL != m_Parent )
if( nullptr != m_Parent )
{
if( aParent == m_Parent )
return true;
@ -72,14 +65,14 @@ bool SGNORMALS::SetParent( SGNODE* aParent, bool notify )
if( notify )
m_Parent->unlinkChildNode( this );
m_Parent = NULL;
m_Parent = nullptr;
if( NULL == aParent )
if( nullptr == aParent )
return true;
}
// 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;
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] )
return NULL;
if( nullptr == aNodeName || 0 == aNodeName[0] )
return nullptr;
if( !m_Name.compare( aNodeName ) )
return this;
return NULL;
return nullptr;
}
void SGNORMALS::unlinkChildNode( const SGNODE* aCaller ) noexcept
{
#ifdef DEBUG
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;
wxCHECK( false, /* void */ );
}
void SGNORMALS::unlinkRefNode( const SGNODE* aCaller ) noexcept
{
#ifdef DEBUG
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;
wxCHECK( false, /* void */ );
}
bool SGNORMALS::AddRefNode( SGNODE* aNode ) noexcept
{
#ifdef DEBUG
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
wxCHECK( false, false );
return false;
}
@ -144,12 +118,7 @@ bool SGNORMALS::AddRefNode( SGNODE* aNode ) noexcept
bool SGNORMALS::AddChildNode( SGNODE* aNode ) noexcept
{
#ifdef DEBUG
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
wxCHECK( false, false );
return false;
}
@ -160,7 +129,7 @@ bool SGNORMALS::GetNormalList( size_t& aListSize, SGVECTOR*& aNormalList )
if( norms.empty() )
{
aListSize = 0;
aNormalList = NULL;
aNormalList = nullptr;
return false;
}
@ -174,27 +143,23 @@ void SGNORMALS::SetNormalList( size_t aListSize, const SGVECTOR* aNormalList )
{
norms.clear();
if( 0 == aListSize || NULL == aNormalList )
if( 0 == aListSize || nullptr == aNormalList )
return;
for( int i = 0; i < (int)aListSize; ++i )
norms.push_back( aNormalList[i] );
return;
}
void SGNORMALS::AddNormal( double aXValue, double aYValue, double aZValue )
{
norms.emplace_back( aXValue, aYValue, aZValue );
return;
}
void SGNORMALS::AddNormal( const SGVECTOR& 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 )
{
if( NULL == parentNode )
if( nullptr == parentNode )
{
if( NULL == m_Parent )
{
#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;
}
wxCHECK( m_Parent, false );
SGNODE* np = m_Parent;
while( NULL != np->GetParent() )
while( nullptr != np->GetParent() )
np = np->GetParent();
if( np->WriteCache( aFile, NULL ) )
if( np->WriteCache( aFile, nullptr ) )
{
m_written = true;
return true;
@ -294,26 +249,12 @@ bool SGNORMALS::WriteCache( std::ostream& aFile, SGNODE* parentNode )
return false;
}
if( parentNode != m_Parent )
{
#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;
}
wxCHECK( parentNode == m_Parent, false );
if( !aFile.good() )
{
#ifdef DEBUG
std::ostringstream ostr;
ostr << __FILE__ << ": " << __FUNCTION__ << ": " << __LINE__ << "\n";
ostr << " * [INFO] bad stream";
wxLogTrace( MASK_3D_SG, "%s\n", ostr.str().c_str() );
#endif
wxLogTrace( MASK_3D_SG, "%s:%s:%d * [INFO] bad stream",
__FILE__, __FUNCTION__, __LINE__ );
return false;
}
@ -335,20 +276,10 @@ bool SGNORMALS::WriteCache( std::ostream& aFile, SGNODE* parentNode )
bool SGNORMALS::ReadCache( std::istream& aFile, SGNODE* parentNode )
{
if( !norms.empty() )
{
#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;
}
wxCHECK( norms.empty(), false );
size_t npts;
aFile.read( (char*)&npts, sizeof(size_t) );
aFile.read( (char*) &npts, sizeof( size_t ) );
SGVECTOR tmp;
if( aFile.fail() )

View File

@ -2,6 +2,7 @@
* 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) 2020 KiCad Developers, see AUTHORS.txt for contributors.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
@ -23,7 +24,6 @@
/**
* @file sg_normals.h
* defines a set of vertex normals for a scene graph object
*/
#ifndef SG_NORMALS_H
@ -32,21 +32,18 @@
#include <vector>
#include "3d_cache/sg/sg_node.h"
/**
* Define a set of vertex normals for a scene graph object
*/
class SGNORMALS : public SGNODE
{
public:
std::vector< SGVECTOR > norms;
void unlinkChildNode( const SGNODE* aNode ) noexcept override;
void unlinkRefNode( const SGNODE* aNode ) noexcept override;
public:
SGNORMALS( SGNODE* aParent );
virtual ~SGNORMALS();
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 AddChildNode( SGNODE* aNode ) noexcept override;
@ -60,6 +57,11 @@ public:
bool WriteCache( std::ostream& 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

View File

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

View File

@ -2,6 +2,7 @@
* 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) 2020 KiCad Developers, see AUTHORS.txt for contributors.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
@ -23,7 +24,6 @@
/**
* @file sg_shape.h
* defines a complex 3D shape for a scenegraph object
*/
@ -36,8 +36,33 @@
class SGAPPEARANCE;
class SGFACESET;
/**
* Define a complex 3D shape for a scenegraph object.
*/
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:
void unlinkNode( const SGNODE* aNode, bool isChild );
bool addNode( SGNODE* aNode, bool isChild );
@ -50,28 +75,6 @@ public:
// referenced nodes
SGAPPEARANCE* m_RAppearance;
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 );
};
/*