KiCad PCB EDA Suite
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 <cirilo.bernardo@gmail.com>
5  *
6  * This program is free software; you can redistribute it and/or
7  * modify it under the terms of the GNU General Public License
8  * as published by the Free Software Foundation; either version 2
9  * of the License, or (at your option) any later version.
10  *
11  * This program is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14  * GNU General Public License for more details.
15  *
16  * You should have received a copy of the GNU General Public License
17  * along with this program; if not, you may find one here:
18  * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
19  * or you may search the http://www.gnu.org website for the version 2 license,
20  * or you may write to the Free Software Foundation, Inc.,
21  * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
22  */
23 
24 
25 #include <iostream>
26 #include <sstream>
27 #include <wx/log.h>
28 
29 #include "vrml2_base.h"
30 #include "vrml2_appearance.h"
31 #include "plugins/3dapi/ifsg_all.h"
32 
33 
35 {
36  material = NULL;
37  texture = NULL;
40  return;
41 }
42 
43 
45 {
46  material = NULL;
47  texture = NULL;
50  m_Parent = aParent;
51 
52  if( NULL != m_Parent )
53  m_Parent->AddChildNode( this );
54 
55  return;
56 }
57 
58 
60 {
61  #if defined( DEBUG_VRML2 ) && ( DEBUG_VRML2 > 2 )
62  do {
63  std::ostringstream ostr;
64  ostr << " * [INFO] Destroying Appearance with " << m_Children.size();
65  ostr << " children, " << m_Refs.size() << " references and ";
66  ostr << m_BackPointers.size() << " backpointers";
67  wxLogTrace( MASK_VRML, "%s\n", ostr.str().c_str() );
68  } while( 0 );
69  #endif
70 }
71 
72 
74 {
75  switch( aType )
76  {
77  case WRL2_MATERIAL:
78  case WRL2_IMAGETEXTURE:
79  case WRL2_PIXELTEXTURE:
80  case WRL2_MOVIETEXTURE:
82  break;
83 
84  default:
85  return false;
86  break;
87  }
88 
89  return true;
90 }
91 
92 
94 {
95  // this node is dangling unless it has a parent of type WRL2_SHAPE
96 
97  if( NULL == m_Parent || m_Parent->GetNodeType() != WRL2_SHAPE )
98  return true;
99 
100  return false;
101 }
102 
103 
105 {
106  if( NULL == aNode )
107  {
108  #ifdef DEBUG_VRML2
109  do {
110  std::ostringstream ostr;
111  ostr << __FILE__ << ": " << __FUNCTION__ << ": " << __LINE__ << "\n";
112  ostr << " * [BUG] NULL passed for aNode";
113  wxLogTrace( MASK_VRML, "%s\n", ostr.str().c_str() );
114  } while( 0 );
115  #endif
116 
117  return false;
118  }
119 
120  WRL2NODES type = aNode->GetNodeType();
121 
122  if( !checkNodeType( type ) )
123  {
124  #if defined( DEBUG_VRML2 ) && ( DEBUG_VRML2 > 1 )
125  do {
126  std::ostringstream ostr;
127  ostr << __FILE__ << ": " << __FUNCTION__ << ": " << __LINE__ << "\n";
128  ostr << " * [INFO] bad file format; unexpected child node '";
129  ostr << aNode->GetNodeTypeName( type ) << "'";
130  wxLogTrace( MASK_VRML, "%s\n", ostr.str().c_str() );
131  } while( 0 );
132  #endif
133 
134  return false;
135  }
136 
137  if( WRL2_MATERIAL == type )
138  {
139  if( NULL != material )
140  {
141  #if defined( DEBUG_VRML2 ) && ( DEBUG_VRML2 > 1 )
142  do {
143  std::ostringstream ostr;
144  ostr << __FILE__ << ": " << __FUNCTION__ << ": " << __LINE__ << "\n";
145  ostr << " * [INFO] bad file format; multiple material nodes";
146  wxLogTrace( MASK_VRML, "%s\n", ostr.str().c_str() );
147  } while( 0 );
148  #endif
149 
150  return false;
151  }
152 
153  material = aNode;
154  return WRL2NODE::AddRefNode( aNode );
155  }
156 
157  if( WRL2_TEXTURETRANSFORM == type )
158  {
159  if( NULL != textureTransform )
160  {
161  #if defined( DEBUG_VRML2 ) && ( DEBUG_VRML2 > 1 )
162  do {
163  std::ostringstream ostr;
164  ostr << __FILE__ << ": " << __FUNCTION__ << ": " << __LINE__ << "\n";
165  ostr << " * [INFO] bad file format; multiple textureTransform nodes";
166  wxLogTrace( MASK_VRML, "%s\n", ostr.str().c_str() );
167  } while( 0 );
168  #endif
169 
170  return false;
171  }
172 
173  textureTransform = aNode;
174  return WRL2NODE::AddRefNode( aNode );
175  }
176 
177  if( NULL != texture )
178  {
179  #if defined( DEBUG_VRML2 ) && ( DEBUG_VRML2 > 1 )
180  do {
181  std::ostringstream ostr;
182  ostr << __FILE__ << ": " << __FUNCTION__ << ": " << __LINE__ << "\n";
183  ostr << " * [INFO] bad file format; multiple texture nodes";
184  wxLogTrace( MASK_VRML, "%s\n", ostr.str().c_str() );
185  } while( 0 );
186  #endif
187 
188  return false;
189  }
190 
191  texture = aNode;
192  return WRL2NODE::AddRefNode( aNode );
193 }
194 
195 
197 {
198  if( NULL == aNode )
199  {
200  #ifdef DEBUG_VRML2
201  do {
202  std::ostringstream ostr;
203  ostr << __FILE__ << ": " << __FUNCTION__ << ": " << __LINE__ << "\n";
204  ostr << " * [BUG] NULL passed for aNode";
205  wxLogTrace( MASK_VRML, "%s\n", ostr.str().c_str() );
206  } while( 0 );
207  #endif
208 
209  return false;
210  }
211 
212  WRL2NODES type = aNode->GetNodeType();
213 
214  if( !checkNodeType( type ) )
215  {
216  #if defined( DEBUG_VRML2 ) && ( DEBUG_VRML2 > 1 )
217  do {
218  std::ostringstream ostr;
219  ostr << __FILE__ << ": " << __FUNCTION__ << ": " << __LINE__ << "\n";
220  ostr << " * [INFO] bad file format; unexpected child node '";
221  ostr << aNode->GetNodeTypeName( type ) << "'";
222  wxLogTrace( MASK_VRML, "%s\n", ostr.str().c_str() );
223  } while( 0 );
224  #endif
225 
226  return false;
227  }
228 
229  if( WRL2_MATERIAL == type )
230  {
231  if( NULL != material )
232  {
233  #if defined( DEBUG_VRML2 ) && ( DEBUG_VRML2 > 1 )
234  do {
235  std::ostringstream ostr;
236  ostr << __FILE__ << ": " << __FUNCTION__ << ": " << __LINE__ << "\n";
237  ostr << " * [INFO] bad file format; multiple material nodes";
238  wxLogTrace( MASK_VRML, "%s\n", ostr.str().c_str() );
239  } while( 0 );
240  #endif
241 
242  return false;
243  }
244 
245  material = aNode;
246  return WRL2NODE::AddChildNode( aNode );
247  }
248 
249  if( WRL2_TEXTURETRANSFORM == type )
250  {
251  if( NULL != textureTransform )
252  {
253  #if defined( DEBUG_VRML2 ) && ( DEBUG_VRML2 > 1 )
254  do {
255  std::ostringstream ostr;
256  ostr << __FILE__ << ": " << __FUNCTION__ << ": " << __LINE__ << "\n";
257  ostr << " * [INFO] bad file format; multiple textureTransform nodes";
258  wxLogTrace( MASK_VRML, "%s\n", ostr.str().c_str() );
259  } while( 0 );
260  #endif
261 
262  return false;
263  }
264 
265  textureTransform = aNode;
266  return WRL2NODE::AddChildNode( aNode );
267  }
268 
269  if( NULL != texture )
270  {
271  #if defined( DEBUG_VRML2 ) && ( DEBUG_VRML2 > 1 )
272  do {
273  std::ostringstream ostr;
274  ostr << __FILE__ << ": " << __FUNCTION__ << ": " << __LINE__ << "\n";
275  ostr << " * [INFO] bad file format; multiple texture nodes";
276  wxLogTrace( MASK_VRML, "%s\n", ostr.str().c_str() );
277  } while( 0 );
278  #endif
279 
280  return false;
281  }
282 
283  texture = aNode;
284  return WRL2NODE::AddChildNode( aNode );
285 }
286 
287 
288 bool WRL2APPEARANCE::Read( WRLPROC& proc, WRL2BASE* aTopNode )
289 {
290  if( NULL == aTopNode )
291  {
292  #ifdef DEBUG_VRML2
293  do {
294  std::ostringstream ostr;
295  ostr << __FILE__ << ": " << __FUNCTION__ << ": " << __LINE__ << "\n";
296  ostr << " * [BUG] aTopNode is NULL";
297  wxLogTrace( MASK_VRML, "%s\n", ostr.str().c_str() );
298  } while( 0 );
299  #endif
300 
301  return false;
302  }
303 
304  size_t line, column;
305  proc.GetFilePosData( line, column );
306 
307  char tok = proc.Peek();
308 
309  if( proc.eof() )
310  {
311  #if defined( DEBUG_VRML2 ) && ( DEBUG_VRML2 > 1 )
312  do {
313  std::ostringstream ostr;
314  ostr << __FILE__ << ": " << __FUNCTION__ << ": " << __LINE__ << "\n";
315  ostr << " * [INFO] bad file format; unexpected eof at line ";
316  ostr << line << ", column " << column;
317  wxLogTrace( MASK_VRML, "%s\n", ostr.str().c_str() );
318  } while( 0 );
319  #endif
320 
321  return false;
322  }
323 
324  if( '{' != tok )
325  {
326  #if defined( DEBUG_VRML2 ) && ( DEBUG_VRML2 > 1 )
327  do {
328  std::ostringstream ostr;
329  ostr << proc.GetError() << "\n";
330  ostr << __FILE__ << ": " << __FUNCTION__ << ": " << __LINE__ << "\n";
331  ostr << " * [INFO] bad file format; expecting '{' but got '" << tok;
332  ostr << "' at line " << line << ", column " << column;
333  wxLogTrace( MASK_VRML, "%s\n", ostr.str().c_str() );
334  } while( 0 );
335  #endif
336 
337  return false;
338  }
339 
340  proc.Pop();
341  std::string glob;
342 
343  while( true )
344  {
345  if( proc.Peek() == '}' )
346  {
347  proc.Pop();
348  break;
349  }
350 
351  if( !proc.ReadName( glob ) )
352  {
353  #if defined( DEBUG_VRML2 ) && ( DEBUG_VRML2 > 1 )
354  do {
355  std::ostringstream ostr;
356  ostr << __FILE__ << ": " << __FUNCTION__ << ": " << __LINE__ << "\n";
357  ostr << proc.GetError();
358  wxLogTrace( MASK_VRML, "%s\n", ostr.str().c_str() );
359  } while( 0 );
360  #endif
361 
362  return false;
363  }
364 
365  // expecting one of:
366  // material
367  // texture
368  // textureTransform
369 
370  proc.GetFilePosData( line, column );
371 
372  if( !glob.compare( "material" ) )
373  {
374  if( !aTopNode->ReadNode( proc, this, NULL ) )
375  {
376  #if defined( DEBUG_VRML2 ) && ( DEBUG_VRML2 > 1 )
377  do {
378  std::ostringstream ostr;
379  ostr << __FILE__ << ": " << __FUNCTION__ << ": " << __LINE__ << "\n";
380  ostr << " * [INFO] could not read material information";
381  wxLogTrace( MASK_VRML, "%s\n", ostr.str().c_str() );
382  } while( 0 );
383  #endif
384 
385  return false;
386  }
387  }
388  else if( !glob.compare( "texture" ) )
389  {
390  if( !aTopNode->ReadNode( proc, this, NULL ) )
391  {
392  #if defined( DEBUG_VRML2 ) && ( DEBUG_VRML2 > 1 )
393  do {
394  std::ostringstream ostr;
395  ostr << __FILE__ << ": " << __FUNCTION__ << ": " << __LINE__ << "\n";
396  ostr << " * [INFO] could not read texture information";
397  wxLogTrace( MASK_VRML, "%s\n", ostr.str().c_str() );
398  } while( 0 );
399  #endif
400 
401  return false;
402  }
403  }
404  else if( !glob.compare( "textureTransform" ) )
405  {
406  if( !aTopNode->ReadNode( proc, this, NULL ) )
407  {
408  #if defined( DEBUG_VRML2 ) && ( DEBUG_VRML2 > 1 )
409  do {
410  std::ostringstream ostr;
411  ostr << __FILE__ << ": " << __FUNCTION__ << ": " << __LINE__ << "\n";
412  ostr << " * [INFO] could not read textureTransform information";
413  wxLogTrace( MASK_VRML, "%s\n", ostr.str().c_str() );
414  } while( 0 );
415  #endif
416 
417  return false;
418  }
419  }
420  else
421  {
422  #if defined( DEBUG_VRML2 ) && ( DEBUG_VRML2 > 1 )
423  do {
424  std::ostringstream ostr;
425  ostr << __FILE__ << ": " << __FUNCTION__ << ": " << __LINE__ << "\n";
426  ostr << " * [INFO] bad Appearance at line " << line << ", column ";
427  ostr << column << "\n";
428  ostr << " * [INFO] file: '" << proc.GetFileName() << "'";
429  wxLogTrace( MASK_VRML, "%s\n", ostr.str().c_str() );
430  } while( 0 );
431  #endif
432 
433  return false;
434  }
435  } // while( true ) -- reading contents of Appearance{}
436 
437  return true;
438 }
439 
440 
442 {
443  if( NULL == material && NULL == texture )
444  return NULL;
445 
446  S3D::SGTYPES ptype = S3D::GetSGNodeType( aParent );
447 
448  if( NULL != aParent && ptype != S3D::SGTYPE_SHAPE )
449  {
450  #ifdef DEBUG_VRML2
451  do {
452  std::ostringstream ostr;
453  ostr << __FILE__ << ": " << __FUNCTION__ << ": " << __LINE__ << "\n";
454  ostr << " * [BUG] Appearance does not have a Shape parent (parent ID: ";
455  ostr << ptype << ")";
456  wxLogTrace( MASK_VRML, "%s\n", ostr.str().c_str() );
457  } while( 0 );
458  #endif
459 
460  return NULL;
461  }
462 
463  #if defined( DEBUG_VRML2 ) && ( DEBUG_VRML2 > 2 )
464  do {
465  std::ostringstream ostr;
466  ostr << " * [INFO] Translating Appearance with " << m_Children.size();
467  ostr << " children, " << m_Refs.size() << " references and ";
468  ostr << m_BackPointers.size() << " backpointers";
469  wxLogTrace( MASK_VRML, "%s\n", ostr.str().c_str() );
470  } while( 0 );
471  #endif
472 
473  if( m_sgNode )
474  {
475  if( NULL != aParent )
476  {
478  && !S3D::AddSGNodeChild( aParent, m_sgNode ) )
479  {
480  return NULL;
481  }
482  else if( aParent != S3D::GetSGNodeParent( m_sgNode )
483  && !S3D::AddSGNodeRef( aParent, m_sgNode ) )
484  {
485  return NULL;
486  }
487  }
488 
489  return m_sgNode;
490  }
491 
492  if( NULL != texture )
493  {
494  // use a default gray appearance
495  IFSG_APPEARANCE matNode( aParent );
496  matNode.SetEmissive( 0.0f, 0.0f, 0.0f );
497  matNode.SetSpecular( 0.65f, 0.65f, 0.65f );
498  matNode.SetDiffuse( 0.65f, 0.65f, 0.65f );
499  // default ambient
500  matNode.SetShininess( 0.2f );
501  matNode.SetTransparency( 0.0f );
502  m_sgNode = matNode.GetRawPtr();
503 
504  return m_sgNode;
505  }
506 
507  m_sgNode = material->TranslateToSG( aParent );
508 
509  return m_sgNode;
510 }
511 
512 
514 {
515  if( NULL == aNode )
516  return;
517 
518  if( aNode->GetParent() == this )
519  {
520  if( aNode == material )
521  material = NULL;
522  else if( aNode == texture )
523  texture = NULL;
524  else if( aNode == textureTransform )
526 
527  }
528 
529  WRL2NODE::unlinkChildNode( aNode );
530  return;
531 }
532 
533 
535 {
536  if( NULL == aNode )
537  return;
538 
539  if( aNode->GetParent() != this )
540  {
541  if( aNode == material )
542  material = NULL;
543  else if( aNode == texture )
544  texture = NULL;
545  else if( aNode == textureTransform )
547 
548  }
549 
550  WRL2NODE::unlinkRefNode( aNode );
551  return;
552 }
WRL2NODE * material
virtual SGNODE * TranslateToSG(SGNODE *aParent)=0
Function TranslateToSG produces a representation of the data using the intermediate scenegraph struct...
void Pop(void)
Definition: wrlproc.cpp:2007
WRL2NODE represents the base class of all VRML2 nodes.
Definition: vrml2_node.h:58
bool checkNodeType(WRL2NODES aType)
Function checkNodeType returns true if the node type is a material description class.
SGNODE * TranslateToSG(SGNODE *aParent) override
Function TranslateToSG produces a representation of the data using the intermediate scenegraph struct...
std::list< WRL2NODE * > m_Children
Definition: vrml2_node.h:66
bool GetFilePosData(size_t &line, size_t &column)
Definition: wrlproc.cpp:1951
bool SetTransparency(float aTransparency) noexcept
#define MASK_VRML
Definition: wrltypes.h:37
bool SetDiffuse(float aRVal, float aGVal, float aBVal)
std::list< WRL2NODE * > m_Refs
Definition: vrml2_node.h:67
void unlinkRefNode(const WRL2NODE *aNode) override
Function unlinkRef removes pointers to a referenced node; it is invoked by the referenced node upon d...
void unlinkChildNode(const WRL2NODE *aNode) override
Function unlinkChild removes references to an owned child; it is invoked by the child upon destructio...
SGLIB_API SGNODE * GetSGNodeParent(SGNODE *aNode)
Definition: ifsg_api.cpp:636
WRL2NODES m_Type
Definition: vrml2_node.h:62
SGNODE represents the base class of all Scene Graph nodes.
Definition: sg_node.h:76
collects header files for all SG* wrappers and the API
SGNODE * GetRawPtr(void) noexcept
Function GetRawPtr() returns the raw internal SGNODE pointer.
Definition: ifsg_node.cpp:66
SGLIB_API bool AddSGNodeRef(SGNODE *aParent, SGNODE *aChild)
Definition: ifsg_api.cpp:645
bool ReadNode(WRLPROC &proc, WRL2NODE *aParent, WRL2NODE **aNode)
Definition: vrml2_base.cpp:371
#define NULL
bool AddRefNode(WRL2NODE *aNode) override
WRL2NODE * m_Parent
Definition: vrml2_node.h:61
SGLIB_API bool AddSGNodeChild(SGNODE *aParent, SGNODE *aChild)
Definition: ifsg_api.cpp:654
SGNODE * m_sgNode
Definition: vrml2_node.h:70
std::list< WRL2NODE * > m_BackPointers
Definition: vrml2_node.h:65
WRL2NODES GetNodeType(void) const
Function GetNodeType returns the type of this node instance.
Definition: vrml2_node.cpp:212
bool SetShininess(float aShininess) noexcept
char Peek(void)
Definition: wrlproc.cpp:1979
std::string GetFileName(void)
Definition: wrlproc.cpp:1967
WRL2BASE represents the top node of a VRML2 model.
Definition: vrml2_base.h:59
WRL2NODE * texture
virtual ~WRL2APPEARANCE()
bool SetEmissive(float aRVal, float aGVal, float aBVal)
const char * GetNodeTypeName(WRL2NODES aNodeType) const
Definition: vrml2_node.cpp:295
SGTYPES
Definition: sg_types.h:34
bool SetSpecular(float aRVal, float aGVal, float aBVal)
SGLIB_API S3D::SGTYPES GetSGNodeType(SGNODE *aNode)
Definition: ifsg_api.cpp:627
WRL2NODE * textureTransform
virtual bool AddChildNode(WRL2NODE *aNode)
Definition: vrml2_node.cpp:377
bool Read(WRLPROC &proc, WRL2BASE *aTopNode) override
bool ReadName(std::string &aName)
Definition: wrlproc.cpp:280
virtual void unlinkRefNode(const WRL2NODE *aNode)
Function unlinkRef removes pointers to a referenced node; it is invoked by the referenced node upon d...
Definition: vrml2_node.cpp:484
WRL2NODE * GetParent(void) const
Function GetParent returns a pointer to the parent SGNODE of this object or NULL if the object has no...
Definition: vrml2_node.cpp:218
bool isDangling(void) override
Function isDangling returns true if the object does not have a parent which is a logical container fo...
WRL2NODES
Definition: wrltypes.h:121
bool AddChildNode(WRL2NODE *aNode) override
std::string GetError(void)
Definition: wrlproc.cpp:1945
virtual void unlinkChildNode(const WRL2NODE *aNode)
Function unlinkChild removes references to an owned child; it is invoked by the child upon destructio...
Definition: vrml2_node.cpp:464
virtual bool AddRefNode(WRL2NODE *aNode)
Definition: vrml2_node.cpp:416
bool eof(void)
Definition: wrlproc.cpp:1939