KiCad PCB EDA Suite
SCENEGRAPH Class Reference

Define the basic data set required to represent a 3D model. More...

#include <scenegraph.h>

Inheritance diagram for SCENEGRAPH:
SGNODE

Public Member Functions

void unlinkChildNode (const SGNODE *aNode) override
 Remove references to an owned child. More...
 
void unlinkRefNode (const SGNODE *aNode) override
 Remove pointers to a referenced node. More...
 
 SCENEGRAPH (SGNODE *aParent)
 
virtual ~SCENEGRAPH ()
 
virtual bool SetParent (SGNODE *aParent, bool notify=true) override
 Set the parent SGNODE of this object. More...
 
SGNODEFindNode (const char *aNodeName, const SGNODE *aCaller) override
 Search the tree of linked nodes and return a reference to the first node found with the given name. More...
 
bool AddRefNode (SGNODE *aNode) override
 
bool AddChildNode (SGNODE *aNode) override
 
void ReNameNodes (void) override
 Rename a node and all its child nodes in preparation for write operations. More...
 
bool WriteVRML (std::ostream &aFile, bool aReuseFlag) override
 Writes this node's data to a VRML file. More...
 
bool WriteCache (std::ostream &aFile, SGNODE *parentNode) override
 Write this node's data to a binary cache file. More...
 
bool ReadCache (std::istream &aFile, SGNODE *parentNode) override
 Reads binary format data from a cache file. More...
 
bool Prepare (const glm::dmat4 *aTransform, S3D::MATLIST &materials, std::vector< SMESH > &meshes)
 
S3D::SGTYPES GetNodeType (void) const noexcept
 Return the type of this node instance. More...
 
