KiCad PCB EDA Suite
vrml1_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) 2015-2016 Cirilo Bernardo <[email protected]>
5 * Copyright (C) 2021 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#include <iostream>
26#include <sstream>
27#include <wx/log.h>
28
29#include "vrml1_base.h"
30#include "vrml1_transform.h"
32
33
34WRL1TRANSFORM::WRL1TRANSFORM( NAMEREGISTER* aDictionary ) : WRL1NODE( aDictionary )
35{
37}
38
39
41 WRL1NODE( aDictionary )
42{
44 m_Parent = aParent;
45
46 if( nullptr != m_Parent )
47 m_Parent->AddChildNode( this );
48}
49
50
52{
53 wxLogTrace( traceVrmlPlugin,
54 wxT( " * [INFO] Destroying Transform node with %zu children, %zu"
55 "references, and %zu back pointers." ),
56 m_Children.size(), m_Refs.size(), m_BackPointers.size() );
57}
58
59
60bool WRL1TRANSFORM::Read( WRLPROC& proc, WRL1BASE* aTopNode )
61{
62 /*
63 * Structure of a Transform node:
64 *
65 * Transform {
66 * SFVec3f center 0 0 0
67 * SFRotation rotation 0 0 1 0
68 * SFVec3f scale 1 1 1
69 * SFRotation scaleOrientation 0 0 1 0
70 * SFVec3f translation 0 0 0
71 * }
72 */
73
74 wxCHECK_MSG( aTopNode, false, wxT( "Invalid top node." ) );
75
76 center.x = 0.0;
77 center.y = 0.0;
78 center.z = 0.0;
79
81
82 rotation.x = 0.0;
83 rotation.y = 0.0;
84 rotation.z = 1.0;
85 rotation.w = 0.0;
86
88
89 scale.x = 1.0;
90 scale.y = 1.0;
91 scale.z = 1.0;
92
93 char tok = proc.Peek();
94
95 if( proc.eof() )
96 {
97 wxLogTrace( traceVrmlPlugin, wxT( "%s:%s:%d\n"
98 " * [INFO] bad file format; unexpected eof %s." ),
99 __FILE__, __FUNCTION__, __LINE__, proc.GetFilePosition() );
100
101 return false;
102 }
103
104 if( '{' != tok )
105 {
106 wxLogTrace( traceVrmlPlugin,
107 wxT( "%s:%s:%d\n"
108 " * [INFO] bad file format; expecting '{' but got '%s' %s." ),
109 __FILE__, __FUNCTION__, __LINE__, tok, proc.GetFilePosition() );
110
111 return false;
112 }
113
114 proc.Pop();
115 std::string glob;
116
117 while( true )
118 {
119 if( proc.Peek() == '}' )
120 {
121 proc.Pop();
122 break;
123 }
124
125 if( !proc.ReadName( glob ) )
126 {
127 wxLogTrace( traceVrmlPlugin, wxT( "%s:%s:%d\n"
128 "%s" ),
129 __FILE__, __FUNCTION__, __LINE__ , proc.GetError() );
130
131 return false;
132 }
133
134 // expecting one of:
135 // center
136 // rotation
137 // scale
138 // ScaleOrientation
139 // translation
140
141 if( !glob.compare( "center" ) )
142 {
143 if( !proc.ReadSFVec3f( center ) )
144 {
145 wxLogTrace( traceVrmlPlugin, wxT( "%s:%s:%d"
146 " * [INFO] invalid center %s\n"
147 " * [INFO] file: '%s'\n"
148 "%s" ),
149 __FILE__, __FUNCTION__, __LINE__, proc.GetFilePosition(),
150 proc.GetFileName(), proc.GetError() );
151
152 return false;
153 }
154
155 // convert from 1 VRML Unit = 0.1 inch to 1 VRML Unit = 1 mm
156 center.x *= 2.54f;
157 center.y *= 2.54f;
158 center.z *= 2.54f;
159 }
160 else if( !glob.compare( "rotation" ) )
161 {
162 if( !proc.ReadSFRotation( rotation ) )
163 {
164 wxLogTrace( traceVrmlPlugin, wxT( "%s:%s:%d"
165 " * [INFO] invalid rotation %s\n"
166 " * [INFO] file: '%s'\n"
167 "%s" ),
168 __FILE__, __FUNCTION__, __LINE__, proc.GetFilePosition(),
169 proc.GetFileName(), proc.GetError() );
170
171 return false;
172 }
173 }
174 else if( !glob.compare( "scaleFactor" ) )
175 {
176 if( !proc.ReadSFVec3f( scale ) )
177 {
178 wxLogTrace( traceVrmlPlugin, wxT( "%s:%s:%d"
179 " * [INFO] invalid scale %s\n"
180 " * [INFO] file: '%s'\n"
181 "%s" ),
182 __FILE__, __FUNCTION__, __LINE__, proc.GetFilePosition(),
183 proc.GetFileName(), proc.GetError() );
184
185 return false;
186 }
187 }
188 else if( !glob.compare( "scaleOrientation" ) )
189 {
190 if( !proc.ReadSFRotation( scaleOrientation ) )
191 {
192 wxLogTrace( traceVrmlPlugin, wxT( "%s:%s:%d"
193 " * [INFO] invalid scaleOrientation %s\n"
194 " * [INFO] file: '%s'\n"
195 "%s" ),
196 __FILE__, __FUNCTION__, __LINE__, proc.GetFilePosition(),
197 proc.GetFileName(), proc.GetError() );
198
199 return false;
200 }
201 }
202 else if( !glob.compare( "translation" ) )
203 {
204 if( !proc.ReadSFVec3f( translation ) )
205 {
206 wxLogTrace( traceVrmlPlugin, wxT( "%s:%s:%d"
207 " * [INFO] invalid translation %s\n"
208 " * [INFO] file: '%s'\n"
209 "%s" ),
210 __FILE__, __FUNCTION__, __LINE__, proc.GetFilePosition(),
211 proc.GetFileName(), proc.GetError() );
212
213 return false;
214 }
215
216 // convert from 1 VRML Unit = 0.1 inch to 1 VRML Unit = 1 mm
217 translation.x *= 2.54f;
218 translation.y *= 2.54f;
219 translation.z *= 2.54f;
220 }
221 else
222 {
223 wxLogTrace( traceVrmlPlugin, wxT( "%s:%s:%d"
224 " * [INFO] invalid Transform %s\n"
225 " * [INFO] file: '%s'" ),
226 __FILE__, __FUNCTION__, __LINE__, proc.GetFilePosition(),
227 proc.GetFileName() );
228
229 return false;
230 }
231 } // while( true ) -- reading contents of Transform{}
232
233 return true;
234}
235
236
238{
239 // this node may not own or reference any other node
240 wxCHECK_MSG( false, false, wxT( "AddRefNode is not applicable" ) );
241}
242
243
245{
246 // this node may not own or reference any other node
247 wxCHECK_MSG( false, false, wxT( "AddChildNode is not applicable." ) );
248}
249
250
252{
253 if( nullptr == m_Parent )
254 return nullptr;
255
257 return nullptr;
258
259 wxCHECK_MSG( sp, nullptr, wxT( "Bad model: no base data given" ) );
260
261 // rotation
262 float rX, rY, rZ, rW;
263 rX = rotation.x;
264 rY = rotation.y;
265 rZ = rotation.z;
266 rW = rotation.w;
267 glm::mat4 rM = glm::rotate( glm::mat4( 1.0f ), rW, glm::vec3( rX, rY, rZ ) );
268
269 // translation
270 float dX, dY, dZ;
271 dX = translation.x;
272 dY = translation.y;
273 dZ = translation.z;
274 glm::mat4 tM = glm::translate( glm::mat4( 1.0f ), glm::vec3( dX, dY, dZ ) );
275
276 // center
277 dX = center.x;
278 dY = center.y;
279 dZ = center.z;
280 glm::mat4 cM = glm::translate( glm::mat4( 1.0f ), glm::vec3( dX, dY, dZ ) );
281 glm::mat4 ncM = glm::translate( glm::mat4( 1.0f ), glm::vec3( -dX, -dY, -dZ ) );
282
283 // scale
284 glm::mat4 sM = glm::scale( glm::mat4( 1.0 ), glm::vec3( scale.x, scale.y, scale.z ) );
285
286 // scaleOrientation
287 rX = scaleOrientation.x;
288 rY = scaleOrientation.y;
289 rZ = scaleOrientation.z;
290 rW = scaleOrientation.w;
291 glm::mat4 srM = glm::rotate( glm::mat4( 1.0f ), rW, glm::vec3( rX, rY, rZ ) );
292 glm::mat4 nsrM = glm::rotate( glm::mat4( 1.0f ), -rW, glm::vec3( rX, rY, rZ ) );
293
294 // resultant transform:
295 // tx' = tM * cM * rM * srM * sM * nsrM * ncM
296 sp->txmatrix = sp->txmatrix * tM * cM * rM * srM * sM * nsrM * ncM;
297
298 return nullptr;
299}
The base class of all Scene Graph nodes.
Definition: sg_node.h:75
Represent the top node of a VRML1 model.
Definition: vrml1_base.h:46
The base class of all VRML1 nodes.
Definition: vrml1_node.h:117
WRL1NODES m_Type
Definition: vrml1_node.h:227
virtual bool AddChildNode(WRL1NODE *aNode)
Definition: vrml1_node.cpp:376
std::list< WRL1NODE * > m_BackPointers
Definition: vrml1_node.h:230
std::list< WRL1NODE * > m_Children
Definition: vrml1_node.h:231
WRL1NODE * m_Parent
Definition: vrml1_node.h:226
std::list< WRL1NODE * > m_Refs
Definition: vrml1_node.h:232
WRL1NODES GetNodeType(void) const
Return the type of this node instance.
Definition: vrml1_node.cpp:254
WRLROTATION rotation
WRL1TRANSFORM(NAMEREGISTER *aDictionary)
bool AddChildNode(WRL1NODE *aNode) override
WRLVEC3F translation
virtual ~WRL1TRANSFORM()
bool AddRefNode(WRL1NODE *aNode) override
WRLROTATION scaleOrientation
bool Read(WRLPROC &proc, WRL1BASE *aTopNode) override
SGNODE * TranslateToSG(SGNODE *aParent, WRL1STATUS *sp) override
Produce a representation of the data using the intermediate scenegraph structures of the kicad_3dsg l...
void Pop(void)
Definition: wrlproc.cpp:2035
char Peek(void)
Definition: wrlproc.cpp:2007
std::string GetFileName(void)
Definition: wrlproc.cpp:1995
std::string GetError(void)
Definition: wrlproc.cpp:1960
bool eof(void)
Definition: wrlproc.cpp:1954
bool ReadName(std::string &aName)
Definition: wrlproc.cpp:289
std::string GetFilePosition() const
Definition: wrlproc.cpp:1982
bool ReadSFRotation(WRLROTATION &aSFRotation)
Definition: wrlproc.cpp:937
bool ReadSFVec3f(WRLVEC3F &aSFVec3f)
Definition: wrlproc.cpp:1082
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
const int scale
glm::mat4 txmatrix
Definition: vrml1_node.h:103