KiCad PCB EDA Suite
SGSHAPE Class Reference

Define a complex 3D shape for a scenegraph object. More...

#include <sg_shape.h>

Inheritance diagram for SGSHAPE:
SGNODE

Public Member Functions

 SGSHAPE (SGNODE *aParent)
 
virtual ~SGSHAPE ()
 
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)
 
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...
 
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

SGAPPEARANCEm_Appearance
 
SGFACESETm_FaceSet
 
SGAPPEARANCEm_RAppearance
 
SGFACESETm_RFaceSet
 

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

SGNODE ** m_Association
 Handle to the instance held by a wrapper. More...
 

Detailed Description

Define a complex 3D shape for a scenegraph object.

Definition at line 42 of file sg_shape.h.

Constructor & Destructor Documentation

◆ SGSHAPE()

SGSHAPE::SGSHAPE ( SGNODE aParent)

Definition at line 40 of file sg_shape.cpp.

40 : SGNODE( aParent )
41{
43 m_Appearance = nullptr;
44 m_RAppearance = nullptr;
45 m_FaceSet = nullptr;
46 m_RFaceSet = nullptr;
47
48 if( nullptr != aParent && S3D::SGTYPE_TRANSFORM != aParent->GetNodeType() )
49 {
50 m_Parent = nullptr;
51
52 wxLogTrace( MASK_3D_SG, wxT( "%s:%s:%d * [BUG] inappropriate parent to SGSHAPE (type %d)" ),
53 __FILE__, __FUNCTION__, __LINE__, aParent->GetNodeType() );
54 }
55 else if( nullptr != aParent && S3D::SGTYPE_TRANSFORM == aParent->GetNodeType() )
56 {
57 m_Parent->AddChildNode( this );
58 }
59}
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
SGFACESET * m_RFaceSet
Definition: sg_shape.h:77
SGFACESET * m_FaceSet
Definition: sg_shape.h:73
SGAPPEARANCE * m_RAppearance
Definition: sg_shape.h:76
SGAPPEARANCE * m_Appearance
Definition: sg_shape.h:72
@ SGTYPE_SHAPE
Definition: sg_types.h:44
@ SGTYPE_TRANSFORM
Definition: sg_types.h:36

References SGNODE::AddChildNode(), SGNODE::GetNodeType(), m_Appearance, m_FaceSet, SGNODE::m_Parent, m_RAppearance, m_RFaceSet, SGNODE::m_SGtype, S3D::SGTYPE_SHAPE, and S3D::SGTYPE_TRANSFORM.

◆ ~SGSHAPE()

SGSHAPE::~SGSHAPE ( )
virtual

Definition at line 62 of file sg_shape.cpp.

63{
64 // drop references
65 if( m_RAppearance )
66 {
68 m_RAppearance = nullptr;
69 }
70
71 if( m_RFaceSet )
72 {
73 m_RFaceSet->delNodeRef( this );
74 m_RFaceSet = nullptr;
75 }
76
77 // delete objects
78 if( m_Appearance )
79 {
80 m_Appearance->SetParent( nullptr, false );
81 delete m_Appearance;
82 m_Appearance = nullptr;
83 }
84
85 if( m_FaceSet )
86 {
87 m_FaceSet->SetParent( nullptr, false );
88 delete m_FaceSet;
89 m_FaceSet = nullptr;
90 }
91}
virtual bool SetParent(SGNODE *aParent, bool notify=true) override
Set the parent SGNODE of this object.
virtual bool SetParent(SGNODE *aParent, bool notify=true) override
Set the parent SGNODE of this object.
Definition: sg_faceset.cpp:119
void delNodeRef(const SGNODE *aNode)
Remove a pointer to a node which references this node, but does not own.
Definition: sg_node.cpp:185

References SGNODE::delNodeRef(), m_Appearance, m_FaceSet, m_RAppearance, m_RFaceSet, SGAPPEARANCE::SetParent(), and SGFACESET::SetParent().

Member Function Documentation

◆ AddChildNode()

bool SGSHAPE::AddChildNode ( SGNODE aNode)
overridevirtual

Implements SGNODE.

Definition at line 292 of file sg_shape.cpp.

