KiCad PCB EDA Suite
vrml2_faceset.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  *
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 
25 #include <iostream>
26 #include <sstream>
27 #include <wx/log.h>
28 
29 #include "vrml2_base.h"
30 #include "vrml2_faceset.h"
31 #include "vrml2_coords.h"
32 #include "vrml2_color.h"
33 #include "wrlfacet.h"
34 #include "plugins/3dapi/ifsg_all.h"
35 
36 
38 {
39  setDefaults();
41 
42  return;
43 }
44 
45 
47 {
48  setDefaults();
50  m_Parent = aParent;
51 
52  if( NULL != m_Parent )
53  m_Parent->AddChildNode( this );
54 
55  return;
56 }
57 
58 
60 {
61  #if defined( DEBUG_VRML2 ) && ( DEBUG_VRML2 > 2 )
62  do {
63  std::ostringstream ostr;
64  ostr << " * [INFO] Destroying IndexedFaceSet with " << m_Children.size();
65  ostr << " children, " << m_Refs.size() << " references and ";
66  ostr << m_BackPointers.size() << " backpointers";
67  wxLogTrace( MASK_VRML, "%s\n", ostr.str().c_str() );
68  } while( 0 );
69  #endif
70 
71  return;
72 }
73 
74 
76 {
77  color = NULL;
78  coord = NULL;
79  normal = NULL;
80  texCoord = NULL;
81 
82  ccw = true;
83  colorPerVertex = true;
84  convex = true;
85  normalPerVertex = true;
86  solid = true;
87 
88  creaseAngle = 0.733f; // approx 42 degrees; this is larger than VRML spec.
89  creaseLimit = 0.74317f; // cos( 0.733 )
90 }
91 
92 
94 {
95  // nodes must be one of:
96  // Color
97  // Coordinate
98  // Normal
99  // TextureCoordinate
100 
101  switch( aType )
102  {
103  case WRL2_COLOR:
104  case WRL2_COORDINATE:
105  case WRL2_NORMAL:
107  break;
108 
109  default:
110  return false;
111  break;
112  }
113 
114  return true;
115 }
116 
117 
119 {
120  // this node is dangling unless it has a parent of type WRL2_SHAPE
121 
122  if( NULL == m_Parent || m_Parent->GetNodeType() != WRL2_SHAPE )
123  return true;
124 
125  return false;
126 }
127 
128 
130 {
131  if( NULL == aNode )
132  {
133  #ifdef DEBUG_VRML2
134  do {
135  std::ostringstream ostr;
136  ostr << __FILE__ << ": " << __FUNCTION__ << ": " << __LINE__ << "\n";
137  ostr << " * [BUG] NULL passed for aNode";
138  wxLogTrace( MASK_VRML, "%s\n", ostr.str().c_str() );
139  } while( 0 );
140  #endif
141 
142  return false;
143  }
144 
145  WRL2NODES type = aNode->GetNodeType();
146 
147  if( !checkNodeType( type ) )
148  {
149  #if defined( DEBUG_VRML2 ) && ( DEBUG_VRML2 > 1 )
150  do {
151  std::ostringstream ostr;
152  ostr << __FILE__ << ": " << __FUNCTION__ << ": " << __LINE__ << "\n";
153  ostr << " * [INFO] bad file format; unexpected child node '";
154  ostr << aNode->GetNodeTypeName( type ) << "'";
155  wxLogTrace( MASK_VRML, "%s\n", ostr.str().c_str() );
156  } while( 0 );
157  #endif
158 
159  return false;
160  }
161 
162  if( WRL2_COLOR == type )
163  {
164  if( NULL != color )
165  {
166  #if defined( DEBUG_VRML2 ) && ( DEBUG_VRML2 > 1 )
167  do {
168  std::ostringstream ostr;
169  ostr << __FILE__ << ": " << __FUNCTION__ << ": " << __LINE__ << "\n";
170  ostr << " * [INFO] bad file format; multiple color nodes";
171  wxLogTrace( MASK_VRML, "%s\n", ostr.str().c_str() );
172  } while( 0 );
173  #endif
174 
175  return false;
176  }
177 
178  color = aNode;
179  return WRL2NODE::AddRefNode( aNode );
180  }
181 
182  if( WRL2_COORDINATE == type )
183  {
184  if( NULL != coord )
185  {
186  #if defined( DEBUG_VRML2 ) && ( DEBUG_VRML2 > 1 )
187  do {
188  std::ostringstream ostr;
189  ostr << __FILE__ << ": " << __FUNCTION__ << ": " << __LINE__ << "\n";
190  ostr << " * [INFO] bad file format; multiple coordinate nodes";
191  wxLogTrace( MASK_VRML, "%s\n", ostr.str().c_str() );
192  } while( 0 );
193  #endif
194 
195  return false;
196  }
197 
198  coord = aNode;
199  return WRL2NODE::AddRefNode( aNode );
200  }
201 
202  if( WRL2_NORMAL == type )
203  {
204  if( NULL != normal )
205  {
206  #if defined( DEBUG_VRML2 ) && ( DEBUG_VRML2 > 1 )
207  do {
208  std::ostringstream ostr;
209  ostr << __FILE__ << ": " << __FUNCTION__ << ": " << __LINE__ << "\n";
210  ostr << " * [INFO] bad file format; multiple normal nodes";
211  wxLogTrace( MASK_VRML, "%s\n", ostr.str().c_str() );
212  } while( 0 );
213  #endif
214 
215  return false;
216  }
217 
218  normal = aNode;
219  return WRL2NODE::AddRefNode( aNode );
220  }
221 
222  if( WRL2_TEXTURECOORDINATE != type )
223  {
224  #ifdef DEBUG_VRML2
225  do {
226  std::ostringstream ostr;
227  ostr << __FILE__ << ": " << __FUNCTION__ << ": " << __LINE__ << "\n";
228  ostr << " * [BUG] unexpected code branch";
229  wxLogTrace( MASK_VRML, "%s\n", ostr.str().c_str() );
230  } while( 0 );
231  #endif
232 
233  return false;
234  }
235 
236  if( NULL != texCoord )
237  {
238  #if defined( DEBUG_VRML2 ) && ( DEBUG_VRML2 > 1 )
239  do {
240  std::ostringstream ostr;
241  ostr << __FILE__ << ": " << __FUNCTION__ << ": " << __LINE__ << "\n";
242  ostr << " * [INFO] bad file format; multiple texCoord nodes";
243  wxLogTrace( MASK_VRML, "%s\n", ostr.str().c_str() );
244  } while( 0 );
245  #endif
246 
247  return false;
248  }
249 
250  texCoord = aNode;
251  return WRL2NODE::AddRefNode( aNode );
252 }
253 
254 
256 {
257  if( NULL == aNode )
258  {
259  #ifdef DEBUG_VRML2
260  do {
261  std::ostringstream ostr;
262  ostr << __FILE__ << ": " << __FUNCTION__ << ": " << __LINE__ << "\n";
263  ostr << " * [BUG] NULL passed for aNode";
264  wxLogTrace( MASK_VRML, "%s\n", ostr.str().c_str() );
265  } while( 0 );
266  #endif
267 
268  return false;
269  }
270 
271  WRL2NODES type = aNode->GetNodeType();
272 
273  if( !checkNodeType( type ) )
274  {
275  #if defined( DEBUG_VRML2 ) && ( DEBUG_VRML2 > 1 )
276  do {
277  std::ostringstream ostr;
278  ostr << __FILE__ << ": " << __FUNCTION__ << ": " << __LINE__ << "\n";
279  ostr << " * [INFO] bad file format; unexpected child node '";
280  ostr << aNode->GetNodeTypeName( type ) << "'";
281  wxLogTrace( MASK_VRML, "%s\n", ostr.str().c_str() );
282  } while( 0 );
283  #endif
284 
285  return false;
286  }
287 
288  if( WRL2_COLOR == type )
289  {
290  if( NULL != color )
291  {
292  #if defined( DEBUG_VRML2 ) && ( DEBUG_VRML2 > 1 )
293  do {
294  std::ostringstream ostr;
295  ostr << __FILE__ << ": " << __FUNCTION__ << ": " << __LINE__ << "\n";
296  ostr << " * [INFO] bad file format; multiple color nodes";
297  wxLogTrace( MASK_VRML, "%s\n", ostr.str().c_str() );
298  } while( 0 );
299  #endif
300 
301  return false;
302  }
303 
304  color = aNode;
305  return WRL2NODE::AddChildNode( aNode );
306  }
307 
308  if( WRL2_COORDINATE == type )
309  {
310  if( NULL != coord )
311  {
312  #if defined( DEBUG_VRML2 ) && ( DEBUG_VRML2 > 1 )
313  do {
314  std::ostringstream ostr;
315  ostr << __FILE__ << ": " << __FUNCTION__ << ": " << __LINE__ << "\n";
316  ostr << " * [INFO] bad file format; multiple coordinate nodes";
317  wxLogTrace( MASK_VRML, "%s\n", ostr.str().c_str() );
318  } while( 0 );
319  #endif
320 
321  return false;
322  }
323 
324  coord = aNode;
325  return WRL2NODE::AddChildNode( aNode );
326  }
327 
328  if( WRL2_NORMAL == type )
329  {
330  if( NULL != normal )
331  {
332  #if defined( DEBUG_VRML2 ) && ( DEBUG_VRML2 > 1 )
333  do {
334  std::ostringstream ostr;
335  ostr << __FILE__ << ": " << __FUNCTION__ << ": " << __LINE__ << "\n";
336  ostr << " * [INFO] bad file format; multiple normal nodes";
337  wxLogTrace( MASK_VRML, "%s\n", ostr.str().c_str() );
338  } while( 0 );
339  #endif
340 
341  return false;
342  }
343 
344  normal = aNode;
345  return WRL2NODE::AddChildNode( aNode );
346  }
347 
348  if( WRL2_TEXTURECOORDINATE != type )
349  {
350  #ifdef DEBUG_VRML2
351  do {
352  std::ostringstream ostr;
353  ostr << __FILE__ << ": " << __FUNCTION__ << ": " << __LINE__ << "\n";
354  ostr << " * [BUG] unexpected code branch";
355  wxLogTrace( MASK_VRML, "%s\n", ostr.str().c_str() );
356  } while( 0 );
357  #endif
358 
359  return false;
360  }
361 
362  if( NULL != texCoord )
363  {
364  #if defined( DEBUG_VRML2 ) && ( DEBUG_VRML2 > 1 )
365  do {
366  std::ostringstream ostr;
367  ostr << __FILE__ << ": " << __FUNCTION__ << ": " << __LINE__ << "\n";
368  ostr << " * [INFO] bad file format; multiple texCoord nodes";
369  wxLogTrace( MASK_VRML, "%s\n", ostr.str().c_str() );
370  } while( 0 );
371  #endif
372 
373  return false;
374  }
375 
376  texCoord = aNode;
377  return WRL2NODE::AddChildNode( aNode );
378 }
379 
380 
381 
382 bool WRL2FACESET::Read( WRLPROC& proc, WRL2BASE* aTopNode )
383 {
384  size_t line, column;
385  proc.GetFilePosData( line, column );
386 
387  char tok = proc.Peek();
388 
389  if( proc.eof() )
390  {
391  #if defined( DEBUG_VRML2 ) && ( DEBUG_VRML2 > 1 )
392  do {
393  std::ostringstream ostr;
394  ostr << __FILE__ << ": " << __FUNCTION__ << ": " << __LINE__ << "\n";
395  ostr << " * [INFO] bad file format; unexpected eof at line ";
396  ostr << line << ", column " << column;
397  wxLogTrace( MASK_VRML, "%s\n", ostr.str().c_str() );
398  } while( 0 );
399  #endif
400 
401  return false;
402  }
403 
404  if( '{' != tok )
405  {
406  #if defined( DEBUG_VRML2 ) && ( DEBUG_VRML2 > 1 )
407  do {
408  std::ostringstream ostr;
409  ostr << proc.GetError() << "\n";
410  ostr << __FILE__ << ": " << __FUNCTION__ << ": " << __LINE__ << "\n";
411  ostr << " * [INFO] bad file format; expecting '{' but got '" << tok;
412  ostr << "' at line " << line << ", column " << column;
413  wxLogTrace( MASK_VRML, "%s\n", ostr.str().c_str() );
414  } while( 0 );
415  #endif
416 
417  return false;
418  }
419 
420  proc.Pop();
421  std::string glob;
422 
423  while( true )
424  {
425  if( proc.Peek() == '}' )
426  {
427  proc.Pop();
428  break;
429  }
430 
431  if( !proc.ReadName( glob ) )
432  {
433  #if defined( DEBUG_VRML2 ) && ( DEBUG_VRML2 > 1 )
434  do {
435  std::ostringstream ostr;
436  ostr << __FILE__ << ": " << __FUNCTION__ << ": " << __LINE__ << "\n";
437  ostr << proc.GetError();
438  wxLogTrace( MASK_VRML, "%s\n", ostr.str().c_str() );
439  } while( 0 );
440  #endif
441 
442  return false;
443  }
444 
445  // expecting one of:
446  // [node]
447  // color
448  // coord
449  // normal
450  // texCoord
451  // [bool]
452  // ccw
453  // colorPerVertex
454  // convex
455  // normalPerVertex
456  // solid
457  // [ vector<int> ]
458  // colorIndex
459  // coordIndex
460  // normalIndex;
461  // [float]
462  // creaseAngle
463 
464  proc.GetFilePosData( line, column );
465 
466  if( !glob.compare( "ccw" ) )
467  {
468  if( !proc.ReadSFBool( ccw ) )
469  {
470  #if defined( DEBUG_VRML2 ) && ( DEBUG_VRML2 > 1 )
471  do {
472  std::ostringstream ostr;
473  ostr << __FILE__ << ": " << __FUNCTION__ << ": " << __LINE__ << "\n";
474  ostr << " * [INFO] invalid ccw at line " << line << ", column ";
475  ostr << column << "\n";
476  ostr << " * [INFO] file: '" << proc.GetFileName() << "'\n";
477  ostr << " * [INFO] message: '" << proc.GetError() << "'";
478  wxLogTrace( MASK_VRML, "%s\n", ostr.str().c_str() );
479  } while( 0 );
480  #endif
481 
482  return false;
483  }
484  }
485  else if( !glob.compare( "colorPerVertex" ) )
486  {
487  if( !proc.ReadSFBool( colorPerVertex ) )
488  {
489  #if defined( DEBUG_VRML2 ) && ( DEBUG_VRML2 > 1 )
490  do {
491  std::ostringstream ostr;
492  ostr << __FILE__ << ": " << __FUNCTION__ << ": " << __LINE__ << "\n";
493  ostr << " * [INFO] invalid colorPerVertex at line " << line << ", column ";
494  ostr << column << "\n";
495  ostr << " * [INFO] file: '" << proc.GetFileName() << "'\n";
496  ostr << " * [INFO] message: '" << proc.GetError() << "'";
497  wxLogTrace( MASK_VRML, "%s\n", ostr.str().c_str() );
498  } while( 0 );
499  #endif
500 
501  return false;
502  }
503  }
504  else if( !glob.compare( "convex" ) )
505  {
506  if( !proc.ReadSFBool( convex ) )
507  {
508  #if defined( DEBUG_VRML2 ) && ( DEBUG_VRML2 > 1 )
509  do {
510  std::ostringstream ostr;
511  ostr << __FILE__ << ": " << __FUNCTION__ << ": " << __LINE__ << "\n";
512  ostr << " * [INFO] invalid convex at line " << line << ", column ";
513  ostr << column << "\n";
514  ostr << " * [INFO] file: '" << proc.GetFileName() << "'\n";
515  ostr << " * [INFO] message: '" << proc.GetError() << "'";
516  wxLogTrace( MASK_VRML, "%s\n", ostr.str().c_str() );
517  } while( 0 );
518  #endif
519 
520  return false;
521  }
522  }
523  else if( !glob.compare( "normalPerVertex" ) )
524  {
525  if( !proc.ReadSFBool( normalPerVertex ) )
526  {
527  #if defined( DEBUG_VRML2 ) && ( DEBUG_VRML2 > 1 )
528  do {
529  std::ostringstream ostr;
530  ostr << __FILE__ << ": " << __FUNCTION__ << ": " << __LINE__ << "\n";
531  ostr << " * [INFO] invalid normalPerVertex at line " << line << ", column ";
532  ostr << column << "\n";
533  ostr << " * [INFO] file: '" << proc.GetFileName() << "'\n";
534  ostr << " * [INFO] message: '" << proc.GetError() << "'";
535  wxLogTrace( MASK_VRML, "%s\n", ostr.str().c_str() );
536  } while( 0 );
537  #endif
538 
539  return false;
540  }
541  }
542  else if( !glob.compare( "solid" ) )
543  {
544  if( !proc.ReadSFBool( solid ) )
545  {
546  #if defined( DEBUG_VRML2 ) && ( DEBUG_VRML2 > 1 )
547  do {
548  std::ostringstream ostr;
549  ostr << __FILE__ << ": " << __FUNCTION__ << ": " << __LINE__ << "\n";
550  ostr << " * [INFO] invalid solid at line " << line << ", column ";
551  ostr << column << "\n";
552  ostr << " * [INFO] file: '" << proc.GetFileName() << "'\n";
553  ostr << " * [INFO] message: '" << proc.GetError() << "'";
554  wxLogTrace( MASK_VRML, "%s\n", ostr.str().c_str() );
555  } while( 0 );
556  #endif
557 
558  return false;
559  }
560  }
561  else if( !glob.compare( "creaseAngle" ) )
562  {
563  if( !proc.ReadSFFloat( creaseAngle ) )
564  {
565  #if defined( DEBUG_VRML2 ) && ( DEBUG_VRML2 > 1 )
566  do {
567  std::ostringstream ostr;
568  ostr << __FILE__ << ": " << __FUNCTION__ << ": " << __LINE__ << "\n";
569  ostr << " * [INFO] invalid creaseAngle at line " << line << ", column ";
570  ostr << column << "\n";
571  ostr << " * [INFO] file: '" << proc.GetFileName() << "'\n";
572  ostr << " * [INFO] message: '" << proc.GetError() << "'\n";
573  wxLogTrace( MASK_VRML, "%s\n", ostr.str().c_str() );
574  } while( 0 );
575  #endif
576 
577  return false;
578  }
579 
580  if( creaseAngle < 0.0 )
581  creaseAngle = 0.0f;
582  else if( creaseAngle > M_PI_2 )
583  creaseAngle = static_cast<float>( M_PI_2 );
584 
585  creaseLimit = cosf( creaseAngle );
586  }
587  else if( !glob.compare( "colorIndex" ) )
588  {
589  if( !proc.ReadMFInt( colorIndex ) )
590  {
591  #if defined( DEBUG_VRML2 ) && ( DEBUG_VRML2 > 1 )
592  do {
593  std::ostringstream ostr;
594  ostr << __FILE__ << ": " << __FUNCTION__ << ": " << __LINE__ << "\n";
595  ostr << " * [INFO] invalid colorIndex at line " << line << ", column ";
596  ostr << column << "\n";
597  ostr << " * [INFO] file: '" << proc.GetFileName() << "'\n";
598  ostr << " * [INFO] message: '" << proc.GetError() << "'";
599  wxLogTrace( MASK_VRML, "%s\n", ostr.str().c_str() );
600  } while( 0 );
601  #endif
602 
603  return false;
604  }
605  }
606  else if( !glob.compare( "coordIndex" ) )
607  {
608  if( !proc.ReadMFInt( coordIndex ) )
609  {
610  #if defined( DEBUG_VRML2 ) && ( DEBUG_VRML2 > 1 )
611  do {
612  std::ostringstream ostr;
613  ostr << __FILE__ << ": " << __FUNCTION__ << ": " << __LINE__ << "\n";
614  ostr << " * [INFO] invalid coordIndex at line " << line << ", column ";
615  ostr << column << "\n";
616  ostr << " * [INFO] file: '" << proc.GetFileName() << "'\n";
617  ostr << " * [INFO] message: '" << proc.GetError() << "'";
618  wxLogTrace( MASK_VRML, "%s\n", ostr.str().c_str() );
619  } while( 0 );
620  #endif
621 
622  return false;
623  }
624  }
625  else if( !glob.compare( "normalIndex" ) )
626  {
627  if( !proc.ReadMFInt( normalIndex ) )
628  {
629  #if defined( DEBUG_VRML2 ) && ( DEBUG_VRML2 > 1 )
630  do {
631  std::ostringstream ostr;
632  ostr << __FILE__ << ": " << __FUNCTION__ << ": " << __LINE__ << "\n";
633  ostr << " * [INFO] invalid normalIndex at line " << line << ", column ";
634  ostr << column << "\n";
635  ostr << " * [INFO] file: '" << proc.GetFileName() << "'\n";
636  ostr << " * [INFO] message: '" << proc.GetError() << "'";
637  wxLogTrace( MASK_VRML, "%s\n", ostr.str().c_str() );
638  } while( 0 );
639  #endif
640 
641  return false;
642  }
643  }
644  else if( !glob.compare( "color" ) )
645  {
646  if( !aTopNode->ReadNode( proc, this, NULL ) )
647  {
648  #if defined( DEBUG_VRML2 ) && ( DEBUG_VRML2 > 1 )
649  do {
650  std::ostringstream ostr;
651  ostr << __FILE__ << ": " << __FUNCTION__ << ": " << __LINE__ << "\n";
652  ostr << " * [INFO] could not read color node information";
653  wxLogTrace( MASK_VRML, "%s\n", ostr.str().c_str() );
654  } while( 0 );
655  #endif
656 
657  return false;
658  }
659  }
660  else if( !glob.compare( "coord" ) )
661  {
662  if( !aTopNode->ReadNode( proc, this, NULL ) )
663  {
664  #if defined( DEBUG_VRML2 ) && ( DEBUG_VRML2 > 1 )
665  do {
666  std::ostringstream ostr;
667  ostr << __FILE__ << ": " << __FUNCTION__ << ": " << __LINE__ << "\n";
668  ostr << " * [INFO] could not read coord node information";
669  wxLogTrace( MASK_VRML, "%s\n", ostr.str().c_str() );
670  } while( 0 );
671  #endif
672 
673  return false;
674  }
675  }
676  else if( !glob.compare( "normal" ) )
677  {
678  if( !aTopNode->ReadNode( proc, this, NULL ) )
679  {
680  #if defined( DEBUG_VRML2 ) && ( DEBUG_VRML2 > 1 )
681  do {
682  std::ostringstream ostr;
683  ostr << __FILE__ << ": " << __FUNCTION__ << ": " << __LINE__ << "\n";
684  ostr << " * [INFO] could not read normal node information";
685  wxLogTrace( MASK_VRML, "%s\n", ostr.str().c_str() );
686  } while( 0 );
687  #endif
688 
689  return false;
690  }
691  }
692  else if( !glob.compare( "texCoord" ) )
693  {
694  if( !aTopNode->ReadNode( proc, this, NULL ) )
695  {
696  #if defined( DEBUG_VRML2 ) && ( DEBUG_VRML2 > 1 )
697  do {
698  std::ostringstream ostr;
699  ostr << __FILE__ << ": " << __FUNCTION__ << ": " << __LINE__ << "\n";
700  ostr << " * [INFO] could not read texCoord node information";
701  wxLogTrace( MASK_VRML, "%s\n", ostr.str().c_str() );
702  } while( 0 );
703  #endif
704 
705  return false;
706  }
707  }
708  else
709  {
710  #if defined( DEBUG_VRML2 ) && ( DEBUG_VRML2 > 1 )
711  do {
712  std::ostringstream ostr;
713  ostr << __FILE__ << ": " << __FUNCTION__ << ": " << __LINE__ << "\n";
714  ostr << " * [INFO] bad IndexedFaceSet at line " << line << ", column ";
715  ostr << column << "\n";
716  ostr << " * [INFO] file: '" << proc.GetFileName() << "'";
717  wxLogTrace( MASK_VRML, "%s\n", ostr.str().c_str() );
718  } while( 0 );
719  #endif
720 
721  return false;
722  }
723  } // while( true ) -- reading contents of IndexedFaceSet{}
724 
725  return true;
726 }
727 
728 
730 {
731  S3D::SGTYPES ptype = S3D::GetSGNodeType( aParent );
732 
733  if( NULL != aParent && ptype != S3D::SGTYPE_SHAPE )
734  {
735  #ifdef DEBUG_VRML2
736  do {
737  std::ostringstream ostr;
738  ostr << __FILE__ << ": " << __FUNCTION__ << ": " << __LINE__ << "\n";
739  ostr << " * [BUG] IndexedFaceSet does not have a Shape parent (parent ID: ";
740  ostr << ptype << ")";
741  wxLogTrace( MASK_VRML, "%s\n", ostr.str().c_str() );
742  } while( 0 );
743  #endif
744 
745  return NULL;
746  }
747 
748  #if defined( DEBUG_VRML2 ) && ( DEBUG_VRML2 > 2 )
749  do {
750  std::ostringstream ostr;
751  ostr << " * [INFO] Translating IndexedFaceSet with " << m_Children.size();
752  ostr << " children, " << m_Refs.size() << " references, ";
753  ostr << m_BackPointers.size() << " backpointers and ";
754  ostr << coordIndex.size() << " coord indices";
755  wxLogTrace( MASK_VRML, "%s\n", ostr.str().c_str() );
756  } while( 0 );
757  #endif
758 
759  if( m_sgNode )
760  {
761  if( NULL != aParent )
762  {
764  && !S3D::AddSGNodeChild( aParent, m_sgNode ) )
765  {
766  return NULL;
767  }
768  else if( aParent != S3D::GetSGNodeParent( m_sgNode )
769  && !S3D::AddSGNodeRef( aParent, m_sgNode ) )
770  {
771  return NULL;
772  }
773  }
774 
775  return m_sgNode;
776  }
777 
778  size_t vsize = coordIndex.size();
779 
780  if( NULL == coord || vsize < 3 )
781  return NULL;
782 
783  WRLVEC3F* pcoords;
784  size_t coordsize;
785  ((WRL2COORDS*) coord)->GetCoords( pcoords, coordsize );
786 
787  if( coordsize < 3 )
788  return NULL;
789 
790  // check that all indices are valid
791  for( size_t idx = 0; idx < vsize; ++idx )
792  {
793  if( coordIndex[idx] < 0 )
794  continue;
795 
796  if( coordIndex[idx] >= (int)coordsize )
797  return NULL;
798  }
799 
800  SHAPE lShape;
801  FACET* fp = NULL;
802  size_t iCoord;
803  int idx; // coordinate index
804  size_t cidx = 0; // color index
805  SGCOLOR pc1;
806 
807  if( NULL == color )
808  {
809  // no per-vertex colors; we can save a few CPU cycles
810  for( iCoord = 0; iCoord < vsize; ++iCoord )
811  {
812  idx = coordIndex[iCoord];
813 
814  if( idx < 0 )
815  {
816  if( NULL != fp )
817  {
818  if( fp->HasMinPoints() )
819  fp = NULL;
820  else
821  fp->Init();
822  }
823 
824  continue;
825  }
826 
827  // if the coordinate is bad then skip it
828  if( idx >= (int)coordsize )
829  continue;
830 
831  if( NULL == fp )
832  fp = lShape.NewFacet();
833 
834  // push the vertex value and index
835  fp->AddVertex( pcoords[idx], idx );
836  }
837  }
838  else
839  {
840  WRL2COLOR* cn = (WRL2COLOR*) color;
841  WRLVEC3F tc;
842 
843  for( iCoord = 0; iCoord < vsize; ++iCoord )
844  {
845  idx = coordIndex[iCoord];
846 
847  if( idx < 0 )
848  {
849  if( NULL != fp )
850  {
851  if( fp->HasMinPoints() )
852  fp = NULL;
853  else
854  fp->Init();
855  }
856 
857  if( !colorPerVertex )
858  ++cidx;
859 
860  continue;
861  }
862 
863  // if the coordinate is bad then skip it
864  if( idx >= (int)coordsize )
865  continue;
866 
867  if( NULL == fp )
868  fp = lShape.NewFacet();
869 
870  // push the vertex value and index
871  fp->AddVertex( pcoords[idx], idx );
872 
873  // push the color if appropriate
874  if( !colorPerVertex )
875  {
876  if( colorIndex.empty() )
877  {
878  cn->GetColor( cidx, tc.x, tc.y, tc.z );
879  pc1.SetColor( tc.x, tc.y, tc.z );
880  fp->AddColor( pc1 );
881  }
882  else
883  {
884  if( cidx < colorIndex.size() )
885  cn->GetColor( colorIndex[cidx], tc.x, tc.y, tc.z );
886  else
887  cn->GetColor( colorIndex.back(), tc.x, tc.y, tc.z );
888 
889  pc1.SetColor( tc.x, tc.y, tc.z );
890  fp->AddColor( pc1 );
891  }
892  }
893  else
894  {
895  if( colorIndex.empty() )
896  {
897  cn->GetColor( idx, tc.x, tc.y, tc.z );
898  pc1.SetColor( tc.x, tc.y, tc.z );
899  fp->AddColor( pc1 );
900  }
901  else
902  {
903  if( iCoord < colorIndex.size() )
904  cn->GetColor( colorIndex[iCoord], tc.x, tc.y, tc.z );
905  else
906  cn->GetColor( colorIndex.back(), tc.x, tc.y, tc.z );
907 
908  pc1.SetColor( tc.x, tc.y, tc.z );
909  fp->AddColor( pc1 );
910  }
911  }
912  }
913  }
914 
915  SGNODE* np = NULL;
916 
917  if( ccw )
918  np = lShape.CalcShape( aParent, NULL, ORD_CCW, creaseLimit, true );
919  else
920  np = lShape.CalcShape( aParent, NULL, ORD_CLOCKWISE, creaseLimit, true );
921 
922  return np;
923 }
924 
925 
927 {
928  if( NULL == aNode )
929  return;
930 
931  if( aNode->GetParent() == this )
932  {
933  if( aNode == color )
934  color = NULL;
935  else if( aNode == coord )
936  coord = NULL;
937  else if( aNode == normal )
938  normal = NULL;
939  else if( aNode == texCoord )
940  texCoord = NULL;
941 
942  }
943 
944  WRL2NODE::unlinkChildNode( aNode );
945  return;
946 }
947 
948 
950 {
951  if( NULL == aNode )
952  return;
953 
954  if( aNode->GetParent() != this )
955  {
956  if( aNode == color )
957  color = NULL;
958  else if( aNode == coord )
959  coord = NULL;
960  else if( aNode == normal )
961  normal = NULL;
962  else if( aNode == texCoord )
963  texCoord = NULL;
964 
965  }
966 
967  WRL2NODE::unlinkRefNode( aNode );
968  return;
969 }
970 
971 
973 {
974  if( NULL == color )
975  return false;
976 
977  return ((WRL2COLOR*) color)->HasColors();
978 }
SGNODE * CalcShape(SGNODE *aParent, SGNODE *aColor, WRL1_ORDER aVertexOrder, float aCreaseLimit=0.74317, bool isVRML2=false)
Definition: wrlfacet.cpp:713
bool isDangling(void) override
Function isDangling returns true if the object does not have a parent which is a logical container fo...
void Pop(void)
Definition: wrlproc.cpp:2007
WRL2COORDS.
Definition: vrml2_coords.h:42
WRL2NODE represents the base class of all VRML2 nodes.
Definition: vrml2_node.h:58
glm::vec3 WRLVEC3F
Definition: wrltypes.h:185
std::list< WRL2NODE * > m_Children
Definition: vrml2_node.h:66
bool HasColors(void)
Function HasColors returns true if the face set has a color node.
bool Read(WRLPROC &proc, WRL2BASE *aTopNode) override
bool GetFilePosData(size_t &line, size_t &column)
Definition: wrlproc.cpp:1951
#define MASK_VRML
Definition: wrltypes.h:37
std::vector< int > coordIndex
Definition: vrml2_faceset.h:57
#define M_PI_2
Definition: transline.cpp:36
bool AddChildNode(WRL2NODE *aNode) override
bool colorPerVertex
Definition: vrml2_faceset.h:51
void AddVertex(WRLVEC3F &aVertex, int aIndex)
Function AddVertex adds the vertex and its associated index to the internal list of polygon vertices.
Definition: wrlfacet.cpp:193
void Init()
Definition: wrlfacet.cpp:158
std::list< WRL2NODE * > m_Refs
Definition: vrml2_node.h:67
SGLIB_API SGNODE * GetSGNodeParent(SGNODE *aNode)
Definition: ifsg_api.cpp:636
WRL2NODE * normal
Definition: vrml2_faceset.h:47
bool ReadMFInt(std::vector< int > &aMFInt32)
Definition: wrlproc.cpp:1488
bool SetColor(float aRedVal, float aGreenVal, float aBlueVal)
Definition: sg_base.cpp:104
WRL2NODES m_Type
Definition: vrml2_node.h:62
void unlinkChildNode(const WRL2NODE *aNode) override
Function unlinkChild removes references to an owned child; it is invoked by the child upon destructio...
SGNODE represents the base class of all Scene Graph nodes.
Definition: sg_node.h:76
collects header files for all SG* wrappers and the API
WRL2NODE * texCoord
Definition: vrml2_faceset.h:48
SGLIB_API bool AddSGNodeRef(SGNODE *aParent, SGNODE *aChild)
Definition: ifsg_api.cpp:645
bool ReadNode(WRLPROC &proc, WRL2NODE *aParent, WRL2NODE **aNode)
Definition: vrml2_base.cpp:371
SGNODE * TranslateToSG(SGNODE *aParent) override
Function TranslateToSG produces a representation of the data using the intermediate scenegraph struct...
WRL2NODE * coord
Definition: vrml2_faceset.h:46
declares classes to help manage normals calculations from VRML files
void AddColor(const SGCOLOR &aColor)
Function AddColor adds the given RGB color to the internal list.
Definition: wrlfacet.cpp:208
float creaseLimit
Definition: vrml2_faceset.h:61
float creaseAngle
Definition: vrml2_faceset.h:60
#define NULL
std::vector< int > colorIndex
Definition: vrml2_faceset.h:56
bool checkNodeType(WRL2NODES aType)
Function checkNodeType returns true if the node type is a valid subnode of FaceSet.
void unlinkRefNode(const WRL2NODE *aNode) override
Function unlinkRef removes pointers to a referenced node; it is invoked by the referenced node upon d...
WRL2NODE * m_Parent
Definition: vrml2_node.h:61
SGLIB_API bool AddSGNodeChild(SGNODE *aParent, SGNODE *aChild)
Definition: ifsg_api.cpp:654
bool ReadSFFloat(float &aSFFloat)
Definition: wrlproc.cpp:789
SGNODE * m_sgNode
Definition: vrml2_node.h:70
std::list< WRL2NODE * > m_BackPointers
Definition: vrml2_node.h:65
SHAPE.
Definition: shape.h:60
void GetColor(int aIndex, float &red, float &green, float &blue)
Function GetColor retrieves the given color (or default 0.8, 0.8, 0.8 if index is invalid)
bool normalPerVertex
Definition: vrml2_faceset.h:53
bool ReadSFBool(bool &aSFBool)
Definition: wrlproc.cpp:720
WRL2NODES GetNodeType(void) const
Function GetNodeType returns the type of this node instance.
Definition: vrml2_node.cpp:212
char Peek(void)
Definition: wrlproc.cpp:1979
std::string GetFileName(void)
Definition: wrlproc.cpp:1967
WRL2BASE represents the top node of a VRML2 model.
Definition: vrml2_base.h:59
const char * GetNodeTypeName(WRL2NODES aNodeType) const
Definition: vrml2_node.cpp:295
WRL2COLOR.
Definition: vrml2_color.h:42
SGTYPES
Definition: sg_types.h:34
virtual ~WRL2FACESET()
SGLIB_API S3D::SGTYPES GetSGNodeType(SGNODE *aNode)
Definition: ifsg_api.cpp:627
void setDefaults(void)
FACET * NewFacet()
Definition: wrlfacet.cpp:705
Definition: wrlfacet.h:41
virtual bool AddChildNode(WRL2NODE *aNode)
Definition: vrml2_node.cpp:377
bool ReadName(std::string &aName)
Definition: wrlproc.cpp:280
virtual void unlinkRefNode(const WRL2NODE *aNode)
Function unlinkRef removes pointers to a referenced node; it is invoked by the referenced node upon d...
Definition: vrml2_node.cpp:484
WRL2NODE * GetParent(void) const
Function GetParent returns a pointer to the parent SGNODE of this object or NULL if the object has no...
Definition: vrml2_node.cpp:218
WRL2NODES
Definition: wrltypes.h:121
std::vector< int > normalIndex
Definition: vrml2_faceset.h:58
std::string GetError(void)
Definition: wrlproc.cpp:1945
virtual void unlinkChildNode(const WRL2NODE *aNode)
Function unlinkChild removes references to an owned child; it is invoked by the child upon destructio...
Definition: vrml2_node.cpp:464
virtual bool AddRefNode(WRL2NODE *aNode)
Definition: vrml2_node.cpp:416
bool eof(void)
Definition: wrlproc.cpp:1939
WRL2NODE * color
Definition: vrml2_faceset.h:45
bool AddRefNode(WRL2NODE *aNode) override
bool HasMinPoints()
Definition: wrlfacet.cpp:175