Improving VRML1/2 parsers

This commit is contained in:
Cirilo Bernardo 2016-01-07 15:43:32 +11:00
parent 8a9eb3bbe8
commit 7dd4bd9f09
13 changed files with 192 additions and 48 deletions

View File

@ -4,7 +4,7 @@ include_directories(
${CMAKE_CURRENT_SOURCE_DIR}/v2
)
add_definitions( -DDEBUG_VRML1=2 -DDEBUG_VRML2=2 )
add_definitions( -DDEBUG_VRML1=3 -DDEBUG_VRML2=3 )
add_library( s3d_plugin_vrml MODULE
vrml.cpp

View File

@ -44,9 +44,11 @@ WRL1BASE::WRL1BASE() : WRL1NODE( NULL )
WRL1BASE::~WRL1BASE()
{
if( m_dictionary )
delete m_dictionary;
#if defined( DEBUG_VRML1 ) && ( DEBUG_VRML1 > 2 )
std::cerr << " * [INFO] Destroying virtual base node\n";
#endif
cancelDict();
return;
}
@ -474,7 +476,8 @@ bool WRL1BASE::ReadNode( WRLPROC& proc, WRL1NODE* aParent, WRL1NODE** aNode )
#if defined( DEBUG_VRML1 ) && ( DEBUG_VRML1 > 1 )
else
{
std::cerr << " * [INFO] discarded node (currently unsupported)\n";
std::cerr << " * [INFO] discarded node '" << glob << "' at line ";
std::cerr << line << ", col " << column << " (currently unsupported)\n";
}
#endif

View File

@ -62,8 +62,17 @@ WRL1MATERIAL::~WRL1MATERIAL()
// destroy any orphaned color nodes
for( int i = 0; i < 2; ++i )
{
if( NULL != colors[i] && NULL == S3D::GetSGNodeParent( colors[i] ) )
if( NULL != colors[i] )
{
#if defined( DEBUG_VRML1 ) && ( DEBUG_VRML1 > 2 )
std::cerr << " * [INFO] Destroying SGCOLOR #" << i << "\n";
#endif
if( NULL == S3D::GetSGNodeParent( colors[i] ) )
S3D::DestroyNode( colors[i] );
#if defined( DEBUG_VRML1 ) && ( DEBUG_VRML1 > 2 )
std::cerr << " * [INFO] destroyed SGCOLOR #" << i << "\n";
#endif
}
}
return;

View File

@ -84,6 +84,7 @@ typedef std::pair< std::string, WRL1NODES > NODEITEM;
typedef std::map< std::string, WRL1NODES > NODEMAP;
static NODEMAP nodenames;
std::string WRL1NODE::tabs = "";
WRL1NODE::WRL1NODE( NAMEREGISTER* aDictionary )
{
@ -136,8 +137,17 @@ WRL1NODE::WRL1NODE( NAMEREGISTER* aDictionary )
WRL1NODE::~WRL1NODE()
{
if( m_dictionary && !m_Name.empty() )
m_dictionary->DelName( m_Name, this );
#if defined( DEBUG_VRML1 ) && ( DEBUG_VRML1 > 2 )
std::cerr << " * [INFO] ^^ Destroying Type " << m_Type << " with " << m_Children.size();
std::cerr << " children, " << m_Refs.size() << " references and ";
std::cerr << m_BackPointers.size() << " backpointers\n";
#endif
m_Items.clear();
// XXX - the dictionary may be bad - don't use it
//if( m_dictionary && !m_Name.empty() )
// m_dictionary->DelName( m_Name, this );
if( m_Parent )
m_Parent->unlinkChildNode( this );
@ -145,31 +155,100 @@ WRL1NODE::~WRL1NODE()
std::list< WRL1NODE* >::iterator sBP = m_BackPointers.begin();
std::list< WRL1NODE* >::iterator eBP = m_BackPointers.end();
#if defined( DEBUG_VRML1 ) && ( DEBUG_VRML1 > 2 )
int acc = 0;
#endif
while( sBP != eBP )
{
#if defined( DEBUG_VRML1 ) && ( DEBUG_VRML1 > 2 )
++acc;
std::cerr << " * [INFO] " << tabs << "Type " << m_Type << " is Unlinking ref #";
std::cerr << acc << "\n";
#endif
(*sBP)->unlinkRefNode( this );
#if defined( DEBUG_VRML1 ) && ( DEBUG_VRML1 > 2 )
std::cerr << " * [INFO] " << tabs << "Type " << m_Type << " has unlinked ref #";
std::cerr << acc << "\n";
#endif
++sBP;
}
m_Refs.clear();
std::list< WRL1NODE* >::iterator sC = m_Children.begin();
std::list< WRL1NODE* >::iterator eC = m_Children.end();
#if defined( DEBUG_VRML1 ) && ( DEBUG_VRML1 > 2 )
std::string otabs = tabs;
tabs.append( " " );
#endif
while( sC != eC )
{
#if defined( DEBUG_VRML1 ) && ( DEBUG_VRML1 > 2 )
++acc;
std::cerr << " * [INFO] " << otabs << "Type " << m_Type << " is Deleting child #";
std::cerr << acc << "\n";
#endif
(*sC)->SetParent( NULL, false );
delete *sC;
#if defined( DEBUG_VRML1 ) && ( DEBUG_VRML1 > 2 )
std::cerr << " * [INFO] " << otabs << "Type " << m_Type << " has unlinked child #";
std::cerr << acc << "\n";
#endif
//delete *sC;
#if defined( DEBUG_VRML1 ) && ( DEBUG_VRML1 > 2 )
std::cerr << " * [INFO] " << otabs << "Type " << m_Type << " has deleted child #";
std::cerr << acc << "\n";
#endif
++sC;
}
#if defined( DEBUG_VRML1 ) && ( DEBUG_VRML1 > 2 )
tabs = otabs;
#endif
m_Children.clear();
return;
}
void WRL1NODE::cancelDict( void )
{
std::list< WRL1NODE* >::iterator sC = m_Children.begin();
std::list< WRL1NODE* >::iterator eC = m_Children.end();
while( sC != eC )
{
(*sC)->cancelDict();
++sC;
}
if( m_Type == WRL1_BASE && NULL != m_dictionary )
delete m_dictionary;
m_dictionary = NULL;
return;
}
void WRL1NODE::addNodeRef( WRL1NODE* aNode )
{
// note: for VRML1 we allow even parent nodes to be held as references
// the parent node must never be added as a backpointer
if( aNode == m_Parent )
return;
std::list< WRL1NODE* >::iterator sR = m_BackPointers.begin();
std::list< WRL1NODE* >::iterator eR = m_BackPointers.end();
while( sR != eR )
{
if( *sR == aNode )
return;
++sR;
}
m_BackPointers.push_back( aNode );
return;
@ -179,7 +258,7 @@ void WRL1NODE::addNodeRef( WRL1NODE* aNode )
void WRL1NODE::delNodeRef( WRL1NODE* aNode )
{
std::list< WRL1NODE* >::iterator np =
std::find( m_BackPointers.begin(), m_BackPointers.end(), aNode );
std::find( m_BackPointers.begin(), m_BackPointers.end(), aNode );
if( np != m_BackPointers.end() )
{
@ -346,10 +425,12 @@ bool WRL1NODE::AddChildNode( WRL1NODE* aNode )
++sC;
}
aNode->SetParent( this );
m_Children.push_back( aNode );
addItem( aNode );
if( aNode->GetParent() != this )
aNode->SetParent( this );
return true;
}
@ -394,14 +475,13 @@ void WRL1NODE::unlinkChildNode( const WRL1NODE* aNode )
if( *sL == aNode )
{
m_Children.erase( sL );
delItem( aNode );
return;
}
++sL;
}
delItem( aNode );
return;
}
@ -416,14 +496,13 @@ void WRL1NODE::unlinkRefNode( const WRL1NODE* aNode )
if( *sL == aNode )
{
m_Refs.erase( sL );
delItem( aNode );
return;
}
++sL;
}
delItem( aNode );
return;
}

