KiCad PCB EDA Suite
sg_colors.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 <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 #include <iostream>
25 #include <sstream>
26 #include <wx/log.h>
27 
28 #include "3d_cache/sg/sg_colors.h"
29 #include "3d_cache/sg/sg_helpers.h"
30 
31 SGCOLORS::SGCOLORS( SGNODE* aParent ) : SGNODE( aParent )
32 {
34 
35  if( NULL != aParent && S3D::SGTYPE_FACESET != aParent->GetNodeType() )
36  {
37  m_Parent = NULL;
38 
39 #ifdef DEBUG
40  std::ostringstream ostr;
41  ostr << __FILE__ << ": " << __FUNCTION__ << ": " << __LINE__ << "\n";
42  ostr << " * [BUG] inappropriate parent to SGCOLORS (type ";
43  ostr << aParent->GetNodeType() << ")";
44  wxLogTrace( MASK_3D_SG, "%s\n", ostr.str().c_str() );
45 #endif
46  }
47  else if( NULL != aParent && S3D::SGTYPE_FACESET == aParent->GetNodeType() )
48  {
49  m_Parent->AddChildNode( this );
50  }
51 
52  return;
53 }
54 
55 
57 {
58  colors.clear();
59  return;
60 }
61 
62 
63 bool SGCOLORS::SetParent( SGNODE* aParent, bool notify )
64 {
65  if( NULL != m_Parent )
66  {
67  if( aParent == m_Parent )
68  return true;
69 
70  // handle the change in parents
71  if( notify )
72  m_Parent->unlinkChildNode( this );
73 
74  m_Parent = NULL;
75 
76  if( NULL == aParent )
77  return true;
78  }
79 
80  // only a SGFACESET may be parent to a SGCOLORS
81  if( NULL != aParent && S3D::SGTYPE_FACESET != aParent->GetNodeType() )
82  return false;
83 
84  m_Parent = aParent;
85 
86  if( m_Parent )
87  m_Parent->AddChildNode( this );
88 
89  return true;
90 }
91 
92 
93 SGNODE* SGCOLORS::FindNode(const char *aNodeName, const SGNODE *aCaller)
94 {
95  if( NULL == aNodeName || 0 == aNodeName[0] )
96  return NULL;
97 
98  if( !m_Name.compare( aNodeName ) )
99  return this;
100 
101  return NULL;
102 }
103 
104 
105 void SGCOLORS::unlinkChildNode( const SGNODE* aCaller )
106 {
107  #ifdef DEBUG
108  std::ostringstream ostr;
109  ostr << __FILE__ << ": " << __FUNCTION__ << ": " << __LINE__ << "\n";
110  ostr << " * [BUG] unexpected code branch; node should have no children or refs";
111  wxLogTrace( MASK_3D_SG, "%s\n", ostr.str().c_str() );
112  #endif
113 
114  return;
115 }
116 
117 
118 void SGCOLORS::unlinkRefNode( const SGNODE* aCaller )
119 {
120  #ifdef DEBUG
121  std::ostringstream ostr;
122  ostr << __FILE__ << ": " << __FUNCTION__ << ": " << __LINE__ << "\n";
123  ostr << " * [BUG] unexpected code branch; node should have no children or refs";
124  wxLogTrace( MASK_3D_SG, "%s\n", ostr.str().c_str() );
125  #endif
126 
127  return;
128 }
129 
130 
132 {
133  #ifdef DEBUG
134  std::ostringstream ostr;
135  ostr << __FILE__ << ": " << __FUNCTION__ << ": " << __LINE__ << "\n";
136  ostr << " * [BUG] this node does not accept children or refs";
137  wxLogTrace( MASK_3D_SG, "%s\n", ostr.str().c_str() );
138  #endif
139 
140  return false;
141 }
142 
143 
145 {
146  #ifdef DEBUG
147  std::ostringstream ostr;
148  ostr << __FILE__ << ": " << __FUNCTION__ << ": " << __LINE__ << "\n";
149  ostr << " * [BUG] this node does not accept children or refs";
150  wxLogTrace( MASK_3D_SG, "%s\n", ostr.str().c_str() );
151  #endif
152 
153  return false;
154 }
155 
156 
157 bool SGCOLORS::GetColorList( size_t& aListSize, SGCOLOR*& aColorList )
158 {
159  if( colors.empty() )
160  {
161  aListSize = 0;
162  aColorList = NULL;
163  return false;
164  }
165 
166  aListSize = colors.size();
167  aColorList = &colors[0];
168  return true;
169 }
170 
171 
172 void SGCOLORS::SetColorList( size_t aListSize, const SGCOLOR* aColorList )
173 {
174  colors.clear();
175 
176  if( 0 == aListSize || NULL == aColorList )
177  return;
178 
179  for( size_t i = 0; i < aListSize; ++i )
180  colors.push_back( aColorList[i] );
181 
182  return;
183 }
184 
185 
186 void SGCOLORS::AddColor( double aRedValue, double aGreenValue, double aBlueValue )
187 {
188  colors.push_back( SGCOLOR( aRedValue, aGreenValue, aBlueValue ) );
189  return;
190 }
191 
192 
193 void SGCOLORS::AddColor( const SGCOLOR& aColor )
194 {
195  colors.push_back( aColor );
196  return;
197 }
198 
199 
201 {
202  m_written = false;
203 
204  // rename this node
205  m_Name.clear();
206  GetName();
207 }
208 
209 
210 bool SGCOLORS::WriteVRML( std::ostream& aFile, bool aReuseFlag )
211 {
212  if( colors.empty() )
213  return false;
214 
215  if( aReuseFlag )
216  {
217  if( !m_written )
218  {
219  aFile << "color DEF " << GetName() << " Color { color [\n ";
220  m_written = true;
221  }
222  else
223  {
224  aFile << "color USE " << GetName() << "\n";
225  return true;
226  }
227  }
228  else
229  {
230  aFile << "color Color { color [\n ";
231  }
232 
233  std::string tmp;
234  size_t n = colors.size();
235  bool nline = false;
236 
237  for( size_t i = 0; i < n; )
238  {
239  S3D::FormatColor( tmp, colors[i] );
240  float r,g,b;
241  colors[i].GetColor(r, g, b);
242  aFile << tmp ;
243  ++i;
244 
245  if( i < n )
246  {
247  aFile << ",";
248 
249  if( nline )
250  {
251  aFile << "\n ";
252  nline = false;
253  }
254  else
255  {
256  nline = true;
257  }
258 
259  }
260  }
261 
262  aFile << "] }\n";
263 
264  return true;
265 }
266 
267 
268 bool SGCOLORS::WriteCache( std::ostream& aFile, SGNODE* parentNode )
269 {
270  if( NULL == parentNode )
271  {
272  if( NULL == m_Parent )
273  {
274  #ifdef DEBUG
275  std::ostringstream ostr;
276  ostr << __FILE__ << ": " << __FUNCTION__ << ": " << __LINE__ << "\n";
277  ostr << " * [BUG] corrupt data; m_aParent is NULL";
278  wxLogTrace( MASK_3D_SG, "%s\n", ostr.str().c_str() );
279  #endif
280 
281  return false;
282  }
283 
284  SGNODE* np = m_Parent;
285 
286  while( NULL != np->GetParent() )
287  np = np->GetParent();
288 
289  if( np->WriteCache( aFile, NULL ) )
290  {
291  m_written = true;
292  return true;
293  }
294 
295  return false;
296  }
297 
298  if( parentNode != m_Parent )
299  {
300  #ifdef DEBUG
301  std::ostringstream ostr;
302  ostr << __FILE__ << ": " << __FUNCTION__ << ": " << __LINE__ << "\n";
303  ostr << " * [BUG] corrupt data; parentNode != m_aParent";
304  wxLogTrace( MASK_3D_SG, "%s\n", ostr.str().c_str() );
305  #endif
306 
307  return false;
308  }
309 
310  if( !aFile.good() )
311  {
312  #ifdef DEBUG
313  std::ostringstream ostr;
314  ostr << __FILE__ << ": " << __FUNCTION__ << ": " << __LINE__ << "\n";
315  ostr << " * [INFO] bad stream";
316  wxLogTrace( MASK_3D_SG, "%s\n", ostr.str().c_str() );
317  #endif
318 
319  return false;
320  }
321 
322  aFile << "[" << GetName() << "]";
323  size_t ncolors = colors.size();
324  aFile.write( (char*)&ncolors, sizeof(size_t) );
325 
326  for( size_t i = 0; i < ncolors; ++i )
327  S3D::WriteColor( aFile, colors[i] );
328 
329  if( aFile.fail() )
330  return false;
331 
332  m_written = true;
333  return true;
334 }
335 
336 
337 bool SGCOLORS::ReadCache( std::istream& aFile, SGNODE* parentNode )
338 {
339  if( !colors.empty() )
340  {
341  #ifdef DEBUG
342  std::ostringstream ostr;
343  ostr << __FILE__ << ": " << __FUNCTION__ << ": " << __LINE__ << "\n";
344  ostr << " * [BUG] non-empty node";
345  wxLogTrace( MASK_3D_SG, "%s\n", ostr.str().c_str() );
346  #endif
347 
348  return false;
349  }
350 
351  size_t ncolors;
352  aFile.read( (char*)&ncolors, sizeof(size_t) );
353  SGCOLOR tmp;
354 
355  if( aFile.fail() )
356  return false;
357 
358  for( size_t i = 0; i < ncolors; ++i )
359  {
360  if( !S3D::ReadColor( aFile, tmp ) || aFile.fail() )
361  return false;
362 
363  colors.push_back( tmp );
364  }
365 
366  return true;
367 }
virtual bool SetParent(SGNODE *aParent, bool notify=true) override
Function SetParent sets the parent SGNODE of this object.
Definition: sg_colors.cpp:63
void AddColor(double aRedValue, double aGreenValue, double aBlueValue)
Definition: sg_colors.cpp:186
bool AddChildNode(SGNODE *aNode) override
Definition: sg_colors.cpp:144
SGNODE * m_Parent
Definition: sg_node.h:83
bool ReadColor(std::istream &aFile, SGCOLOR &aColor)
Definition: sg_helpers.cpp:324
bool GetColorList(size_t &aListSize, SGCOLOR *&aColorList)
Definition: sg_colors.cpp:157
void FormatColor(std::string &result, const SGCOLOR &aColor)
Definition: sg_helpers.cpp:146
bool ReadCache(std::istream &aFile, SGNODE *parentNode) override
Function ReadCache Reads binary format data from a cache file.
Definition: sg_colors.cpp:337
bool WriteColor(std::ostream &aFile, const SGCOLOR &aColor)
Definition: sg_helpers.cpp:193
Class SGNODE represents the base class of all Scene Graph nodes.
Definition: sg_node.h:76
void unlinkChildNode(const SGNODE *aNode) override
Function unlinkChild removes references to an owned child; it is invoked by the child upon destructio...
Definition: sg_colors.cpp:105
S3D::SGTYPES GetNodeType(void) const
Function GetNodeType returns the type of this node instance.
Definition: sg_node.cpp:108
bool AddRefNode(SGNODE *aNode) override
Definition: sg_colors.cpp:131
void ReNameNodes(void) override
Function ReNameNodes renames a node and all its child nodes in preparation for Write() operations...
Definition: sg_colors.cpp:200
const char * GetName(void)
Definition: sg_node.cpp:150
bool m_written
Definition: sg_node.h:86
SGNODE * GetParent(void) const
Function GetParent returns a pointer to the parent SGNODE of this object or NULL if the object has no...
Definition: sg_node.cpp:114
virtual void unlinkChildNode(const SGNODE *aNode)=0
Function unlinkChild removes references to an owned child; it is invoked by the child upon destructio...
bool WriteVRML(std::ostream &aFile, bool aReuseFlag) override
Function WriteVRML writes this node's data to a VRML file; this includes all data of child and refere...
Definition: sg_colors.cpp:210
std::vector< SGCOLOR > colors
Definition: sg_colors.h:38
virtual ~SGCOLORS()
Definition: sg_colors.cpp:56
void unlinkRefNode(const SGNODE *aNode) override
Function unlinkRef removes pointers to a referenced node; it is invoked by the referenced node upon d...
Definition: sg_colors.cpp:118
SGNODE * FindNode(const char *aNodeName, const SGNODE *aCaller) override
Function FindNode searches the tree of linked nodes and returns a reference to the first node found w...
Definition: sg_colors.cpp:93
std::string m_Name
Definition: sg_node.h:85
virtual bool WriteCache(std::ostream &aFile, SGNODE *parentNode)=0
Function WriteCache write's this node's data to a binary cache file; the data includes all data of ch...
S3D::SGTYPES m_SGtype
Definition: sg_node.h:84
bool WriteCache(std::ostream &aFile, SGNODE *parentNode) override
Function WriteCache write's this node's data to a binary cache file; the data includes all data of ch...
Definition: sg_colors.cpp:268
defines an RGB color set for a scenegraph object
void SetColorList(size_t aListSize, const SGCOLOR *aColorList)
Definition: sg_colors.cpp:172
virtual bool AddChildNode(SGNODE *aNode)=0
defines a number of macro functions to aid in repetitious code which is probably best expressed as a ...
SGCOLORS(SGNODE *aParent)
Definition: sg_colors.cpp:31