KiCad PCB EDA Suite
vrml2_material.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_material.h"
31 #include "plugins/3dapi/ifsg_all.h"
32 
33 
35 {
36  setDefaults();
38  return;
39 }
40 
41 
43 {
44  setDefaults();
46  m_Parent = aParent;
47 
48  if( NULL != m_Parent )
49  m_Parent->AddChildNode( this );
50 
51  return;
52 }
53 
54 
56 {
57  #if defined( DEBUG_VRML2 ) && ( DEBUG_VRML2 > 2 )
58  wxLogTrace( MASK_VRML, " * [INFO] Destroying Material node\n" );
59  #endif
60 
61  return;
62 }
63 
64 
66 {
67  // default material values as per VRML2 spec
68  diffuseColor.x = 0.8f;
69  diffuseColor.y = 0.8f;
70  diffuseColor.z = 0.8f;
71 
72  emissiveColor.x = 0.0f;
73  emissiveColor.y = 0.0f;
74  emissiveColor.z = 0.0f;
75 
77 
78  ambientIntensity = 0.2f;
79  shininess = 0.2f;
80  transparency = 0.0f;
81 
82  return;
83 }
84 
85 
87 {
88  // this node is dangling unless it has a parent of type WRL2_APPEARANCE
89 
91  return true;
92 
93  return false;
94 }
95 
96 
98 {
99  // this node may not own or reference any other node
100 
101  #ifdef DEBUG_VRML2
102  do {
103  std::ostringstream ostr;
104  ostr << __FILE__ << ": " << __FUNCTION__ << ": " << __LINE__ << "\n";
105  ostr << " * [BUG] AddRefNode is not applicable";
106  wxLogTrace( MASK_VRML, "%s\n", ostr.str().c_str() );
107  } while( 0 );
108  #endif
109 
110  return false;
111 }
112 
113 
115 {
116  // this node may not own or reference any other node
117 
118  #ifdef DEBUG_VRML2
119  do {
120  std::ostringstream ostr;
121  ostr << __FILE__ << ": " << __FUNCTION__ << ": " << __LINE__ << "\n";
122  ostr << " * [BUG] AddChildNode is not applicable";
123  wxLogTrace( MASK_VRML, "%s\n", ostr.str().c_str() );
124  } while( 0 );
125  #endif
126 
127  return false;
128 }
129 
130 
131 bool WRL2MATERIAL::Read( WRLPROC& proc, WRL2BASE* aTopNode )
132 {
133  if( NULL == aTopNode )
134  {
135  #ifdef DEBUG_VRML2
136  do {
137  std::ostringstream ostr;
138  ostr << __FILE__ << ": " << __FUNCTION__ << ": " << __LINE__ << "\n";
139  ostr << " * [BUG] aTopNode is NULL";
140  wxLogTrace( MASK_VRML, "%s\n", ostr.str().c_str() );
141  } while( 0 );
142  #endif
143 
144  return false;
145  }
146 
147  size_t line, column;
148  proc.GetFilePosData( line, column );
149 
150  char tok = proc.Peek();
151 
152  if( proc.eof() )
153  {
154  #if defined( DEBUG_VRML2 ) && ( DEBUG_VRML2 > 1 )
155  do {
156  std::ostringstream ostr;
157  ostr << __FILE__ << ": " << __FUNCTION__ << ": " << __LINE__ << "\n";
158  ostr << " * [INFO] bad file format; unexpected eof at line ";
159  ostr << line << ", column " << column;
160  wxLogTrace( MASK_VRML, "%s\n", ostr.str().c_str() );
161  } while( 0 );
162  #endif
163 
164  return false;
165  }
166 
167  if( '{' != tok )
168  {
169  #if defined( DEBUG_VRML2 ) && ( DEBUG_VRML2 > 1 )
170  do {
171  std::ostringstream ostr;
172  ostr << proc.GetError() << "\n";
173  ostr << __FILE__ << ": " << __FUNCTION__ << ": " << __LINE__ << "\n";
174  ostr << " * [INFO] bad file format; expecting '{' but got '" << tok;
175  ostr << "' at line " << line << ", column " << column;
176  wxLogTrace( MASK_VRML, "%s\n", ostr.str().c_str() );
177  } while( 0 );
178  #endif
179 
180  return false;
181  }
182 
183  proc.Pop();
184  std::string glob;
185 
186  while( true )
187  {
188  if( proc.Peek() == '}' )
189  {
190  proc.Pop();
191  break;
192  }
193 
194  if( !proc.ReadName( glob ) )
195  {
196  #if defined( DEBUG_VRML2 ) && ( DEBUG_VRML2 > 1 )
197  do {
198  std::ostringstream ostr;
199  ostr << __FILE__ << ": " << __FUNCTION__ << ": " << __LINE__ << "\n";
200  ostr << proc.GetError();
201  wxLogTrace( MASK_VRML, "%s\n", ostr.str().c_str() );
202  } while( 0 );
203  #endif
204 
205  return false;
206  }
207 
208  // expecting one of:
209  // ambientIntensity
210  // diffuseColor
211  // emissiveColor
212  // shininess
213  // specularColor
214  // transparency
215 
216  proc.GetFilePosData( line, column );
217 
218  if( !glob.compare( "specularColor" ) )
219  {
220  if( !proc.ReadSFVec3f( specularColor ) )
221  {
222  #if defined( DEBUG_VRML2 ) && ( DEBUG_VRML2 > 1 )
223  do {
224  std::ostringstream ostr;
225  ostr << __FILE__ << ": " << __FUNCTION__ << ": " << __LINE__ << "\n";
226  ostr << " * [INFO] invalid specularColor at line " << line << ", column ";
227  ostr << column << "\n";
228  ostr << " * [INFO] file: '" << proc.GetFileName() << "'\n";
229  ostr << " * [INFO] message: '" << proc.GetError() << "'";
230  wxLogTrace( MASK_VRML, "%s\n", ostr.str().c_str() );
231  } while( 0 );
232  #endif
233 
234  return false;
235  }
236  }
237  else if( !glob.compare( "diffuseColor" ) )
238  {
239  if( !proc.ReadSFVec3f( diffuseColor ) )
240  {
241  #if defined( DEBUG_VRML2 ) && ( DEBUG_VRML2 > 1 )
242  do {
243  std::ostringstream ostr;
244  ostr << __FILE__ << ": " << __FUNCTION__ << ": " << __LINE__ << "\n";
245  ostr << " * [INFO] invalid diffuseColor at line " << line << ", column ";
246  ostr << column << "\n";
247  ostr << " * [INFO] file: '" << proc.GetFileName() << "'\n";
248  ostr << " * [INFO] message: '" << proc.GetError() << "'";
249  wxLogTrace( MASK_VRML, "%s\n", ostr.str().c_str() );
250  } while( 0 );
251  #endif
252 
253  return false;
254  }
255  }
256  else if( !glob.compare( "emissiveColor" ) )
257  {
258  if( !proc.ReadSFVec3f( emissiveColor ) )
259  {
260  #if defined( DEBUG_VRML2 ) && ( DEBUG_VRML2 > 1 )
261  do {
262  std::ostringstream ostr;
263  ostr << __FILE__ << ": " << __FUNCTION__ << ": " << __LINE__ << "\n";
264  ostr << " * [INFO] invalid emissiveColor at line " << line << ", column ";
265  ostr << column << "\n";
266  ostr << " * [INFO] file: '" << proc.GetFileName() << "'\n";
267  ostr << " * [INFO] message: '" << proc.GetError() << "'";
268  wxLogTrace( MASK_VRML, "%s\n", ostr.str().c_str() );
269  } while( 0 );
270  #endif
271 
272  return false;
273  }
274  }
275  else if( !glob.compare( "shininess" ) )
276  {
277  if( !proc.ReadSFFloat( shininess ) )
278  {
279  #if defined( DEBUG_VRML2 ) && ( DEBUG_VRML2 > 1 )
280  do {
281  std::ostringstream ostr;
282  ostr << __FILE__ << ": " << __FUNCTION__ << ": " << __LINE__ << "\n";
283  ostr << " * [INFO] invalid shininess at line " << line << ", column ";
284  ostr << column << "\n";
285  ostr << " * [INFO] file: '" << proc.GetFileName() << "'\n";
286  ostr << " * [INFO] message: '" << proc.GetError() << "'";
287  wxLogTrace( MASK_VRML, "%s\n", ostr.str().c_str() );
288  } while( 0 );
289  #endif
290 
291  return false;
292  }
293  }
294  else if( !glob.compare( "transparency" ) )
295  {
296  if( !proc.ReadSFFloat( transparency ) )
297  {
298  #if defined( DEBUG_VRML2 ) && ( DEBUG_VRML2 > 1 )
299  do {
300  std::ostringstream ostr;
301  ostr << __FILE__ << ": " << __FUNCTION__ << ": " << __LINE__ << "\n";
302  ostr << " * [INFO] invalid transparency at line " << line << ", column ";
303  ostr << column << "\n";
304  ostr << " * [INFO] file: '" << proc.GetFileName() << "'\n";
305  ostr << " * [INFO] message: '" << proc.GetError() << "'";
306  wxLogTrace( MASK_VRML, "%s\n", ostr.str().c_str() );
307  } while( 0 );
308  #endif
309 
310  return false;
311  }
312  }
313  else if( !glob.compare( "ambientIntensity" ) )
314  {
315  if( !proc.ReadSFFloat( ambientIntensity ) )
316  {
317  #if defined( DEBUG_VRML2 ) && ( DEBUG_VRML2 > 1 )
318  do {
319  std::ostringstream ostr;
320  ostr << __FILE__ << ": " << __FUNCTION__ << ": " << __LINE__ << "\n";
321  ostr << " * [INFO] invalid ambientIntensity at line " << line << ", column ";
322  ostr << column << "\n";
323  ostr << " * [INFO] file: '" << proc.GetFileName() << "'\n";
324  ostr << " * [INFO] message: '" << proc.GetError() << "'";
325  wxLogTrace( MASK_VRML, "%s\n", ostr.str().c_str() );
326  } while( 0 );
327  #endif
328 
329  return false;
330  }
331  }
332  else
333  {
334  #if defined( DEBUG_VRML2 ) && ( DEBUG_VRML2 > 1 )
335  do {
336  std::ostringstream ostr;
337  ostr << __FILE__ << ": " << __FUNCTION__ << ": " << __LINE__ << "\n";
338  ostr << " * [INFO] bad Material at line " << line << ", column ";
339  ostr << column << "\n";
340  ostr << " * [INFO] file: '" << proc.GetFileName() << "'";
341  wxLogTrace( MASK_VRML, "%s\n", ostr.str().c_str() );
342  } while( 0 );
343  #endif
344 
345  return false;
346  }
347  } // while( true ) -- reading contents of Material{}
348 
349  return true;
350 }
351 
352 
354 {
355  S3D::SGTYPES ptype = S3D::GetSGNodeType( aParent );
356 
357  if( NULL != aParent && ptype != S3D::SGTYPE_SHAPE )
358  {
359  #ifdef DEBUG_VRML2
360  do {
361  std::ostringstream ostr;
362  ostr << __FILE__ << ": " << __FUNCTION__ << ": " << __LINE__ << "\n";
363  ostr << " * [BUG] Material does not have a Shape parent (parent ID: ";
364  ostr << ptype << ")";
365  wxLogTrace( MASK_VRML, "%s\n", ostr.str().c_str() );
366  } while( 0 );
367  #endif
368 
369  return NULL;
370  }
371 
372  #if defined( DEBUG_VRML2 ) && ( DEBUG_VRML2 > 2 )
373  do {
374  std::ostringstream ostr;
375  ostr << " * [INFO] Translating Material with " << m_Children.size();
376  ostr << " children, " << m_Refs.size() << " references and ";
377  ostr << m_BackPointers.size() << " backpointers";
378  wxLogTrace( MASK_VRML, "%s\n", ostr.str().c_str() );
379  } while( 0 );
380  #endif
381 
382  if( m_sgNode )
383  {
384  if( NULL != aParent )
385  {
387  && !S3D::AddSGNodeChild( aParent, m_sgNode ) )
388  {
389  return NULL;
390  }
391  else if( aParent != S3D::GetSGNodeParent( m_sgNode )
392  && !S3D::AddSGNodeRef( aParent, m_sgNode ) )
393  {
394  return NULL;
395  }
396  }
397 
398  return m_sgNode;
399  }
400 
401  IFSG_APPEARANCE matNode( aParent );
405  float ambr = ambientIntensity * diffuseColor.x;
406  float ambg = ambientIntensity * diffuseColor.y;
407  float ambb = ambientIntensity * diffuseColor.z;
408  matNode.SetAmbient( ambr, ambg, ambb );
409  matNode.SetShininess( shininess );
410  matNode.SetTransparency( transparency );
411  m_sgNode = matNode.GetRawPtr();
412 
413  return m_sgNode;
414 }
bool Read(WRLPROC &proc, WRL2BASE *aTopNode) override
bool isDangling(void) override
Function isDangling returns true if the object does not have a parent which is a logical container fo...
void Pop(void)
Definition: wrlproc.cpp:2007
WRL2NODE represents the base class of all VRML2 nodes.
Definition: vrml2_node.h:58
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
bool ReadSFVec3f(WRLVEC3F &aSFVec3f)
Definition: wrlproc.cpp:1065
#define MASK_VRML
Definition: wrltypes.h:37
bool AddChildNode(WRL2NODE *aNode) override
float transparency
bool SetDiffuse(float aRVal, float aGVal, float aBVal)
void setDefaults(void)
std::list< WRL2NODE * > m_Refs
Definition: vrml2_node.h:67
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
WRLVEC3F emissiveColor
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
WRLVEC3F diffuseColor
#define NULL
bool SetAmbient(float aRVal, float aGVal, float aBVal)
WRL2NODE * m_Parent
Definition: vrml2_node.h:61
SGLIB_API bool AddSGNodeChild(SGNODE *aParent, SGNODE *aChild)
Definition: ifsg_api.cpp:654
bool ReadSFFloat(float &aSFFloat)
Definition: wrlproc.cpp:789
SGNODE * m_sgNode
Definition: vrml2_node.h:70
std::list< WRL2NODE * > m_BackPointers
Definition: vrml2_node.h:65
SGNODE * TranslateToSG(SGNODE *aParent) override
Function TranslateToSG produces a representation of the data using the intermediate scenegraph struct...
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
bool SetEmissive(float aRVal, float aGVal, float aBVal)
virtual ~WRL2MATERIAL()
SGTYPES
Definition: sg_types.h:34
WRLVEC3F specularColor
bool AddRefNode(WRL2NODE *aNode) override
bool SetSpecular(float aRVal, float aGVal, float aBVal)
SGLIB_API S3D::SGTYPES GetSGNodeType(SGNODE *aNode)
Definition: ifsg_api.cpp:627
virtual bool AddChildNode(WRL2NODE *aNode)
Definition: vrml2_node.cpp:377
float ambientIntensity
bool ReadName(std::string &aName)
Definition: wrlproc.cpp:280
std::string GetError(void)
Definition: wrlproc.cpp:1945
bool eof(void)
Definition: wrlproc.cpp:1939