SGNODEGetParent (void) const noexcept
 Returns a pointer to the parent SGNODE of this object or NULL if the object has no parent (ie. More...
 
bool SwapParent (SGNODE *aNewParent)
 Swap the ownership with the given parent. More...
 
const char * GetName (void)
 
void SetName (const char *aName)
 
const char * GetNodeTypeName (S3D::SGTYPES aNodeType) const noexcept
 
void AssociateWrapper (SGNODE **aWrapperRef) noexcept
 Associate this object with a handle to itself. More...
 
void DisassociateWrapper (SGNODE **aWrapperRef) noexcept
 Remove the association between an IFSG* wrapper object and this object. More...
 
void ResetNodeIndex (void) noexcept
 Reset the global SG* node indices in preparation for write operations. More...
 
void addNodeRef (SGNODE *aNode)
 Add a pointer to a node which references this node, but does not own. More...
 
void delNodeRef (const SGNODE *aNode)
 Remove a pointer to a node which references this node, but does not own. More...
 
bool isWritten (void) noexcept
 Return true if the object had already been written to a cache file or VRML file. More...
 

Public Attributes

SGPOINT center
 
SGPOINT translation
 
SGVECTOR rotation_axis
 
double rotation_angle
 
SGPOINT scale
 
SGVECTOR scale_axis
 
double scale_angle
 

Protected Attributes

std::list< SGNODE * > m_BackPointers
 nodes which hold a reference to this. More...
 
SGNODEm_Parent
 Pointer to parent node; may be NULL for top level transform. More...
 
S3D::SGTYPES m_SGtype
 Type of Scene Graph node. More...
 
std::string m_Name
 name to use for referencing the entity by name. More...
 
bool m_written
 Set to true when the object has been written after a ReNameNodes(). More...
 

Private Member Functions

void unlinkNode (const SGNODE *aNode, bool isChild)
 
bool addNode (SGNODE *aNode, bool isChild)
 

Private Attributes

std::vector< SCENEGRAPH * > m_Transforms
 
std::vector< SGSHAPE * > m_Shape
 
std::vector< SCENEGRAPH * > m_RTransforms
 
std::vector< SGSHAPE * > m_RShape
 
SGNODE ** m_Association
 Handle to the instance held by a wrapper. More...
 

Detailed Description

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.

Definition at line 44 of file scenegraph.h.

Constructor & Destructor Documentation

◆ SCENEGRAPH()

SCENEGRAPH::SCENEGRAPH ( SGNODE aParent)

Definition at line 38 of file scenegraph.cpp.

38 : SGNODE( aParent )
39{
41 rotation_angle = 0.0;
42 scale_angle = 0.0;
43
44 scale.x = 1.0;
45 scale.y = 1.0;
46 scale.z = 1.0;
47
48 if( nullptr != aParent && S3D::SGTYPE_TRANSFORM != aParent->GetNodeType() )
49 {
50 m_Parent = nullptr;
51
52 wxLogTrace( MASK_3D_SG,
53 wxT( "%s:%s:%d * [BUG] inappropriate parent to SCENEGRAPH (type %d)" ),
54 __FILE__, __FUNCTION__, __LINE__,
55 aParent->GetNodeType() );
56 }
57 else if( nullptr != aParent && S3D::SGTYPE_TRANSFORM == aParent->GetNodeType() )
58 {
59 m_Parent->AddChildNode( this );
60 }
61}
double rotation_angle
Definition: scenegraph.h:76
double scale_angle
Definition: scenegraph.h:79
SGPOINT scale
Definition: scenegraph.h:77
S3D::SGTYPES GetNodeType(void) const noexcept
Return the type of this node instance.
Definition: sg_node.cpp:104
virtual bool AddChildNode(SGNODE *aNode)=0
SGNODE * m_Parent
Pointer to parent node; may be NULL for top level transform.
Definition: sg_node.h:227
SGNODE(SGNODE *aParent)
Definition: sg_node.cpp:76
S3D::SGTYPES m_SGtype
Type of Scene Graph node.
Definition: sg_node.h:228
double z
Definition: sg_base.h:72
double x
Definition: sg_base.h:70
double y
Definition: sg_base.h:71
@ SGTYPE_TRANSFORM
Definition: sg_types.h:36

References SGNODE::AddChildNode(), SGNODE::GetNodeType(), SGNODE::m_Parent, SGNODE::m_SGtype, rotation_angle, scale, scale_angle, S3D::SGTYPE_TRANSFORM, SGPOINT::x, SGPOINT::y, and SGPOINT::z.

Referenced by ReadCache().

◆ ~SCENEGRAPH()

SCENEGRAPH::~SCENEGRAPH ( )
virtual

Definition at line 64 of file scenegraph.cpp.

65{
66 // drop references
69
70 // delete owned objects
73}
Define the basic data set required to represent a 3D model.
Definition: scenegraph.h:45
std::vector< SGSHAPE * > m_RShape
Definition: scenegraph.h:92
std::vector< SCENEGRAPH * > m_RTransforms
Definition: scenegraph.h:91
std::vector< SGSHAPE * > m_Shape
Definition: scenegraph.h:89
std::vector< SCENEGRAPH * > m_Transforms
Definition: scenegraph.h:88
Define a complex 3D shape for a scenegraph object.
Definition: sg_shape.h:43
#define DEL_OBJS(aType, aList)
Definition: sg_helpers.h:69
#define DROP_REFS(aType, aList)
Definition: sg_helpers.h:52

References DEL_OBJS, DROP_REFS, m_RShape, m_RTransforms, m_Shape, and m_Transforms.

Member Function Documentation

◆ AddChildNode()

bool SCENEGRAPH::AddChildNode ( SGNODE aNode)
overridevirtual

Implements SGNODE.

Definition at line 187 of file scenegraph.cpp.

188{
189 return addNode( aNode, true );
190}
bool addNode(SGNODE *aNode, bool isChild)
Definition: scenegraph.cpp:164

References addNode().

◆ addNode()

bool SCENEGRAPH::addNode ( SGNODE aNode,
bool  isChild 
)
private

Definition at line 164 of file scenegraph.cpp.

165{
166 wxCHECK( aNode, false );
167
169 ADD_NODE( S3D::SGTYPE_SHAPE, SGSHAPE, aNode, m_Shape, m_RShape, isChild );
170
171 wxLogTrace( MASK_3D_SG,
172 wxT( "%s:%s:%d * [BUG] object '%s' is not a valid type for this object (%d)" ),
173 __FILE__, __FUNCTION__, __LINE__,
174 aNode->GetName(),
175 aNode->GetNodeType() );
176
177 return false;
178}
const char * GetName(void)
Definition: sg_node.cpp:146
@ SGTYPE_SHAPE
Definition: sg_types.h:44
#define ADD_NODE(aNodeID, aType, aNode, aOwnedList, aRefList, isChild)
Definition: sg_helpers.h:132

References ADD_NODE, SGNODE::GetName(), SGNODE::GetNodeType(), m_RShape, m_RTransforms, m_Shape, m_Transforms, S3D::SGTYPE_SHAPE, and S3D::SGTYPE_TRANSFORM.

Referenced by AddChildNode(), and AddRefNode().

◆ addNodeRef()

void SGNODE::addNodeRef ( SGNODE aNode)
inherited

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.

Parameters
aNodeis the node holding a reference to this object.

Definition at line 170 of file sg_node.cpp.

171{
172 if( nullptr == aNode )
173 return;
174
175 std::list< SGNODE* >::iterator np =
176 std::find( m_BackPointers.begin(), m_BackPointers.end(), aNode );
177
178 if( np != m_BackPointers.end() )
179 return;
180
181 m_BackPointers.push_back( aNode );
182}
std::list< SGNODE * > m_BackPointers
nodes which hold a reference to this.
Definition: sg_node.h:226

References SGNODE::m_BackPointers.

Referenced by SGFACESET::addNode(), SGSHAPE::addNode(), SGFACESET::ReadCache(), and SGSHAPE::ReadCache().

◆ AddRefNode()

bool SCENEGRAPH::AddRefNode ( SGNODE aNode)
overridevirtual

Implements SGNODE.

Definition at line 181 of file scenegraph.cpp.

182{
183 return addNode( aNode, false );
184}

References addNode().

Referenced by ReadCache().

◆ AssociateWrapper()

void SGNODE::AssociateWrapper ( SGNODE **  aWrapperRef)
noexceptinherited

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.

Definition at line 207 of file sg_node.cpp.

208{
209 wxCHECK( aWrapperRef && *aWrapperRef == this, /* void */ );
210
211 // if there is an existing association then break it and emit a warning
212 // just in case the behavior is undesired
213 if( m_Association )
214 {
215 *m_Association = nullptr;
216
217 wxLogTrace( MASK_3D_SG, wxT( "%s:%s:%d * [WARNING] association being broken with "
218 "previous wrapper" ),
219 __FILE__, __FUNCTION__, __LINE__ );
220 }
221
222 m_Association = aWrapperRef;
223}
SGNODE ** m_Association
Handle to the instance held by a wrapper.
Definition: sg_node.h:233

Referenced by S3D::AssociateSGNodeWrapper(), IFSG_APPEARANCE::Attach(), IFSG_COLORS::Attach(), IFSG_COORDINDEX::Attach(), IFSG_COORDS::Attach(), IFSG_FACESET::Attach(), IFSG_NORMALS::Attach(), IFSG_SHAPE::Attach(), IFSG_TRANSFORM::Attach(), IFSG_APPEARANCE::IFSG_APPEARANCE(), IFSG_COLORS::IFSG_COLORS(), IFSG_COORDINDEX::IFSG_COORDINDEX(), IFSG_COORDS::IFSG_COORDS(), IFSG_FACESET::IFSG_FACESET(), IFSG_NORMALS::IFSG_NORMALS(), IFSG_SHAPE::IFSG_SHAPE(), IFSG_TRANSFORM::IFSG_TRANSFORM(), IFSG_APPEARANCE::NewNode(), IFSG_COLORS::NewNode(), IFSG_COORDINDEX::NewNode(), IFSG_COORDS::NewNode(), IFSG_FACESET::NewNode(), IFSG_NORMALS::NewNode(), IFSG_SHAPE::NewNode(), and IFSG_TRANSFORM::NewNode().

◆ delNodeRef()

void SGNODE::delNodeRef ( const SGNODE aNode)
inherited

Remove a pointer to a node which references this node, but does not own.

Parameters
aNodeis the node holding a reference to this object.

Definition at line 185 of file sg_node.cpp.

186{
187 if( nullptr == aNode )
188 return;
189
190 std::list< SGNODE* >::iterator np =
191 std::find( m_BackPointers.begin(), m_BackPointers.end(), aNode );
192
193 if( np != m_BackPointers.end() )
194 {
195 m_BackPointers.erase( np );
196 return;
197 }
198
199 wxLogTrace( MASK_3D_SG, wxT( "%s:%s:%d * [BUG] delNodeRef() did not find its target, this "
200 "node type %d, referenced node type %d" ),
201 __FILE__, __FUNCTION__, __LINE__,
202 m_SGtype,
203 aNode->GetNodeType() );
204}

References SGNODE::GetNodeType(), SGNODE::m_BackPointers, and SGNODE::m_SGtype.

Referenced by SGFACESET::unlinkNode(), SGSHAPE::unlinkNode(), SGFACESET::~SGFACESET(), and SGSHAPE::~SGSHAPE().

◆ DisassociateWrapper()

void SGNODE::DisassociateWrapper ( SGNODE **  aWrapperRef)
noexceptinherited

Remove the association between an IFSG* wrapper object and this object.

Definition at line 225 of file sg_node.cpp.

226{
227 if( !m_Association )
228 return;
229
230 wxCHECK( aWrapperRef, /* void */ );
231
232 wxCHECK( *aWrapperRef == *m_Association && aWrapperRef == m_Association, /* void */ );
233
234 m_Association = nullptr;
235}

Referenced by IFSG_APPEARANCE::Attach(), IFSG_COLORS::Attach(), IFSG_COORDINDEX::Attach(), IFSG_COORDS::Attach(), IFSG_FACESET::Attach(), IFSG_NORMALS::Attach(), IFSG_SHAPE::Attach(), IFSG_TRANSFORM::Attach(), IFSG_NODE::Destroy(), IFSG_APPEARANCE::NewNode(), IFSG_COLORS::NewNode(), IFSG_COORDINDEX::NewNode(), IFSG_COORDS::NewNode(), IFSG_FACESET::NewNode(), IFSG_NORMALS::NewNode(), IFSG_SHAPE::NewNode(), IFSG_TRANSFORM::NewNode(), and IFSG_NODE::~IFSG_NODE().

◆ FindNode()

SGNODE * SCENEGRAPH::FindNode ( const char *  aNodeName,
const SGNODE aCaller 
)
overridevirtual

Search the tree of linked nodes and return a reference to the first node found with the given name.

The reference is then typically added to another node via AddRefNode().

Parameters
aNodeNameis the name of the node to search for.
aCalleris a pointer to the node invoking this function.
Returns
is a valid node pointer on success, otherwise NULL.

Implements SGNODE.

Definition at line 106 of file scenegraph.cpp.

107{
108 if( nullptr == aNodeName || 0 == aNodeName[0] )
109 return nullptr;
110
111 if( !m_Name.compare( aNodeName ) )
112 return this;
113
114 FIND_NODE( SCENEGRAPH, aNodeName, m_Transforms, aCaller );
115 FIND_NODE( SGSHAPE, aNodeName, m_Shape, aCaller );
116
117 // query the parent if appropriate
118 if( aCaller == m_Parent || nullptr == m_Parent )
119 return nullptr;
120
121 return m_Parent->FindNode( aNodeName, this );
122}
virtual SGNODE * FindNode(const char *aNodeName, const SGNODE *aCaller)=0
Search the tree of linked nodes and return a reference to the first node found with the given name.
std::string m_Name
name to use for referencing the entity by name.
Definition: sg_node.h:229
#define FIND_NODE(aType, aName, aNodeList, aCallingNode)
Definition: sg_helpers.h:173

References FIND_NODE, SGNODE::FindNode(), SGNODE::m_Name, SGNODE::m_Parent, m_Shape, and m_Transforms.

Referenced by ReadCache().

◆ GetName()

◆ GetNodeType()

◆ GetNodeTypeName()

const char * SGNODE::GetNodeTypeName ( S3D::SGTYPES  aNodeType) const
noexceptinherited

Definition at line 164 of file sg_node.cpp.

165{
166 return node_names[aNodeType].c_str();
167}
static const std::string node_names[S3D::SGTYPE_END+1]
Definition: sg_node.cpp:36

References node_names.

Referenced by IFSG_NODE::GetNodeTypeName(), IFSG_APPEARANCE::NewNode(), IFSG_COLORS::NewNode(), IFSG_COORDINDEX::NewNode(), IFSG_COORDS::NewNode(), IFSG_FACESET::NewNode(), IFSG_NORMALS::NewNode(), IFSG_SHAPE::NewNode(), and IFSG_TRANSFORM::NewNode().

◆ GetParent()

◆ isWritten()

bool SGNODE::isWritten ( void  )
inlinenoexceptinherited

Return true if the object had already been written to a cache file or VRML file.

For internal use only.

Definition at line 220 of file sg_node.h.

221 {
222 return m_written;
223 }
bool m_written
Set to true when the object has been written after a ReNameNodes().
Definition: sg_node.h:230

References SGNODE::m_written.

Referenced by WriteCache(), SGFACESET::WriteCache(), and SGSHAPE::WriteCache().

◆ Prepare()

bool SCENEGRAPH::Prepare ( const glm::dmat4 *  aTransform,
S3D::MATLIST materials,
std::vector< SMESH > &  meshes 
)

Definition at line 647 of file scenegraph.cpp.

649{
650 // calculate the accumulated transform
651 double rX, rY, rZ;
652
653 // rotation
654 rotation_axis.GetVector( rX, rY, rZ );
655 glm::dmat4 rM = glm::rotate( glm::dmat4( 1.0 ), rotation_angle, glm::dvec3( rX, rY, rZ ) );
656
657 // translation
658 glm::dmat4 tM = glm::translate( glm::dmat4( 1.0 ), glm::dvec3( translation.x, translation.y,
659 translation.z ) );
660 // center
661 glm::dmat4 cM = glm::translate( glm::dmat4( 1.0 ), glm::dvec3( center.x, center.y, center.z ) );
662 glm::dmat4 ncM = glm::translate( glm::dmat4( 1.0 ), glm::dvec3( -center.x, -center.y,
663 -center.z ) );
664
665 // scale
666 glm::dmat4 sM = glm::scale( glm::dmat4( 1.0 ), glm::dvec3( scale.x, scale.y, scale.z ) );
667
668 // scaleOrientation
669 scale_axis.GetVector( rX, rY, rZ );
670 glm::dmat4 srM = glm::rotate( glm::dmat4( 1.0 ), scale_angle, glm::dvec3( rX, rY, rZ ) );
671 glm::dmat4 nsrM = glm::rotate( glm::dmat4( 1.0 ), -scale_angle, glm::dvec3( rX, rY, rZ ) );
672
673 // resultant point:
674 // P' = T x C x R x SR x S x -SR x -C x P
675 // resultant transform:
676 // tx0 = tM * cM * rM * srM * sM * nsrM * ncM
677 glm::dmat4 tx0;
678
679 if( nullptr != aTransform )
680 tx0 = (*aTransform) * tM * cM * rM * srM * sM * nsrM * ncM;
681 else
682 tx0 = tM * cM * rM * srM * sM * nsrM * ncM;
683
684 bool ok = true;
685
686 // prepare all shapes
687 do
688 {
689 std::vector< SGSHAPE* >::iterator sL = m_Shape.begin();
690 std::vector< SGSHAPE* >::iterator eL = m_Shape.end();
691
692 while( sL != eL && ok )
693 {
694 ok = (*sL)->Prepare( &tx0, materials, meshes );
695 ++sL;
696 }
697
698 sL = m_RShape.begin();
699 eL = m_RShape.end();
700
701 while( sL != eL && ok )
702 {
703 ok = (*sL)->Prepare( &tx0, materials, meshes );
704 ++sL;
705 }
706
707 } while( 0 );
708
709 // prepare all transforms
710 do
711 {
712 std::vector< SCENEGRAPH* >::iterator sL = m_Transforms.begin();
713 std::vector< SCENEGRAPH* >::iterator eL = m_Transforms.end();
714
715 while( sL != eL && ok )
716 {
717 ok = (*sL)->Prepare( &tx0, materials, meshes );
718 ++sL;
719 }
720
721 sL = m_RTransforms.begin();
722 eL = m_RTransforms.end();
723
724 while( sL != eL && ok )
725 {
726 ok = (*sL)->Prepare( &tx0, materials, meshes );
727 ++sL;
728 }
729
730 } while( 0 );
731
732 return ok;
733}
SGVECTOR scale_axis
Definition: scenegraph.h:78
SGPOINT center
Definition: scenegraph.h:73
SGVECTOR rotation_axis
Definition: scenegraph.h:75
SGPOINT translation
Definition: scenegraph.h:74
void GetVector(double &aXVal, double &aYVal, double &aZVal) const noexcept
Definition: sg_base.cpp:225
const int scale

References center, SGVECTOR::GetVector(), m_RShape, m_RTransforms, m_Shape, m_Transforms, rotation_angle, rotation_axis, scale, scale, scale_angle, scale_axis, translation, SGPOINT::x, SGPOINT::y, and SGPOINT::z.

Referenced by S3D::GetModel().

◆ ReadCache()

bool SCENEGRAPH::ReadCache ( std::istream &  aFile,
SGNODE parentNode 
)
overridevirtual

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.

Implements SGNODE.

Definition at line 466 of file scenegraph.cpp.

467{
468 wxCHECK( m_Transforms.empty() && m_RTransforms.empty() && m_Shape.empty() && m_RShape.empty(),
469 false );
470
471 std::string name; // name of the node
472
473 if( nullptr == parentNode )
474 {
475 // we need to read the tag and verify its type
476 if( S3D::SGTYPE_TRANSFORM != S3D::ReadTag( aFile, name ) )
477 {
478 wxLogTrace( MASK_3D_SG, wxT( "%s:%s:%d * [INFO] corrupt data; tag mismatch at position "
479 "%ul" ),
480 __FILE__, __FUNCTION__, __LINE__,
481 static_cast<unsigned long>( aFile.tellg() ) );
482
483 return false;
484 }
485
486 m_Name = name;
487 }
488
489 // read fixed member data
490 S3D::ReadPoint( aFile, center );
491 S3D::ReadPoint( aFile, translation );
493 aFile.read( (char*)&rotation_angle, sizeof( rotation_angle ) );
494 S3D::ReadPoint( aFile, scale );
495 S3D::ReadVector( aFile, scale_axis );
496 aFile.read( (char*)&scale_angle, sizeof( scale_angle ) );
497
498 size_t sizeCT = 0; // child transforms
499 size_t sizeRT = 0; // referenced transforms
500 size_t sizeCS = 0; // child shapes
501 size_t sizeRS = 0; // referenced shapes
502
503 aFile.read( (char*)&sizeCT, sizeof( size_t ) );
504 aFile.read( (char*)&sizeRT, sizeof( size_t ) );
505 aFile.read( (char*)&sizeCS, sizeof( size_t ) );
506 aFile.read( (char*)&sizeRS, sizeof( size_t ) );
507
508 size_t i;
509
510 // read child transforms
511 for( i = 0; i < sizeCT; ++i )
512 {
513 if( S3D::SGTYPE_TRANSFORM != S3D::ReadTag( aFile, name ) )
514 {
515 wxLogTrace( MASK_3D_SG, wxT( "%s:%s:%d * [INFO] corrupt data; bad child transform tag "
516 "at position %ul" ),
517 __FILE__, __FUNCTION__, __LINE__,
518 static_cast<unsigned long>( aFile.tellg() ) );
519
520 return false;
521 }
522
523 SCENEGRAPH* sp = new SCENEGRAPH( this );
524 sp->SetName( name.c_str() );
525
526 if( !sp->ReadCache( aFile, this ) )
527 {
528 wxLogTrace( MASK_3D_SG, wxT( "%s:%s:%d * [INFO] corrupt data while reading transform "
529 "%ul" ),
530 __FILE__, __FUNCTION__, __LINE__,
531 static_cast<unsigned long>( aFile.tellg() ) );
532
533 return false;
534 }
535 }
536
537 // read referenced transforms
538 for( i = 0; i < sizeRT; ++i )
539 {
540 if( S3D::SGTYPE_TRANSFORM != S3D::ReadTag( aFile, name ) )
541 {
542 wxLogTrace( MASK_3D_SG, wxT( "%s:%s:%d * [INFO] corrupt data; bad ref transform tag at "
543 "position %ul" ),
544 __FILE__, __FUNCTION__, __LINE__,
545 static_cast<unsigned long>( aFile.tellg() ) );
546
547 return false;
548 }
549
550 SGNODE* sp = FindNode( name.c_str(), this );
551
552 if( !sp )
553 {
554 wxLogTrace( MASK_3D_SG, wxT( "%s:%s:%d * [INFO] corrupt data: cannot find ref "
555 "transform at position %ul" ),
556 __FILE__, __FUNCTION__, __LINE__,
557 static_cast<unsigned long>( aFile.tellg() ) );
558
559 return false;
560 }
561
563 {
564 wxLogTrace( MASK_3D_SG, wxT( "%s:%s:%d * [INFO] corrupt data: type is not TRANSFORM "
565 "at position %ul" ),
566 __FILE__, __FUNCTION__, __LINE__,
567 static_cast<unsigned long>( aFile.tellg() ) );
568
569 return false;
570 }
571
572 AddRefNode( sp );
573 }
574
575 // read child shapes
576 for( i = 0; i < sizeCS; ++i )
577 {
578 if( S3D::SGTYPE_SHAPE != S3D::ReadTag( aFile, name ) )
579 {
580 wxLogTrace( MASK_3D_SG, wxT( "%s:%s:%d * [INFO] corrupt data; bad child shape tag at "
581 "position %ul" ),
582 __FILE__, __FUNCTION__, __LINE__,
583 static_cast<unsigned long>( aFile.tellg() ) );
584
585 return false;
586 }
587
588 SGSHAPE* sp = new SGSHAPE( this );
589 sp->SetName( name.c_str() );
590
591 if( !sp->ReadCache( aFile, this ) )
592 {
593 wxLogTrace( MASK_3D_SG, wxT( "%s:%s:%d * [INFO] corrupt data; corrupt data while "
594 "reading shape at position %ul" ),
595 __FILE__, __FUNCTION__, __LINE__,
596 static_cast<unsigned long>( aFile.tellg() ) );
597
598 return false;
599 }
600 }
601
602 // read referenced shapes
603 for( i = 0; i < sizeRS; ++i )
604 {
605 if( S3D::SGTYPE_SHAPE != S3D::ReadTag( aFile, name ) )
606 {
607 wxLogTrace( MASK_3D_SG, wxT( "%s:%s:%d * [INFO] corrupt data; bad ref shape tag at "
608 "position %ul" ),
609 __FILE__, __FUNCTION__, __LINE__,
610 static_cast<unsigned long>( aFile.tellg() ) );
611
612 return false;
613 }
614
615 SGNODE* sp = FindNode( name.c_str(), this );
616
617 if( !sp )
618 {
619 wxLogTrace( MASK_3D_SG, wxT( "%s:%s:%d * [INFO] corrupt data: cannot find ref shape "
620 "at position %ul" ),
621 __FILE__, __FUNCTION__, __LINE__,
622 static_cast<unsigned long>( aFile.tellg() ) );
623
624 return false;
625 }
626
627 if( S3D::SGTYPE_SHAPE != sp->GetNodeType() )
628 {
629 wxLogTrace( MASK_3D_SG, wxT( "%s:%s:%d * [INFO] corrupt data: type is not SGSHAPE at "
630 "position %ul" ),
631 __FILE__, __FUNCTION__, __LINE__,
632 static_cast<unsigned long>( aFile.tellg() ) );
633
634 return false;
635 }
636
637 AddRefNode( sp );
638 }
639
640 if( aFile.fail() )
641 return false;
642
643 return true;
644}
const char * name
Definition: DXF_plotter.cpp:56
bool ReadCache(std::istream &aFile, SGNODE *parentNode) override
Reads binary format data from a cache file.
Definition: scenegraph.cpp:466
SCENEGRAPH(SGNODE *aParent)
Definition: scenegraph.cpp:38
SGNODE * FindNode(const char *aNodeName, const SGNODE *aCaller) override
Search the tree of linked nodes and return a reference to the first node found with the given name.
Definition: scenegraph.cpp:106
bool AddRefNode(SGNODE *aNode) override
Definition: scenegraph.cpp:181
The base class of all Scene Graph nodes.
Definition: sg_node.h:75
void SetName(const char *aName)
Definition: sg_node.cpp:155
bool ReadCache(std::istream &aFile, SGNODE *parentNode) override
Reads binary format data from a cache file.
Definition: sg_shape.cpp:447
bool ReadVector(std::istream &aFile, SGVECTOR &aVector)
Definition: sg_helpers.cpp:280
bool ReadPoint(std::istream &aFile, SGPOINT &aPoint)
Definition: sg_helpers.cpp:267
S3D::SGTYPES ReadTag(std::istream &aFile, std::string &aName)
Read the text tag of a binary cache file which is the NodeTag and unique ID number combined.
Definition: sg_helpers.cpp:195

References AddRefNode(), center, FindNode(), SGNODE::GetNodeType(), SGNODE::m_Name, m_RShape, m_RTransforms, m_Shape, m_Transforms, name, ReadCache(), SGSHAPE::ReadCache(), S3D::ReadPoint(), S3D::ReadTag(), S3D::ReadVector(), rotation_angle, rotation_axis, scale, scale_angle, scale_axis, SCENEGRAPH(), SGNODE::SetName(), S3D::SGTYPE_SHAPE, S3D::SGTYPE_TRANSFORM, and translation.

Referenced by ReadCache().

◆ ReNameNodes()

void SCENEGRAPH::ReNameNodes ( void  )
overridevirtual

Rename a node and all its child nodes in preparation for write operations.

Implements SGNODE.

Definition at line 193 of file scenegraph.cpp.

194{
195 m_written = false;
196
197 // rename this node
198 m_Name.clear();
199 GetName();
200
201 // rename all shapes
202 do
203 {
204 std::vector< SGSHAPE* >::iterator sL = m_Shape.begin();
205 std::vector< SGSHAPE* >::iterator eL = m_Shape.end();
206
207 while( sL != eL )
208 {
209 (*sL)->ReNameNodes();
210 ++sL;
211 }
212
213 } while( 0 );
214
215 // rename all transforms
216 do
217 {
218 std::vector< SCENEGRAPH* >::iterator sL = m_Transforms.begin();
219 std::vector< SCENEGRAPH* >::iterator eL = m_Transforms.end();
220
221 while( sL != eL )
222 {
223 (*sL)->ReNameNodes();
224 ++sL;
225 }
226
227 } while( 0 );
228}

References SGNODE::GetName(), SGNODE::m_Name, m_Shape, m_Transforms, and SGNODE::m_written.

Referenced by WriteCache().

◆ ResetNodeIndex()

void SGNODE::ResetNodeIndex ( void  )
noexceptinherited

Reset the global SG* node indices in preparation for write operations.

Definition at line 238 of file sg_node.cpp.

239{
240 for( int i = 0; i < (int)S3D::SGTYPE_END; ++i )
241 node_counts[i] = 1;
242}
@ SGTYPE_END
Definition: sg_types.h:45
static unsigned int node_counts[S3D::SGTYPE_END]
Definition: sg_node.cpp:50

References node_counts, and S3D::SGTYPE_END.

Referenced by S3D::ResetNodeIndex(), WriteCache(), and S3D::WriteVRML().

◆ SetName()

void SGNODE::SetName ( const char *  aName)
inherited

Definition at line 155 of file sg_node.cpp.

156{
157 if( nullptr == aName || 0 == aName[0] )
159 else
160 m_Name = aName;
161}

References getNodeName(), SGNODE::m_Name, and SGNODE::m_SGtype.

Referenced by ReadCache(), SGFACESET::ReadCache(), SGSHAPE::ReadCache(), and IFSG_NODE::SetName().

◆ SetParent()

bool SCENEGRAPH::SetParent ( SGNODE aParent,
bool  notify = true 
)
overridevirtual

Set the parent SGNODE of this object.

Parameters
aParent[in] is the desired parent node
Returns
true if the operation succeeds; false if the given node is not allowed to be a parent to the derived object.

Implements SGNODE.

Definition at line 76 of file scenegraph.cpp.

77{
78 if( nullptr != m_Parent )
79 {
80 if( aParent == m_Parent )
81 return true;
82
83 // handle the change in parents
84 if( notify )
86
87 m_Parent = nullptr;
88
89 if( nullptr == aParent )
90 return true;
91 }
92
93 // only a transform may be parent to a transform
94 if( nullptr != aParent && S3D::SGTYPE_TRANSFORM != aParent->GetNodeType() )
95 return false;
96
97 m_Parent = aParent;
98
99 if( m_Parent )
100 m_Parent->AddChildNode( this );
101
102 return true;
103}
virtual void unlinkChildNode(const SGNODE *aNode)=0
Remove references to an owned child.

References SGNODE::AddChildNode(), SGNODE::GetNodeType(), SGNODE::m_Parent, S3D::SGTYPE_TRANSFORM, and SGNODE::unlinkChildNode().

◆ SwapParent()

bool SGNODE::SwapParent ( SGNODE aNewParent)
inherited

Swap the ownership with the given parent.

This operation may be required when reordering nodes for optimization.

Parameters
aNewParentwill become the new parent to the object; it must be the same type as the parent of this instance.

Definition at line 116 of file sg_node.cpp.

117{
118 if( aNewParent == m_Parent )
119 return true;
120
121 if( nullptr == aNewParent )
122 return false;
123
124 if( nullptr == m_Parent )
125 {
126 if( aNewParent->AddChildNode( this ) )
127 return true;
128
129 return false;
130 }
131
132 if( aNewParent->GetNodeType() != m_Parent->GetNodeType() )
133 return false;
134
135 SGNODE* oldParent = m_Parent;
136 m_Parent->unlinkChildNode( this );
137 m_Parent = nullptr;
138 aNewParent->unlinkRefNode( this );
139 aNewParent->AddChildNode( this );
140 oldParent->AddRefNode( this );
141
142 return true;
143}
virtual bool AddRefNode(SGNODE *aNode)=0
virtual void unlinkRefNode(const SGNODE *aNode)=0
Remove pointers to a referenced node.

References SGNODE::AddChildNode(), SGNODE::AddRefNode(), SGNODE::GetNodeType(), SGNODE::m_Parent, SGNODE::unlinkChildNode(), and SGNODE::unlinkRefNode().

Referenced by SGFACESET::WriteCache(), and SGSHAPE::WriteCache().

◆ unlinkChildNode()

void SCENEGRAPH::unlinkChildNode ( const SGNODE aNode)
overridevirtual

Remove references to an owned child.

This is invoked by the child upon destruction to ensure that the parent has no invalid references.

Parameters
aNodeis the child which is being deleted.

Implements SGNODE.

Definition at line 150 of file scenegraph.cpp.

151{
152 unlinkNode( aNode, true );
153 return;
154}
void unlinkNode(const SGNODE *aNode, bool isChild)
Definition: scenegraph.cpp:125

References unlinkNode().

◆ unlinkNode()

void SCENEGRAPH::unlinkNode ( const SGNODE aNode,
bool  isChild 
)
private

Definition at line 125 of file scenegraph.cpp.

126{
127 if( nullptr == aNode )
128 return;
129
130 switch( aNode->GetNodeType() )
131 {
134 isChild );
135 break;
136
139 break;
140
141 default:
142 break;
143 }
144
145 wxLogTrace( MASK_3D_SG, wxT( "%s:%s:%d * [BUG] unlinkNode() did not find its target" ),
146 __FILE__, __FUNCTION__, __LINE__ );
147}
#define UNLINK_NODE(aNodeID, aType, aNode, aOwnedList, aRefList, isChild)
Definition: sg_helpers.h:86

