KiCad PCB EDA Suite
vrml2_base.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-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 #include <iostream>
25 #include <sstream>
26 #include <utility>
27 #include <wx/string.h>
28 #include <wx/filename.h>
29 #include <wx/log.h>
30 
31 #include "vrml2_base.h"
32 #include "vrml2_transform.h"
33 #include "vrml2_shape.h"
34 #include "vrml2_appearance.h"
35 #include "vrml2_material.h"
36 #include "vrml2_faceset.h"
37 #include "vrml2_lineset.h"
38 #include "vrml2_pointset.h"
39 #include "vrml2_coords.h"
40 #include "vrml2_norms.h"
41 #include "vrml2_color.h"
42 #include "vrml2_box.h"
43 #include "vrml2_switch.h"
44 #include "vrml2_inline.h"
45 #include "plugins/3dapi/ifsg_all.h"
46 
47 
48 SCENEGRAPH* LoadVRML( const wxString& aFileName, bool useInline );
49 
51 {
52  m_useInline = false;
53  m_Type = WRL2_BASE;
54  return;
55 }
56 
57 
59 {
60  std::map< std::string, SGNODE* >::iterator iS = m_inlineModels.begin();
61  std::map< std::string, SGNODE* >::iterator eS = m_inlineModels.end();
62 
63  while( iS != eS )
64  {
65  SGNODE* np = iS->second;
66 
67  // destroy any orphaned Inline{} node data
68  if( np && NULL == S3D::GetSGNodeParent( np ) )
69  S3D::DestroyNode( np );
70 
71  ++iS;
72  }
73 
74  m_inlineModels.clear();
75 
76  return;
77 }
78 
79 
80 // functions inherited from WRL2NODE
81 bool WRL2BASE::SetParent( WRL2NODE* aParent, bool /* doUnlink */ )
82 {
83  #ifdef DEBUG_VRML2
84  do {
85  std::ostringstream ostr;
86  ostr << __FILE__ << ": " << __FUNCTION__ << ": " << __LINE__ << "\n";
87  ostr << " * [BUG] attempting to set parent on WRL2BASE node";
88  wxLogTrace( MASK_VRML, "%s\n", ostr.str().c_str() );
89  } while( 0 );
90  #endif
91 
92  return false;
93 }
94 
95 
96 void WRL2BASE::SetEnableInline( bool enable )
97 {
98  m_useInline = enable;
99  return;
100 }
101 
102 
104 {
105  return m_useInline;
106 }
107 
108 
109 SGNODE* WRL2BASE::GetInlineData( const std::string& aName )
110 {
111  if( aName.empty() )
112  return NULL;
113 
114  std::map< std::string, SGNODE* >::iterator dp = m_inlineModels.find( aName );
115 
116  if( dp != m_inlineModels.end() )
117  return dp->second;
118 
119  wxString tname;
120 
121  if( aName.compare( 0, 7, "file://" ) == 0 )
122  {
123  if( aName.length() <= 7 )
124  return NULL;
125 
126  tname = wxString::FromUTF8Unchecked( aName.substr( 7 ).c_str() );
127  }
128  else
129  {
130  tname = wxString::FromUTF8Unchecked( aName.c_str() );
131  }
132 
133  wxFileName fn;
134  fn.Assign( tname );
135 
136  if( fn.IsRelative() && !m_dir.empty() )
137  {
138  wxString fname = wxString::FromUTF8Unchecked( m_dir.c_str() );
139  fname.append( tname );
140  fn.Assign( fname );
141  }
142 
143  if( !fn.Normalize() )
144  {
145  m_inlineModels.insert( std::pair< std::string, SGNODE* >( aName, NULL ) );
146  return NULL;
147  }
148 
149  SCENEGRAPH* sp = LoadVRML( fn.GetFullPath(), false );
150 
151  if( NULL == sp )
152  {
153  m_inlineModels.insert( std::pair< std::string, SGNODE* >( aName, NULL ) );
154  return NULL;
155  }
156 
157  m_inlineModels.insert( std::pair< std::string, SGNODE* >( aName, (SGNODE*)sp ) );
158 
159  return (SGNODE*)sp;
160 }
161 
162 
163 std::string WRL2BASE::GetName( void )
164 {
165  #ifdef DEBUG_VRML2
166  do {
167  std::ostringstream ostr;
168  ostr << __FILE__ << ": " << __FUNCTION__ << ": " << __LINE__ << "\n";
169  ostr << " * [BUG] attempting to extract name from virtual base node";
170  wxLogTrace( MASK_VRML, "%s\n", ostr.str().c_str() );
171  } while( 0 );
172  #endif
173 
174  return std::string( "" );
175 }
176 
177 
178 bool WRL2BASE::SetName( const std::string& aName )
179 {
180  #ifdef DEBUG_VRML2
181  do {
182  std::ostringstream ostr;
183  ostr << __FILE__ << ": " << __FUNCTION__ << ": " << __LINE__ << "\n";
184  ostr << " * [BUG] attempting to set name on virtual base node";
185  wxLogTrace( MASK_VRML, "%s\n", ostr.str().c_str() );
186  } while( 0 );
187  #endif
188 
189  return false;
190 }
191 
192 
193 bool WRL2BASE::Read( WRLPROC& proc )
194 {
195  if( proc.GetVRMLType() != VRML_V2 )
196  {
197  #ifdef DEBUG_VRML2
198  do {
199  std::ostringstream ostr;
200  ostr << __FILE__ << ": " << __FUNCTION__ << ": " << __LINE__ << "\n";
201  ostr << " * [BUG] no open file or file is not a VRML2 file";
202  wxLogTrace( MASK_VRML, "%s\n", ostr.str().c_str() );
203  } while( 0 );
204  #endif
205 
206  return false;
207  }
208 
209  WRL2NODE* node = NULL;
210  m_dir = proc.GetParentDir();
211 
212  while( ReadNode( proc, this, &node ) && !proc.eof() );
213 
214  if( proc.eof() )
215  return true;
216 
217  return false;
218 }
219 
220 
222 {
223  // the base node is never dangling
224  return false;
225 }
226 
227 
228 bool WRL2BASE::implementUse( WRLPROC& proc, WRL2NODE* aParent, WRL2NODE** aNode )
229 {
230  if( NULL != aNode )
231  *aNode = NULL;
232 
233  if( !aParent )
234  {
235  #ifdef DEBUG_VRML2
236  do {
237  std::ostringstream ostr;
238  ostr << __FILE__ << ": " << __FUNCTION__ << ": " << __LINE__ << "\n";
239  ostr << " * [BUG] invoked with NULL parent";
240  wxLogTrace( MASK_VRML, "%s\n", ostr.str().c_str() );
241  } while( 0 );
242  #endif
243 
244  return false;
245  }
246 
247  std::string glob;
248 
249  if( !proc.ReadName( glob ) )
250  {
251  #if defined( DEBUG_VRML2 ) && ( DEBUG_VRML2 > 1 )
252  do {
253  std::ostringstream ostr;
254  ostr << __FILE__ << ": " << __FUNCTION__ << ": " << __LINE__ << "\n";
255  ostr << proc.GetError();
256  wxLogTrace( MASK_VRML, "%s\n", ostr.str().c_str() );
257  } while( 0 );
258  #endif
259 
260  return false;
261  }
262 
263  WRL2NODE* ref = aParent->FindNode( glob, NULL );
264 
265  // return 'true' - the file may be defective but it may still be somewhat OK
266  if( NULL == ref )
267  {
268  #if defined( DEBUG_VRML2 ) && ( DEBUG_VRML2 > 1 )
269  do {
270  std::ostringstream ostr;
271  ostr << __FILE__ << ": " << __FUNCTION__ << ": " << __LINE__ << "\n";
272  ostr << " * [INFO] node '" << glob << "' not found";
273  wxLogTrace( MASK_VRML, "%s\n", ostr.str().c_str() );
274  } while( 0 );
275  #endif
276 
277  return true;
278  }
279 
280  if( !aParent->AddRefNode( ref ) )
281  {
282  #if defined( DEBUG_VRML2 ) && ( DEBUG_VRML2 > 1 )
283  do {
284  std::ostringstream ostr;
285  ostr << __FILE__ << ": " << __FUNCTION__ << ": " << __LINE__ << "\n";
286  ostr << " * [INFO] failed to add node '" << glob << "' (";
287  ostr << ref->GetNodeTypeName( ref->GetNodeType() ) << ") to parent of type ";
288  ostr << aParent->GetNodeTypeName( aParent->GetNodeType() );
289  wxLogTrace( MASK_VRML, "%s\n", ostr.str().c_str() );
290  } while( 0 );
291  #endif
292 
293  return false;
294  }
295 
296  if( NULL != aNode )
297  *aNode = ref;
298 
299  return true;
300 }
301 
302 
303 bool WRL2BASE::implementDef( WRLPROC& proc, WRL2NODE* aParent, WRL2NODE** aNode )
304 {
305  if( NULL != aNode )
306  *aNode = NULL;
307 
308  if( NULL == aParent )
309  {
310  #ifdef DEBUG_VRML2
311  do {
312  std::ostringstream ostr;
313  ostr << __FILE__ << ": " << __FUNCTION__ << ": " << __LINE__ << "\n";
314  ostr << " * [BUG] invalid parent pointer (NULL)";
315  wxLogTrace( MASK_VRML, "%s\n", ostr.str().c_str() );
316  } while( 0 );
317  #endif
318 
319  return false;
320  }
321 
322  std::string glob;
323  WRL2NODE* lnode = NULL;
324 
325  if( !proc.ReadName( glob ) )
326  {
327  #if defined( DEBUG_VRML2 ) && ( DEBUG_VRML2 > 1 )
328  do {
329  std::ostringstream ostr;
330  ostr << __FILE__ << ": " << __FUNCTION__ << ": " << __LINE__ << "\n";
331  ostr << proc.GetError();
332  wxLogTrace( MASK_VRML, "%s\n", ostr.str().c_str() );
333  } while( 0 );
334  #endif
335 
336  return false;
337  }
338 
339  size_t line, column;
340  proc.GetFilePosData( line, column );
341 
342  if( ReadNode( proc, aParent, &lnode ) )
343  {
344  if( NULL != aNode )
345  *aNode = lnode;
346 
347  if( lnode && !lnode->SetName( glob ) )
348  {
349  #if defined( DEBUG_VRML2 ) && ( DEBUG_VRML2 > 1 )
350  do {
351  std::ostringstream ostr;
352  size_t line, column;
353  proc.GetFilePosData( line, column );
354  ostr << __FILE__ << ": " << __FUNCTION__ << ": " << __LINE__ << "\n";
355  ostr << " * [INFO] bad formatting (invalid name) at line";
356  ostr << line << ", column " << column;
357  wxLogTrace( MASK_VRML, "%s\n", ostr.str().c_str() );
358  } while( 0 );
359  #endif
360 
361  return false;
362  }
363 
364  return true;
365  }
366 
367  return false;
368 }
369 
370 
371 bool WRL2BASE::ReadNode( WRLPROC& proc, WRL2NODE* aParent, WRL2NODE** aNode )
372 {
373  // This function reads a node and stores a pointer to it in aNode.
374  // A value 'true' is returned if a node is successfully read or,
375  // if the node is not supported, successfully discarded. Callers
376  // must always check the value of aNode when the function returns
377  // 'true' since it will be NULL if the node type is not supported.
378 
379  if( NULL != aNode )
380  *aNode = NULL;
381 
382  if( NULL == aParent )
383  {
384  #ifdef DEBUG_VRML2
385  do {
386  std::ostringstream ostr;
387  ostr << __FILE__ << ": " << __FUNCTION__ << ": " << __LINE__ << "\n";
388  ostr << " * [BUG] invalid parent pointer (NULL)";
389  wxLogTrace( MASK_VRML, "%s\n", ostr.str().c_str() );
390  } while( 0 );
391  #endif
392 
393  return false;
394  }
395 
396  std::string glob;
397  WRL2NODES ntype;
398 
399  if( !proc.ReadName( glob ) )
400  {
401  #if defined( DEBUG_VRML2 ) && ( DEBUG_VRML2 > 1 )
402  if( !proc.eof() )
403  {
404  std::ostringstream ostr;
405  ostr << __FILE__ << ": " << __FUNCTION__ << ": " << __LINE__ << "\n";
406  ostr << proc.GetError();
407  wxLogTrace( MASK_VRML, "%s\n", ostr.str().c_str() );
408  }
409  #endif
410 
411  return false;
412  }
413 
414  // Process node name:
415  // the names encountered at this point should be one of the
416  // built-in node names or one of:
417  // DEF, USE
418  // PROTO, EXTERNPROTO
419  // ROUTE
420  // any PROTO or EXTERNPROTO defined name
421  // since we do not support PROTO or EXTERNPROTO, any unmatched names are
422  // assumed to be defined via PROTO/EXTERNPROTO and deleted according to
423  // a typical pattern.
424 
425  if( !glob.compare( "USE" ) )
426  {
427  if( !implementUse( proc, aParent, aNode ) )
428  {
429  #if defined( DEBUG_VRML2 ) && ( DEBUG_VRML2 > 1 )
430  do {
431  std::ostringstream ostr;
432  ostr << __FILE__ << ": " << __FUNCTION__ << ": " << __LINE__ << "\n";
433  ostr << proc.GetError();
434  wxLogTrace( MASK_VRML, "%s\n", ostr.str().c_str() );
435  } while( 0 );
436  #endif
437 
438  return false;
439  }
440 
441  return true;
442  }
443 
444  if( !glob.compare( "DEF" ) )
445  {
446  if( !implementDef( proc, aParent, aNode ) )
447  {
448  #if defined( DEBUG_VRML2 ) && ( DEBUG_VRML2 > 1 )
449  do {
450  std::ostringstream ostr;
451  ostr << __FILE__ << ": " << __FUNCTION__ << ": " << __LINE__ << "\n";
452  ostr << proc.GetError();
453  wxLogTrace( MASK_VRML, "%s\n", ostr.str().c_str() );
454  } while( 0 );
455  #endif
456 
457  return false;
458  }
459 
460  return true;
461  }
462 
463  // pattern to skip: PROTO name list
464  if( !glob.compare( "PROTO" ) )
465  {
466  if( !proc.ReadName( glob ) || !proc.DiscardList() )
467  {
468  #if defined( DEBUG_VRML2 ) && ( DEBUG_VRML2 > 1 )
469  do {
470  std::ostringstream ostr;
471  ostr << __FILE__ << ": " << __FUNCTION__ << ": " << __LINE__ << "\n";
472  ostr << proc.GetError();
473  wxLogTrace( MASK_VRML, "%s\n", ostr.str().c_str() );
474  } while( 0 );
475  #endif
476 
477  return false;
478  }
479 
480  return true;
481  }
482 
483  // pattern to skip: EXTERNPROTO name1 name2 list
484  if( !glob.compare( "EXTERNPROTO" ) )
485  {
486  if( !proc.ReadName( glob ) || !proc.ReadName( glob ) || !proc.DiscardList() )
487  {
488  #if defined( DEBUG_VRML2 ) && ( DEBUG_VRML2 > 1 )
489  do {
490  std::ostringstream ostr;
491  ostr << __FILE__ << ": " << __FUNCTION__ << ": " << __LINE__ << "\n";
492  ostr << proc.GetError();
493  wxLogTrace( MASK_VRML, "%s\n", ostr.str().c_str() );
494  } while( 0 );
495  #endif
496 
497  return false;
498  }
499 
500  return true;
501  }
502 
503  // pattern to skip: ROUTE glob1 glob2 glob3
504  if( !glob.compare( "ROUTE" ) )
505  {
506  if( !proc.ReadGlob( glob ) || !proc.ReadGlob( glob ) || !proc.ReadGlob( glob ) )
507  {
508  #if defined( DEBUG_VRML2 ) && ( DEBUG_VRML2 > 1 )
509  do {
510  std::ostringstream ostr;
511  ostr << __FILE__ << ": " << __FUNCTION__ << ": " << __LINE__ << "\n";
512  ostr << proc.GetError();
513  wxLogTrace( MASK_VRML, "%s\n", ostr.str().c_str() );
514  } while( 0 );
515  #endif
516 
517  return false;
518  }
519 
520  return true;
521  }
522 
523  ntype = getNodeTypeID( glob );
524  size_t line = 0;
525  size_t column = 0;
526  proc.GetFilePosData( line, column );
527 
528  #if defined( DEBUG_VRML2 ) && ( DEBUG_VRML2 > 2 )
529  do {
530  std::ostringstream ostr;
531  ostr << " * [INFO] Processing node '" << glob << "' ID: " << ntype;
532  wxLogTrace( MASK_VRML, "%s\n", ostr.str().c_str() );
533  } while( 0 );
534  #endif
535 
536  switch( ntype )
537  {
538  //
539  // items to be implemented:
540  //
541  case WRL2_APPEARANCE:
542 
543  if( !readAppearance( proc, aParent, aNode ) )
544  return false;
545 
546  break;
547 
548  case WRL2_BOX:
549 
550  if( !readBox( proc, aParent, aNode ) )
551  return false;
552 
553  break;
554 
555  case WRL2_COLOR:
556 
557  if( !readColor( proc, aParent, aNode ) )
558  return false;
559 
560  break;
561 
562  case WRL2_CONE:
563  // XXX - IMPLEMENT
564  if( !proc.DiscardNode() )
565  {
566  #ifdef DEBUG_VRML2
567  do {
568  std::ostringstream ostr;
569  ostr << " * [INFO] FAIL: discard " << glob << " node at l";
570  ostr << line << ", c" << column;
571  wxLogTrace( MASK_VRML, "%s\n", ostr.str().c_str() );
572  } while( 0 );
573  #endif
574 
575  return false;
576  }
577  #ifdef DEBUG_VRML2
578  else
579  {
580  do {
581  std::ostringstream ostr;
582  ostr << " * [INFO] OK: discard " << glob << " node at l";
583  ostr << line << ", c" << column;
584  wxLogTrace( MASK_VRML, "%s\n", ostr.str().c_str() );
585  } while( 0 );
586  }
587  #endif
588 
589  break;
590 
591  case WRL2_COORDINATE:
592 
593  if( !readCoords( proc, aParent, aNode ) )
594  return false;
595 
596  break;
597 
598  case WRL2_CYLINDER:
599  // XXX - IMPLEMENT
600  if( !proc.DiscardNode() )
601  {
602  #ifdef DEBUG_VRML2
603  do {
604  std::ostringstream ostr;
605  ostr << " * [INFO] FAIL: discard " << glob << " node at l";
606  ostr << line << ", c" << column;
607  wxLogTrace( MASK_VRML, "%s\n", ostr.str().c_str() );
608  } while( 0 );
609  #endif
610 
611  return false;
612  }
613  #ifdef DEBUG_VRML2
614  else
615  {
616  std::ostringstream ostr;
617  ostr << " * [INFO] OK: discard " << glob << " node at l";
618  ostr << line << ", c" << column;
619  wxLogTrace( MASK_VRML, "%s\n", ostr.str().c_str() );
620  }
621  #endif
622 
623  break;
624 
625  case WRL2_ELEVATIONGRID:
626  // XXX - IMPLEMENT
627  if( !proc.DiscardNode() )
628  {
629  #ifdef DEBUG_VRML2
630  do {
631  std::ostringstream ostr;
632  ostr << " * [INFO] FAIL: discard " << glob << " node at l";
633  ostr << line << ", c" << column;
634  wxLogTrace( MASK_VRML, "%s\n", ostr.str().c_str() );
635  } while( 0 );
636  #endif
637 
638  return false;
639  }
640  #ifdef DEBUG_VRML2
641  else
642  {
643  do {
644  std::ostringstream ostr;
645  ostr << " * [INFO] OK: discard " << glob << " node at l";
646  ostr << line << ", c" << column;
647  wxLogTrace( MASK_VRML, "%s\n", ostr.str().c_str() );
648  } while( 0 );
649  }
650  #endif
651 
652  break;
653 
654  case WRL2_EXTRUSION:
655  // XXX - IMPLEMENT
656  if( !proc.DiscardNode() )
657  {
658  #ifdef DEBUG_VRML2
659  do {
660  std::ostringstream ostr;
661  ostr << " * [INFO] FAIL: discard " << glob << " node at l";
662  ostr << line << ", c" << column;
663  wxLogTrace( MASK_VRML, "%s\n", ostr.str().c_str() );
664  } while( 0 );
665  #endif
666 
667  return false;
668  }
669  #ifdef DEBUG_VRML2
670  else
671  {
672  std::ostringstream ostr;
673  ostr << " * [INFO] OK: discard " << glob << " node at l";
674  ostr << line << ", c" << column;
675  wxLogTrace( MASK_VRML, "%s\n", ostr.str().c_str() );
676  }
677  #endif
678 
679  break;
680 
681  case WRL2_INDEXEDFACESET:
682 
683  if( !readFaceSet( proc, aParent, aNode ) )
684  return false;
685 
686  break;
687 
688  case WRL2_INDEXEDLINESET:
689 
690  if( !readLineSet( proc, aParent, aNode ) )
691  return false;
692 
693  break;
694 
695  case WRL2_POINTSET:
696 
697  if( !readPointSet( proc, aParent, aNode ) )
698  return false;
699 
700  break;
701 
702  case WRL2_MATERIAL:
703 
704  if( !readMaterial( proc, aParent, aNode ) )
705  return false;
706 
707  break;
708 
709  case WRL2_NORMAL:
710 
711  if( !readNorms( proc, aParent, aNode ) )
712  return false;
713 
714  break;
715 
716  case WRL2_SHAPE:
717 
718  if( !readShape( proc, aParent, aNode ) )
719  return false;
720 
721  break;
722 
723  case WRL2_SPHERE:
724  // XXX - IMPLEMENT
725  if( !proc.DiscardNode() )
726  {
727  #ifdef DEBUG_VRML2
728  do {
729  std::ostringstream ostr;
730  ostr << " * [INFO] FAIL: discard " << glob << " node at l";
731  ostr << line << ", c" << column;
732  wxLogTrace( MASK_VRML, "%s\n", ostr.str().c_str() );
733  } while( 0 );
734  #endif
735 
736  return false;
737  }
738  #ifdef DEBUG_VRML2
739  else
740  {
741  std::ostringstream ostr;
742  ostr << " * [INFO] OK: discard " << glob << " node at l";
743  ostr << line << ", c" << column;
744  wxLogTrace( MASK_VRML, "%s\n", ostr.str().c_str() );
745  }
746  #endif
747 
748  break;
749 
750  case WRL2_SWITCH:
751 
752  if( !readSwitch( proc, aParent, aNode ) )
753  return false;
754 
755  break;
756 
757  case WRL2_TRANSFORM:
758  case WRL2_GROUP:
759 
760  if( !readTransform( proc, aParent, aNode ) )
761  return false;
762 
763  break;
764 
765  case WRL2_INLINE:
766 
767  if( !readInline( proc, aParent, aNode ) )
768  return false;
769 
770  break;
771 
772  //
773  // items not implemented or for optional future implementation:
774  //
775  case WRL2_ANCHOR:
776  case WRL2_AUDIOCLIP:
777  case WRL2_BACKGROUND:
778  case WRL2_BILLBOARD:
779  case WRL2_COLLISION:
782  case WRL2_CYLINDERSENSOR:
784  case WRL2_FOG:
785  case WRL2_FONTSTYLE:
786  case WRL2_IMAGETEXTURE:
787  case WRL2_LOD:
788  case WRL2_MOVIETEXTURE:
789  case WRL2_NAVIGATIONINFO:
792  case WRL2_PIXELTEXTURE:
793  case WRL2_PLANESENSOR:
794  case WRL2_POINTLIGHT:
798  case WRL2_SCRIPT:
799  case WRL2_SOUND:
800  case WRL2_SPHERESENSOR:
801  case WRL2_SPOTLIGHT:
802  case WRL2_TEXT:
805  case WRL2_TIMESENSOR:
806  case WRL2_TOUCHSENSOR:
807  case WRL2_VIEWPOINT:
809  case WRL2_WORLDINFO:
810  case WRL2_INVALID:
811  default:
812 
813  proc.GetFilePosData( line, column );
814 
815  if( !proc.DiscardNode() )
816  {
817  #if defined( DEBUG_VRML2 ) && ( DEBUG_VRML2 > 1 )
818  do {
819  std::ostringstream ostr;
820  ostr << proc.GetError() << "\n";
821  ostr << __FILE__ << ": " << __FUNCTION__ << ": " << __LINE__ << "\n";
822  ostr << " * [INFO] could not discard node at line " << line;
823  ostr << ", column " << column;
824  wxLogTrace( MASK_VRML, "%s\n", ostr.str().c_str() );
825  } while( 0 );
826  #endif
827 
828  return false;
829  }
830  #ifdef DEBUG_VRML2
831  else
832  {
833  std::ostringstream ostr;
834  ostr << " * [INFO] OK: discard unsupported " << glob << " node at l";
835  ostr << line << ", c" << column;
836  wxLogTrace( MASK_VRML, "%s\n", ostr.str().c_str() );
837  }
838  #endif
839 
840  break;
841  }
842 
843  return true;
844 }
845 
846 
847 bool WRL2BASE::Read( WRLPROC& proc, WRL2BASE* aTopNode )
848 {
849  // this function makes no sense in the base node
850  #ifdef DEBUG_VRML2
851  do {
852  std::ostringstream ostr;
853  ostr << proc.GetError() << "\n";
854  ostr << __FILE__ << ": " << __FUNCTION__ << ": " << __LINE__ << "\n";
855  ostr << " * [BUG] this method must never be invoked on a WRL2BASE object";
856  wxLogTrace( MASK_VRML, "%s\n", ostr.str().c_str() );
857  } while( 0 );
858  #endif
859 
860  return false;
861 }
862 
863 
864 bool WRL2BASE::readTransform( WRLPROC& proc, WRL2NODE* aParent, WRL2NODE** aNode )
865 {
866  if( NULL != aNode )
867  *aNode = NULL;
868 
869  WRL2TRANSFORM* np = new WRL2TRANSFORM( aParent );
870 
871  if( !np->Read( proc, this ) )
872  {
873  delete np;
874  return false;
875  }
876 
877  if( NULL != aNode )
878  *aNode = (WRL2NODE*) np;
879 
880  return true;
881 }
882 
883 
884 bool WRL2BASE::readShape( WRLPROC& proc, WRL2NODE* aParent, WRL2NODE** aNode )
885 {
886  if( NULL != aNode )
887  *aNode = NULL;
888 
889  WRL2SHAPE* np = new WRL2SHAPE( aParent );
890 
891  if( !np->Read( proc, this ) )
892  {
893  delete np;
894  return false;
895  }
896 
897  if( NULL != aNode )
898  *aNode = (WRL2NODE*) np;
899 
900  return true;
901 }
902 
903 
904 bool WRL2BASE::readAppearance( WRLPROC& proc, WRL2NODE* aParent, WRL2NODE** aNode )
905 {
906  if( NULL != aNode )
907  *aNode = NULL;
908 
909  WRL2APPEARANCE* np = new WRL2APPEARANCE( aParent );
910 
911  if( !np->Read( proc, this ) )
912  {
913  delete np;
914  return false;
915  }
916 
917  if( NULL != aNode )
918  *aNode = (WRL2NODE*) np;
919 
920  return true;
921 }
922 
923 
924 bool WRL2BASE::readMaterial( WRLPROC& proc, WRL2NODE* aParent, WRL2NODE** aNode )
925 {
926  if( NULL != aNode )
927  *aNode = NULL;
928 
929  WRL2MATERIAL* np = new WRL2MATERIAL( aParent );
930 
931  if( !np->Read( proc, this ) )
932  {
933  delete np;
934  return false;
935  }
936 
937  if( NULL != aNode )
938  *aNode = (WRL2NODE*) np;
939 
940  return true;
941 }
942 
943 
944 bool WRL2BASE::readFaceSet( WRLPROC& proc, WRL2NODE* aParent, WRL2NODE** aNode )
945 {
946  if( NULL != aNode )
947  *aNode = NULL;
948 
949  WRL2FACESET* np = new WRL2FACESET( aParent );
950 
951  if( !np->Read( proc, this ) )
952  {
953  delete np;
954  return false;
955  }
956 
957  if( NULL != aNode )
958  *aNode = (WRL2NODE*) np;
959 
960  return true;
961 }
962 
963 
964 bool WRL2BASE::readLineSet( WRLPROC& proc, WRL2NODE* aParent, WRL2NODE** aNode )
965 {
966  if( NULL != aNode )
967  *aNode = NULL;
968 
969  WRL2LINESET* np = new WRL2LINESET( aParent );
970 
971  if( !np->Read( proc, this ) )
972  {
973  delete np;
974  return false;
975  }
976 
977  if( NULL != aNode )
978  *aNode = (WRL2NODE*) np;
979 
980  return true;
981 }
982 
983 
984 bool WRL2BASE::readPointSet( WRLPROC& proc, WRL2NODE* aParent, WRL2NODE** aNode )
985 {
986  if( NULL != aNode )
987  *aNode = NULL;
988 
989  WRL2POINTSET* np = new WRL2POINTSET( aParent );
990 
991  if( !np->Read( proc, this ) )
992  {
993  delete np;
994  return false;
995  }
996 
997  if( NULL != aNode )
998  *aNode = (WRL2NODE*) np;
999 
1000  return true;
1001 }
1002 
1003 
1004 bool WRL2BASE::readCoords( WRLPROC& proc, WRL2NODE* aParent, WRL2NODE** aNode )
1005 {
1006  if( NULL != aNode )
1007  *aNode = NULL;
1008 
1009  WRL2COORDS* np = new WRL2COORDS( aParent );
1010 
1011  if( !np->Read( proc, this ) )
1012  {
1013  delete np;
1014  return false;
1015  }
1016 
1017  if( NULL != aNode )
1018  *aNode = (WRL2NODE*) np;
1019 
1020  return true;
1021 }
1022 
1023 
1024 bool WRL2BASE::readNorms( WRLPROC& proc, WRL2NODE* aParent, WRL2NODE** aNode )
1025 {
1026  if( NULL != aNode )
1027  *aNode = NULL;
1028 
1029  WRL2NORMS* np = new WRL2NORMS( aParent );
1030 
1031  if( !np->Read( proc, this ) )
1032  {
1033  delete np;
1034  return false;
1035  }
1036 
1037  if( NULL != aNode )
1038  *aNode = (WRL2NODE*) np;
1039 
1040  return true;
1041 }
1042 
1043 
1044 bool WRL2BASE::readColor( WRLPROC& proc, WRL2NODE* aParent, WRL2NODE** aNode )
1045 {
1046  if( NULL != aNode )
1047  *aNode = NULL;
1048 
1049  WRL2COLOR* np = new WRL2COLOR( aParent );
1050 
1051  if( !np->Read( proc, this ) )
1052  {
1053  delete np;
1054  return false;
1055  }
1056 
1057  if( NULL != aNode )
1058  *aNode = (WRL2NODE*) np;
1059 
1060  return true;
1061 }
1062 
1063 
1064 bool WRL2BASE::readBox( WRLPROC& proc, WRL2NODE* aParent, WRL2NODE** aNode )
1065 {
1066  if( NULL != aNode )
1067  *aNode = NULL;
1068 
1069  WRL2BOX* np = new WRL2BOX( aParent );
1070 
1071  if( !np->Read( proc, this ) )
1072  {
1073  delete np;
1074  return false;
1075  }
1076 
1077  if( NULL != aNode )
1078  *aNode = (WRL2NODE*) np;
1079 
1080  return true;
1081 }
1082 
1083 
1084 bool WRL2BASE::readSwitch( WRLPROC& proc, WRL2NODE* aParent, WRL2NODE** aNode )
1085 {
1086  if( NULL != aNode )
1087  *aNode = NULL;
1088 
1089  WRL2SWITCH* np = new WRL2SWITCH( aParent );
1090 
1091  if( !np->Read( proc, this ) )
1092  {
1093  delete np;
1094  return false;
1095  }
1096 
1097  if( NULL != aNode )
1098  *aNode = (WRL2NODE*) np;
1099 
1100  return true;
1101 }
1102 
1103 
1104 bool WRL2BASE::readInline( WRLPROC& proc, WRL2NODE* aParent, WRL2NODE** aNode )
1105 {
1106  if( NULL != aNode )
1107  *aNode = NULL;
1108 
1109  if( !m_useInline )
1110  {
1111  size_t line = 0;
1112  size_t column = 0;
1113  proc.GetFilePosData( line, column );
1114 
1115  if( !proc.DiscardNode() )
1116  {
1117  #if defined( DEBUG_VRML2 ) && ( DEBUG_VRML2 > 1 )
1118  do {
1119  std::ostringstream ostr;
1120  ostr << proc.GetError() << "\n";
1121  ostr << __FILE__ << ": " << __FUNCTION__ << ": " << __LINE__ << "\n";
1122  ostr << " * [INFO] could not discard Inline node at line " << line;
1123  ostr << ", column " << column;
1124  wxLogTrace( MASK_VRML, "%s\n", ostr.str().c_str() );
1125  } while( 0 );
1126  #endif
1127 
1128  return false;
1129  }
1130 
1131  return true;
1132  }
1133 
1134  WRL2INLINE* np = new WRL2INLINE( aParent );
1135 
1136  if( !np->Read( proc, this ) )
1137  {
1138  delete np;
1139  return false;
1140  }
1141 
1142  if( NULL != aNode )
1143  *aNode = (WRL2NODE*) np;
1144 
1145  return true;
1146 }
1147 
1148 
1150 {
1151  if( m_Children.empty() )
1152  return NULL;
1153 
1154  S3D::SGTYPES ptype = S3D::GetSGNodeType( aParent );
1155 
1156  if( NULL != aParent && ptype != S3D::SGTYPE_SHAPE )
1157  {
1158  #ifdef DEBUG_VRML2
1159  do {
1160  std::ostringstream ostr;
1161  ostr << __FILE__ << ": " << __FUNCTION__ << ": " << __LINE__ << "\n";
1162  ostr << " * [BUG] WRL2BASE does not have a Transform parent (parent ID: ";
1163  ostr << ptype << ")";
1164  wxLogTrace( MASK_VRML, "%s\n", ostr.str().c_str() );
1165  } while( 0 );
1166  #endif
1167 
1168  return NULL;
1169  }
1170 
1171  if( m_sgNode )
1172  {
1173  if( NULL != aParent )
1174  {
1176  && !S3D::AddSGNodeChild( aParent, m_sgNode ) )
1177  {
1178  return NULL;
1179  }
1180  else if( aParent != S3D::GetSGNodeParent( m_sgNode )
1181  && !S3D::AddSGNodeRef( aParent, m_sgNode ) )
1182  {
1183  return NULL;
1184  }
1185  }
1186 
1187  return m_sgNode;
1188  }
1189 
1190  IFSG_TRANSFORM topNode( aParent );
1191 
1192  std::list< WRL2NODE* >::iterator sC = m_Children.begin();
1193  std::list< WRL2NODE* >::iterator eC = m_Children.end();
1194  WRL2NODES type;
1195 
1196  // Include only Shape and Transform nodes in the top node
1197  bool test = false; // set to true if there are any subnodes for display
1198 
1199  while( sC != eC )
1200  {
1201  type = (*sC)->GetNodeType();
1202 
1203  switch( type )
1204  {
1205  case WRL2_SHAPE:
1206  // wrap the shape in a transform
1207  do
1208  {
1209  IFSG_TRANSFORM wrapper( topNode.GetRawPtr() );
1210  SGNODE* pshape = (*sC)->TranslateToSG( wrapper.GetRawPtr() );
1211 
1212  if( NULL != pshape )
1213  test = true;
1214  else
1215  wrapper.Destroy();
1216 
1217  } while( 0 );
1218 
1219  break;
1220 
1221  case WRL2_TRANSFORM:
1222  case WRL2_SWITCH:
1223  case WRL2_INLINE:
1224 
1225  if( NULL != (*sC)->TranslateToSG( topNode.GetRawPtr() ) )
1226  test = true;
1227 
1228  break;
1229 
1230  default:
1231  break;
1232  }
1233 
1234  ++ sC;
1235  }
1236 
1237  if( false == test )
1238  {
1239  topNode.Destroy();
1240  return NULL;
1241  }
1242 
1243  m_sgNode = topNode.GetRawPtr();
1244 
1245  return m_sgNode;
1246 }
bool Read(WRLPROC &proc, WRL2BASE *aTopNode) override
bool Read(WRLPROC &proc, WRL2BASE *aTopNode) override
bool implementDef(WRLPROC &proc, WRL2NODE *aParent, WRL2NODE **aNode)
Definition: vrml2_base.cpp:303
bool Read(WRLPROC &proc, WRL2BASE *aTopNode) override
WRL2APPEARANCE.
WRL2COORDS.
Definition: vrml2_coords.h:42
WRL2NODE represents the base class of all VRML2 nodes.
Definition: vrml2_node.h:58
virtual ~WRL2BASE()
Definition: vrml2_base.cpp:58
std::list< WRL2NODE * > m_Children
Definition: vrml2_node.h:66
bool readShape(WRLPROC &proc, WRL2NODE *aParent, WRL2NODE **aNode)
Definition: vrml2_base.cpp:884
bool readMaterial(WRLPROC &proc, WRL2NODE *aParent, WRL2NODE **aNode)
Definition: vrml2_base.cpp:924
bool Read(WRLPROC &proc, WRL2BASE *aTopNode) override
bool GetFilePosData(size_t &line, size_t &column)
Definition: wrlproc.cpp:1951
bool readLineSet(WRLPROC &proc, WRL2NODE *aParent, WRL2NODE **aNode)
Definition: vrml2_base.cpp:964
bool readCoords(WRLPROC &proc, WRL2NODE *aParent, WRL2NODE **aNode)
#define MASK_VRML
Definition: wrltypes.h:37
bool Read(WRLPROC &proc, WRL2BASE *aTopNode) override
WRLVERSION GetVRMLType(void)
Definition: wrlproc.cpp:221
bool Read(WRLPROC &proc)
Definition: vrml2_base.cpp:193
SGLIB_API SGNODE * GetSGNodeParent(SGNODE *aNode)
Definition: ifsg_api.cpp:636
WRL2NODES m_Type
Definition: vrml2_node.h:62
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
bool readAppearance(WRLPROC &proc, WRL2NODE *aParent, WRL2NODE **aNode)
Definition: vrml2_base.cpp:904
SGNODE * GetRawPtr(void) noexcept
Function GetRawPtr() returns the raw internal SGNODE pointer.
Definition: ifsg_node.cpp:66
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
virtual bool SetName(const std::string &aName)
Definition: vrml2_node.cpp:230
WRL2NODES getNodeTypeID(const std::string &aNodeName)
Function getNodeTypeID returns the ID based on the given aNodeName or WRL2_INVALID (WRL2_END) if no s...
Definition: vrml2_node.cpp:310
SGNODE * GetInlineData(const std::string &aName)
Definition: vrml2_base.cpp:109
bool isDangling(void) override
Function isDangling returns true if the object does not have a parent which is a logical container fo...
Definition: vrml2_base.cpp:221
WRL2SHAPE.
Definition: vrml2_shape.h:40
bool ReadGlob(std::string &aGlob)
Definition: wrlproc.cpp:236
void SetEnableInline(bool enable)
Definition: vrml2_base.cpp:96
bool GetEnableInline(void)
Definition: vrml2_base.cpp:103
SGLIB_API void DestroyNode(SGNODE *aNode) noexcept
Function DestroyNode deletes the given SG* class node.
Definition: ifsg_api.cpp:210
#define NULL
bool Read(WRLPROC &proc, WRL2BASE *aTopNode) override
bool Read(WRLPROC &proc, WRL2BASE *aTopNode) override
bool readColor(WRLPROC &proc, WRL2NODE *aParent, WRL2NODE **aNode)
WRL2NORMS.
Definition: vrml2_norms.h:42
bool DiscardNode(void)
Definition: wrlproc.cpp:359
bool readFaceSet(WRLPROC &proc, WRL2NODE *aParent, WRL2NODE **aNode)
Definition: vrml2_base.cpp:944
SGLIB_API bool AddSGNodeChild(SGNODE *aParent, SGNODE *aChild)
Definition: ifsg_api.cpp:654
SGNODE * m_sgNode
Definition: vrml2_node.h:70
WRL2MATERIAL.
std::map< std::string, SGNODE * > m_inlineModels
Definition: vrml2_base.h:83
WRL2FACESET.
Definition: vrml2_faceset.h:42
WRL2NODES GetNodeType(void) const
Function GetNodeType returns the type of this node instance.
Definition: vrml2_node.cpp:212
const char * GetParentDir(void)
Definition: wrlproc.cpp:227
WRL2BASE represents the top node of a VRML2 model.
Definition: vrml2_base.h:59
virtual bool SetName(const std::string &aName) override
Definition: vrml2_base.cpp:178
WRL2POINTSET.
bool m_useInline
Definition: vrml2_base.h:62
bool Read(WRLPROC &proc, WRL2BASE *aTopNode) override
const char * GetNodeTypeName(WRL2NODES aNodeType) const
Definition: vrml2_node.cpp:295
WRL2COLOR.
Definition: vrml2_color.h:42
SGTYPES
Definition: sg_types.h:34
SGLIB_API S3D::SGTYPES GetSGNodeType(SGNODE *aNode)
Definition: ifsg_api.cpp:627
WRL2TRANSFORM.
bool Read(WRLPROC &proc, WRL2BASE *aTopNode) override
WRL2LINESET.
Definition: vrml2_lineset.h:42
bool Read(WRLPROC &proc, WRL2BASE *aTopNode) override
bool ReadName(std::string &aName)
Definition: wrlproc.cpp:280
bool readTransform(WRLPROC &proc, WRL2NODE *aParent, WRL2NODE **aNode)
Definition: vrml2_base.cpp:864
WRL2BOX.
Definition: vrml2_box.h:40
IFSG_TRANSFORM is the wrapper for the VRML compatible TRANSFORM block class SCENEGRAPH.
virtual std::string GetName(void) override
Definition: vrml2_base.cpp:163
bool SetParent(WRL2NODE *aParent, bool doUnlink=true) override
Function SetParent sets the parent WRL2NODE of this object.
Definition: vrml2_base.cpp:81
bool Read(WRLPROC &proc, WRL2BASE *aTopNode) override
SCENEGRAPH * LoadVRML(const wxString &aFileName, bool useInline)
Definition: vrml.cpp:161
WRL2NODES
Definition: wrltypes.h:121
bool Read(WRLPROC &proc, WRL2BASE *aTopNode) override
bool readSwitch(WRLPROC &proc, WRL2NODE *aParent, WRL2NODE **aNode)
bool readNorms(WRLPROC &proc, WRL2NODE *aParent, WRL2NODE **aNode)
std::string GetError(void)
Definition: wrlproc.cpp:1945
bool readBox(WRLPROC &proc, WRL2NODE *aParent, WRL2NODE **aNode)
void Destroy(void)
Function Destroy deletes the object held by this wrapper.
Definition: ifsg_node.cpp:54
virtual bool AddRefNode(WRL2NODE *aNode)
Definition: vrml2_node.cpp:416
bool DiscardList(void)
Definition: wrlproc.cpp:482
bool readPointSet(WRLPROC &proc, WRL2NODE *aParent, WRL2NODE **aNode)
Definition: vrml2_base.cpp:984
bool eof(void)
Definition: wrlproc.cpp:1939
bool Read(WRLPROC &proc, WRL2BASE *aTopNode) override
Definition: vrml2_box.cpp:81
virtual WRL2NODE * FindNode(const std::string &aNodeName, const WRL2NODE *aCaller)
Function FindNode searches the tree of linked nodes and returns a reference to the first node found w...
Definition: vrml2_node.cpp:327
bool readInline(WRLPROC &proc, WRL2NODE *aParent, WRL2NODE **aNode)
std::string m_dir
Definition: vrml2_base.h:63
WRL2INLINE.
Definition: vrml2_inline.h:40
WRL2SWITCH.
Definition: vrml2_switch.h:40
SGNODE * TranslateToSG(SGNODE *aParent) override
Function TranslateToSG produces a representation of the data using the intermediate scenegraph struct...
bool implementUse(WRLPROC &proc, WRL2NODE *aParent, WRL2NODE **aNode)
Definition: vrml2_base.cpp:228