KiCad PCB EDA Suite
Loading...
Searching...
No Matches
x3d_transform.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_transform.h"
29
30
36
37
39{
41 init();
42
43 if( nullptr != aParent )
44 {
45 X3DNODES ptype = aParent->GetNodeType();
46
47 if( X3D_TRANSFORM == ptype || X3D_SWITCH == ptype )
48 m_Parent = aParent;
49 }
50
51 if( nullptr != m_Parent )
52 m_Parent->AddChildNode( this );
53}
54
55
57{
58 wxLogTrace( traceVrmlPlugin,
59 wxT( " * [INFO] Destroying Transform with %zu children, %zu references, "
60 "and %zu back pointers." ),
61 m_Children.size(), m_Refs.size(), m_BackPointers.size() );
62}
63
64
66{
67 center.x = 0.0;
68 center.y = 0.0;
69 center.z = 0.0;
70
71 scale.x = 1.0;
72 scale.y = 1.0;
73 scale.z = 1.0;
74
76
77 rotation.x = 0.0;
78 rotation.y = 0.0;
79 rotation.z = 1.0;
80
82
85}
86
87
88void X3DTRANSFORM::readFields( wxXmlNode* aNode )
89{
90 // DEF
91 // center
92 // scale
93 // translation
94 // rotation
95 // scaleOrientation
96 // bboxCenter (ignored)
97 // bboxSize (ignored)
98
99 wxXmlAttribute* prop;
100
101 // note: center/translation are multiplied by 2.54 to retain
102 // legacy behavior of 1 X3D unit = 0.1 inch; the SG*
103 // classes expect all units in mm.
104
105 for( prop = aNode->GetAttributes(); prop != nullptr; prop = prop->GetNext() )
106 {
107 const wxString& pname = prop->GetName();
108
109 if( pname == wxT( "DEF" ) )
110 {
111 m_Name = prop->GetValue();
112 m_Dict->AddName( m_Name, this );
113 }
114 else if( pname == wxT( "center" ) )
115 {
116 X3D::ParseSFVec3( prop->GetValue(), center );
117 center *= 2.54;
118 }
119 else if( pname == wxT( "scale" ) )
120 {
121 X3D::ParseSFVec3( prop->GetValue(), scale );
122 }
123 else if( pname == wxT( "translation" ) )
124 {
125 X3D::ParseSFVec3( prop->GetValue(), translation );
126 translation *= 2.54;
127 }
128 else if( pname == wxT( "rotation" ) )
129 {
130 X3D::ParseSFRotation( prop->GetValue(), rotation );
131 }
132 else if( pname == wxT( "scaleOrientation" ) )
133 {
134 X3D::ParseSFRotation( prop->GetValue(), scaleOrientation );
135 }
136 }
137}
138
139
140bool X3DTRANSFORM::Read( wxXmlNode* aNode, X3DNODE* aTopNode, X3D_DICT& aDict )
141{
142 if( nullptr == aTopNode || nullptr == aNode )
143 return false;
144
145 m_Dict = &aDict;
146 readFields( aNode );
147 bool ok = false;
148
149 for( wxXmlNode* child = aNode->GetChildren(); child != nullptr; child = child->GetNext() )
150 {
151 wxString name = child->GetName();
152
153 if( name == wxT( "Transform" ) || name == wxT( "Group" ) )
154 ok |= X3D::ReadTransform( child, this, aDict );
155 else if( name == wxT( "Switch" ) )
156 ok |= X3D::ReadSwitch( child, this, aDict );
157 else if( name == wxT( "Shape" ) )
158 ok |= X3D::ReadShape( child, this, aDict );
159
160 }
161
162 if( !ok )
163 return false;
164
165 if( !SetParent( aTopNode ) )
166 return false;
167
168 return true;
169}
170
171
172bool X3DTRANSFORM::SetParent( X3DNODE* aParent, bool doUnlink )
173{
174 if( aParent == m_Parent )
175 return true;
176
177 if( nullptr != aParent )
178 {
179 X3DNODES nt = aParent->GetNodeType();
180
181 if( nt != X3D_SWITCH && nt != X3D_TRANSFORM )
182 return false;
183 }
184
185 if( nullptr != m_Parent && doUnlink )
186 m_Parent->unlinkChildNode( this );
187
188 m_Parent = aParent;
189
190 if( nullptr != m_Parent )
191 m_Parent->AddChildNode( this );
192
193 return true;
194}
195
196
198{
199 if( nullptr == aNode )
200 return false;
201
202 X3DNODES tchild = aNode->GetNodeType();
203
204 if( X3D_SWITCH != tchild && X3D_TRANSFORM != tchild && X3D_SHAPE != tchild )
205 return false;
206
207 std::list< X3DNODE* >::iterator sC = m_Children.begin();
208 std::list< X3DNODE* >::iterator eC = m_Children.end();
209
210 while( sC != eC )
211 {
212 if( *sC == aNode )
213 return false;
214
215 ++sC;
216 }
217
218 m_Children.push_back( aNode );
219
220 if( aNode->GetParent() != this )
221 aNode->SetParent( this );
222
223 return true;
224}
225
226
228{
229 if( nullptr == aNode )
230 return false;
231
232 X3DNODES tchild = aNode->GetNodeType();
233
234 if( X3D_SWITCH != tchild && X3D_TRANSFORM != tchild && X3D_SHAPE != tchild )
235 return false;
236
237 std::list< X3DNODE* >::iterator sR = m_Refs.begin();
238 std::list< X3DNODE* >::iterator eR = m_Refs.end();
239
240 while( sR != eR )
241 {
242 if( *sR == aNode )
243 return true;
244
245 ++sR;
246 }
247
248 m_Refs.push_back( aNode );
249 aNode->addNodeRef( this );
250
251 return true;
252}
253
254
256{
257 wxLogTrace( traceVrmlPlugin,
258 wxT( " * [INFO] Translating Transform with %zu children, %zu references, "
259 "and %zu back pointers." ),
260 m_Children.size(), m_Refs.size(), m_BackPointers.size() );
261
262 if( m_Children.empty() && m_Refs.empty() )
263 return nullptr;
264
265 S3D::SGTYPES ptype = S3D::GetSGNodeType( aParent );
266
267 if( nullptr != aParent && ptype != S3D::SGTYPE_TRANSFORM )
268 {
269 wxLogTrace( traceVrmlPlugin,
270 wxT( " * [BUG] Transform does not have a Transform parent (parent ID: %d)" ),
271 ptype );
272
273 return nullptr;
274 }
275
276 if( m_sgNode )
277 {
278 if( nullptr != aParent )
279 {
280 if( nullptr == S3D::GetSGNodeParent( m_sgNode )
281 && !S3D::AddSGNodeChild( aParent, m_sgNode ) )
282 {
283 return nullptr;
284 }
285 else if( aParent != S3D::GetSGNodeParent( m_sgNode )
286 && !S3D::AddSGNodeRef( aParent, m_sgNode ) )
287 {
288 return nullptr;
289 }
290 }
291
292 return m_sgNode;
293 }
294
295 IFSG_TRANSFORM txNode( aParent );
296
297 std::list< X3DNODE* >::iterator sC = m_Children.begin();
298 std::list< X3DNODE* >::iterator eC = m_Children.end();
299 X3DNODES type;
300
301 // Include only the following in a Transform node:
302 // Shape
303 // Switch
304 // Transform
305 // Inline
306 bool test = false; // set to true if there are any subnodes for display
307
308 for( int i = 0; i < 2; ++i )
309 {
310 while( sC != eC )
311 {
312 type = (*sC)->GetNodeType();
313
314 switch( type )
315 {
316 case X3D_SHAPE:
317 case X3D_SWITCH:
318 case X3D_TRANSFORM:
319
320 if( nullptr != (*sC)->TranslateToSG( txNode.GetRawPtr() ) )
321 test = true;
322
323 break;
324
325 default:
326 break;
327 }
328
329 ++ sC;
330 }
331
332 sC = m_Refs.begin();
333 eC = m_Refs.end();
334 }
335
336 if( false == test )
337 {
338 txNode.Destroy();
339 return nullptr;
340 }
341
342 txNode.SetScale( SGPOINT( scale.x, scale.y, scale.z ) );
343 txNode.SetCenter( SGPOINT( center.x, center.y, center.z ) );
347 txNode.SetRotation( SGVECTOR( rotation.x, rotation.y, rotation.z ), rotation.w );
348
349 m_sgNode = txNode.GetRawPtr();
350
351 return m_sgNode;
352}
const char * name
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 VRML compatible TRANSFORM block class SCENEGRAPH.
bool SetTranslation(const SGPOINT &aTranslation) noexcept
bool SetScaleOrientation(const SGVECTOR &aScaleAxis, double aAngle)
bool SetCenter(const SGPOINT &aCenter) noexcept
bool SetRotation(const SGVECTOR &aRotationAxis, double aAngle)
bool SetScale(const SGPOINT &aScale) noexcept
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 bool SetParent(X3DNODE *aParent, bool doUnlink=true)=0
Set the parent X3DNODE of this object.
X3D_DICT * m_Dict
Definition x3d_base.h:157
virtual ~X3DTRANSFORM()
bool AddRefNode(X3DNODE *aNode) override
WRLVEC3F bboxCenter
bool AddChildNode(X3DNODE *aNode) override
bool SetParent(X3DNODE *aParent, bool doUnlink=true) override
Set the parent X3DNODE of this object.
SGNODE * TranslateToSG(SGNODE *aParent) override
Produce a representation of the data using the intermediate scenegraph structures of the kicad_3dsg l...
WRLVEC3F scale
void readFields(wxXmlNode *aNode)
WRLVEC3F bboxSize
WRLVEC3F center
bool Read(wxXmlNode *aNode, X3DNODE *aTopNode, X3D_DICT &aDict) override
WRLVEC3F translation
WRLROTATION rotation
WRLROTATION scaleOrientation
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 ParseSFRotation(const wxString &aSource, WRLROTATION &aResult)
Definition x3d_ops.cpp:280
bool ParseSFVec3(const wxString &aSource, WRLVEC3F &aResult)
Definition x3d_ops.cpp:260
bool ReadSwitch(wxXmlNode *aNode, X3DNODE *aParent, X3D_DICT &aDict)
Definition x3d_ops.cpp:68
bool ReadShape(wxXmlNode *aNode, X3DNODE *aParent, X3D_DICT &aDict)
Definition x3d_ops.cpp:75
bool ReadTransform(wxXmlNode *aNode, X3DNODE *aParent, X3D_DICT &aDict)
Definition x3d_ops.cpp:30
X3DNODES
Definition x3d_base.h:56
@ X3D_TRANSFORM
Definition x3d_base.h:57
@ X3D_SWITCH
Definition x3d_base.h:58
@ X3D_SHAPE
Definition x3d_base.h:59