KiCad PCB EDA Suite
Loading...
Searching...
No Matches
vrml2_box.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 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/log.h>
29
30#include "vrml2_base.h"
31#include "vrml2_box.h"
33
34
36{
37 m_Type = WRL2NODES::WRL2_BOX;
38 size.x = 2.0;
39 size.y = 2.0;
40 size.z = 2.0;
41}
42
43
45{
46 m_Type = WRL2NODES::WRL2_BOX;
47 m_Parent = aParent;
48 size.x = 2.0;
49 size.y = 2.0;
50 size.z = 2.0;
51
52 if( nullptr != m_Parent )
53 m_Parent->AddChildNode( this );
54}
55
56
58{
59 wxLogTrace( traceVrmlPlugin, wxT( " * [INFO] Destroying Box node." ) );
60}
61
62
64{
65 // this node is dangling unless it has a parent of type WRL2_SHAPE
66
67 if( nullptr == m_Parent || m_Parent->GetNodeType() != WRL2NODES::WRL2_SHAPE )
68 return true;
69
70 return false;
71}
72
73
74bool WRL2BOX::Read( WRLPROC& proc, WRL2BASE* aTopNode )
75{
76 char tok = proc.Peek();
77
78 if( proc.eof() )
79 {
80 wxLogTrace( traceVrmlPlugin, wxT( "%s:%s:%d\n"
81 " * [INFO] bad file format; unexpected eof %s." ),
82 __FILE__, __FUNCTION__, __LINE__, proc.GetFilePosition() );
83
84 return false;
85 }
86
87 if( '{' != tok )
88 {
89 wxLogTrace( traceVrmlPlugin,
90 wxT( "%s:%s:%d\n"
91 " * [INFO] bad file format; expecting '{' but got '%s' %s." ),
92 __FILE__, __FUNCTION__, __LINE__, tok, proc.GetFilePosition() );
93
94 return false;
95 }
96
97 proc.Pop();
98 std::string glob;
99
100 if( proc.Peek() == '}' )
101 {
102 proc.Pop();
103 return true;
104 }
105
106 if( !proc.ReadName( glob ) )
107 {
108 wxLogTrace( traceVrmlPlugin, wxT( "%s:%s:%d\n"
109 "%s" ),
110 __FILE__, __FUNCTION__, __LINE__ , proc.GetError() );
111
112 return false;
113 }
114
115 // expecting 'size'
116 if( !glob.compare( "size" ) )
117 {
118 if( !proc.ReadSFVec3f( size ) )
119 {
120 wxLogTrace( traceVrmlPlugin, wxT( "%s:%s:%d"
121 " * [INFO] invalid size %s\n"
122 " * [INFO] file: '%s'\n"
123 "%s" ),
124 __FILE__, __FUNCTION__, __LINE__, proc.GetFilePosition(),
125 proc.GetFileName(), proc.GetError() );
126
127 return false;
128 }
129
130 // for legacy KiCad support we interpret units as 0.1 inch
131 size *= 2.54;
132 }
133 else
134 {
135 wxLogTrace( traceVrmlPlugin, wxT( "%s:%s:%d"
136 " * [INFO] invalid Box %s\n"
137 " * [INFO] file: '%s'\n" ),
138 __FILE__, __FUNCTION__, __LINE__, proc.GetFilePosition(),
139 proc.GetFileName() );
140
141 return false;
142 }
143
144 if( size.x < 1e-6 || size.y < 1e-6 || size.z < 1e-6 )
145 {
146 wxLogTrace( traceVrmlPlugin, wxT( "%s:%s:%d"
147 " * [INFO] invalid Box size %s\n"
148 " * [INFO] file: '%s'\n" ),
149 __FILE__, __FUNCTION__, __LINE__, proc.GetFilePosition(),
150 proc.GetFileName() );
151
153 }
154
155 if( proc.Peek() == '}' )
156 {
157 proc.Pop();
158 return true;
159 }
160
161 wxLogTrace( traceVrmlPlugin, wxT( "%s:%s:%d"
162 " * [INFO] invalid size %s (no closing brace).\n"
163 " * [INFO] file: '%s'\n" ),
164 __FILE__, __FUNCTION__, __LINE__, proc.GetFilePosition(), proc.GetFileName() );
165
166 return false;
167}
168
169
171{
172 // this node may not own or reference any other node
173 wxCHECK_MSG( false, false, wxT( "AddRefNode is not applicable." ) );
174}
175
176
178{
179 // this node may not own or reference any other node
180 wxCHECK_MSG( false, false, wxT( "AddChildNode is not applicable." ) );
181}
182
183
185{
186 S3D::SGTYPES ptype = S3D::GetSGNodeType( aParent );
187
188 wxCHECK_MSG( aParent && ( ptype == S3D::SGTYPE_SHAPE ), nullptr,
189 wxString::Format( wxT( "Box does not have a Shape parent (parent ID: %s)" ),
190 ptype ) );
191
192 // do not render a bad box
193 if( size.x < 1e-6 || size.y < 1e-6 || size.z < 1e-6 )
194 return nullptr;
195
196 if( m_sgNode )
197 {
198 if( nullptr != aParent )
199 {
200 if( nullptr == S3D::GetSGNodeParent( m_sgNode )
201 && !S3D::AddSGNodeChild( aParent, m_sgNode ) )
202 {
203 return nullptr;
204 }
205 else if( aParent != S3D::GetSGNodeParent( m_sgNode )
206 && !S3D::AddSGNodeRef( aParent, m_sgNode ) )
207 {
208 return nullptr;
209 }
210 }
211
212 return m_sgNode;
213 }
214
215 // create the vertices, triangle indices, and normals
216 float x = size.x / 2.0;
217 float y = size.y / 2.0;
218 float z = size.z / 2.0;
219 std::vector< SGPOINT > vertices;
220 std::vector< SGVECTOR > norms;
221 std::vector< int > idx;
222 int base = 0;
223
224 vertices.reserve( 6 * 4 );
225 norms.reserve( 6 * 4 );
226 idx.reserve( 6 * 6 );
227
228 // top
229 vertices.emplace_back( -x, -y, z );
230 vertices.emplace_back( x, -y, z );
231 vertices.emplace_back( x, y, z );
232 vertices.emplace_back( -x, y, z );
233 norms.emplace_back( 0.0, 0.0, 1.0 );
234 norms.emplace_back( 0.0, 0.0, 1.0 );
235 norms.emplace_back( 0.0, 0.0, 1.0 );
236 norms.emplace_back( 0.0, 0.0, 1.0 );
237 idx.push_back( base );
238 idx.push_back( base + 1 );
239 idx.push_back( base + 2 );
240 idx.push_back( base );
241 idx.push_back( base + 2 );
242 idx.push_back( base + 3 );
243 base += 4;
244
245 // bottom
246 vertices.emplace_back( -x, -y, -z );
247 vertices.emplace_back( x, -y, -z );
248 vertices.emplace_back( x, y, -z );
249 vertices.emplace_back( -x, y, -z );
250 norms.emplace_back( 0.0, 0.0, -1.0 );
251 norms.emplace_back( 0.0, 0.0, -1.0 );
252 norms.emplace_back( 0.0, 0.0, -1.0 );
253 norms.emplace_back( 0.0, 0.0, -1.0 );
254 idx.push_back( base );
255 idx.push_back( base + 2 );
256 idx.push_back( base + 1 );
257 idx.push_back( base );
258 idx.push_back( base + 3 );
259 idx.push_back( base + 2 );
260 base += 4;
261
262 // front
263 vertices.emplace_back( -x, -y, z );
264 vertices.emplace_back( -x, -y, -z );
265 vertices.emplace_back( x, -y, -z );
266 vertices.emplace_back( x, -y, z );
267 norms.emplace_back( 0.0, -1.0, 0.0 );
268 norms.emplace_back( 0.0, -1.0, 0.0 );
269 norms.emplace_back( 0.0, -1.0, 0.0 );
270 norms.emplace_back( 0.0, -1.0, 0.0 );
271 idx.push_back( base );
272 idx.push_back( base + 1 );
273 idx.push_back( base + 2 );
274 idx.push_back( base );
275 idx.push_back( base + 2 );
276 idx.push_back( base + 3 );
277 base += 4;
278
279 // back
280 vertices.emplace_back( -x, y, z );
281 vertices.emplace_back( -x, y, -z );
282 vertices.emplace_back( x, y, -z );
283 vertices.emplace_back( x, y, z );
284 norms.emplace_back( 0.0, 1.0, 0.0 );
285 norms.emplace_back( 0.0, 1.0, 0.0 );
286 norms.emplace_back( 0.0, 1.0, 0.0 );
287 norms.emplace_back( 0.0, 1.0, 0.0 );
288 idx.push_back( base );
289 idx.push_back( base + 2 );
290 idx.push_back( base + 1 );
291 idx.push_back( base );
292 idx.push_back( base + 3 );
293 idx.push_back( base + 2 );
294 base += 4;
295
296 // left
297 vertices.emplace_back( -x, -y, -z );
298 vertices.emplace_back( -x, -y, z );
299 vertices.emplace_back( -x, y, z );
300 vertices.emplace_back( -x, y, -z );
301 norms.emplace_back( -1.0, 0.0, 0.0 );
302 norms.emplace_back( -1.0, 0.0, 0.0 );
303 norms.emplace_back( -1.0, 0.0, 0.0 );
304 norms.emplace_back( -1.0, 0.0, 0.0 );
305 idx.push_back( base );
306 idx.push_back( base + 1 );
307 idx.push_back( base + 2 );
308 idx.push_back( base );
309 idx.push_back( base + 2 );
310 idx.push_back( base + 3 );
311 base += 4;
312
313 // right
314 vertices.emplace_back( x, -y, -z );
315 vertices.emplace_back( x, -y, z );
316 vertices.emplace_back( x, y, z );
317 vertices.emplace_back( x, y, -z );
318 norms.emplace_back( 1.0, 0.0, 0.0 );
319 norms.emplace_back( 1.0, 0.0, 0.0 );
320 norms.emplace_back( 1.0, 0.0, 0.0 );
321 norms.emplace_back( 1.0, 0.0, 0.0 );
322 idx.push_back( base );
323 idx.push_back( base + 2 );
324 idx.push_back( base + 1 );
325 idx.push_back( base );
326 idx.push_back( base + 3 );
327 idx.push_back( base + 2 );
328
329 IFSG_FACESET fsNode( aParent );
330 IFSG_COORDS cpNode( fsNode );
331 cpNode.SetCoordsList( vertices.size(), &vertices[0] );
332 IFSG_COORDINDEX ciNode( fsNode );
333 ciNode.SetIndices( idx.size(), &idx[0] );
334 IFSG_NORMALS nmNode( fsNode );
335 nmNode.SetNormalList( norms.size(), &norms[0] );
336
337 m_sgNode = fsNode.GetRawPtr();
338
339 return m_sgNode;
340}
IFSG_COORDINDEX is the wrapper for SGCOORDINDEX.
IFSG_COORDS is the wrapper for SGCOORDS.
Definition: ifsg_coords.h:41
bool SetCoordsList(size_t aListSize, const SGPOINT *aCoordsList)
IFSG_FACESET is the wrapper for the SGFACESET class.
Definition: ifsg_faceset.h:41
bool SetIndices(size_t nIndices, int *aIndexList)
Function SetIndices sets the number of indices and creates a copy of the given index data.
Definition: ifsg_index.cpp:47
SGNODE * GetRawPtr(void) noexcept
Function GetRawPtr() returns the raw internal SGNODE pointer.
Definition: ifsg_node.cpp:65
IFSG_NORMALS is the wrapper for the SGNORMALS class.
Definition: ifsg_normals.h:41
bool SetNormalList(size_t aListSize, const SGVECTOR *aNormalList)
The base class of all Scene Graph nodes.
Definition: sg_node.h:75
The top node of a VRML2 model.
Definition: vrml2_base.h:60
bool AddRefNode(WRL2NODE *aNode) override
Definition: vrml2_box.cpp:170
bool isDangling(void) override
Determine whether an object should be moved to a different parent during the VRML to SG* translation.
Definition: vrml2_box.cpp:63
bool AddChildNode(WRL2NODE *aNode) override
Definition: vrml2_box.cpp:177
bool Read(WRLPROC &proc, WRL2BASE *aTopNode) override
Definition: vrml2_box.cpp:74
SGNODE * TranslateToSG(SGNODE *aParent) override
Produce a representation of the data using the intermediate scenegraph structures of the kicad_3dsg l...
Definition: vrml2_box.cpp:184
virtual ~WRL2BOX()
Definition: vrml2_box.cpp:57
WRLVEC3F size
Definition: vrml2_box.h:53
SGNODE * m_sgNode
Definition: vrml2_node.h:178
WRL2NODE * m_Parent
Definition: vrml2_node.h:169
WRL2NODES m_Type
Definition: vrml2_node.h:170
WRL2NODES GetNodeType(void) const
Definition: vrml2_node.cpp:204
virtual bool AddChildNode(WRL2NODE *aNode)
Definition: vrml2_node.cpp:356
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 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
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_SHAPE
Definition: sg_types.h:44
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