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