Work on SG consistency checks: fixed a number of bugs and improved integrity checking when writing cache files

This commit is contained in:
Cirilo Bernardo 2016-03-14 12:30:59 +11:00
parent 0085d1aea7
commit 30f9aba7c9
11 changed files with 197 additions and 26 deletions

View File

@ -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

View File

@ -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;
}

View File

@ -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;
}

View File

@ -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;
}

View File

@ -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;
}

View File

@ -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 )

View File

@ -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;
}

View File

@ -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

View File

@ -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);

View File

@ -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;
}

View File

@ -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;
}