KiCad PCB EDA Suite
Loading...
Searching...
No Matches
vrml2_appearance.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/log.h>
25
26#include "vrml2_base.h"
27#include "vrml2_appearance.h"
29
30
38
39
41{
42 material = nullptr;
43 texture = nullptr;
44 textureTransform = nullptr;
46 m_Parent = aParent;
47
48 if( nullptr != m_Parent )
49 m_Parent->AddChildNode( this );
50}
51
52
54{
55 wxLogTrace( traceVrmlPlugin,
56 wxT( " * [INFO] Destroying Appearance node with %zu children, %zu"
57 "references, and %zu back pointers." ),
58 m_Children.size(), m_Refs.size(), m_BackPointers.size() );
59}
60
61
63{
64 switch( aType )
65 {
71 break;
72
73 default:
74 return false;
75 break;
76 }
77
78 return true;
79}
80
81
83{
84 // this node is dangling unless it has a parent of type WRL2_SHAPE
85 if( nullptr == m_Parent || m_Parent->GetNodeType() != WRL2NODES::WRL2_SHAPE )
86 return true;
87
88 return false;
89}
90
91
93{
94 wxCHECK_MSG( aNode, false, wxT( "Invalid node." ) );
95
96 WRL2NODES type = aNode->GetNodeType();
97
98 if( !checkNodeType( type ) )
99 {
100 wxLogTrace( traceVrmlPlugin,
101 wxT( "%s:%s:%d\n"
102 " * [INFO] bad file format; unexpected child node '%s'." ),
103 __FILE__, __FUNCTION__, __LINE__, aNode->GetNodeTypeName( type ) );
104
105 return false;
106 }
107
108 if( WRL2NODES::WRL2_MATERIAL == type )
109 {
110 if( nullptr != material )
111 {
112 wxLogTrace( traceVrmlPlugin,
113 wxT( "%s:%s:%d\n"
114 " * [INFO] bad file format; multiple material nodes." ),
115 __FILE__, __FUNCTION__, __LINE__ );
116
117 return false;
118 }
119
120 material = aNode;
121 return WRL2NODE::AddRefNode( aNode );
122 }
123
125 {
126 if( nullptr != textureTransform )
127 {
128 wxLogTrace( traceVrmlPlugin,
129 wxT( "%s:%s:%d\n"
130 " * [INFO] bad file format; multiple textureTransform nodes." ),
131 __FILE__, __FUNCTION__, __LINE__ );
132
133 return false;
134 }
135
136 textureTransform = aNode;
137 return WRL2NODE::AddRefNode( aNode );
138 }
139
140 if( nullptr != texture )
141 {
142 wxLogTrace( traceVrmlPlugin,
143 wxT( "%s:%s:%d\n"
144 " * [INFO] bad file format; multiple texture nodes." ),
145 __FILE__, __FUNCTION__, __LINE__ );
146
147 return false;
148 }
149
150 texture = aNode;
151 return WRL2NODE::AddRefNode( aNode );
152}
153
154
156{
157 wxCHECK_MSG( aNode, false, wxT( "Invalid node." ) );
158
159 WRL2NODES type = aNode->GetNodeType();
160
161 if( !checkNodeType( type ) )
162 {
163 wxLogTrace( traceVrmlPlugin,
164 wxT( "%s:%s:%d\n"
165 " * [INFO] bad file format; unexpected child node '%s'." ),
166 __FILE__, __FUNCTION__, __LINE__, aNode->GetNodeTypeName( type ) );
167
168 return false;
169 }
170
171 if( WRL2NODES::WRL2_MATERIAL == type )
172 {
173 if( nullptr != material )
174 {
175 wxLogTrace( traceVrmlPlugin,
176 wxT( "%s:%s:%d\n"
177 " * [INFO] bad file format; multiple material nodes." ),
178 __FILE__, __FUNCTION__, __LINE__ );
179
180 return false;
181 }
182
183 material = aNode;
184 return WRL2NODE::AddChildNode( aNode );
185 }
186
188 {
189 if( nullptr != textureTransform )
190 {
191 wxLogTrace( traceVrmlPlugin,
192 wxT( "%s:%s:%d\n"
193 " * [INFO] bad file format; multiple textureTransform nodes." ),
194 __FILE__, __FUNCTION__, __LINE__ );
195
196 return false;
197 }
198
199 textureTransform = aNode;
200 return WRL2NODE::AddChildNode( aNode );
201 }
202
203 if( nullptr != texture )
204 {
205 wxLogTrace( traceVrmlPlugin,
206 wxT( "%s:%s:%d\n"
207 " * [INFO] bad file format; multiple texture nodes." ),
208 __FILE__, __FUNCTION__, __LINE__ );
209
210 return false;
211 }
212
213 texture = aNode;
214 return WRL2NODE::AddChildNode( aNode );
215}
216
217
218bool WRL2APPEARANCE::Read( WRLPROC& proc, WRL2BASE* aTopNode )
219{
220 wxCHECK_MSG( aTopNode, false, wxT( "Invalid top node." ) );
221
222 char tok = proc.Peek();
223
224 if( proc.eof() )
225 {
226 wxLogTrace( traceVrmlPlugin, wxT( "%s:%s:%d\n"
227 " * [INFO] bad file format; unexpected eof %s." ),
228 __FILE__, __FUNCTION__, __LINE__, proc.GetFilePosition() );
229
230 return false;
231 }
232
233 if( '{' != tok )
234 {
235 wxLogTrace( traceVrmlPlugin,
236 wxT( "%s:%s:%d\n"
237 " * [INFO] bad file format; expecting '{' but got '%s' %s." ),
238 __FILE__, __FUNCTION__, __LINE__, tok, proc.GetFilePosition() );
239
240 return false;
241 }
242
243 proc.Pop();
244 std::string glob;
245
246 while( true )
247 {
248 if( proc.Peek() == '}' )
249 {
250 proc.Pop();
251 break;
252 }
253
254 if( !proc.ReadName( glob ) )
255 {
256 wxLogTrace( traceVrmlPlugin, wxT( "%s:%s:%d\n"
257 "%s" ),
258 __FILE__, __FUNCTION__, __LINE__ , proc.GetError() );
259
260 return false;
261 }
262
263 // expecting one of:
264 // material
265 // texture
266 // textureTransform
267
268 if( !glob.compare( "material" ) )
269 {
270 if( !aTopNode->ReadNode( proc, this, nullptr ) )
271 {
272 wxLogTrace( traceVrmlPlugin,
273 wxT( "%s:%s:%d\n"
274 " * [INFO] could not read material information." ),
275 __FILE__, __FUNCTION__, __LINE__ );
276
277 return false;
278 }
279 }
280 else if( !glob.compare( "texture" ) )
281 {
282 if( !aTopNode->ReadNode( proc, this, nullptr ) )
283 {
284 wxLogTrace( traceVrmlPlugin,
285 wxT( "%s:%s:%d\n"
286 " * [INFO] could not read texture information." ),
287 __FILE__, __FUNCTION__, __LINE__ );
288
289 return false;
290 }
291 }
292 else if( !glob.compare( "textureTransform" ) )
293 {
294 if( !aTopNode->ReadNode( proc, this, nullptr ) )
295 {
296 wxLogTrace( traceVrmlPlugin,
297 wxT( "%s:%s:%d\n"
298 " * [INFO] could not read textureTransform information." ),
299 __FILE__, __FUNCTION__, __LINE__ );
300
301 return false;
302 }
303 }
304 else
305 {
306 wxLogTrace( traceVrmlPlugin, wxT( "%s:%s:%d\n"
307 " * [INFO] bad Appearance %s.\n"
308 " * [INFO] file: '%s'" ),
309 __FILE__, __FUNCTION__, __LINE__, proc.GetFilePosition(),
310 proc.GetFileName() );
311
312 return false;
313 }
314 } // while( true ) -- reading contents of Appearance{}
315
316 return true;
317}
318
319
321{
322 if( nullptr == material && nullptr == texture )
323 return nullptr;
324
325 S3D::SGTYPES ptype = S3D::GetSGNodeType( aParent );
326
327 wxCHECK_MSG( aParent && ( ptype == S3D::SGTYPE_SHAPE ), nullptr,
328 wxString::Format( wxT( " * [BUG] Appearance does not have a Shape parent "
329 "(parent ID: %d)." ), ptype ) );
330
331 wxLogTrace( traceVrmlPlugin,
332 wxT( " * [INFO] Translating Appearance node with %zu children, %zu"
333 "references, and %zu back pointers." ),
334 m_Children.size(), m_Refs.size(), m_BackPointers.size() );
335
336 if( m_sgNode )
337 {
338 if( nullptr != aParent )
339 {
340 if( nullptr == S3D::GetSGNodeParent( m_sgNode )
341 && !S3D::AddSGNodeChild( aParent, m_sgNode ) )
342 {
343 return nullptr;
344 }
345 else if( aParent != S3D::GetSGNodeParent( m_sgNode )
346 && !S3D::AddSGNodeRef( aParent, m_sgNode ) )
347 {
348 return nullptr;
349 }
350 }
351
352 return m_sgNode;
353 }
354
355 if( nullptr != texture )
356 {
357 // use a default gray appearance
358 IFSG_APPEARANCE matNode( aParent );
359 matNode.SetEmissive( 0.0f, 0.0f, 0.0f );
360 matNode.SetSpecular( 0.65f, 0.65f, 0.65f );
361 matNode.SetDiffuse( 0.65f, 0.65f, 0.65f );
362
363 // default ambient
364 matNode.SetShininess( 0.2f );
365 matNode.SetTransparency( 0.0f );
366 m_sgNode = matNode.GetRawPtr();
367
368 return m_sgNode;
369 }
370
371 m_sgNode = material->TranslateToSG( aParent );
372
373 return m_sgNode;
374}
375
376
378{
379 if( nullptr == aNode )
380 return;
381
382 if( aNode->GetParent() == this )
383 {
384 if( aNode == material )
385 material = nullptr;
386 else if( aNode == texture )
387 texture = nullptr;
388 else if( aNode == textureTransform )
389 textureTransform = nullptr;
390
391 }
392
394}
395
396
398{
399 if( nullptr == aNode )
400 return;
401
402 if( aNode->GetParent() != this )
403 {
404 if( aNode == material )
405 material = nullptr;
406 else if( aNode == texture )
407 texture = nullptr;
408 else if( aNode == textureTransform )
409 textureTransform = nullptr;
410 }
411
413}
bool SetDiffuse(float aRVal, float aGVal, float aBVal)
bool SetEmissive(float aRVal, float aGVal, float aBVal)
bool SetSpecular(float aRVal, float aGVal, float aBVal)
bool SetShininess(float aShininess) noexcept
bool SetTransparency(float aTransparency) noexcept
SGNODE * GetRawPtr(void) noexcept
Return the raw internal SGNODE pointer.
Definition ifsg_node.cpp:61
The base class of all Scene Graph nodes.
Definition sg_node.h:71
bool AddRefNode(WRL2NODE *aNode) override
bool checkNodeType(WRL2NODES aType)
Return true if the node type is a material description class.
bool Read(WRLPROC &proc, WRL2BASE *aTopNode) override
WRL2NODE * textureTransform
void unlinkRefNode(const WRL2NODE *aNode) override
Remove pointers to a referenced node.
SGNODE * TranslateToSG(SGNODE *aParent) override
Produce a representation of the data using the intermediate scenegraph structures of the kicad_3dsg l...
bool isDangling(void) override
Determine whether an object should be moved to a different parent during the VRML to SG* translation.
virtual ~WRL2APPEARANCE()
WRL2NODE * material
void unlinkChildNode(const WRL2NODE *aNode) override
Remove references to an owned child.
bool AddChildNode(WRL2NODE *aNode) override
The top node of a VRML2 model.
Definition vrml2_base.h:56
bool ReadNode(WRLPROC &proc, WRL2NODE *aParent, WRL2NODE **aNode)
SGNODE * m_sgNode
Definition vrml2_node.h:174
std::list< WRL2NODE * > m_BackPointers
Definition vrml2_node.h:169
WRL2NODE * GetParent(void) const
virtual void unlinkChildNode(const WRL2NODE *aNode)
Remove references to an owned child.
WRL2NODE * m_Parent
Definition vrml2_node.h:165
std::list< WRL2NODE * > m_Children
Definition vrml2_node.h:170
WRL2NODES m_Type
Definition vrml2_node.h:166
virtual bool AddRefNode(WRL2NODE *aNode)
virtual void unlinkRefNode(const WRL2NODE *aNode)
Remove pointers to a referenced node.
const char * GetNodeTypeName(WRL2NODES aNodeType) const
WRL2NODES GetNodeType(void) const
std::list< WRL2NODE * > m_Refs
Definition vrml2_node.h:171
virtual bool AddChildNode(WRL2NODE *aNode)
void Pop(void)
Definition wrlproc.cpp:2031
char Peek(void)
Definition wrlproc.cpp:2003
std::string GetFileName(void)
Definition wrlproc.cpp:1991
std::string GetError(void)
Definition wrlproc.cpp:1956
bool eof(void)
Definition wrlproc.cpp:1950
bool ReadName(std::string &aName)
Definition wrlproc.cpp:285
std::string GetFilePosition() const
Definition wrlproc.cpp:1978
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_SHAPE
Definition sg_types.h:41
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
WRL2NODES
Definition wrltypes.h:121
@ WRL2_MOVIETEXTURE
Definition wrltypes.h:150
@ WRL2_TEXTURETRANSFORM
Definition wrltypes.h:171
@ WRL2_PIXELTEXTURE
Definition wrltypes.h:155
@ WRL2_MATERIAL
Definition wrltypes.h:149
@ WRL2_IMAGETEXTURE
Definition wrltypes.h:144
@ WRL2_APPEARANCE
Definition wrltypes.h:125