KiCad PCB EDA Suite
x3d_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  * 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 #include <wx/xml/xml.h>
30 #include "x3d_ops.h"
31 #include "x3d_appearance.h"
32 #include "plugins/3dapi/ifsg_all.h"
33 
34 
36 {
38  init();
39 }
40 
41 
43 {
45  init();
46 
47  if( nullptr != aParent )
48  {
49  X3DNODES ptype = aParent->GetNodeType();
50 
51  if( X3D_SHAPE == ptype )
52  m_Parent = aParent;
53  }
54 
55  if( nullptr != m_Parent )
56  m_Parent->AddChildNode( this );
57 }
58 
59 
61 {
62  wxLogTrace( traceVrmlPlugin, " * [INFO] Destroying Appearance" );
63 
64  if( !m_MatName.empty() && m_Dict )
65  m_Dict->DelName( m_MatName, this );
66 }
67 
68 
70 {
71  // default material values as per VRML2 spec
72  diffuseColor.x = 0.8f;
73  diffuseColor.y = 0.8f;
74  diffuseColor.z = 0.8f;
75 
76  emissiveColor.x = 0.0f;
77  emissiveColor.y = 0.0f;
78  emissiveColor.z = 0.0f;
79 
81 
82  ambientIntensity = 0.2f;
83  shininess = 0.2f;
84  transparency = 0.0f;
85 
86  return;
87 }
88 
89 
90 void X3DAPP::readFields( wxXmlNode* aNode )
91 {
92  // DEF
93  // diffuseColor
94  // emissiveColor
95  // specularColor
96  // ambientIntensity
97  // shininess
98  // transparency
99 
100  wxXmlAttribute* prop;
101 
102  for( prop = aNode->GetAttributes(); prop != nullptr; prop = prop->GetNext() )
103  {
104  const wxString& pname = prop->GetName();
105 
106  if( pname == "DEF" )
107  {
108  m_MatName = prop->GetValue();
109  m_Dict->AddName( m_MatName, this );
110  }
111  else if( pname == "USE" )
112  {
113  X3DNODE* np = m_Dict->FindName( prop->GetValue() );
114 
115  if( nullptr != np && np->GetNodeType() == X3D_APPEARANCE )
116  {
117  X3DAPP* ap = (X3DAPP*) np;
122  shininess = ap->shininess;
124  }
125  }
126  else if( pname == "diffuseColor" )
127  {
128  X3D::ParseSFVec3( prop->GetValue(), diffuseColor );
129  }
130  else if( pname == "emissiveColor" )
131  {
132  X3D::ParseSFVec3( prop->GetValue(), emissiveColor );
133  }
134  else if( pname == "specularColor" )
135  {
136  X3D::ParseSFVec3( prop->GetValue(), specularColor );
137  }
138  else if( pname == "ambientIntensity" )
139  {
140  X3D::ParseSFFloat( prop->GetValue(), ambientIntensity );
141  }
142  else if( pname == "shininess" )
143  {
144  X3D::ParseSFFloat( prop->GetValue(), shininess );
145  }
146  else if( pname == "transparency" )
147  {
148  X3D::ParseSFFloat( prop->GetValue(), transparency );
149  }
150  }
151 }
152 
153 
154 bool X3DAPP::Read( wxXmlNode* aNode, X3DNODE* aTopNode, X3D_DICT& aDict )
155 {
156  if( nullptr == aTopNode || nullptr == aNode )
157  return false;
158 
159  m_Dict = &aDict;
160  wxXmlAttribute* prop;
161 
162  for( prop = aNode->GetAttributes(); prop != nullptr; prop = prop->GetNext() )
163  {
164  const wxString& pname = prop->GetName();
165 
166  if( pname == "DEF" )
167  {
168  m_Name = prop->GetValue();
169  m_Dict->AddName( m_Name, this );
170  }
171  }
172 
173  wxXmlNode* pmat = nullptr;
174 
175  for( wxXmlNode* child = aNode->GetChildren(); child != nullptr; child = child->GetNext() )
176  {
177  if( child->GetName() == "Material" )
178  pmat = child;
179 
180  }
181 
182  if( nullptr == pmat )
183  return false;
184 
185  readFields( pmat );
186 
187  if( !SetParent( aTopNode ) )
188  return false;
189 
190  return true;
191 }
192 
193 
194 bool X3DAPP::SetParent( X3DNODE* aParent, bool doUnlink )
195 {
196  if( aParent == m_Parent )
197  return true;
198 
199  if( nullptr != aParent )
200  {
201  X3DNODES nt = aParent->GetNodeType();
202 
203  if( nt != X3D_SHAPE )
204  return false;
205  }
206 
207  if( nullptr != m_Parent && doUnlink )
208  m_Parent->unlinkChildNode( this );
209 
210  m_Parent = aParent;
211 
212  if( nullptr != m_Parent )
213  m_Parent->AddChildNode( this );
214 
215  return true;
216 }
217 
218 
220 {
221  return false;
222 }
223 
224 
226 {
227  return false;
228 }
229 
230 
232 {
233  S3D::SGTYPES ptype = S3D::GetSGNodeType( aParent );
234 
235  wxCHECK_MSG( aParent && ( ptype == S3D::SGTYPE_SHAPE ), nullptr,
236  wxString::Format( wxT( "Appearance does not have a Shape parent (parent ID: %d)" ),
237  ptype ) );
238 
239  wxLogTrace( traceVrmlPlugin,
240  wxT( " * [INFO] Translating Appearance node with %zu children, %zu"
241  "references, and %zu back pointers." ),
242  m_Children.size(), m_Refs.size(), m_BackPointers.size() );
243 
244  if( m_sgNode )
245  {
246  if( nullptr != aParent )
247  {
248  if( nullptr == S3D::GetSGNodeParent( m_sgNode )
249  && !S3D::AddSGNodeChild( aParent, m_sgNode ) )
250  {
251  return nullptr;
252  }
253  else if( aParent != S3D::GetSGNodeParent( m_sgNode )
254  && !S3D::AddSGNodeRef( aParent, m_sgNode ) )
255  {
256  return nullptr;
257  }
258  }
259 
260  return m_sgNode;
261  }
262 
263  IFSG_APPEARANCE matNode( aParent );
267  float ambr = ambientIntensity * diffuseColor.x;
268  float ambg = ambientIntensity * diffuseColor.y;
269  float ambb = ambientIntensity * diffuseColor.z;
270  matNode.SetAmbient( ambr, ambg, ambb );
271  matNode.SetShininess( shininess );
272  matNode.SetTransparency( transparency );
273  m_sgNode = matNode.GetRawPtr();
274 
275  return m_sgNode;
276 }
void init()
bool AddChildNode(X3DNODE *aNode) override
float ambientIntensity
std::list< X3DNODE * > m_BackPointers
Definition: x3d_base.h:163
bool SetTransparency(float aTransparency) noexcept
X3DNODE * FindName(const wxString &aName)
Definition: x3d_base.cpp:68
bool SetDiffuse(float aRVal, float aGVal, float aBVal)
X3DNODES m_Type
Definition: x3d_base.h:160
bool DelName(const wxString &aName, X3DNODE *aNode)
Definition: x3d_base.cpp:51
wxString m_Name
Definition: x3d_base.h:168
SGLIB_API SGNODE * GetSGNodeParent(SGNODE *aNode)
Definition: ifsg_api.cpp:492
The base class of all Scene Graph nodes.
Definition: sg_node.h:74
collects header files for all SG* wrappers and the API
WRLVEC3F specularColor
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
std::list< X3DNODE * > m_Children
Definition: x3d_base.h:164
wxString m_MatName
The base class of all X3D nodes.
Definition: x3d_base.h:74
float transparency
WRLVEC3F diffuseColor
bool SetParent(X3DNODE *aParent, bool doUnlink=true) override
Set the parent X3DNODE of this object.
bool SetAmbient(float aRVal, float aGVal, float aBVal)
bool AddRefNode(X3DNODE *aNode) override
SGLIB_API bool AddSGNodeChild(SGNODE *aParent, SGNODE *aChild)
Definition: ifsg_api.cpp:510
bool ParseSFFloat(const wxString &aSource, float &aResult)
Definition: x3d_ops.cpp:252
SGNODE * TranslateToSG(SGNODE *aParent) override
Produce a representation of the data using the intermediate scenegraph structures of the kicad_3dsg l...
virtual bool AddChildNode(X3DNODE *aNode)=0
bool SetShininess(float aShininess) noexcept
X3DNODES GetNodeType(void) const
Return the type of this node instance.
Definition: x3d_base.cpp:184
virtual void unlinkChildNode(const X3DNODE *aNode)
Remove references to an owned child; it is invoked by the child upon destruction to ensure that the p...
Definition: x3d_base.cpp:102
const wxChar *const traceVrmlPlugin
Flag to enable VRML plugin trace output.
Definition: vrml.cpp:63
bool SetEmissive(float aRVal, float aGVal, float aBVal)
bool AddName(const wxString &aName, X3DNODE *aNode)
Definition: x3d_base.cpp:35
virtual ~X3DAPP()
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
SGNODE * m_sgNode
Definition: x3d_base.h:169
bool SetSpecular(float aRVal, float aGVal, float aBVal)
SGLIB_API S3D::SGTYPES GetSGNodeType(SGNODE *aNode)
Definition: ifsg_api.cpp:483
X3DNODE * m_Parent
Definition: x3d_base.h:159
bool Read(wxXmlNode *aNode, X3DNODE *aTopNode, X3D_DICT &aDict) override
bool ParseSFVec3(const wxString &aSource, WRLVEC3F &aResult)
Definition: x3d_ops.cpp:264
void readFields(wxXmlNode *aNode)
X3DNODES
Definition: x3d_base.h:59
X3D_DICT * m_Dict
Definition: x3d_base.h:161
float shininess
WRLVEC3F emissiveColor
std::list< X3DNODE * > m_Refs
Definition: x3d_base.h:165