KiCad PCB EDA Suite
sg_index.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_index.h"
29 
30 
31 SGINDEX::SGINDEX( SGNODE* aParent ) : SGNODE( aParent )
32 {
33  if( NULL != aParent && S3D::SGTYPE_FACESET != aParent->GetNodeType() )
34  {
35  m_Parent = NULL;
36 
37 #ifdef DEBUG
38  std::ostringstream ostr;
39  ostr << __FILE__ << ": " << __FUNCTION__ << ": " << __LINE__ << "\n";
40  ostr << " * [BUG] inappropriate parent to SGINDEX (type ";
41  ostr << aParent->GetNodeType() << ")";
42  wxLogTrace( MASK_3D_SG, "%s\n", ostr.str().c_str() );
43 #endif
44  }
45 
46  return;
47 }
48 
49 
51 {
52  index.clear();
53  return;
54 }
55 
56 
57 bool SGINDEX::SetParent( SGNODE* aParent, bool notify )
58 {
59  if( NULL != m_Parent )
60  {
61  if( aParent == m_Parent )
62  return true;
63 
64  // handle the change in parents
65  if( notify )
66  m_Parent->unlinkChildNode( this );
67 
68  m_Parent = NULL;
69 
70  if( NULL == aParent )
71  return true;
72  }
73 
74  // only a SGFACESET may be parent to a SGINDEX and derived types
75  if( NULL != aParent && S3D::SGTYPE_FACESET != aParent->GetNodeType() )
76  return false;
77 
78  m_Parent = aParent;
79 
80  if( m_Parent )
81  m_Parent->AddChildNode( this );
82 
83  return true;
84 }
85 
86 
87 SGNODE* SGINDEX::FindNode(const char *aNodeName, const SGNODE *aCaller)
88 {
89  if( NULL == aNodeName || 0 == aNodeName[0] )
90  return NULL;
91 
92  if( !m_Name.compare( aNodeName ) )
93  return this;
94 
95  return NULL;
96 }
97 
98 
99 void SGINDEX::unlinkChildNode( const SGNODE* aCaller )
100 {
101  #ifdef DEBUG
102  std::ostringstream ostr;
103  ostr << __FILE__ << ": " << __FUNCTION__ << ": " << __LINE__ << "\n";
104  ostr << " * [BUG] unexpected code branch; node should have no children or refs";
105  wxLogTrace( MASK_3D_SG, "%s\n", ostr.str().c_str() );
106  #endif
107 
108  return;
109 }
110 
111 
112 void SGINDEX::unlinkRefNode( const SGNODE* aCaller )
113 {
114  #ifdef DEBUG
115  std::ostringstream ostr;
116  ostr << __FILE__ << ": " << __FUNCTION__ << ": " << __LINE__ << "\n";
117  ostr << " * [BUG] unexpected code branch; node should have no children or refs";
118  wxLogTrace( MASK_3D_SG, "%s\n", ostr.str().c_str() );
119  #endif
120 
121  return;
122 }
123 
124 
126 {
127  #ifdef DEBUG
128  std::ostringstream ostr;
129  ostr << __FILE__ << ": " << __FUNCTION__ << ": " << __LINE__ << "\n";
130  ostr << " * [BUG] this node does not accept children or refs";
131  wxLogTrace( MASK_3D_SG, "%s\n", ostr.str().c_str() );
132  #endif
133 
134  return false;
135 }
136 
137 
139 {
140  #ifdef DEBUG
141  std::ostringstream ostr;
142  ostr << __FILE__ << ": " << __FUNCTION__ << ": " << __LINE__ << "\n";
143  ostr << " * [BUG] this node does not accept children or refs";
144  wxLogTrace( MASK_3D_SG, "%s\n", ostr.str().c_str() );
145  #endif
146 
147  return false;
148 }
149 
150 
151 bool SGINDEX::GetIndices( size_t& nIndices, int*& aIndexList )
152 {
153  if( index.empty() )
154  {
155  nIndices = 0;
156  aIndexList = NULL;
157  return false;
158  }
159 
160  nIndices = index.size();
161  aIndexList = & index[0];
162  return true;
163 }
164 
165 
166 void SGINDEX::SetIndices( size_t nIndices, int* aIndexList )
167 {
168  index.clear();
169 
170  if( 0 == nIndices || NULL == aIndexList )
171  return;
172 
173  for( size_t i = 0; i < nIndices; ++i )
174  index.push_back( aIndexList[i] );
175 
176  return;
177 }
178 
179 
180 void SGINDEX::AddIndex( int aIndex )
181 {
182  index.push_back( aIndex );
183  return;
184 }
185 
186 
188 {
189  m_written = false;
190 
191  // rename this node
192  m_Name.clear();
193  GetName();
194 }
195 
196 
197 bool SGINDEX::WriteVRML( std::ostream& aFile, bool aReuseFlag )
198 {
199  if( index.empty() )
200  return false;
201 
203  return writeCoordIndex( aFile );
204 
205  return writeColorIndex( aFile );
206 }
207 
208 
209 bool SGINDEX::writeCoordIndex( std::ostream& aFile )
210 {
211  size_t n = index.size();
212 
213  if( n % 3 )
214  {
215  #ifdef DEBUG
216  std::ostringstream ostr;
217  ostr << __FILE__ << ": " << __FUNCTION__ << ": " << __LINE__ << "\n";
218  ostr << " * [BUG] coord index is not divisible by three (violates triangle constraint)";
219  wxLogTrace( MASK_3D_SG, "%s\n", ostr.str().c_str() );
220  #endif
221 
222  return false;
223  }
224 
225  aFile << " coordIndex [\n ";
226 
227  // indices to control formatting
228  int nv0 = 0;
229  int nv1 = 0;
230 
231  for( size_t i = 0; i < n; )
232  {
233  aFile << index[i];
234  ++i;
235 
236  if( ++nv0 == 3 )
237  {
238  aFile << ",-1";
239  ++nv1;
240  nv0 = 0;
241  }
242 
243  if( i < n )
244  {
245  aFile << ",";
246 
247  if( nv1 == 8 )
248  {
249  nv1 = 0;
250  aFile << "\n ";
251  }
252  }
253  }
254 
255  aFile << "]\n";
256 
257  return true;
258 }
259 
260 
261 bool SGINDEX::writeColorIndex( std::ostream& aFile )
262 {
263  aFile << " colorIndex [\n ";
264  return writeIndexList( aFile );
265 }
266 
267 
268 bool SGINDEX::writeIndexList( std::ostream& aFile )
269 {
270  // index to control formatting
271  int nv = 0;
272  size_t n = index.size();
273 
274  for( size_t i = 0; i < n; )
275  {
276  aFile << index[i];
277  ++i;
278 
279  if( i < n )
280  {
281  aFile << ",";
282 
283  if( ++nv == 20 )
284  {
285  aFile << "\n ";
286  nv = 0;
287  }
288  }
289  }
290 
291  aFile << "]\n";
292 
293  return true;
294 }
295 
296 
297 bool SGINDEX::WriteCache( std::ostream& aFile, SGNODE* parentNode )
298 {
299  if( NULL == parentNode )
300  {
301  if( NULL == m_Parent )
302  {
303  #ifdef DEBUG
304  std::ostringstream ostr;
305  ostr << __FILE__ << ": " << __FUNCTION__ << ": " << __LINE__ << "\n";
306  ostr << " * [BUG] corrupt data; m_aParent is NULL";
307  wxLogTrace( MASK_3D_SG, "%s\n", ostr.str().c_str() );
308  #endif
309 
310  return false;
311  }
312 
313  SGNODE* np = m_Parent;
314 
315  while( NULL != np->GetParent() )
316  np = np->GetParent();
317 
318  if( np->WriteCache( aFile, NULL ) )
319  {
320  m_written = true;
321  return true;
322  }
323 
324  return false;
325  }
326 
327  if( parentNode != m_Parent )
328  {
329  #ifdef DEBUG
330  std::ostringstream ostr;
331  ostr << __FILE__ << ": " << __FUNCTION__ << ": " << __LINE__ << "\n";
332  ostr << " * [BUG] corrupt data; parentNode != m_aParent";
333  wxLogTrace( MASK_3D_SG, "%s\n", ostr.str().c_str() );
334  #endif
335 
336  return false;
337  }
338 
339  if( !aFile.good() )
340  {
341  #ifdef DEBUG
342  std::ostringstream ostr;
343  ostr << __FILE__ << ": " << __FUNCTION__ << ": " << __LINE__ << "\n";
344  ostr << " * [INFO] bad stream";
345  wxLogTrace( MASK_3D_SG, "%s\n", ostr.str().c_str() );
346  #endif
347 
348  return false;
349  }
350 
351  aFile << "[" << GetName() << "]";
352  size_t npts = index.size();
353  aFile.write( (char*)&npts, sizeof(size_t) );
354 
355  for( size_t i = 0; i < npts; ++i )
356  aFile.write( (char*)&index[i], sizeof(int) );
357 
358  if( aFile.fail() )
359  return false;
360 
361  m_written = true;
362  return true;
363 }
364 
365 
366 bool SGINDEX::ReadCache( std::istream& aFile, SGNODE* parentNode )
367 {
368  if( !index.empty() )
369  {
370  #ifdef DEBUG
371  std::ostringstream ostr;
372  ostr << __FILE__ << ": " << __FUNCTION__ << ": " << __LINE__ << "\n";
373  ostr << " * [BUG] non-empty node";
374  wxLogTrace( MASK_3D_SG, "%s\n", ostr.str().c_str() );
375  #endif
376 
377  return false;
378  }
379 
380  size_t npts;
381  aFile.read( (char*)&npts, sizeof(size_t) );
382  int tmp;
383 
384  if( aFile.fail() )
385  return false;
386 
387  for( size_t i = 0; i < npts; ++i )
388  {
389  aFile.read( (char*)&tmp, sizeof(int) );
390 
391  if( aFile.fail() )
392  return false;
393 
394  index.push_back( tmp );
395  }
396 
397  return true;
398 }
SGINDEX(SGNODE *aParent)
Definition: sg_index.cpp:31
SGNODE * m_Parent
Definition: sg_node.h:83
virtual bool SetParent(SGNODE *aParent, bool notify=true) override
Function SetParent sets the parent SGNODE of this object.
Definition: sg_index.cpp:57
bool AddChildNode(SGNODE *aNode) override
Definition: sg_index.cpp:138
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_index.cpp:197
bool writeColorIndex(std::ostream &aFile)
Definition: sg_index.cpp:261
std::vector< int > index
Definition: sg_index.h:44
Class SGNODE represents the base class of all Scene Graph nodes.
Definition: sg_node.h:76
S3D::SGTYPES GetNodeType(void) const
Function GetNodeType returns the type of this node instance.
Definition: sg_node.cpp:108
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_index.cpp:297
void ReNameNodes(void) override
Function ReNameNodes renames a node and all its child nodes in preparation for Write() operations...
Definition: sg_index.cpp:187
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
bool writeCoordIndex(std::ostream &aFile)
Definition: sg_index.cpp:209
virtual void unlinkChildNode(const SGNODE *aNode)=0
Function unlinkChild removes references to an owned child; it is invoked by the child upon destructio...
void unlinkRefNode(const SGNODE *aCaller) override
Function unlinkRef removes pointers to a referenced node; it is invoked by the referenced node upon d...
Definition: sg_index.cpp:112
bool GetIndices(size_t &nIndices, int *&aIndexList)
Function GetIndices retrieves the number of indices and a pointer to the list.
Definition: sg_index.cpp:151
virtual ~SGINDEX()
Definition: sg_index.cpp:50
bool writeIndexList(std::ostream &aFile)
Definition: sg_index.cpp:268
defines a generic Index interface for a scenegraph object
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_index.cpp:87
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 ReadCache(std::istream &aFile, SGNODE *parentNode) override
Function ReadCache Reads binary format data from a cache file.
Definition: sg_index.cpp:366
void SetIndices(size_t nIndices, int *aIndexList)
Function SetIndices sets the number of indices and creates a copy of the given index data...
Definition: sg_index.cpp:166
bool AddRefNode(SGNODE *aNode) override
Definition: sg_index.cpp:125
virtual bool AddChildNode(SGNODE *aNode)=0
void unlinkChildNode(const SGNODE *aCaller) override
Function unlinkChild removes references to an owned child; it is invoked by the child upon destructio...
Definition: sg_index.cpp:99
void AddIndex(int aIndex)
Function AddIndex adds a single index to the list.
Definition: sg_index.cpp:180