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 <[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_material.h"
32 #include "plugins/3dapi/ifsg_all.h"
33 
34 
36 {
37  setDefaults();
39 }
40 
41 
43 {
44  setDefaults();
46  m_Parent = aParent;
47 
48  if( nullptr != m_Parent )
49  m_Parent->AddChildNode( this );
50 }
51 
52 
54 {
55  wxLogTrace( traceVrmlPlugin, " * [INFO] Destroying Material node." );
56 }
57 
58 
60 {
61  // default material values as per VRML2 spec
62  diffuseColor.x = 0.8f;
63  diffuseColor.y = 0.8f;
64  diffuseColor.z = 0.8f;
65 
66  emissiveColor.x = 0.0f;
67  emissiveColor.y = 0.0f;
68  emissiveColor.z = 0.0f;
69 
71 
72  ambientIntensity = 0.2f;
73  shininess = 0.2f;
74  transparency = 0.0f;
75 }
76 
77 
79 {
80  // this node is dangling unless it has a parent of type WRL2NODES::WRL2_APPEARANCE
81 
83  return true;
84 
85  return false;
86 }
87 
88 
90 {
91  // this node may not own or reference any other node
92  wxCHECK_MSG( false, false, wxT( "AddRefNode is not applicable." ) );
93 }
94 
95 
97 {
98  // this node may not own or reference any other node
99  wxCHECK_MSG( false, false, wxT( "AddChildNode is not applicable." ) );
100 }
101 
102 
103 bool WRL2MATERIAL::Read( WRLPROC& proc, WRL2BASE* aTopNode )
104 {
105  wxCHECK_MSG( aTopNode, false, wxT( "Invalid top node." ) );
106 
107  char tok = proc.Peek();
108 
109  if( proc.eof() )
110  {
111  wxLogTrace( traceVrmlPlugin, wxT( "%s:%s:%d\n"
112  " * [INFO] bad file format; unexpected eof %s." ),
113  __FILE__, __FUNCTION__, __LINE__, proc.GetFilePosition() );
114 
115  return false;
116  }
117 
118  if( '{' != tok )
119  {
120  wxLogTrace( traceVrmlPlugin,
121  wxT( "%s:%s:%d\n"
122  " * [INFO] bad file format; expecting '{' but got '%s' %s." ),
123  __FILE__, __FUNCTION__, __LINE__, tok, proc.GetFilePosition() );
124 
125  return false;
126  }
127 
128  proc.Pop();
129  std::string glob;
130 
131  while( true )
132  {
133  if( proc.Peek() == '}' )
134  {
135  proc.Pop();
136  break;
137  }
138 
139  if( !proc.ReadName( glob ) )
140  {
141  wxLogTrace( traceVrmlPlugin, wxT( "%s:%s:%d\n"
142  "%s" ),
143  __FILE__, __FUNCTION__, __LINE__ , proc.GetError() );
144 
145  return false;
146  }
147 
148  // expecting one of:
149  // ambientIntensity
150  // diffuseColor
151  // emissiveColor
152  // shininess
153  // specularColor
154  // transparency
155 
156  if( !glob.compare( "specularColor" ) )
157  {
158  if( !proc.ReadSFVec3f( specularColor ) )
159  {
160  wxLogTrace( traceVrmlPlugin, wxT( "%s:%s:%d\n"
161  " * [INFO] invalid specularColor set %s\n"
162  " * [INFO] file: '%s'\n"
163  "%s" ),
164  __FILE__, __FUNCTION__, __LINE__, proc.GetFilePosition(),
165  proc.GetFileName(), proc.GetError() );
166 
167  return false;
168  }
169  }
170  else if( !glob.compare( "diffuseColor" ) )
171  {
172  if( !proc.ReadSFVec3f( diffuseColor ) )
173  {
174  wxLogTrace( traceVrmlPlugin, wxT( "%s:%s:%d\n"
175  " * [INFO] invalid diffuseColor set %s\n"
176  " * [INFO] file: '%s'\n"
177  "%s" ),
178  __FILE__, __FUNCTION__, __LINE__, proc.GetFilePosition(),
179  proc.GetFileName(), proc.GetError() );
180 
181  return false;
182  }
183  }
184  else if( !glob.compare( "emissiveColor" ) )
185  {
186  if( !proc.ReadSFVec3f( emissiveColor ) )
187  {
188  wxLogTrace( traceVrmlPlugin, wxT( "%s:%s:%d\n"
189  " * [INFO] invalid emissiveColor set %s\n"
190  " * [INFO] file: '%s'\n"
191  "%s" ),
192  __FILE__, __FUNCTION__, __LINE__, proc.GetFilePosition(),
193  proc.GetFileName(), proc.GetError() );
194 
195  return false;
196  }
197  }
198  else if( !glob.compare( "shininess" ) )
199  {
200  if( !proc.ReadSFFloat( shininess ) )
201  {
202  wxLogTrace( traceVrmlPlugin, wxT( "%s:%s:%d\n"
203  " * [INFO] invalid shininess set %s\n"
204  " * [INFO] file: '%s'\n"
205  "%s" ),
206  __FILE__, __FUNCTION__, __LINE__, proc.GetFilePosition(),
207  proc.GetFileName(), proc.GetError() );
208 
209  return false;
210  }
211  }
212  else if( !glob.compare( "transparency" ) )
213  {
214  if( !proc.ReadSFFloat( transparency ) )
215  {
216  wxLogTrace( traceVrmlPlugin, wxT( "%s:%s:%d\n"
217  " * [INFO] invalid transparency set %s\n"
218  " * [INFO] file: '%s'\n"
219  "%s" ),
220  __FILE__, __FUNCTION__, __LINE__, proc.GetFilePosition(),
221  proc.GetFileName(), proc.GetError() );
222 
223  return false;
224  }
225  }
226  else if( !glob.compare( "ambientIntensity" ) )
227  {
228  if( !proc.ReadSFFloat( ambientIntensity ) )
229  {
230  wxLogTrace( traceVrmlPlugin, wxT( "%s:%s:%d\n"
231  " * [INFO] invalid ambientIntensity set %s\n"
232  " * [INFO] file: '%s'\n"
233  "%s" ),
234  __FILE__, __FUNCTION__, __LINE__, proc.GetFilePosition(),
235  proc.GetFileName(), proc.GetError() );
236 
237  return false;
238  }
239  }
240  else
241  {
242  wxLogTrace( traceVrmlPlugin, wxT( "%s:%s:%d\n"
243  " * [INFO] invalid Material %s.\n"
244  " * [INFO] file: '%s'\n" ),
245  __FILE__, __FUNCTION__, __LINE__, proc.GetFilePosition(),
246  proc.GetFileName() );
247 
248  return false;
249  }
250  } // while( true ) -- reading contents of Material{}
251 
252  return true;
253 }
254 
255 
257 {
258  S3D::SGTYPES ptype = S3D::GetSGNodeType( aParent );
259 
260  wxCHECK_MSG( aParent && ( ptype == S3D::SGTYPE_SHAPE ), nullptr,
261  wxString::Format( wxT( "IndexedFaceSet does not have a Shape parent (parent "
262  "ID: %d)." ), ptype ) );
263 
264  wxLogTrace( traceVrmlPlugin,
265  wxT( " * [INFO] Translating IndexedFaceSet with %zu children, %zu references, and"
266  "%zu back pointers." ),
267  m_Children.size(), m_Refs.size(), m_BackPointers.size() );
268 
269  if( m_sgNode )
270  {
271  if( nullptr != aParent )
272  {
273  if( nullptr == S3D::GetSGNodeParent( m_sgNode )
274  && !S3D::AddSGNodeChild( aParent, m_sgNode ) )
275  {
276  return nullptr;
277  }
278  else if( aParent != S3D::GetSGNodeParent( m_sgNode )
279  && !S3D::AddSGNodeRef( aParent, m_sgNode ) )
280  {
281  return nullptr;
282  }
283  }
284 
285  return m_sgNode;
286  }
287 
288  IFSG_APPEARANCE matNode( aParent );
292  float ambr = ambientIntensity * diffuseColor.x;
293  float ambg = ambientIntensity * diffuseColor.y;
294  float ambb = ambientIntensity * diffuseColor.z;
295  matNode.SetAmbient( ambr, ambg, ambb );
296  matNode.SetShininess( shininess );
297  matNode.SetTransparency( transparency );
298  m_sgNode = matNode.GetRawPtr();
299 
300  return m_sgNode;
301 }
bool Read(WRLPROC &proc, WRL2BASE *aTopNode) override
bool isDangling(void) override
Determine whether an object should be moved to a different parent during the VRML to SG* translation.
void Pop(void)
Definition: wrlproc.cpp:2035
std::list< WRL2NODE * > m_Children
Definition: vrml2_node.h:174
bool SetTransparency(float aTransparency) noexcept
bool ReadSFVec3f(WRLVEC3F &aSFVec3f)
Definition: wrlproc.cpp:1082
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:175
SGLIB_API SGNODE * GetSGNodeParent(SGNODE *aNode)
Definition: ifsg_api.cpp:492
WRL2NODES m_Type
Definition: vrml2_node.h:170
The base class of all Scene Graph nodes.
Definition: sg_node.h:74
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:65
SGLIB_API bool AddSGNodeRef(SGNODE *aParent, SGNODE *aChild)
Definition: ifsg_api.cpp:501
WRLVEC3F diffuseColor
bool SetAmbient(float aRVal, float aGVal, float aBVal)
WRL2NODE * m_Parent
Definition: vrml2_node.h:169
SGLIB_API bool AddSGNodeChild(SGNODE *aParent, SGNODE *aChild)
Definition: ifsg_api.cpp:510
std::string GetFilePosition() const
Definition: wrlproc.cpp:1982
bool ReadSFFloat(float &aSFFloat)
Definition: wrlproc.cpp:806
SGNODE * m_sgNode
Definition: vrml2_node.h:178
std::list< WRL2NODE * > m_BackPointers
Definition: vrml2_node.h:173
SGNODE * TranslateToSG(SGNODE *aParent) override
Produce a representation of the data using the intermediate scenegraph structures of the kicad_3dsg l...
WRL2NODES GetNodeType(void) const
Definition: vrml2_node.cpp:204
bool SetShininess(float aShininess) noexcept
char Peek(void)
Definition: wrlproc.cpp:2007
std::string GetFileName(void)
Definition: wrlproc.cpp:1995
The top node of a VRML2 model.
Definition: vrml2_base.h:59
const wxChar *const traceVrmlPlugin
Flag to enable VRML plugin trace output.
Definition: vrml.cpp:63
bool SetEmissive(float aRVal, float aGVal, float aBVal)
virtual ~WRL2MATERIAL()
SGTYPES
Definition: sg_types.h:34
void Format(OUTPUTFORMATTER *out, int aNestLevel, int aCtl, const CPTREE &aTree)
Output a PTREE into s-expression format via an OUTPUTFORMATTER derivative.
Definition: ptree.cpp:200
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:483
virtual bool AddChildNode(WRL2NODE *aNode)
Definition: vrml2_node.cpp:356
float ambientIntensity
bool ReadName(std::string &aName)
Definition: wrlproc.cpp:289
std::string GetError(void)
Definition: wrlproc.cpp:1960
bool eof(void)
Definition: wrlproc.cpp:1954