293{
294 return addNode( aNode, true );
295}
bool addNode(SGNODE *aNode, bool isChild)
Definition: sg_shape.cpp:215

References addNode().

◆ addNode()

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

Definition at line 215 of file sg_shape.cpp.

216{
217 wxCHECK( aNode, false );
218
219 if( S3D::SGTYPE_APPEARANCE == aNode->GetNodeType() )
220 {
222 {
223 if( aNode != m_Appearance && aNode != m_RAppearance )
224 {
225 wxLogTrace( MASK_3D_SG, wxT( "%s:%s:%d * [BUG] assigning multiple Appearance "
226 "nodes" ),
227 __FILE__, __FUNCTION__, __LINE__ );
228
229 return false;
230 }
231
232 return true;
233 }
234
235 if( isChild )
236 {
237 m_Appearance = (SGAPPEARANCE*)aNode;
238 m_Appearance->SetParent( this );
239 }
240 else
241 {
242 m_RAppearance = (SGAPPEARANCE*)aNode;
243 m_RAppearance->addNodeRef( this );
244 }
245
246 return true;
247 }
248
249 if( S3D::SGTYPE_FACESET == aNode->GetNodeType() )
250 {
251 if( m_FaceSet || m_RFaceSet )
252 {
253 if( aNode != m_FaceSet && aNode != m_RFaceSet )
254 {
255 wxLogTrace( MASK_3D_SG, wxT( "%s:%s:%d * [BUG] assigning multiple FaceSet nodes" ),
256 __FILE__, __FUNCTION__, __LINE__ );
257
258 return false;
259 }
260
261 return true;
262 }
263
264 if( isChild )
265 {
266 m_FaceSet = (SGFACESET*)aNode;
267 m_FaceSet->SetParent( this );
268 }
269 else
270 {
271 m_RFaceSet = (SGFACESET*)aNode;
272 m_RFaceSet->addNodeRef( this );
273 }
274
275 return true;
276 }
277
278 wxLogTrace( MASK_3D_SG, wxT( "%s:%s:%d * [BUG] object %s is not a valid type for this "
279 "object (%d)" ),
280 __FILE__, __FUNCTION__, __LINE__, aNode->GetName(), aNode->GetNodeType() );
281
282 return false;
283}
Defines the generic material appearance of a scenegraph object.
Definition: sg_appearance.h:38
Define an indexed face set for a scenegraph.
Definition: sg_faceset.h:47
const char * GetName(void)
Definition: sg_node.cpp:146
void addNodeRef(SGNODE *aNode)
Add a pointer to a node which references this node, but does not own.
Definition: sg_node.cpp:170
@ SGTYPE_FACESET
Definition: sg_types.h:40
@ SGTYPE_APPEARANCE
Definition: sg_types.h:37

References SGNODE::addNodeRef(), SGNODE::GetName(), SGNODE::GetNodeType(), m_Appearance, m_FaceSet, m_RAppearance, m_RFaceSet, SGAPPEARANCE::SetParent(), SGFACESET::SetParent(), S3D::SGTYPE_APPEARANCE, and S3D::SGTYPE_FACESET.

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(), addNode(), SGFACESET::ReadCache(), and ReadCache().

◆ AddRefNode()

bool SGSHAPE::AddRefNode ( SGNODE aNode)
overridevirtual

Implements SGNODE.

Definition at line 286 of file sg_shape.cpp.

287{
288 return addNode( aNode, false );
289}

References addNode().

◆ 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(), unlinkNode(), SGFACESET::~SGFACESET(), and ~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 * SGSHAPE::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 124 of file sg_shape.cpp.

125{
126 if( nullptr == aNodeName || 0 == aNodeName[0] )
127 return nullptr;
128
129 if( !m_Name.compare( aNodeName ) )
130 return this;
131
132 SGNODE* tmp = nullptr;
133
134 if( nullptr != m_Appearance )
135 {
136 tmp = m_Appearance->FindNode( aNodeName, this );
137
138 if( tmp )
139 {
140 return tmp;
141 }
142 }
143
144 if( nullptr != m_FaceSet )
145 {
146 tmp = m_FaceSet->FindNode( aNodeName, this );
147
148 if( tmp )
149 {
150 return tmp;
151 }
152 }
153
154 // query the parent if appropriate
155 if( aCaller == m_Parent || nullptr == m_Parent )
156 return nullptr;
157
158 return m_Parent->FindNode( aNodeName, this );
159}
SGNODE * FindNode(const char *aNodeName, const SGNODE *aCaller) noexcept override
Search the tree of linked nodes and return a reference to the first node found with the given name.
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: sg_faceset.cpp:149
The base class of all Scene Graph nodes.
Definition: sg_node.h:75
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

References SGAPPEARANCE::FindNode(), SGFACESET::FindNode(), SGNODE::FindNode(), m_Appearance, m_FaceSet, SGNODE::m_Name, and SGNODE::m_Parent.

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 SCENEGRAPH::WriteCache(), SGFACESET::WriteCache(), and WriteCache().

◆ Prepare()

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

Definition at line 603 of file sg_shape.cpp.

605{
606 SMESH m;
607 S3D::INIT_SMESH( m );
608
610 SGFACESET* pf = m_FaceSet;
611
612 if( nullptr == pa )
613 pa = m_RAppearance;
614
615 if( nullptr == pf )
616 pf = m_RFaceSet;
617
618 // no face sets = nothing to render, which is valid though pointless
619 if( nullptr == pf )
620 return true;
621
622 if( !pf->validate() )
623 {
624 wxLogTrace( MASK_3D_SG, wxT( "%s:%s:%d * [INFO] bad model; inconsistent data" ),
625 __FILE__, __FUNCTION__, __LINE__ );
626
627 return true;
628 }
629
630 if( nullptr == pa )
631 {
632 m.m_MaterialIdx = 0;
633 }
634 else
635 {
636 int idx;
637
638 if( !S3D::GetMatIndex( materials, pa, idx ) )
639 {
640 m.m_MaterialIdx = 0;
641 }
642 else
643 {
644 m.m_MaterialIdx = idx;
645 }
646 }
647
648 SGCOLORS* pc = pf->m_Colors;
649 SGCOORDS* pv = pf->m_Coords;
650 SGCOORDINDEX* vidx = pf->m_CoordIndices;
651 SGNORMALS* pn = pf->m_Normals;
652
653 if( nullptr == pc )
654 pc = pf->m_RColors;
655
656 if( nullptr == pv )
657 pv = pf->m_RCoords;
658
659 if( nullptr == pn )
660 pn = pf->m_RNormals;
661
662 // set the vertex points and indices
663 size_t nCoords = 0;
664 SGPOINT* pCoords = nullptr;
665 pv->GetCoordsList( nCoords, pCoords );
666
667 size_t nColors = 0;
668 SGCOLOR* pColors = nullptr;
669
670 if( pc )
671 {
672 // check the vertex colors
673 pc->GetColorList( nColors, pColors );
674
675 if( nColors < nCoords )
676 {
677 wxLogTrace( MASK_3D_SG, wxT( "%s:%s:%d * [INFO] bad model; not enough colors per "
678 "vertex (%ul vs %ul)" ),
679 __FILE__, __FUNCTION__, __LINE__, static_cast<unsigned long>( nColors ),
680 static_cast<unsigned long>( nCoords ) );
681
682 return true;
683 }
684 }
685
686 // set the vertex indices
687 size_t nvidx = 0;
688 int* lv = nullptr;
689 vidx->GetIndices( nvidx, lv );
690
691 // note: reduce the vertex set to include only the referenced vertices
692 std::vector< int > vertices; // store the list of temp vertex indices
693 std::map< int, unsigned int > indexmap; // map temp vertex to true vertex
694 std::map< int, unsigned int >::iterator mit;
695
696 for( unsigned int i = 0; i < nvidx; ++i )
697 {
698 mit = indexmap.find( lv[i] );
699
700 if( mit == indexmap.end() )
701 {
702 indexmap.emplace( lv[i], vertices.size() );
703 vertices.push_back( lv[i] );
704 }
705 }
706
707 if( vertices.size() < 3 )
708 {
709 wxLogTrace( MASK_3D_SG, wxT( "%s:%s:%d * [INFO] bad model; not enough vertices" ),
710 __FILE__, __FUNCTION__, __LINE__ );
711
712 return true;
713 }
714
715 // construct the final vertex/color list
716 SFVEC3F* lColors = nullptr;
717 SFVEC3F* lCoords = new SFVEC3F[ vertices.size() ];
718 int ti;
719
720 if( pc )
721 {
722 lColors = new SFVEC3F[vertices.size()];
723 m.m_Color = lColors;
724 }
725
726 if( pc )
727 {
728 for( size_t i = 0; i < vertices.size(); ++i )
729 {
730 ti = vertices[i];
731 glm::dvec4 pt( pCoords[ti].x, pCoords[ti].y, pCoords[ti].z, 1.0 );
732 pt = (*aTransform) * pt;
733 pColors[ti].GetColor( lColors[i].x, lColors[i].y, lColors[i].z );
734 lCoords[i] = SFVEC3F( pt.x, pt.y, pt.z );
735 }
736 }
737 else
738 {
739 for( size_t i = 0; i < vertices.size(); ++i )
740 {
741 ti = vertices[i];
742 glm::dvec4 pt( pCoords[ti].x, pCoords[ti].y, pCoords[ti].z, 1.0 );
743 pt = (*aTransform) * pt;
744 lCoords[i] = SFVEC3F( pt.x, pt.y, pt.z );
745 }
746 }
747
748 m.m_VertexSize = (unsigned int) vertices.size();
749 m.m_Positions = lCoords;
750 unsigned int* lvidx = new unsigned int[ nvidx ];
751
752 for( unsigned int i = 0; i < nvidx; ++i )
753 {
754 mit = indexmap.find( lv[i] );
755 lvidx[i] = mit->second;
756 }
757
758 m.m_FaceIdxSize = (unsigned int )nvidx;
759 m.m_FaceIdx = lvidx;
760
761 // set the per-vertex normals
762 size_t nNorms = 0;
763 SGVECTOR* pNorms = nullptr;
764 double x, y, z;
765
766 pn->GetNormalList( nNorms, pNorms );
767 SFVEC3F* lNorms = new SFVEC3F[ vertices.size() ];
768
769 for( size_t i = 0; i < vertices.size(); ++i )
770 {
771 ti = vertices[i];
772 pNorms[ti].GetVector( x, y, z );
773 glm::dvec4 pt( x, y, z, 0.0 );
774 pt = (*aTransform) * pt;
775
776 lNorms[i] = SFVEC3F( pt.x, pt.y, pt.z );
777 }
778
779 m.m_Normals = lNorms;
780 meshes.push_back( m );
781
782 return true;
783}
Define an RGB color set for a scenegraph object.
Definition: sg_colors.h:39
bool GetColorList(size_t &aListSize, SGCOLOR *&aColorList)
Definition: sg_colors.cpp:128
void GetColor(float &aRedVal, float &aGreenVal, float &aBlueVal) const noexcept
Definition: sg_base.cpp:59
An object to maintain a coordinate index list.
Definition: sg_coordindex.h:43
Define a vertex coordinate set for a scenegraph object.
Definition: sg_coords.h:41
bool GetCoordsList(size_t &aListSize, SGPOINT *&aCoordsList)
Definition: sg_coords.cpp:130
SGCOORDS * m_RCoords
Definition: sg_faceset.h:86
SGCOORDINDEX * m_CoordIndices
Definition: sg_faceset.h:81
SGCOORDS * m_Coords
Definition: sg_faceset.h:80
SGNORMALS * m_Normals
Definition: sg_faceset.h:82
SGCOLORS * m_RColors
Definition: sg_faceset.h:85
SGNORMALS * m_RNormals
Definition: sg_faceset.h:87
bool validate(void)
Definition: sg_faceset.cpp:854
SGCOLORS * m_Colors
Definition: sg_faceset.h:79
bool GetIndices(size_t &nIndices, int *&aIndexList)
Retrieve the number of indices and a pointer to the list.
Definition: sg_index.cpp:126
Define a set of vertex normals for a scene graph object.
Definition: sg_normals.h:39
bool GetNormalList(size_t &aListSize, SGVECTOR *&aNormalList)
Definition: sg_normals.cpp:129
void GetVector(double &aXVal, double &aYVal, double &aZVal) const noexcept
Definition: sg_base.cpp:225
void INIT_SMESH(SMESH &aMesh) noexcept
Definition: sg_node.cpp:276
bool GetMatIndex(MATLIST &aList, SGNODE *aNode, int &aIndex)
Definition: sg_node.cpp:245
Per-vertex normal/color/texcoors structure.
Definition: c3dmodel.h:77
unsigned int * m_FaceIdx
Triangle Face Indexes.
Definition: c3dmodel.h:84
SFVEC3F * m_Normals
Vertex normals array.
Definition: c3dmodel.h:80
unsigned int m_MaterialIdx
Material Index to be used in this mesh (must be < m_MaterialsSize )
Definition: c3dmodel.h:85
unsigned int m_VertexSize
Number of vertex in the arrays.
Definition: c3dmodel.h:78
unsigned int m_FaceIdxSize
Number of elements of the m_FaceIdx array.
Definition: c3dmodel.h:83
SFVEC3F * m_Color
Vertex color array, can be NULL.
Definition: c3dmodel.h:82
SFVEC3F * m_Positions
Vertex position array.
Definition: c3dmodel.h:79
glm::vec3 SFVEC3F
Definition: xv3d_types.h:44

References SGCOLOR::GetColor(), SGCOLORS::GetColorList(), SGCOORDS::GetCoordsList(), SGINDEX::GetIndices(), S3D::GetMatIndex(), SGNORMALS::GetNormalList(), SGVECTOR::GetVector(), S3D::INIT_SMESH(), m_Appearance, SMESH::m_Color, SGFACESET::m_Colors, SGFACESET::m_CoordIndices, SGFACESET::m_Coords, SMESH::m_FaceIdx, SMESH::m_FaceIdxSize, m_FaceSet, SMESH::m_MaterialIdx, SGFACESET::m_Normals, SMESH::m_Normals, SMESH::m_Positions, m_RAppearance, SGFACESET::m_RColors, SGFACESET::m_RCoords, m_RFaceSet, SGFACESET::m_RNormals, SMESH::m_VertexSize, and SGFACESET::validate().

◆ ReadCache()

bool SGSHAPE::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 447 of file sg_shape.cpp.

448{
449 wxCHECK( m_Appearance == nullptr && m_RAppearance == nullptr && m_FaceSet == nullptr &&
450 m_RFaceSet == nullptr, false );
451
452 #define NITEMS 4
453 bool items[NITEMS];
454
455 for( int i = 0; i < NITEMS; ++i )
456 aFile.read( (char*)&items[i], sizeof(bool) );
457
458 if( ( items[0] && items[1] ) || ( items[2] && items[3] ) )
459 {
460 wxLogTrace( MASK_3D_SG, wxT( "%s:%s:%d * [INFO] corrupt data; multiple item definitions "
461 "at position %ul" ),
462 __FILE__, __FUNCTION__, __LINE__,
463 static_cast<unsigned long>( aFile.tellg() ) );
464
465 return false;
466 }
467
468 std::string name;
469
470 if( items[0] )
471 {
472 if( S3D::SGTYPE_APPEARANCE != S3D::ReadTag( aFile, name ) )
473 {
474 wxLogTrace( MASK_3D_SG, wxT( "%s:%s:%d * [INFO] corrupt data; bad child appearance "
475 "tag at position %ul" ),
476 __FILE__, __FUNCTION__, __LINE__,
477 static_cast<unsigned long>( aFile.tellg() ) );
478
479 return false;
480 }
481
482 m_Appearance = new SGAPPEARANCE( this );
483 m_Appearance->SetName( name.c_str() );
484
485 if( !m_Appearance->ReadCache( aFile, this ) )
486 {
487 wxLogTrace( MASK_3D_SG, wxT( "%s:%s:%d * [INFO] corrupt data while reading appearance "
488 "'%s'" ),
489 __FILE__, __FUNCTION__, __LINE__, name );
490
491 return false;
492 }
493 }
494
495 if( items[1] )
496 {
497 if( S3D::SGTYPE_APPEARANCE != S3D::ReadTag( aFile, name ) )
498 {
499 wxLogTrace( MASK_3D_SG, wxT( "%s:%s:%d * [INFO] corrupt data; bad ref appearance tag "
500 "at position %ul" ),
501 __FILE__, __FUNCTION__, __LINE__,
502 static_cast<unsigned long>( aFile.tellg() ) );
503
504 return false;
505 }
506
507 SGNODE* np = FindNode( name.c_str(), this );
508
509 if( !np )
510 {
511 wxLogTrace( MASK_3D_SG, wxT( "%s:%s:%d * [INFO] corrupt data: cannot find ref "
512 "appearance '%s'" ),
513 __FILE__, __FUNCTION__, __LINE__,
514 name );
515
516 return false;
517 }
518
520 {
521 wxLogTrace( MASK_3D_SG, wxT( "%s:%s:%d * [INFO] corrupt data: type is not "
522 "SGAPPEARANCE '%s'" ),
523 __FILE__, __FUNCTION__, __LINE__,
524 name );
525
526 return false;
527 }
528
530 m_RAppearance->addNodeRef( this );
531 }
532
533 if( items[2] )
534 {
535 if( S3D::SGTYPE_FACESET != S3D::ReadTag( aFile, name ) )
536 {
537 wxLogTrace( MASK_3D_SG, wxT( "%s:%s:%d * [INFO] corrupt data; bad child face set tag "
538 "at position %ul" ),
539 __FILE__, __FUNCTION__, __LINE__,
540 static_cast<unsigned long>( aFile.tellg() ) );
541
542 return false;
543 }
544
545 m_FaceSet = new SGFACESET( this );
546 m_FaceSet->SetName( name.c_str() );
547
548 if( !m_FaceSet->ReadCache( aFile, this ) )
549 {
550 wxLogTrace( MASK_3D_SG, wxT( "%s:%s:%d * [INFO] corrupt data while reading face set "
551 "'%s'" ),
552 __FILE__, __FUNCTION__, __LINE__, name );
553
554 return false;
555 }
556 }
557
558 if( items[3] )
559 {
560 if( S3D::SGTYPE_FACESET != S3D::ReadTag( aFile, name ) )
561 {
562 wxLogTrace( MASK_3D_SG, wxT( "%s:%s:%d * [INFO] corrupt data; bad ref face set tag at "
563 "position %ul" ),
564 __FILE__, __FUNCTION__, __LINE__,
565 static_cast<unsigned long>( aFile.tellg() ) );
566
567 return false;
568 }
569
570 SGNODE* np = FindNode( name.c_str(), this );
571
572 if( !np )
573 {
574 wxLogTrace( MASK_3D_SG, wxT( "%s:%s:%d * [INFO] corrupt data: cannot find ref face "
575 "set '%s'" ),
576 __FILE__, __FUNCTION__, __LINE__,
577 name );
578
579 return false;
580 }
581
582 if( S3D::SGTYPE_FACESET != np->GetNodeType() )
583 {
584 wxLogTrace( MASK_3D_SG, wxT( "%s:%s:%d * [INFO] corrupt data: type is not SGFACESET "
585 "'%s'" ),
586 __FILE__, __FUNCTION__, __LINE__,
587 name );
588
589 return false;
590 }
591
592 m_RFaceSet = (SGFACESET*)np;
593 m_RFaceSet->addNodeRef( this );
594 }
595
596 if( aFile.fail() )
597 return false;
598
599 return true;
600}
const char * name
Definition: DXF_plotter.cpp:56
bool ReadCache(std::istream &aFile, SGNODE *parentNode) override
Reads binary format data from a cache file.
bool ReadCache(std::istream &aFile, SGNODE *parentNode) override
Reads binary format data from a cache file.
Definition: sg_faceset.cpp:601
void SetName(const char *aName)
Definition: sg_node.cpp:155
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: sg_shape.cpp:124
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
#define NITEMS

References SGNODE::addNodeRef(), FindNode(), SGNODE::GetNodeType(), m_Appearance, m_FaceSet, m_RAppearance, m_RFaceSet, name, NITEMS, SGAPPEARANCE::ReadCache(), SGFACESET::ReadCache(), S3D::ReadTag(), SGNODE::SetName(), S3D::SGTYPE_APPEARANCE, and S3D::SGTYPE_FACESET.

Referenced by SCENEGRAPH::ReadCache().

◆ ReNameNodes()

void SGSHAPE::ReNameNodes ( void  )
overridevirtual

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

Implements SGNODE.

Definition at line 298 of file sg_shape.cpp.

299{
300 m_written = false;
301
302 // rename this node
303 m_Name.clear();
304 GetName();
305
306 // rename Appearance
307 if( m_Appearance )
309
310 // rename FaceSet
311 if( m_FaceSet )
313}
void ReNameNodes(void) override
Rename a node and all its child nodes in preparation for write operations.
void ReNameNodes(void) override
Rename a node and all its child nodes in preparation for write operations.
Definition: sg_faceset.cpp:413

References SGNODE::GetName(), m_Appearance, m_FaceSet, SGNODE::m_Name, SGNODE::m_written, SGAPPEARANCE::ReNameNodes(), and SGFACESET::ReNameNodes().

◆ 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(), SCENEGRAPH::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 SCENEGRAPH::ReadCache(), SGFACESET::ReadCache(), ReadCache(), and IFSG_NODE::SetName().

◆ SetParent()

bool SGSHAPE::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 94 of file sg_shape.cpp.

95{
96 if( nullptr != m_Parent )
97 {
98 if( aParent == m_Parent )
99 return true;
100
101 // handle the change in parents
102 if( notify )
103 m_Parent->unlinkChildNode( this );
104
105 m_Parent = nullptr;
106
107 if( nullptr == aParent )
108 return true;
109 }
110
111 // only a SGTRANSFORM may be parent to a SGSHAPE
112 if( nullptr != aParent && S3D::SGTYPE_TRANSFORM != aParent->GetNodeType() )
113 return false;
114
115 m_Parent = aParent;
116
117 if( m_Parent )
118 m_Parent->AddChildNode( this );
119
120 return true;
121}
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 WriteCache().

◆ unlinkChildNode()

void SGSHAPE::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 203 of file sg_shape.cpp.

204{
205 unlinkNode( aNode, true );
206}
void unlinkNode(const SGNODE *aNode, bool isChild)
Definition: sg_shape.cpp:162

References unlinkNode().

◆ unlinkNode()

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

Definition at line 162 of file sg_shape.cpp.

163{
164 if( nullptr == aNode )
165 return;
166
167 if( isChild )
168 {
169 if( aNode == m_Appearance )
170 {
171 m_Appearance = nullptr;
172 return;
173 }
174
175 if( aNode == m_FaceSet )
176 {
177 m_FaceSet = nullptr;
178 return;
179 }
180 }
181 else
182 {
183 if( aNode == m_RAppearance )
184 {
185 delNodeRef( this );
186 m_RAppearance = nullptr;
187 return;
188 }
189
190 if( aNode == m_RFaceSet )
191 {
192 delNodeRef( this );
193 m_RFaceSet = nullptr;
194 return;
195 }
196 }
197
198 wxLogTrace( MASK_3D_SG, wxT( "%s:%s:%d * [BUG] unlinkNode() did not find its target" ),
199 __FILE__, __FUNCTION__, __LINE__ );
200}

References SGNODE::delNodeRef(), m_Appearance, m_FaceSet, m_RAppearance, and m_RFaceSet.

Referenced by unlinkChildNode(), and unlinkRefNode().

◆ unlinkRefNode()

void SGSHAPE::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 209 of file sg_shape.cpp.

210{
211 unlinkNode( aNode, false );
212}

References unlinkNode().

◆ WriteCache()

bool SGSHAPE::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 359 of file sg_shape.cpp.

360{
361 if( nullptr == parentNode )
362 {
363 wxCHECK( m_Parent, false );
364
365 SGNODE* np = m_Parent;
366
367 while( nullptr != np->GetParent() )
368 np = np->GetParent();
369
370 if( np->WriteCache( aFile, nullptr ) )
371 {
372 m_written = true;
373 return true;
374 }
375
376 return false;
377 }
378
379 wxCHECK( parentNode == m_Parent, false );
380
381 if( !aFile.good() )
382 {
383 wxLogTrace( MASK_3D_SG, wxT( "%s:%s:%d * [BUG] bad stream" ),
384 __FILE__, __FUNCTION__, __LINE__ );
385
386 return false;
387 }
388
389 // check if any references are unwritten and swap parents if so
390 if( nullptr != m_RAppearance && !m_RAppearance->isWritten() )
392
393 if( nullptr != m_RFaceSet && !m_RFaceSet->isWritten() )
394 m_RFaceSet->SwapParent( this );
395
396 aFile << "[" << GetName() << "]";
397 #define NITEMS 4
398 bool items[NITEMS];
399 int i;
400
401 for( i = 0; i < NITEMS; ++i )
402 items[i] = 0;
403
404 i = 0;
405
406 if( nullptr != m_Appearance )
407 items[i] = true;
408
409 ++i;
410
411 if( nullptr != m_RAppearance )
412 items[i] = true;
413
414 ++i;
415
416 if( nullptr != m_FaceSet )
417 items[i] = true;
418
419 ++i;
420
421 if( nullptr != m_RFaceSet )
422 items[i] = true;
423
424 for( int jj = 0; jj < NITEMS; ++jj )
425 aFile.write( (char*)&items[jj], sizeof(bool) );
426
427 if( items[0] )
428 m_Appearance->WriteCache( aFile, this );
429
430 if( items[1] )
431 aFile << "[" << m_RAppearance->GetName() << "]";
432
433 if( items[2] )
434 m_FaceSet->WriteCache( aFile, this );
435
436 if( items[3] )
437 aFile << "[" << m_RFaceSet->GetName() << "]";
438
439 if( aFile.fail() )
440 return false;
441
442 m_written = true;
443 return true;
444}
bool WriteCache(std::ostream &aFile, SGNODE *parentNode) override
Write this node's data to a binary cache file.
bool WriteCache(std::ostream &aFile, SGNODE *parentNode) override
Write this node's data to a binary cache file.
Definition: sg_faceset.cpp:493
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 SwapParent(SGNODE *aNewParent)
Swap the ownership with the given parent.
Definition: sg_node.cpp:116

References SGNODE::GetName(), SGNODE::GetParent(), SGNODE::isWritten(), m_Appearance, m_FaceSet, SGNODE::m_Parent, m_RAppearance, m_RFaceSet, SGNODE::m_written, NITEMS, SGNODE::SwapParent(), SGAPPEARANCE::WriteCache(), SGFACESET::WriteCache(), and SGNODE::WriteCache().

◆ WriteVRML()

bool SGSHAPE::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 316 of file sg_shape.cpp.

317{
319 {
320 return false;
321 }
322
323 if( aReuseFlag )
324 {
325 if( !m_written )
326 {
327 aFile << "DEF " << GetName() << " Shape {\n";
328 m_written = true;
329 }
330 else
331 {
332 aFile << " USE " << GetName() << "\n";
333 return true;
334 }
335 }
336 else
337 {
338 aFile << " Shape {\n";
339 }
340
341 if( m_Appearance )
342 m_Appearance->WriteVRML( aFile, aReuseFlag );
343
344 if( m_RAppearance )
345 m_RAppearance->WriteVRML( aFile, aReuseFlag );
346
347 if( m_FaceSet )
348 m_FaceSet->WriteVRML( aFile, aReuseFlag );
349
350 if( m_RFaceSet )
351 m_RFaceSet->WriteVRML( aFile, aReuseFlag );
352
353 aFile << "}\n";
354
355 return true;
356}
bool WriteVRML(std::ostream &aFile, bool aReuseFlag) override
Writes this node's data to a VRML file.
bool WriteVRML(std::ostream &aFile, bool aReuseFlag) override
Writes this node's data to a VRML file.
Definition: sg_faceset.cpp:438

References SGNODE::GetName(), m_Appearance, m_FaceSet, m_RAppearance, m_RFaceSet, SGNODE::m_written, SGAPPEARANCE::WriteVRML(), and SGFACESET::WriteVRML().

Member Data Documentation

◆ m_Appearance

SGAPPEARANCE* SGSHAPE::m_Appearance

◆ 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_FaceSet

SGFACESET* SGSHAPE::m_FaceSet

◆ m_Name

◆ m_Parent

◆ m_RAppearance

SGAPPEARANCE* SGSHAPE::m_RAppearance

Definition at line 76 of file sg_shape.h.

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

◆ m_RFaceSet

SGFACESET* SGSHAPE::m_RFaceSet

Definition at line 77 of file sg_shape.h.

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

◆ m_SGtype

◆ m_written


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