References SGNODE::GetNodeType(), m_RShape, m_RTransforms, m_Shape, m_Transforms, S3D::SGTYPE_SHAPE, S3D::SGTYPE_TRANSFORM, and UNLINK_NODE.

Referenced by unlinkChildNode(), and unlinkRefNode().

◆ unlinkRefNode()

void SCENEGRAPH::unlinkRefNode ( const SGNODE aNode)
overridevirtual

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.

Parameters
aNodeis the node which is being deleted.

Implements SGNODE.

Definition at line 157 of file scenegraph.cpp.

158{
159 unlinkNode( aNode, false );
160 return;
161}

References unlinkNode().

◆ WriteCache()

bool SCENEGRAPH::WriteCache ( std::ostream &  aFile,
SGNODE parentNode 
)
overridevirtual

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.

Implements SGNODE.

Definition at line 337 of file scenegraph.cpp.

338{
339 if( nullptr == parentNode && nullptr != m_Parent )
340 {
341 SGNODE* np = m_Parent;
342
343 while( nullptr != np->GetParent() )
344 np = np->GetParent();
345
346 if( np->WriteCache( aFile, nullptr ) )
347 {
348 m_written = true;
349 return true;
350 }
351
352 return false;
353 }
354
355 wxCHECK( parentNode == m_Parent, false );
356
357 if( nullptr == m_Parent )
358 {
359 // ensure unique node names
361 ReNameNodes();
362 }
363
364 if( aFile.fail() )
365 {
366 wxLogTrace( MASK_3D_SG, wxT( "%s:%s:%d * [INFO] bad stream" ),
367 __FILE__, __FUNCTION__, __LINE__ );
368
369 return false;
370 }
371
372 aFile << "[" << GetName() << "]";
373 S3D::WritePoint( aFile, center );
376 aFile.write( (char*)&rotation_angle, sizeof( rotation_angle ) );
377 S3D::WritePoint( aFile, scale );
379 aFile.write( (char*)&scale_angle, sizeof( scale_angle ) );
380
381 // Transfer ownership of any Transform references which hadn't been written
382 size_t asize = m_RTransforms.size();
383 size_t i;
384
385 for( i = 0; i < asize; ++i )
386 {
387 if( !m_RTransforms[i]->isWritten() )
388 {
389 m_RTransforms[i]->SwapParent( this );
390 --asize;
391 --i;
392 }
393 }
394
395 // Transfer ownership of any Shape references which hadn't been written
396 asize = m_RShape.size();
397
398 for( i = 0; i < asize; ++i )
399 {
400 if( !m_RShape[i]->isWritten() )
401 {
402 m_RShape[i]->SwapParent( this );
403 --asize;
404 --i;
405 }
406 }
407
408 asize = m_Transforms.size();
409 aFile.write( (char*)&asize, sizeof( size_t ) );
410 asize = m_RTransforms.size();
411 aFile.write( (char*)&asize, sizeof( size_t ) );
412 asize = m_Shape.size();
413 aFile.write( (char*)&asize, sizeof( size_t ) );
414 asize = m_RShape.size();
415 aFile.write( (char*)&asize, sizeof( size_t ) );
416 asize = m_Transforms.size();
417
418 // write child transforms
419 for( i = 0; i < asize; ++i )
420 {
421 if( !m_Transforms[i]->WriteCache( aFile, this ) )
422 {
423 wxLogTrace( MASK_3D_SG,
424 wxT( "%s:%s:%d * [INFO] bad stream while writing child transforms" ),
425 __FILE__, __FUNCTION__, __LINE__ );
426
427 return false;
428 }
429 }
430
431 // write referenced transform names
432 asize = m_RTransforms.size();
433
434 for( i = 0; i < asize; ++i )
435 aFile << "[" << m_RTransforms[i]->GetName() << "]";
436
437 // write child shapes
438 asize = m_Shape.size();
439
440 for( i = 0; i < asize; ++i )
441 {
442 if( !m_Shape[i]->WriteCache( aFile, this ) )
443 {
444 wxLogTrace( MASK_3D_SG,
445 wxT( "%s:%s:%d * [INFO] bad stream while writing child shapes" ),
446 __FILE__, __FUNCTION__, __LINE__ );
447
448 return false;
449 }
450 }
451
452 // write referenced transform names
453 asize = m_RShape.size();
454
455 for( i = 0; i < asize; ++i )
456 aFile << "[" << m_RShape[i]->GetName() << "]";
457
458 if( aFile.fail() )
459 return false;
460
461 m_written = true;
462 return true;
463}
void ReNameNodes(void) override
Rename a node and all its child nodes in preparation for write operations.
Definition: scenegraph.cpp:193
bool WriteCache(std::ostream &aFile, SGNODE *parentNode) override
Write this node's data to a binary cache file.
Definition: scenegraph.cpp:337
void ResetNodeIndex(void) noexcept
Reset the global SG* node indices in preparation for write operations.
Definition: sg_node.cpp:238
virtual bool WriteCache(std::ostream &aFile, SGNODE *parentNode)=0
Write this node's data to a binary cache file.
bool isWritten(void) noexcept
Return true if the object had already been written to a cache file or VRML file.
Definition: sg_node.h:220
SGNODE * GetParent(void) const noexcept
Returns a pointer to the parent SGNODE of this object or NULL if the object has no parent (ie.
Definition: sg_node.cpp:110
bool WritePoint(std::ostream &aFile, const SGPOINT &aPoint)
Definition: sg_helpers.cpp:152
bool WriteVector(std::ostream &aFile, const SGVECTOR &aVector)
Definition: sg_helpers.cpp:165

References center, SGNODE::GetName(), SGNODE::GetParent(), SGNODE::isWritten(), SGNODE::m_Parent, m_RShape, m_RTransforms, m_Shape, m_Transforms, SGNODE::m_written, ReNameNodes(), SGNODE::ResetNodeIndex(), rotation_angle, rotation_axis, scale, scale_angle, scale_axis, translation, WriteCache(), SGNODE::WriteCache(), S3D::WritePoint(), and S3D::WriteVector().

Referenced by WriteCache().

◆ WriteVRML()

bool SCENEGRAPH::WriteVRML ( std::ostream &  aFile,
bool  aReuseFlag 
)
overridevirtual

Writes this node's data to a VRML file.

This includes all data of child and referenced nodes.

Implements SGNODE.

Definition at line 231 of file scenegraph.cpp.

232{
233 if( m_Transforms.empty() && m_RTransforms.empty() && m_Shape.empty() && m_RShape.empty() )
234 {
235 return false;
236 }
237
238 std::string tmp;
239
240 if( aReuseFlag )
241 {
242 if( !m_written )
243 {
244 aFile << "DEF " << GetName() << " Transform {\n";
245 m_written = true;
246 }
247 else
248 {
249 aFile << "USE " << GetName() << "\n";
250 return true;
251 }
252 }
253 else
254 {
255 aFile << " Transform {\n";
256 }
257
258 // convert center to 1VRML unit = 0.1 inch
259 SGPOINT pt = center;
260 pt.x /= 2.54;
261 pt.y /= 2.54;
262 pt.z /= 2.54;
263
264 S3D::FormatPoint( tmp, pt );
265 aFile << " center " << tmp << "\n";
267 aFile << " rotation " << tmp << "\n";
268 S3D::FormatPoint( tmp, scale );
269 aFile << " scale " << tmp << "\n";
271 aFile << " scaleOrientation " << tmp << "\n";
272
273 // convert translation to 1VRML unit = 0.1 inch
274 pt = translation;
275 pt.x /= 2.54;
276 pt.y /= 2.54;
277 pt.z /= 2.54;
278 S3D::FormatPoint( tmp, pt );
279 aFile << " translation " << tmp << "\n";
280
281 aFile << " children [\n";
282
283 if( !m_Transforms.empty() )
284 {
285 std::vector< SCENEGRAPH* >::iterator sL = m_Transforms.begin();
286 std::vector< SCENEGRAPH* >::iterator eL = m_Transforms.end();
287
288 while( sL != eL )
289 {
290 (*sL)->WriteVRML( aFile, aReuseFlag );
291 ++sL;
292 }
293 }
294
295 if( !m_RTransforms.empty() )
296 {
297 std::vector< SCENEGRAPH* >::iterator sL = m_RTransforms.begin();
298 std::vector< SCENEGRAPH* >::iterator eL = m_RTransforms.end();
299
300 while( sL != eL )
301 {
302 (*sL)->WriteVRML( aFile, aReuseFlag );
303 ++sL;
304 }
305 }
306
307 if( !m_Shape.empty() )
308 {
309 std::vector< SGSHAPE* >::iterator sL = m_Shape.begin();
310 std::vector< SGSHAPE* >::iterator eL = m_Shape.end();
311
312 while( sL != eL )
313 {
314 (*sL)->WriteVRML( aFile, aReuseFlag );
315 ++sL;
316 }
317 }
318
319 if( !m_RShape.empty() )
320 {
321 std::vector< SGSHAPE* >::iterator sL = m_RShape.begin();
322 std::vector< SGSHAPE* >::iterator eL = m_RShape.end();
323
324 while( sL != eL )
325 {
326 (*sL)->WriteVRML( aFile, aReuseFlag );
327 ++sL;
328 }
329 }
330
331 aFile << "] }\n";
332
333 return true;
334}
void FormatPoint(std::string &result, const SGPOINT &point)
Definition: sg_helpers.cpp:103
void FormatOrientation(std::string &result, const SGVECTOR &axis, double rotation)
Definition: sg_helpers.cpp:82

References center, S3D::FormatOrientation(), S3D::FormatPoint(), SGNODE::GetName(), m_RShape, m_RTransforms, m_Shape, m_Transforms, SGNODE::m_written, rotation_angle, rotation_axis, scale, scale_angle, scale_axis, translation, SGPOINT::x, SGPOINT::y, and SGPOINT::z.

Member Data Documentation

◆ center

SGPOINT SCENEGRAPH::center

Definition at line 73 of file scenegraph.h.

Referenced by Prepare(), ReadCache(), WriteCache(), and WriteVRML().

◆ m_Association

SGNODE** SGNODE::m_Association
privateinherited

Handle to the instance held by a wrapper.

Definition at line 233 of file sg_node.h.

Referenced by SGNODE::SGNODE(), and SGNODE::~SGNODE().

◆ m_BackPointers

std::list< SGNODE* > SGNODE::m_BackPointers
protectedinherited

nodes which hold a reference to this.

Definition at line 226 of file sg_node.h.

Referenced by SGNODE::addNodeRef(), SGCOORDS::CalcNormals(), SGNODE::delNodeRef(), and SGNODE::~SGNODE().

◆ m_Name

◆ m_Parent

◆ m_RShape

std::vector< SGSHAPE* > SCENEGRAPH::m_RShape
private

Definition at line 92 of file scenegraph.h.

Referenced by addNode(), Prepare(), ReadCache(), unlinkNode(), WriteCache(), WriteVRML(), and ~SCENEGRAPH().

◆ m_RTransforms

std::vector< SCENEGRAPH* > SCENEGRAPH::m_RTransforms
private

Definition at line 91 of file scenegraph.h.

Referenced by addNode(), Prepare(), ReadCache(), unlinkNode(), WriteCache(), WriteVRML(), and ~SCENEGRAPH().

◆ m_SGtype

◆ m_Shape

std::vector< SGSHAPE* > SCENEGRAPH::m_Shape
private

◆ m_Transforms

std::vector< SCENEGRAPH* > SCENEGRAPH::m_Transforms
private

◆ m_written

◆ rotation_angle

double SCENEGRAPH::rotation_angle

Definition at line 76 of file scenegraph.h.

Referenced by Prepare(), ReadCache(), SCENEGRAPH(), WriteCache(), and WriteVRML().

◆ rotation_axis

SGVECTOR SCENEGRAPH::rotation_axis

Definition at line 75 of file scenegraph.h.

Referenced by Prepare(), ReadCache(), WriteCache(), and WriteVRML().

◆ scale

SGPOINT SCENEGRAPH::scale

Definition at line 77 of file scenegraph.h.

Referenced by Prepare(), ReadCache(), SCENEGRAPH(), WriteCache(), and WriteVRML().

◆ scale_angle

double SCENEGRAPH::scale_angle

Definition at line 79 of file scenegraph.h.

Referenced by Prepare(), ReadCache(), SCENEGRAPH(), WriteCache(), and WriteVRML().

◆ scale_axis

SGVECTOR SCENEGRAPH::scale_axis

Definition at line 78 of file scenegraph.h.

Referenced by Prepare(), ReadCache(), WriteCache(), and WriteVRML().

◆ translation

SGPOINT SCENEGRAPH::translation

Definition at line 74 of file scenegraph.h.

Referenced by Prepare(), ReadCache(), WriteCache(), and WriteVRML().


The documentation for this class was generated from the following files: