KiCad PCB EDA Suite
Loading...
Searching...
No Matches
sg_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) 2015-2017 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#include <iostream>
22#include <utility>
23#include <sstream>
24#include <wx/log.h>
25
28
29
31{
33
34 // defaults in accord with VRML2.0 spec
35 ambient.SetColor( 0.05317f, 0.17879f, 0.01804f );
36 shininess = 0.2f;
37 transparency = 0.0f;
38 diffuse.SetColor( 0.8f, 0.8f, 0.8f );
39
40 if( nullptr != aParent && S3D::SGTYPE_SHAPE != aParent->GetNodeType() )
41 {
42 m_Parent = nullptr;
43
44 wxLogTrace( MASK_3D_SG,
45 wxT( "%s:%s:%d * [BUG] inappropriate parent to SGAPPEARANCE (type %s )" ),
46 __FILE__, __FUNCTION__, __LINE__, aParent->GetNodeType() );
47 }
48 else if( nullptr != aParent && S3D::SGTYPE_SHAPE == aParent->GetNodeType() )
49 {
50 m_Parent->AddChildNode( this );
51 }
52}
53
54
58
59
60bool SGAPPEARANCE::SetParent( SGNODE* aParent, bool notify )
61{
62 if( nullptr != m_Parent )
63 {
64 if( aParent == m_Parent )
65 return true;
66
67 // handle the change in parents
68 if( notify )
69 m_Parent->unlinkChildNode( this );
70
71 m_Parent = nullptr;
72
73 if( nullptr == aParent )
74 return true;
75 }
76
77 // only a SGSHAPE may be parent to a SGAPPEARANCE
78 if( nullptr != aParent && S3D::SGTYPE_SHAPE != aParent->GetNodeType() )
79 return false;
80
81 m_Parent = aParent;
82
83 if( m_Parent )
84 m_Parent->AddChildNode( this );
85
86 return true;
87}
88
89
90bool SGAPPEARANCE::SetEmissive( float aRVal, float aGVal, float aBVal )
91{
92 return emissive.SetColor( aRVal, aGVal, aBVal );
93}
94
95
96bool SGAPPEARANCE::SetEmissive( const SGCOLOR* aRGBColor )
97{
98 wxCHECK_MSG( aRGBColor, false, wxT( "NULL pointer passed for aRGBColor" ) );
99
100 return emissive.SetColor( aRGBColor );
101}
102
103
104bool SGAPPEARANCE::SetEmissive( const SGCOLOR& aRGBColor )
105{
106 return emissive.SetColor( aRGBColor );
107}
108
109
110bool SGAPPEARANCE::SetDiffuse( float aRVal, float aGVal, float aBVal )
111{
112 return diffuse.SetColor( aRVal, aGVal, aBVal );
113}
114
115
116bool SGAPPEARANCE::SetDiffuse( const SGCOLOR* aRGBColor )
117{
118 wxCHECK_MSG( aRGBColor, false, wxT( "NULL pointer passed for aRGBColor" ) );
119
120 return diffuse.SetColor( aRGBColor );
121}
122
123
124bool SGAPPEARANCE::SetDiffuse( const SGCOLOR& aRGBColor )
125{
126 return diffuse.SetColor( aRGBColor );
127}
128
129
130bool SGAPPEARANCE::SetSpecular( float aRVal, float aGVal, float aBVal )
131{
132 return specular.SetColor( aRVal, aGVal, aBVal );
133}
134
135
136bool SGAPPEARANCE::SetSpecular( const SGCOLOR* aRGBColor )
137{
138 wxCHECK_MSG( aRGBColor, false, wxT( "NULL pointer passed for aRGBColor" ) );
139
140 return specular.SetColor( aRGBColor );
141}
142
143bool SGAPPEARANCE::SetSpecular( const SGCOLOR& aRGBColor )
144{
145 return specular.SetColor( aRGBColor );
146}
147
148
149bool SGAPPEARANCE::SetAmbient( float aRVal, float aGVal, float aBVal )
150{
151 return ambient.SetColor( aRVal, aGVal, aBVal );
152}
153
154
155bool SGAPPEARANCE::SetAmbient( const SGCOLOR* aRGBColor )
156{
157 wxCHECK_MSG( aRGBColor, false, wxT( "NULL pointer passed for aRGBColor" ) );
158
159 return ambient.SetColor( aRGBColor );
160}
161
162
163bool SGAPPEARANCE::SetAmbient( const SGCOLOR& aRGBColor )
164{
165 return ambient.SetColor( aRGBColor );
166}
167
168
169SGNODE* SGAPPEARANCE::FindNode( const char* aNodeName, const SGNODE* aCaller) noexcept
170{
171 if( nullptr == aNodeName || 0 == aNodeName[0] )
172 return nullptr;
173
174 if( !m_Name.compare( aNodeName ) )
175 return this;
176
177 return nullptr;
178}
179
180
181void SGAPPEARANCE::unlinkChildNode( const SGNODE* aCaller ) noexcept
182{
183 wxCHECK_MSG( aCaller, /* void */,
184 wxT( "unexpected code branch; node should have no children or refs" ) );
185}
186
187
188void SGAPPEARANCE::unlinkRefNode( const SGNODE* aCaller ) noexcept
189{
190 wxCHECK_MSG( aCaller, /* void */,
191 wxT( "unexpected code branch; node should have no children or refs" ) );
192}
193
194
195bool SGAPPEARANCE::AddRefNode( SGNODE* aNode ) noexcept
196{
197 wxCHECK_MSG( aNode, false, wxT( "this node does not accept children or refs" ) );
198
199 // This is redundant but it keeps gcc from generating a warning on debug builds.
200 return false;
201}
202
203
204bool SGAPPEARANCE::AddChildNode( SGNODE* aNode ) noexcept
205{
206 wxCHECK_MSG( aNode, false, wxT( "this node does not accept children or refs" ) );
207
208 // This is redundant but it keeps gcc from generating a warning on debug builds.
209 return false;
210}
211
212
214{
215 m_written = false;
216
217 // rename this node
218 m_Name.clear();
219 GetName();
220}
221
222
223bool SGAPPEARANCE::WriteVRML( std::ostream& aFile, bool aReuseFlag )
224{
225 if( aReuseFlag )
226 {
227 if( !m_written )
228 {
229 aFile << " appearance DEF " << GetName() << " Appearance {\n";
230 m_written = true;
231 }
232 else
233 {
234 aFile << " appearance USE " << GetName() << "\n";
235 return true;
236 }
237 }
238 else
239 {
240 aFile << " appearance Appearance {\n";
241 }
242
243 aFile << " material Material {\n";
244
245 std::string tmp;
246 float ambr, ambg, ambb;
247 ambient.GetColor( ambr, ambg, ambb );
248 float amb = ( 0.212671 * ambr + 0.71516 * ambg + 0.072169 * ambb );
249 diffuse.GetColor( ambr, ambg, ambb );
250 float den = ( 0.212671 * ambr + 0.71516 * ambg + 0.072169 * ambb );
251
252 if( den < 0.004f )
253 den = 0.004f;
254
255 amb /= den;
256
257 if( amb > 1.0f )
258 amb = 1.0f;
259
260 S3D::FormatFloat( tmp, amb );
261 aFile << " ambientIntensity " << tmp << "\n";
262
263 float red, green, blue;
264 diffuse.GetColor( red, green, blue );
265 S3D::FormatFloat( tmp, red );
266 aFile << " diffuseColor " << tmp << " ";
267 S3D::FormatFloat( tmp, green );
268 aFile << tmp << " ";
269 S3D::FormatFloat( tmp, blue);
270 aFile << tmp << "\n";
271
272 emissive.GetColor( red, green, blue );
273 S3D::FormatFloat( tmp, red );
274 aFile << " emissiveColor " << tmp << " ";
275 S3D::FormatFloat( tmp, green );
276 aFile << tmp << " ";
277 S3D::FormatFloat( tmp, blue);
278 aFile << tmp << "\n";
279
281 aFile << " shininess " << tmp << "\n";
282
283 specular.GetColor( red, green, blue );
284 S3D::FormatFloat( tmp, red );
285 aFile << " specularColor " << tmp << " ";
286 S3D::FormatFloat( tmp, green );
287 aFile << tmp << " ";
288 S3D::FormatFloat( tmp, blue);
289 aFile << tmp << "\n";
290
292 aFile << " transparency " << tmp << "\n";
293
294 aFile << "} }\n";
295
296 return true;
297}
298
299
300bool SGAPPEARANCE::WriteCache( std::ostream& aFile, SGNODE* parentNode )
301{
302 if( nullptr == parentNode )
303 {
304 wxCHECK_MSG( m_Parent, false, wxT( "corrupt data; m_aParent is NULL" ) );
305
306 SGNODE* np = m_Parent;
307
308 while( nullptr != np->GetParent() )
309 np = np->GetParent();
310
311 if( np->WriteCache( aFile, nullptr ) )
312 {
313 m_written = true;
314 return true;
315 }
316
317 return false;
318 }
319
320 wxCHECK_MSG( parentNode == m_Parent, false, wxT( "corrupt data; parentNode != m_aParent" ) );
321
322 if( !aFile.good() )
323 {
324 wxLogTrace( MASK_3D_SG, wxT( "%s:%s:%d * [INFO] bad stream" ),
325 __FILE__, __FUNCTION__, __LINE__ );
326
327 return false;
328 }
329
330 aFile << "[" << GetName() << "]";
331 S3D::WriteColor( aFile, ambient );
332 aFile.write( (char*) &shininess, sizeof( shininess ) );
333 aFile.write( (char*) &transparency, sizeof( transparency ) );
334 S3D::WriteColor( aFile, diffuse );
335 S3D::WriteColor( aFile, emissive );
336 S3D::WriteColor( aFile, specular );
337
338 if( aFile.fail() )
339 return false;
340
341 m_written = true;
342 return true;
343}
344
345
346bool SGAPPEARANCE::ReadCache( std::istream& aFile, SGNODE* parentNode )
347{
348 S3D::ReadColor( aFile, ambient );
349 aFile.read( (char*) &shininess, sizeof( shininess ) );
350 aFile.read( (char*) &transparency, sizeof( transparency ) );
351 S3D::ReadColor( aFile, diffuse );
352 S3D::ReadColor( aFile, emissive );
353 S3D::ReadColor( aFile, specular );
354
355 if( aFile.fail() )
356 return false;
357
358 return true;
359}
int blue
int red
int green
SGNODE * FindNode(const char *aNodeName, const SGNODE *aCaller) noexcept override
Search the tree of linked nodes and return a reference to the first node found with the given name.
bool AddRefNode(SGNODE *aNode) noexcept override
bool SetSpecular(float aRVal, float aGVal, float aBVal)
void unlinkRefNode(const SGNODE *aNode) noexcept override
Remove pointers to a referenced node.
SGCOLOR diffuse
SGCOLOR ambient
bool AddChildNode(SGNODE *aNode) noexcept override
void unlinkChildNode(const SGNODE *aNode) noexcept override
Remove references to an owned child.
SGAPPEARANCE(SGNODE *aParent)
bool SetEmissive(float aRVal, float aGVal, float aBVal)
bool WriteVRML(std::ostream &aFile, bool aReuseFlag) override
Writes this node's data to a VRML file.
bool ReadCache(std::istream &aFile, SGNODE *parentNode) override
Reads binary format data from a cache file.
SGCOLOR specular
bool SetDiffuse(float aRVal, float aGVal, float aBVal)
bool SetAmbient(float aRVal, float aGVal, float aBVal)
bool WriteCache(std::ostream &aFile, SGNODE *parentNode) override
Write this node's data to a binary cache file.
virtual ~SGAPPEARANCE()
SGCOLOR emissive
void ReNameNodes(void) override
Rename a node and all its child nodes in preparation for write operations.
virtual bool SetParent(SGNODE *aParent, bool notify=true) override
Set the parent SGNODE of this object.
virtual bool WriteCache(std::ostream &aFile, SGNODE *parentNode)=0
Write this node's data to a binary cache file.
const char * GetName(void)
Definition sg_node.cpp:142
SGNODE * GetParent(void) const noexcept
Returns a pointer to the parent SGNODE of this object or NULL if the object has no parent (ie.
Definition sg_node.cpp:106
S3D::SGTYPES GetNodeType(void) const noexcept
Return the type of this node instance.
Definition sg_node.cpp:100
SGNODE * m_Parent
Pointer to parent node; may be NULL for top level transform.
Definition sg_node.h:223
SGNODE(SGNODE *aParent)
Definition sg_node.cpp:72
std::string m_Name
name to use for referencing the entity by name.
Definition sg_node.h:225
bool m_written
Set to true when the object has been written after a ReNameNodes().
Definition sg_node.h:226
S3D::SGTYPES m_SGtype
Type of Scene Graph node.
Definition sg_node.h:224
bool WriteColor(std::ostream &aFile, const SGCOLOR &aColor)
void FormatFloat(std::string &result, double value)
@ SGTYPE_SHAPE
Definition sg_types.h:41
@ SGTYPE_APPEARANCE
Definition sg_types.h:34
bool ReadColor(std::istream &aFile, SGCOLOR &aColor)
Define a number of macros to aid in repetitious code which is probably best expressed as a preprocess...