Work on SG consistency checks: fixed a number of bugs and improved integrity checking when writing cache files
This commit is contained in:
parent
0085d1aea7
commit
30f9aba7c9
|
@ -363,7 +363,13 @@ bool SCENEGRAPH::WriteCache( std::ofstream& aFile, SGNODE* parentNode )
|
|||
while( NULL != np->GetParent() )
|
||||
np = np->GetParent();
|
||||
|
||||
return np->WriteCache( aFile, NULL );
|
||||
if( np->WriteCache( aFile, NULL ) )
|
||||
{
|
||||
m_written = true;
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
if( parentNode != m_Parent )
|
||||
|
@ -406,7 +412,34 @@ bool SCENEGRAPH::WriteCache( std::ofstream& aFile, SGNODE* parentNode )
|
|||
S3D::WriteVector( aFile, scale_axis );
|
||||
aFile.write( (char*)&scale_angle, sizeof( scale_angle ) );
|
||||
|
||||
size_t asize = m_Transforms.size();
|
||||
// Transfer ownership of any Transform references which hadn't been written
|
||||
size_t asize = m_RTransforms.size();
|
||||
size_t i;
|
||||
|
||||
for( i = 0; i < asize; ++i )
|
||||
{
|
||||
if( !m_RTransforms[i]->isWritten() )
|
||||
{
|
||||
m_RTransforms[i]->SwapParent( this );
|
||||
--asize;
|
||||
--i;
|
||||
}
|
||||
}
|
||||
|
||||
// Transfer ownership of any Shape references which hadn't been written
|
||||
asize = m_RShape.size();
|
||||
|
||||
for( i = 0; i < asize; ++i )
|
||||
{
|
||||
if( !m_RShape[i]->isWritten() )
|
||||
{
|
||||
m_RShape[i]->SwapParent( this );
|
||||
--asize;
|
||||
--i;
|
||||
}
|
||||
}
|
||||
|
||||
asize = m_Transforms.size();
|
||||
aFile.write( (char*)&asize, sizeof( size_t ) );
|
||||
asize = m_RTransforms.size();
|
||||
aFile.write( (char*)&asize, sizeof( size_t ) );
|
||||
|
@ -414,8 +447,6 @@ bool SCENEGRAPH::WriteCache( std::ofstream& aFile, SGNODE* parentNode )
|
|||
aFile.write( (char*)&asize, sizeof( size_t ) );
|
||||
asize = m_RShape.size();
|
||||
aFile.write( (char*)&asize, sizeof( size_t ) );
|
||||
|
||||
size_t i;
|
||||
asize = m_Transforms.size();
|
||||
|
||||
// write child transforms
|
||||
|
@ -464,6 +495,7 @@ bool SCENEGRAPH::WriteCache( std::ofstream& aFile, SGNODE* parentNode )
|
|||
if( aFile.fail() )
|
||||
return false;
|
||||
|
||||
m_written = true;
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -550,7 +582,7 @@ bool SCENEGRAPH::ReadCache( std::ifstream& aFile, SGNODE* parentNode )
|
|||
std::ostringstream ostr;
|
||||
ostr << __FILE__ << ": " << __FUNCTION__ << ": " << __LINE__ << "\n";
|
||||
ostr << " * [INFO] corrupt data while reading transform '";
|
||||
ostr << name << "'";
|
||||
ostr << name << "' pos " << aFile.tellg();
|
||||
wxLogTrace( MASK_3D_SG, "%s\n", ostr.str().c_str() );
|
||||
#endif
|
||||
|
||||
|
@ -582,7 +614,7 @@ bool SCENEGRAPH::ReadCache( std::ifstream& aFile, SGNODE* parentNode )
|
|||
std::ostringstream ostr;
|
||||
ostr << __FILE__ << ": " << __FUNCTION__ << ": " << __LINE__ << "\n";
|
||||
ostr << " * [INFO] corrupt data: cannot find ref transform '";
|
||||
ostr << name << "'";
|
||||
ostr << name << "' pos " << aFile.tellg();
|
||||
wxLogTrace( MASK_3D_SG, "%s\n", ostr.str().c_str() );
|
||||
#endif
|
||||
|
||||
|
@ -595,7 +627,7 @@ bool SCENEGRAPH::ReadCache( std::ifstream& aFile, SGNODE* parentNode )
|
|||
std::ostringstream ostr;
|
||||
ostr << __FILE__ << ": " << __FUNCTION__ << ": " << __LINE__ << "\n";
|
||||
ostr << " * [INFO] corrupt data: type is not TRANSFORM '";
|
||||
ostr << name << "'";
|
||||
ostr << name << "' pos " << aFile.tellg();
|
||||
wxLogTrace( MASK_3D_SG, "%s\n", ostr.str().c_str() );
|
||||
#endif
|
||||
|
||||
|
@ -630,7 +662,7 @@ bool SCENEGRAPH::ReadCache( std::ifstream& aFile, SGNODE* parentNode )
|
|||
std::ostringstream ostr;
|
||||
ostr << __FILE__ << ": " << __FUNCTION__ << ": " << __LINE__ << "\n";
|
||||
ostr << " * [INFO] corrupt data while reading shape '";
|
||||
ostr << name << "'";
|
||||
ostr << name << "' pos " << aFile.tellg();
|
||||
wxLogTrace( MASK_3D_SG, "%s\n", ostr.str().c_str() );
|
||||
#endif
|
||||
|
||||
|
@ -662,7 +694,7 @@ bool SCENEGRAPH::ReadCache( std::ifstream& aFile, SGNODE* parentNode )
|
|||
std::ostringstream ostr;
|
||||
ostr << __FILE__ << ": " << __FUNCTION__ << ": " << __LINE__ << "\n";
|
||||
ostr << " * [INFO] corrupt data: cannot find ref shape '";
|
||||
ostr << name << "'";
|
||||
ostr << name << "' pos " << aFile.tellg();
|
||||
wxLogTrace( MASK_3D_SG, "%s\n", ostr.str().c_str() );
|
||||
#endif
|
||||
|
||||
|
@ -675,7 +707,7 @@ bool SCENEGRAPH::ReadCache( std::ifstream& aFile, SGNODE* parentNode )
|
|||
std::ostringstream ostr;
|
||||
ostr << __FILE__ << ": " << __FUNCTION__ << ": " << __LINE__ << "\n";
|
||||
ostr << " * [INFO] corrupt data: type is not SGSHAPE '";
|
||||
ostr << name << "'";
|
||||
ostr << name << "' pos " << aFile.tellg();
|
||||
wxLogTrace( MASK_3D_SG, "%s\n", ostr.str().c_str() );
|
||||
#endif
|
||||
|
||||
|
|
|
@ -387,7 +387,13 @@ bool SGAPPEARANCE::WriteCache( std::ofstream& aFile, SGNODE* parentNode )
|
|||
while( NULL != np->GetParent() )
|
||||
np = np->GetParent();
|
||||
|
||||
return np->WriteCache( aFile, NULL );
|
||||
if( np->WriteCache( aFile, NULL ) )
|
||||
{
|
||||
m_written = true;
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
if( parentNode != m_Parent )
|
||||
|
@ -425,6 +431,7 @@ bool SGAPPEARANCE::WriteCache( std::ofstream& aFile, SGNODE* parentNode )
|
|||
if( aFile.fail() )
|
||||
return false;
|
||||
|
||||
m_written = true;
|
||||
return true;
|
||||
}
|
||||
|
||||
|
|
|
@ -286,7 +286,13 @@ bool SGCOLORS::WriteCache( std::ofstream& aFile, SGNODE* parentNode )
|
|||
while( NULL != np->GetParent() )
|
||||
np = np->GetParent();
|
||||
|
||||
return np->WriteCache( aFile, NULL );
|
||||
if( np->WriteCache( aFile, NULL ) )
|
||||
{
|
||||
m_written = true;
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
if( parentNode != m_Parent )
|
||||
|
@ -323,6 +329,7 @@ bool SGCOLORS::WriteCache( std::ofstream& aFile, SGNODE* parentNode )
|
|||
if( aFile.fail() )
|
||||
return false;
|
||||
|
||||
m_written = true;
|
||||
return true;
|
||||
}
|
||||
|
||||
|
|
|
@ -293,7 +293,13 @@ bool SGCOORDS::WriteCache( std::ofstream& aFile, SGNODE* parentNode )
|
|||
while( NULL != np->GetParent() )
|
||||
np = np->GetParent();
|
||||
|
||||
return np->WriteCache( aFile, NULL );
|
||||
if( np->WriteCache( aFile, NULL ) )
|
||||
{
|
||||
m_written = true;
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
if( parentNode != m_Parent )
|
||||
|
@ -330,6 +336,7 @@ bool SGCOORDS::WriteCache( std::ofstream& aFile, SGNODE* parentNode )
|
|||
if( aFile.fail() )
|
||||
return false;
|
||||
|
||||
m_written = true;
|
||||
return true;
|
||||
}
|
||||
|
||||
|
|
|
@ -239,18 +239,21 @@ void SGFACESET::unlinkNode( const SGNODE* aNode, bool isChild )
|
|||
{
|
||||
if( aNode == m_RColors )
|
||||
{
|
||||
delNodeRef( this );
|
||||
m_RColors = NULL;
|
||||
return;
|
||||
}
|
||||
|
||||
if( aNode == m_RCoords )
|
||||
{
|
||||
delNodeRef( this );
|
||||
m_RCoords = NULL;
|
||||
return;
|
||||
}
|
||||
|
||||
if( aNode == m_RNormals )
|
||||
{
|
||||
delNodeRef( this );
|
||||
m_RNormals = NULL;
|
||||
return;
|
||||
}
|
||||
|
@ -558,7 +561,13 @@ bool SGFACESET::WriteCache( std::ofstream& aFile, SGNODE* parentNode )
|
|||
while( NULL != np->GetParent() )
|
||||
np = np->GetParent();
|
||||
|
||||
return np->WriteCache( aFile, NULL );
|
||||
if( np->WriteCache( aFile, NULL ) )
|
||||
{
|
||||
m_written = true;
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
if( parentNode != m_Parent )
|
||||
|
@ -585,6 +594,16 @@ bool SGFACESET::WriteCache( std::ofstream& aFile, SGNODE* parentNode )
|
|||
return false;
|
||||
}
|
||||
|
||||
// check if any references are unwritten and swap parents if so
|
||||
if( NULL != m_RCoords && !m_RCoords->isWritten() )
|
||||
m_RCoords->SwapParent( this );
|
||||
|
||||
if( NULL != m_RNormals && !m_RNormals->isWritten() )
|
||||
m_RNormals->SwapParent( this );
|
||||
|
||||
if( NULL != m_RColors && !m_RColors->isWritten() )
|
||||
m_RColors->SwapParent( this );
|
||||
|
||||
aFile << "[" << GetName() << "]";
|
||||
#define NITEMS 7
|
||||
bool items[NITEMS];
|
||||
|
@ -648,6 +667,7 @@ bool SGFACESET::WriteCache( std::ofstream& aFile, SGNODE* parentNode )
|
|||
if( aFile.fail() )
|
||||
return false;
|
||||
|
||||
m_written = true;
|
||||
return true;
|
||||
}
|
||||
|
||||
|
|
|
@ -84,17 +84,25 @@ class SGCOORDINDEX;
|
|||
oSL = &aOwnedList; \
|
||||
sL = aOwnedList.begin(); \
|
||||
eL = aOwnedList.end(); \
|
||||
while( sL != eL ) { \
|
||||
if( (SGNODE*)*sL == aNode ) { \
|
||||
oSL->erase( sL ); \
|
||||
return; \
|
||||
} \
|
||||
++sL; \
|
||||
} \
|
||||
} else { \
|
||||
oSL = &aRefList; \
|
||||
sL = aRefList.begin(); \
|
||||
eL = aRefList.end(); \
|
||||
} \
|
||||
while( sL != eL ) { \
|
||||
if( (SGNODE*)*sL == aNode ) { \
|
||||
oSL->erase( sL ); \
|
||||
return; \
|
||||
while( sL != eL ) { \
|
||||
if( (SGNODE*)*sL == aNode ) { \
|
||||
delNodeRef( this ); \
|
||||
oSL->erase( sL ); \
|
||||
return; \
|
||||
} \
|
||||
++sL; \
|
||||
} \
|
||||
++sL; \
|
||||
} \
|
||||
return; \
|
||||
} } while( 0 )
|
||||
|
|
|
@ -316,7 +316,13 @@ bool SGINDEX::WriteCache( std::ofstream& aFile, SGNODE* parentNode )
|
|||
while( NULL != np->GetParent() )
|
||||
np = np->GetParent();
|
||||
|
||||
return np->WriteCache( aFile, NULL );
|
||||
if( np->WriteCache( aFile, NULL ) )
|
||||
{
|
||||
m_written = true;
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
if( parentNode != m_Parent )
|
||||
|
@ -353,6 +359,7 @@ bool SGINDEX::WriteCache( std::ofstream& aFile, SGNODE* parentNode )
|
|||
if( aFile.fail() )
|
||||
return false;
|
||||
|
||||
m_written = true;
|
||||
return true;
|
||||
}
|
||||
|
||||
|
|
|
@ -117,6 +117,36 @@ SGNODE* SGNODE::GetParent( void ) const
|
|||
}
|
||||
|
||||
|
||||
bool SGNODE::SwapParent( SGNODE* aNewParent )
|
||||
{
|
||||
if( aNewParent == m_Parent )
|
||||
return true;
|
||||
|
||||
if( NULL == aNewParent )
|
||||
return false;
|
||||
|
||||
if( NULL == m_Parent )
|
||||
{
|
||||
if( aNewParent->AddChildNode( this ) )
|
||||
return true;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
if( aNewParent->GetNodeType() != m_Parent->GetNodeType() )
|
||||
return false;
|
||||
|
||||
SGNODE* oldParent = m_Parent;
|
||||
m_Parent->unlinkChildNode( this );
|
||||
m_Parent = NULL;
|
||||
aNewParent->unlinkRefNode( this );
|
||||
aNewParent->AddChildNode( this );
|
||||
oldParent->AddRefNode( this );
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
const char* SGNODE::GetName( void )
|
||||
{
|
||||
if( m_Name.empty() )
|
||||
|
@ -145,6 +175,9 @@ const char * SGNODE::GetNodeTypeName( S3D::SGTYPES aNodeType ) const
|
|||
|
||||
void SGNODE::addNodeRef( SGNODE* aNode )
|
||||
{
|
||||
if( NULL == aNode )
|
||||
return;
|
||||
|
||||
std::list< SGNODE* >::iterator np =
|
||||
std::find( m_BackPointers.begin(), m_BackPointers.end(), aNode );
|
||||
|
||||
|
@ -156,8 +189,11 @@ void SGNODE::addNodeRef( SGNODE* aNode )
|
|||
}
|
||||
|
||||
|
||||
void SGNODE::delNodeRef( SGNODE* aNode )
|
||||
void SGNODE::delNodeRef( const SGNODE* aNode )
|
||||
{
|
||||
if( NULL == aNode )
|
||||
return;
|
||||
|
||||
std::list< SGNODE* >::iterator np =
|
||||
std::find( m_BackPointers.begin(), m_BackPointers.end(), aNode );
|
||||
|
||||
|
@ -170,7 +206,9 @@ void SGNODE::delNodeRef( SGNODE* aNode )
|
|||
#ifdef DEBUG
|
||||
std::ostringstream ostr;
|
||||
ostr << __FILE__ << ": " << __FUNCTION__ << ": " << __LINE__ << "\n";
|
||||
ostr << " * [BUG] delNodeRef() did not find its target";
|
||||
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
|
||||
|
||||
|
|
|
@ -120,7 +120,17 @@ public:
|
|||
*
|
||||
* @param aNode is the node holding a reference to this object
|
||||
*/
|
||||
void delNodeRef( SGNODE* aNode );
|
||||
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 )
|
||||
{
|
||||
return m_written;
|
||||
}
|
||||
|
||||
public:
|
||||
SGNODE( SGNODE* aParent );
|
||||
|
@ -150,6 +160,17 @@ public:
|
|||
*/
|
||||
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.
|
||||
*
|
||||
* @param aNewParent [in] will become the new parent to the
|
||||
* object; it must be the same type as the parent of this
|
||||
* instance.
|
||||
*/
|
||||
bool SwapParent( SGNODE* aNewParent );
|
||||
|
||||
const char* GetName( void );
|
||||
void SetName(const char *aName);
|
||||
|
||||
|
|
|
@ -285,7 +285,13 @@ bool SGNORMALS::WriteCache( std::ofstream& aFile, SGNODE* parentNode )
|
|||
while( NULL != np->GetParent() )
|
||||
np = np->GetParent();
|
||||
|
||||
return np->WriteCache( aFile, NULL );
|
||||
if( np->WriteCache( aFile, NULL ) )
|
||||
{
|
||||
m_written = true;
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
if( parentNode != m_Parent )
|
||||
|
@ -322,6 +328,7 @@ bool SGNORMALS::WriteCache( std::ofstream& aFile, SGNODE* parentNode )
|
|||
if( aFile.fail() )
|
||||
return false;
|
||||
|
||||
m_written = true;
|
||||
return true;
|
||||
}
|
||||
|
||||
|
|
|
@ -191,13 +191,16 @@ void SGSHAPE::unlinkNode( const SGNODE* aNode, bool isChild )
|
|||
{
|
||||
if( aNode == m_RAppearance )
|
||||
{
|
||||
delNodeRef( this );
|
||||
m_RAppearance = NULL;
|
||||
return;
|
||||
}
|
||||
|
||||
if( aNode == m_RFaceSet )
|
||||
{
|
||||
delNodeRef( this );
|
||||
m_RFaceSet = NULL;
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -421,7 +424,13 @@ bool SGSHAPE::WriteCache( std::ofstream& aFile, SGNODE* parentNode )
|
|||
while( NULL != np->GetParent() )
|
||||
np = np->GetParent();
|
||||
|
||||
return np->WriteCache( aFile, NULL );
|
||||
if( np->WriteCache( aFile, NULL ) )
|
||||
{
|
||||
m_written = true;
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
if( parentNode != m_Parent )
|
||||
|
@ -448,6 +457,13 @@ bool SGSHAPE::WriteCache( std::ofstream& aFile, SGNODE* parentNode )
|
|||
return false;
|
||||
}
|
||||
|
||||
// check if any references are unwritten and swap parents if so
|
||||
if( NULL != m_RAppearance && !m_RAppearance->isWritten() )
|
||||
m_RAppearance->SwapParent(this);
|
||||
|
||||
if( NULL != m_RFaceSet && !m_RFaceSet->isWritten() )
|
||||
m_RFaceSet->SwapParent( this );
|
||||
|
||||
aFile << "[" << GetName() << "]";
|
||||
#define NITEMS 4
|
||||
bool items[NITEMS];
|
||||
|
@ -490,6 +506,7 @@ bool SGSHAPE::WriteCache( std::ofstream& aFile, SGNODE* parentNode )
|
|||
if( aFile.fail() )
|
||||
return false;
|
||||
|
||||
m_written = true;
|
||||
return true;
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue