KiCad PCB EDA Suite
Loading...
Searching...
No Matches
sg_node.cpp
Go to the documentation of this file.
1/*
2 * This program source code file is part of KiCad, a free EDA CAD application.
3 *
4 * Copyright (C) 2015 Cirilo Bernardo <[email protected]>
5 * Copyright The KiCad Developers, see AUTHORS.txt for contributors.
6 *
7 * This program is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU General Public License
9 * as published by the Free Software Foundation; either version 2
10 * of the License, or (at your option) any later version.
11 *
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
16 *
17 * You should have received a copy of the GNU General Public License
18 * along with this program. If not, see <https://www.gnu.org/licenses/>.
19 */
20
21#include <algorithm>
22#include <cmath>
23#include <cstring>
24#include <iostream>
25#include <sstream>
26#include <wx/log.h>
27
28#include "3d_cache/sg/sg_node.h"
30
31
32static const std::string node_names[S3D::SGTYPE_END + 1] = {
33 "TXFM",
34 "APP",
35 "COL",
36 "COLIDX",
37 "FACE",
38 "COORD",
39 "COORDIDX",
40 "NORM",
41 "SHAPE",
42 "INVALID"
43};
44
45
46static unsigned int node_counts[S3D::SGTYPE_END] = { 1, 1, 1, 1, 1, 1, 1, 1, 1 };
47
48
49char const* S3D::GetNodeTypeName( S3D::SGTYPES aType ) noexcept
50{
51 return node_names[aType].c_str();
52}
53
54
55static void getNodeName( S3D::SGTYPES nodeType, std::string& aName )
56{
57 if( nodeType < 0 || nodeType >= S3D::SGTYPE_END )
58 {
60 return;
61 }
62
63 unsigned int seqNum = node_counts[nodeType];
64 ++node_counts[nodeType];
65
66 std::ostringstream ostr;
67 ostr << node_names[nodeType] << "_" << seqNum;
68 aName = ostr.str();
69}
70
71
73{
74 m_Parent = aParent;
75 m_Association = nullptr;
76 m_written = false;
78}
79
80
82{
83 if( m_Parent )
84 m_Parent->unlinkChildNode( this );
85
86 if( m_Association )
87 *m_Association = nullptr;
88
89 std::list< SGNODE* >::iterator sBP = m_BackPointers.begin();
90 std::list< SGNODE* >::iterator eBP = m_BackPointers.end();
91
92 while( sBP != eBP )
93 {
94 (*sBP)->unlinkRefNode( this );
95 ++sBP;
96 }
97}
98
99
100S3D::SGTYPES SGNODE::GetNodeType( void ) const noexcept
101{
102 return m_SGtype;
103}
104
105
106SGNODE* SGNODE::GetParent( void ) const noexcept
107{
108 return m_Parent;
109}
110
111
112bool SGNODE::SwapParent( SGNODE* aNewParent )
113{
114 if( aNewParent == m_Parent )
115 return true;
116
117 if( nullptr == aNewParent )
118 return false;
119
120 if( nullptr == m_Parent )
121 {
122 if( aNewParent->AddChildNode( this ) )
123 return true;
124
125 return false;
126 }
127
128 if( aNewParent->GetNodeType() != m_Parent->GetNodeType() )
129 return false;
130
131 SGNODE* oldParent = m_Parent;
132 m_Parent->unlinkChildNode( this );
133 m_Parent = nullptr;
134 aNewParent->unlinkRefNode( this );
135 aNewParent->AddChildNode( this );
136 oldParent->AddRefNode( this );
137
138 return true;
139}
140
141
142const char* SGNODE::GetName( void )
143{
144 if( m_Name.empty() )
146
147 return m_Name.c_str();
148}
149
150
151void SGNODE::SetName( const char* aName )
152{
153 if( nullptr == aName || 0 == aName[0] )
155 else
156 m_Name = aName;
157}
158
159
160const char* SGNODE::GetNodeTypeName( S3D::SGTYPES aNodeType ) const noexcept
161{
162 return node_names[aNodeType].c_str();
163}
164
165
167{
168 if( nullptr == aNode )
169 return;
170
171 std::list< SGNODE* >::iterator np =
172 std::find( m_BackPointers.begin(), m_BackPointers.end(), aNode );
173
174 if( np != m_BackPointers.end() )
175 return;
176
177 m_BackPointers.push_back( aNode );
178}
179
180
181void SGNODE::delNodeRef( const SGNODE* aNode )
182{
183 if( nullptr == aNode )
184 return;
185
186 std::list< SGNODE* >::iterator np =
187 std::find( m_BackPointers.begin(), m_BackPointers.end(), aNode );
188
189 if( np != m_BackPointers.end() )
190 {
191 m_BackPointers.erase( np );
192 return;
193 }
194
195 wxLogTrace( MASK_3D_SG, wxT( "%s:%s:%d * [BUG] delNodeRef() did not find its target, this "
196 "node type %d, referenced node type %d" ),
197 __FILE__, __FUNCTION__, __LINE__,
198 m_SGtype,
199 aNode->GetNodeType() );
200}
201
202
203void SGNODE::AssociateWrapper( SGNODE** aWrapperRef ) noexcept
204{
205 wxCHECK( aWrapperRef && *aWrapperRef == this, /* void */ );
206
207 // if there is an existing association then break it and emit a warning
208 // just in case the behavior is undesired
209 if( m_Association )
210 {
211 *m_Association = nullptr;
212
213 wxLogTrace( MASK_3D_SG, wxT( "%s:%s:%d * [WARNING] association being broken with "
214 "previous wrapper" ),
215 __FILE__, __FUNCTION__, __LINE__ );
216 }
217
218 m_Association = aWrapperRef;
219}
220
221void SGNODE::DisassociateWrapper( SGNODE** aWrapperRef ) noexcept
222{
223 if( !m_Association )
224 return;
225
226 wxCHECK( aWrapperRef, /* void */ );
227
228 wxCHECK( *aWrapperRef == *m_Association && aWrapperRef == m_Association, /* void */ );
229
230 m_Association = nullptr;
231}
232
233
234void SGNODE::ResetNodeIndex( void ) noexcept
235{
236 for( int i = 0; i < (int)S3D::SGTYPE_END; ++i )
237 node_counts[i] = 1;
238}
239
240
241bool S3D::GetMatIndex( MATLIST& aList, SGNODE* aNode, int& aIndex )
242{
243 aIndex = 0;
244
245 wxCHECK( aNode && S3D::SGTYPE_APPEARANCE == aNode->GetNodeType(), false );
246
247 SGAPPEARANCE* node = (SGAPPEARANCE*)aNode;
248
249 std::map< SGAPPEARANCE const*, int >::iterator it = aList.matmap.find( node );
250
251 if( it != aList.matmap.end() )
252 {
253 aIndex = it->second;
254 return true;
255 }
256
257 int idx = (int)aList.matorder.size();
258 aList.matorder.push_back( node );
259 aList.matmap.emplace( node, idx );
260 aIndex = idx;
261
262 return true;
263}
264
265
267{
268 aMaterial = {};
269}
270
271
272void S3D::INIT_SMESH( SMESH& aMesh ) noexcept
273{
274 aMesh = {};
275}
276
277
278void S3D::INIT_S3DMODEL( S3DMODEL& aModel ) noexcept
279{
280 aModel = {};
281}
282
283
284void S3D::FREE_SMESH( SMESH& aMesh ) noexcept
285{
286 if( nullptr != aMesh.m_Positions )
287 {
288 delete [] aMesh.m_Positions;
289 aMesh.m_Positions = nullptr;
290 }
291
292 if( nullptr != aMesh.m_Normals )
293 {
294 delete [] aMesh.m_Normals;
295 aMesh.m_Normals = nullptr;
296 }
297
298 if( nullptr != aMesh.m_Texcoords )
299 {
300 delete [] aMesh.m_Texcoords;
301 aMesh.m_Texcoords = nullptr;
302 }
303
304 if( nullptr != aMesh.m_Color )
305 {
306 delete [] aMesh.m_Color;
307 aMesh.m_Color = nullptr;
308 }
309
310 if( nullptr != aMesh.m_FaceIdx )
311 {
312 delete [] aMesh.m_FaceIdx;
313 aMesh.m_FaceIdx = nullptr;
314 }
315
316 aMesh.m_VertexSize = 0;
317 aMesh.m_FaceIdxSize = 0;
318 aMesh.m_MaterialIdx = 0;
319}
320
321
323{
324 if( nullptr != aModel.m_Materials )
325 {
326 delete [] aModel.m_Materials;
327 aModel.m_Materials = nullptr;
328 }
329
330 aModel.m_MaterialsSize = 0;
331
332 if( nullptr != aModel.m_Meshes )
333 {
334 for( unsigned int i = 0; i < aModel.m_MeshesSize; ++i )
335 FREE_SMESH( aModel.m_Meshes[i] );
336
337 delete [] aModel.m_Meshes;
338 aModel.m_Meshes = nullptr;
339 }
340
341 aModel.m_MeshesSize = 0;
342}
define an internal structure to be used by the 3D renders
Defines the generic material appearance of a scenegraph object.
The base class of all Scene Graph nodes.
Definition sg_node.h:71
void SetName(const char *aName)
Definition sg_node.cpp:151
void ResetNodeIndex(void) noexcept
Reset the global SG* node indices in preparation for write operations.
Definition sg_node.cpp:234
virtual bool AddRefNode(SGNODE *aNode)=0
const char * GetName(void)
Definition sg_node.cpp:142
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:106
S3D::SGTYPES GetNodeType(void) const noexcept
Return the type of this node instance.
Definition sg_node.cpp:100
virtual bool AddChildNode(SGNODE *aNode)=0
virtual ~SGNODE()
Definition sg_node.cpp:81
SGNODE ** m_Association
Handle to the instance held by a wrapper.
Definition sg_node.h:229
void AssociateWrapper(SGNODE **aWrapperRef) noexcept
Associate this object with a handle to itself.
Definition sg_node.cpp:203
std::list< SGNODE * > m_BackPointers
nodes which hold a reference to this.
Definition sg_node.h:222
const char * GetNodeTypeName(S3D::SGTYPES aNodeType) const noexcept
Definition sg_node.cpp:160
SGNODE * m_Parent
Pointer to parent node; may be NULL for top level transform.
Definition sg_node.h:223
SGNODE(SGNODE *aParent)
Definition sg_node.cpp:72
std::string m_Name
name to use for referencing the entity by name.
Definition sg_node.h:225
void addNodeRef(SGNODE *aNode)
Add a pointer to a node which references this node, but does not own.
Definition sg_node.cpp:166
void DisassociateWrapper(SGNODE **aWrapperRef) noexcept
Remove the association between an IFSG* wrapper object and this object.
Definition sg_node.cpp:221
void delNodeRef(const SGNODE *aNode)
Remove a pointer to a node which references this node, but does not own.
Definition sg_node.cpp:181
bool m_written
Set to true when the object has been written after a ReNameNodes().
Definition sg_node.h:226
S3D::SGTYPES m_SGtype
Type of Scene Graph node.
Definition sg_node.h:224
bool SwapParent(SGNODE *aNewParent)
Swap the ownership with the given parent.
Definition sg_node.cpp:112
virtual void unlinkRefNode(const SGNODE *aNode)=0
Remove pointers to a referenced node.
void INIT_SMESH(SMESH &aMesh) noexcept
Definition sg_node.cpp:272
char const * GetNodeTypeName(S3D::SGTYPES aType) noexcept
Return the name of the given type of node.
Definition sg_node.cpp:49
bool GetMatIndex(MATLIST &aList, SGNODE *aNode, int &aIndex)
Definition sg_node.cpp:241
void INIT_SMATERIAL(SMATERIAL &aMaterial)
Definition sg_node.cpp:266
SGTYPES
Definition sg_types.h:32
@ SGTYPE_APPEARANCE
Definition sg_types.h:34
@ SGTYPE_END
Definition sg_types.h:42
void FREE_SMESH(SMESH &aMesh) noexcept
Definition sg_node.cpp:284
void INIT_S3DMODEL(S3DMODEL &aModel) noexcept
Definition sg_node.cpp:278
void FREE_S3DMODEL(S3DMODEL &aModel)
Definition sg_node.cpp:322
static const std::string node_names[S3D::SGTYPE_END+1]
Definition sg_node.cpp:32
static unsigned int node_counts[S3D::SGTYPE_END]
Definition sg_node.cpp:46
static void getNodeName(S3D::SGTYPES nodeType, std::string &aName)
Definition sg_node.cpp:55
Store the a model based on meshes and materials.
Definition c3dmodel.h:91
SMATERIAL * m_Materials
The materials list of this model.
Definition c3dmodel.h:96
unsigned int m_MeshesSize
Number of meshes in the array.
Definition c3dmodel.h:92
SMESH * m_Meshes
The meshes list of this model.
Definition c3dmodel.h:93
unsigned int m_MaterialsSize
Number of materials in the material array.
Definition c3dmodel.h:95
std::vector< SGAPPEARANCE const * > matorder
Definition sg_node.h:52
std::map< SGAPPEARANCE const *, int > matmap
Definition sg_node.h:53
Per-vertex normal/color/texcoors structure.
Definition c3dmodel.h:77