View File

@ -132,6 +132,12 @@ protected:
NAMEREGISTER* m_dictionary;
public:
#if defined( DEBUG_VRML1 ) && ( DEBUG_VRML1 > 2 )
static std::string tabs;
#endif
// cancel the dictionary pointer; for internal use only
void cancelDict( void );
/**
* Function GetCurrentSettings

View File

@ -367,6 +367,12 @@ SGNODE* WRL2APPEARANCE::TranslateToSG( SGNODE* aParent, bool calcNormals )
return NULL;
}
#if defined( DEBUG_VRML2 ) && ( DEBUG_VRML2 > 2 )
std::cerr << " * [INFO] Translating Appearance with " << m_Children.size();
std::cerr << " children, " << m_Refs.size() << " references and ";
std::cerr << m_BackPointers.size() << " backpointers\n";
#endif
if( m_sgNode )
{
if( NULL != aParent )

View File

@ -634,6 +634,13 @@ bool WRL2BASE::ReadNode( WRLPROC& proc, WRL2NODE* aParent, WRL2NODE** aNode )
return false;
}
#ifdef DEBUG_VRML2
else
{
std::cerr << " * [INFO] OK: discard unsupported " << glob << " node at l";
std::cerr << line << ", c" << column << "\n";
}
#endif
break;
}

View File

@ -577,6 +577,13 @@ SGNODE* WRL2FACESET::TranslateToSG( SGNODE* aParent, bool calcNormals )
return NULL;
}
#if defined( DEBUG_VRML2 ) && ( DEBUG_VRML2 > 2 )
std::cerr << " * [INFO] Translating IndexedFaceSet with " << m_Children.size();
std::cerr << " children, " << m_Refs.size() << " references, ";
std::cerr << m_BackPointers.size() << " backpointers and ";
std::cerr << coordIndex.size() << " coord indices\n";
#endif
if( m_sgNode )
{
if( NULL != aParent )

View File

@ -303,6 +303,12 @@ SGNODE* WRL2MATERIAL::TranslateToSG( SGNODE* aParent, bool calcNormals )
return NULL;
}
#if defined( DEBUG_VRML2 ) && ( DEBUG_VRML2 > 2 )
std::cerr << " * [INFO] Translating Material with " << m_Children.size();
std::cerr << " children, " << m_Refs.size() << " references and ";
std::cerr << m_BackPointers.size() << " backpointers\n";
#endif
if( m_sgNode )
{
if( NULL != aParent )

View File

@ -346,6 +346,9 @@ bool WRL2NODE::SetParent( WRL2NODE* aParent, bool doUnlink )
bool WRL2NODE::AddChildNode( WRL2NODE* aNode )
{
if( aNode == NULL )
return false;
if( aNode->GetNodeType() == WRL2_BASE )
{
#ifdef DEBUG_VRML2
@ -366,9 +369,11 @@ bool WRL2NODE::AddChildNode( WRL2NODE* aNode )
++sC;
}
aNode->SetParent( this );
m_Children.push_back( aNode );
if( aNode->GetParent() != this )
aNode->SetParent( this );
return true;
}

View File

@ -322,7 +322,30 @@ SGNODE* WRL2SHAPE::TranslateToSG( SGNODE* aParent, bool calcNormals )
if( NULL == geometry )
return NULL;
bool vcolors = ((WRL2FACESET*)geometry)->HasColors();
WRL2NODES geomType = geometry->GetNodeType();
switch( geomType )
{
case WRL2_INDEXEDLINESET:
case WRL2_POINTSET:
case WRL2_TEXT:
return NULL;
break;
default:
break;
}
#if defined( DEBUG_VRML2 ) && ( DEBUG_VRML2 > 2 )
std::cerr << " * [INFO] Translating Shape with " << m_Children.size();
std::cerr << " children, " << m_Refs.size() << " references and ";
std::cerr << m_BackPointers.size() << " backpointers\n";
#endif
bool vcolors = false;
if( WRL2_INDEXEDFACESET == geometry->GetNodeType() )
vcolors = ((WRL2FACESET*)geometry)->HasColors();
// if there is no appearance, make use of the per vertex colors if available
if( NULL == appearance )
@ -406,14 +429,10 @@ void WRL2SHAPE::unlinkChildNode( const WRL2NODE* aNode )
if( NULL == aNode )
return;
if( aNode->GetParent() == this )
{
if( aNode == appearance )
appearance = NULL;
else if( aNode == geometry )
geometry = NULL;
}
if( aNode == appearance )
appearance = NULL;
else if( aNode == geometry )
geometry = NULL;
WRL2NODE::unlinkChildNode( aNode );
return;
@ -425,14 +444,10 @@ void WRL2SHAPE::unlinkRefNode( const WRL2NODE* aNode )
if( NULL == aNode )
return;
if( aNode->GetParent() != this )
{
if( aNode == appearance )
appearance = NULL;
else if( aNode == geometry )
geometry = NULL;
}
if( aNode == appearance )
appearance = NULL;
else if( aNode == geometry )
geometry = NULL;
WRL2NODE::unlinkRefNode( aNode );
return;

View File

@ -1131,17 +1131,15 @@ bool WRLPROC::ReadSFVec3f( WRLVEC3F& aSFVec3f, bool* hasComma )
return false;
}
if( lComma && i != 2 )
// ignore any commas
if( !lComma )
{
std::ostringstream ostr;
ostr << __FILE__ << ":" << __FUNCTION__ << ":" << __LINE__ << "\n";
ostr << " * [INFO] failed on file '" << m_filename << "'\n";
ostr << " * [INFO] line " << fileline << ", char " << linepos << " -- ";
ostr << "line " << m_fileline << ", char " << m_linepos << "\n";
ostr << " * [INFO] comma encountered in space delimited triplet";
m_error = ostr.str();
if( !EatSpace() )
return false;
if( Peek() == ',' )
Pop();
return false;
}
std::istringstream istr;
@ -1680,7 +1678,10 @@ bool WRLPROC::ReadMFInt( std::vector< int >& aMFInt32 )
break;
if( ',' == m_buf[m_linepos] )
{
lcomma = true;
Pop();
}
}
if( !EatSpace() )

View File

@ -33,11 +33,11 @@
using namespace std;
void writeLeaded( FILE* fp, double width, double length, double height,
void writeLeaded( FILE* fp, double width, double length,
double wireDia, double pitch, bool inch );
void writeLeadless( FILE* fp, double width, double length,
double height, double chamfer, bool inch );
double chamfer, bool inch );
int main( int argc, char **argv )
{
@ -305,9 +305,9 @@ int main( int argc, char **argv )
}
if( leaded )
writeLeaded( fp, width, length, height, wireDia, pitch, inch );
writeLeaded( fp, width, length, wireDia, pitch, inch );
else
writeLeadless( fp, width, length, height, chamfer, inch );
writeLeadless( fp, width, length, chamfer, inch );
fprintf( fp, ".END_ELECTRICAL\n" );
fclose( fp );
@ -319,7 +319,7 @@ int main( int argc, char **argv )
void writeLeaded( FILE* fp, double width, double length,
double height, double wireDia, double pitch, bool inch )
double wireDia, double pitch, bool inch )
{
if( inch )
{
@ -370,7 +370,7 @@ void writeLeaded( FILE* fp, double width, double length,
}
void writeLeadless( FILE* fp, double width, double length,
double height, double chamfer, bool inch )
double chamfer, bool inch )
{
if( chamfer < 0.001 )
{