KiCad PCB EDA Suite
Loading...
Searching...
No Matches
x3d_shape.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) 2016 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
22#include <iostream>
23#include <sstream>
24#include <wx/xml/xml.h>
25#include <wx/log.h>
26#include "x3d_ops.h"
27#include "x3d_shape.h"
29
30
32{
34 appearance = nullptr;
35 geometry = nullptr;
36}
37
38
40{
42 appearance = nullptr;
43 geometry = nullptr;
44
45 if( nullptr != aParent )
46 {
47 X3DNODES ptype = aParent->GetNodeType();
48
49 if( X3D_TRANSFORM == ptype || X3D_SWITCH == ptype )
50 m_Parent = aParent;
51 }
52
53 if( nullptr != m_Parent )
54 m_Parent->AddChildNode( this );
55}
56
57
59{
60 wxLogTrace( traceVrmlPlugin,
61 wxT( " * [INFO] Destroying Shape with %zu children, %zu references, "
62 "%and ul back pointers." ),
63 m_Children.size(), m_Refs.size(), m_BackPointers.size() );
64}
65
66
67bool X3DSHAPE::Read( wxXmlNode* aNode, X3DNODE* aTopNode, X3D_DICT& aDict )
68{
69 if( nullptr == aTopNode || nullptr == aNode )
70 return false;
71
72 if( nullptr != appearance || nullptr != geometry )
73 return false;
74
75 m_Dict = &aDict;
76 wxXmlAttribute* prop;
77
78 for( prop = aNode->GetAttributes(); prop != nullptr; prop = prop->GetNext() )
79 {
80 const wxString& pname = prop->GetName();
81
82 if( pname == wxT( "DEF" ) )
83 {
84 m_Name = prop->GetValue();
85 m_Dict->AddName( m_Name, this );
86 }
87 }
88
89 for( wxXmlNode* child = aNode->GetChildren(); child != nullptr; child = child->GetNext() )
90 {
91 wxString name = child->GetName();
92
93 if( name == wxT( "Appearance" ) && nullptr == appearance )
94 X3D::ReadAppearance( child, this, aDict );
95 else if( name == wxT( "IndexedFaceSet" ) && nullptr == geometry )
96 X3D::ReadIndexedFaceSet( child, this, aDict );
97 }
98
99 if( nullptr == appearance || nullptr == geometry )
100 return false;
101
102 if( !SetParent( aTopNode ) )
103 return false;
104
105 return true;
106}
107
108
109bool X3DSHAPE::SetParent( X3DNODE* aParent, bool doUnlink )
110{
111 if( aParent == m_Parent )
112 return true;
113
114 if( nullptr != aParent )
115 {
116 X3DNODES nt = aParent->GetNodeType();
117
118 if( nt != X3D_SWITCH && nt != X3D_TRANSFORM )
119 return false;
120 }
121
122 if( nullptr != m_Parent && doUnlink )
123 m_Parent->unlinkChildNode( this );
124
125 m_Parent = aParent;
126
127 if( nullptr != m_Parent )
128 m_Parent->AddChildNode( this );
129
130 return true;
131}
132
133
135{
136 if( nullptr == aNode )
137 return false;
138
139 X3DNODES tchild = aNode->GetNodeType();
140
141 if( X3D_APPEARANCE != tchild && X3D_INDEXED_FACE_SET != tchild )
142 return false;
143
144 std::list< X3DNODE* >::iterator sC = m_Children.begin();
145 std::list< X3DNODE* >::iterator eC = m_Children.end();
146
147 while( sC != eC )
148 {
149 if( *sC == aNode )
150 return false;
151
152 ++sC;
153 }
154
155 if( X3D_APPEARANCE == tchild )
156 {
157 if( nullptr == appearance )
158 {
159 m_Children.push_back( aNode );
160 appearance = aNode;
161 }
162 else
163 {
164 return false;
165 }
166 }
167 else
168 {
169 if( nullptr == geometry )
170 {
171 m_Children.push_back( aNode );
172 geometry = aNode;
173 }
174 else
175 {
176 return false;
177 }
178 }
179
180 if( aNode->GetParent() != this )
181 aNode->SetParent( this );
182
183 return true;
184}
185
186
188{
189 if( nullptr == aNode )
190 return false;
191
192 X3DNODES tchild = aNode->GetNodeType();
193
194 if( X3D_APPEARANCE != tchild && X3D_INDEXED_FACE_SET != tchild )
195 return false;
196
197 std::list< X3DNODE* >::iterator sR = m_Refs.begin();
198 std::list< X3DNODE* >::iterator eR = m_Refs.end();
199
200 while( sR != eR )
201 {
202 if( *sR == aNode )
203 return false;
204
205 ++sR;
206 }
207
208 if( X3D_APPEARANCE == tchild )
209 {
210 if( nullptr == appearance )
211 {
212 m_Refs.push_back( aNode );
213 aNode->addNodeRef( this );
214 appearance = aNode;
215 }
216 else
217 {
218 return false;
219 }
220 }
221 else
222 {
223 if( nullptr == geometry )
224 {
225 m_Refs.push_back( aNode );
226 aNode->addNodeRef( this );
227 geometry = aNode;
228 }
229 else
230 {
231 return false;
232 }
233 }
234
235 return true;
236}
237
238
240{
241 if( nullptr == geometry || nullptr == appearance )
242 return nullptr;
243
244 wxLogTrace( traceVrmlPlugin,
245 wxT( " * [INFO] Translating Shape with %zu children, %zu references, "
246 "and %zu back pointers." ),
247 m_Children.size(), m_Refs.size(), m_BackPointers.size() );
248
249 S3D::SGTYPES ptype = S3D::GetSGNodeType( aParent );
250
251 if( nullptr != aParent && ptype != S3D::SGTYPE_TRANSFORM )
252 {
253 wxLogTrace( traceVrmlPlugin,
254 wxT( " * [BUG] Shape does not have a Transform parent (parent ID: %d)" ),
255 ptype );
256
257 return nullptr;
258 }
259
260 if( m_sgNode )
261 {
262 if( nullptr != aParent )
263 {
264 if( nullptr == S3D::GetSGNodeParent( m_sgNode )
265 && !S3D::AddSGNodeChild( aParent, m_sgNode ) )
266 {
267 return nullptr;
268 }
269 else if( aParent != S3D::GetSGNodeParent( m_sgNode )
270 && !S3D::AddSGNodeRef( aParent, m_sgNode ) )
271 {
272 return nullptr;
273 }
274 }
275
276 return m_sgNode;
277 }
278
279 IFSG_SHAPE shNode( aParent );
280
281 SGNODE* pShape = shNode.GetRawPtr();
282 SGNODE* pGeom = geometry->TranslateToSG( pShape );
283 SGNODE* pApp = appearance->TranslateToSG( pShape );
284
285 if( nullptr == pApp || nullptr == pGeom )
286 {
287 if( pGeom )
288 {
289 IFSG_FACESET tmp( false );
290 tmp.Attach( pGeom );
291 tmp.Destroy();
292 }
293
294 if( pApp )
295 {
296 IFSG_APPEARANCE tmp( false );
297 tmp.Attach( pApp );
298 tmp.Destroy();
299 }
300
301 shNode.Destroy();
302 return nullptr;
303 }
304
305 m_sgNode = shNode.GetRawPtr();
306
307 return m_sgNode;
308}
309
310
312{
313 if( nullptr == aNode )
314 return;
315
316 if( aNode == appearance )
317 appearance = nullptr;
318 else if( aNode == geometry )
319 geometry = nullptr;
320
322}
323
324
326{
327 if( nullptr == aNode )
328 return;
329
330 if( aNode == appearance )
331 appearance = nullptr;
332 else if( aNode == geometry )
333 geometry = nullptr;
334
335 X3DNODE::unlinkRefNode( aNode );
336}
const char * name
bool Attach(SGNODE *aNode) override
Associate a given SGNODE* with this wrapper.
The wrapper for the SGFACESET class.
bool Attach(SGNODE *aNode) override
Associate a given SGNODE* with this wrapper.
SGNODE * GetRawPtr(void) noexcept
Return the raw internal SGNODE pointer.
Definition ifsg_node.cpp:61
void Destroy(void)
Delete the object held by this wrapper.
Definition ifsg_node.cpp:51
The wrapper for the SGSHAPE class.
Definition ifsg_shape.h:36
The base class of all Scene Graph nodes.
Definition sg_node.h:71
X3DNODES m_Type
Definition x3d_base.h:156
void addNodeRef(X3DNODE *aNode)
Add a pointer to a node which references, but does not own, this node.
Definition x3d_base.cpp:138
std::list< X3DNODE * > m_Children
Definition x3d_base.h:160
SGNODE * m_sgNode
Definition x3d_base.h:165
std::list< X3DNODE * > m_BackPointers
Definition x3d_base.h:159
X3DNODE * m_Parent
Definition x3d_base.h:155
std::list< X3DNODE * > m_Refs
Definition x3d_base.h:161
X3DNODES GetNodeType(void) const
Return the type of this node instance.
Definition x3d_base.cpp:180
X3DNODE * GetParent(void) const
Return a pointer to the parent node of this object or NULL if the object has no parent (ie.
Definition x3d_base.cpp:186
wxString m_Name
Definition x3d_base.h:164
virtual void unlinkRefNode(const X3DNODE *aNode)
Remove pointers to a referenced node; it is invoked by the referenced node upon destruction to ensure...
Definition x3d_base.cpp:118
virtual bool SetParent(X3DNODE *aParent, bool doUnlink=true)=0
Set the parent X3DNODE of this object.
virtual void unlinkChildNode(const X3DNODE *aNode)
Remove references to an owned child; it is invoked by the child upon destruction to ensure that the p...
Definition x3d_base.cpp:98
X3D_DICT * m_Dict
Definition x3d_base.h:157
virtual void unlinkRefNode(const X3DNODE *aNode) override
Remove pointers to a referenced node; it is invoked by the referenced node upon destruction to ensure...
SGNODE * TranslateToSG(SGNODE *aParent) override
Produce a representation of the data using the intermediate scenegraph structures of the kicad_3dsg l...
bool SetParent(X3DNODE *aParent, bool doUnlink=true) override
Set the parent X3DNODE of this object.
bool AddChildNode(X3DNODE *aNode) override
bool Read(wxXmlNode *aNode, X3DNODE *aTopNode, X3D_DICT &aDict) override
Definition x3d_shape.cpp:67
X3DNODE * appearance
Definition x3d_shape.h:52
virtual ~X3DSHAPE()
Definition x3d_shape.cpp:58
X3DNODE * geometry
Definition x3d_shape.h:53
bool AddRefNode(X3DNODE *aNode) override
virtual void unlinkChildNode(const X3DNODE *aNode) override
Remove references to an owned child; it is invoked by the child upon destruction to ensure that the p...
const wxChar *const traceVrmlPlugin
Flag to enable VRML plugin trace output.
Definition vrml.cpp:59
collects header files for all SG* wrappers and the API
SGLIB_API S3D::SGTYPES GetSGNodeType(SGNODE *aNode)
Definition ifsg_api.cpp:481
SGLIB_API SGNODE * GetSGNodeParent(SGNODE *aNode)
Definition ifsg_api.cpp:490
SGTYPES
Definition sg_types.h:32
@ SGTYPE_TRANSFORM
Definition sg_types.h:33
SGLIB_API bool AddSGNodeChild(SGNODE *aParent, SGNODE *aChild)
Definition ifsg_api.cpp:508
SGLIB_API bool AddSGNodeRef(SGNODE *aParent, SGNODE *aChild)
Definition ifsg_api.cpp:499
bool ReadIndexedFaceSet(wxXmlNode *aNode, X3DNODE *aParent, X3D_DICT &aDict)
Definition x3d_ops.cpp:151
bool ReadAppearance(wxXmlNode *aNode, X3DNODE *aParent, X3D_DICT &aDict)
Definition x3d_ops.cpp:113
X3DNODES
Definition x3d_base.h:56
@ X3D_TRANSFORM
Definition x3d_base.h:57
@ X3D_SWITCH
Definition x3d_base.h:58
@ X3D_APPEARANCE
Definition x3d_base.h:60
@ X3D_SHAPE
Definition x3d_base.h:59
@ X3D_INDEXED_FACE_SET
Definition x3d_base.h:61