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  * Copyright (C) 2021 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, you may find one here:
19  * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
20  * or you may search the http://www.gnu.org website for the version 2 license,
21  * or you may write to the Free Software Foundation, Inc.,
22  * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
23  */
24 
25 #include <iostream>
26 #include <sstream>
27 #include <utility>
28 #include <wx/string.h>
29 #include <wx/filename.h>
30 #include <wx/log.h>
31 
32 #include "vrml2_base.h"
33 #include "vrml2_transform.h"
34 #include "vrml2_shape.h"
35 #include "vrml2_appearance.h"
36 #include "vrml2_material.h"
37 #include "vrml2_faceset.h"
38 #include "vrml2_lineset.h"
39 #include "vrml2_pointset.h"
40 #include "vrml2_coords.h"
41 #include "vrml2_norms.h"
42 #include "vrml2_color.h"
43 #include "vrml2_box.h"
44 #include "vrml2_switch.h"
45 #include "vrml2_inline.h"
46 #include "plugins/3dapi/ifsg_all.h"
47 
48 
49 SCENEGRAPH* LoadVRML( const wxString& aFileName, bool useInline );
50 
51 
53 {
54  m_useInline = false;
56 }
57 
58 
60 {
61  std::map< std::string, SGNODE* >::iterator iS = m_inlineModels.begin();
62  std::map< std::string, SGNODE* >::iterator eS = m_inlineModels.end();
63 
64  while( iS != eS )
65  {
66  SGNODE* np = iS->second;
67 
68  // destroy any orphaned Inline{} node data
69  if( np && nullptr == S3D::GetSGNodeParent( np ) )
70  S3D::DestroyNode( np );
71 
72  ++iS;
73  }
74 
75  m_inlineModels.clear();
76 }
77 
78 
79 bool WRL2BASE::SetParent( WRL2NODE* aParent, bool /* doUnlink */ )
80 {
81  wxCHECK_MSG( false, false, wxT( "Attempt to set parent on WRL2BASE node." ) );
82 }
83 
84 
85 void WRL2BASE::SetEnableInline( bool enable )
86 {
87  m_useInline = enable;
88 }
89 
90 
92 {
93  return m_useInline;
94 }
95 
96 
97 SGNODE* WRL2BASE::GetInlineData( const std::string& aName )
98 {
99  if( aName.empty() )
100  return nullptr;
101 
102  std::map< std::string, SGNODE* >::iterator dp = m_inlineModels.find( aName );
103 
104  if( dp != m_inlineModels.end() )
105  return dp->second;
106 
107  wxString tname;
108 
109  if( aName.compare( 0, 7, "file://" ) == 0 )
110  {
111  if( aName.length() <= 7 )
112  return nullptr;
113 
114  tname = wxString::FromUTF8Unchecked( aName.substr( 7 ).c_str() );
115  }
116  else
117  {
118  tname = wxString::FromUTF8Unchecked( aName.c_str() );
119  }
120 
121  wxFileName fn;
122  fn.Assign( tname );
123 
124  if( fn.IsRelative() && !m_dir.empty() )
125  {
126  wxString fname = wxString::FromUTF8Unchecked( m_dir.c_str() );
127  fname.append( tname );
128  fn.Assign( fname );
129  }
130 
131  if( !fn.Normalize() )
132  {
133  m_inlineModels.insert( std::pair< std::string, SGNODE* >( aName, nullptr ) );
134  return nullptr;
135  }
136 
137  SCENEGRAPH* sp = LoadVRML( fn.GetFullPath(), false );
138 
139  if( nullptr == sp )
140  {
141  m_inlineModels.insert( std::pair< std::string, SGNODE* >( aName, nullptr ) );
142  return nullptr;
143  }
144 
145  m_inlineModels.insert( std::pair< std::string, SGNODE* >( aName, (SGNODE*)sp ) );
146 
147  return (SGNODE*)sp;
148 }
149 
150 
151 std::string WRL2BASE::GetName( void )
152 {
153  wxCHECK_MSG( false, std::string( "" ), wxT( "Attempt to extract name from base node." ) );
154 }
155 
156 
157 bool WRL2BASE::SetName( const std::string& aName )
158 {
159  wxCHECK_MSG( false, false, wxT( "Attempt to set name of base node." ) );
160 }
161 
162 
163 bool WRL2BASE::Read( WRLPROC& proc )
164 {
165  wxCHECK_MSG( proc.GetVRMLType() == WRLVERSION::VRML_V2, false,
166  wxT( "No open file or file is not a VRML2 file." ) );
167 
168  WRL2NODE* node = nullptr;
169  m_dir = proc.GetParentDir();
170 
171  while( ReadNode( proc, this, &node ) && !proc.eof() );
172 
173  if( proc.eof() )
174  return true;
175 
176  return false;
177 }
178 
179 
181 {
182  // the base node is never dangling
183  return false;
184 }
185 
186 
187 bool WRL2BASE::implementUse( WRLPROC& proc, WRL2NODE* aParent, WRL2NODE** aNode )
188 {
189  if( nullptr != aNode )
190  *aNode = nullptr;
191 
192  wxCHECK_MSG( aParent, false, wxT( "Invalid parent." ) );
193 
194  std::string glob;
195 
196  if( !proc.ReadName( glob ) )
197  {
198  wxLogTrace( traceVrmlPlugin, wxT( "%s:%s:%d\n"
199  "%s" ),
200  __FILE__, __FUNCTION__, __LINE__ , proc.GetError() );
201 
202  return false;
203  }
204 
205  WRL2NODE* ref = aParent->FindNode( glob, nullptr );
206 
207  // return 'true' - the file may be defective but it may still be somewhat OK
208  if( nullptr == ref )
209  {
210  wxLogTrace( traceVrmlPlugin, wxT( "%s:%s:%d\n"
211  " * [INFO] node '%s' not found." ),
212  __FILE__, __FUNCTION__, __LINE__, glob );
213 
214  return true;
215  }
216 
217  if( !aParent->AddRefNode( ref ) )
218  {
219  wxLogTrace( traceVrmlPlugin,
220  wxT( "%s:%s:%d\n"
221  " * [INFO] failed to add node '%s' (%d) to parent of type %d" ),
222  __FILE__, __FUNCTION__, __LINE__, glob, ref->GetNodeType(),
223  aParent->GetNodeType() );
224 
225  return false;
226  }
227 
228  if( nullptr != aNode )
229  *aNode = ref;
230 
231  return true;
232 }
233 
234 
235 bool WRL2BASE::implementDef( WRLPROC& proc, WRL2NODE* aParent, WRL2NODE** aNode )
236 {
237  if( nullptr != aNode )
238  *aNode = nullptr;
239 
240  wxCHECK_MSG( aParent, false, wxT( "Invalid parent." ) );
241 
242  std::string glob;
243  WRL2NODE* lnode = nullptr;
244 
245  if( !proc.ReadName( glob ) )
246  {
247  wxLogTrace( traceVrmlPlugin, wxT( "%s:%s:%d\n"
248  "%s" ),
249  __FILE__, __FUNCTION__, __LINE__ , proc.GetError() );
250 
251  return false;
252  }
253 
254  if( ReadNode( proc, aParent, &lnode ) )
255  {
256  if( nullptr != aNode )
257  *aNode = lnode;
258 
259  if( lnode && !lnode->SetName( glob ) )
260  {
261  wxLogTrace( traceVrmlPlugin,
262  wxT( "%s:%s:%d\n"
263  " * [INFO] bad formatting (invalid name) %s." ),
264  __FILE__, __FUNCTION__, __LINE__, proc.GetFilePosition() );
265 
266  return false;
267  }
268 
269  return true;
270  }
271 
272  return false;
273 }
274 
275 
276 bool WRL2BASE::ReadNode( WRLPROC& proc, WRL2NODE* aParent, WRL2NODE** aNode )
277 {
278  // This function reads a node and stores a pointer to it in aNode.
279  // A value 'true' is returned if a node is successfully read or,
280  // if the node is not supported, successfully discarded. Callers
281  // must always check the value of aNode when the function returns
282  // 'true' since it will be NULL if the node type is not supported.
283 
284  if( nullptr != aNode )
285  *aNode = nullptr;
286 
287  wxCHECK_MSG( aParent, false, wxT( "Invalid parent." ) );
288 
289  std::string glob;
290  WRL2NODES ntype;
291 
292  if( !proc.ReadName( glob ) )
293  {
294  wxLogTrace( traceVrmlPlugin, wxT( "%s:%s:%d\n"
295  "%s" ),
296  __FILE__, __FUNCTION__, __LINE__ , proc.GetError() );
297 
298  return false;
299  }
300 
301  // Process node name:
302  // the names encountered at this point should be one of the
303  // built-in node names or one of:
304  // DEF, USE
305  // PROTO, EXTERNPROTO
306  // ROUTE
307  // any PROTO or EXTERNPROTO defined name
308  // since we do not support PROTO or EXTERNPROTO, any unmatched names are
309  // assumed to be defined via PROTO/EXTERNPROTO and deleted according to
310  // a typical pattern.
311 
312  if( !glob.compare( "USE" ) )
313  {
314  if( !implementUse( proc, aParent, aNode ) )
315  {
316  wxLogTrace( traceVrmlPlugin, wxT( "%s:%s:%d\n"
317  "%s" ),
318  __FILE__, __FUNCTION__, __LINE__ , proc.GetError() );
319 
320  return false;
321  }
322 
323  return true;
324  }
325 
326  if( !glob.compare( "DEF" ) )
327  {
328  if( !implementDef( proc, aParent, aNode ) )
329  {
330  wxLogTrace( traceVrmlPlugin, wxT( "%s:%s:%d\n"
331  "%s" ),
332  __FILE__, __FUNCTION__, __LINE__ , proc.GetError() );
333 
334  return false;
335  }
336 
337  return true;
338  }
339 
340  // pattern to skip: PROTO name list
341  if( !glob.compare( "PROTO" ) )
342  {
343  if( !proc.ReadName( glob ) || !proc.DiscardList() )
344  {
345  wxLogTrace( traceVrmlPlugin, wxT( "%s:%s:%d\n"
346  "%s" ),
347  __FILE__, __FUNCTION__, __LINE__ , proc.GetError() );
348 
349  return false;
350  }
351 
352  return true;
353  }
354 
355  // pattern to skip: EXTERNPROTO name1 name2 list
356  if( !glob.compare( "EXTERNPROTO" ) )
357  {
358  if( !proc.ReadName( glob ) || !proc.ReadName( glob ) || !proc.DiscardList() )
359  {
360  wxLogTrace( traceVrmlPlugin, wxT( "%s:%s:%d\n"
361  "%s" ),
362  __FILE__, __FUNCTION__, __LINE__ , proc.GetError() );
363 
364  return false;
365  }
366 
367  return true;
368  }
369 
370  // pattern to skip: ROUTE glob1 glob2 glob3
371  if( !glob.compare( "ROUTE" ) )
372  {
373  if( !proc.ReadGlob( glob ) || !proc.ReadGlob( glob ) || !proc.ReadGlob( glob ) )
374  {
375  wxLogTrace( traceVrmlPlugin, wxT( "%s:%s:%d\n"
376  "%s" ),
377  __FILE__, __FUNCTION__, __LINE__ , proc.GetError() );
378 
379  return false;
380  }
381 
382  return true;
383  }
384 
385  ntype = getNodeTypeID( glob );
386 
387  wxLogTrace( traceVrmlPlugin, wxT( " * [INFO] Processing node '%s' ID: %d" ), glob, ntype );
388 
389  switch( ntype )
390  {
391  //
392  // items to be implemented:
393  //
395 
396  if( !readAppearance( proc, aParent, aNode ) )
397  return false;
398 
399  break;
400 
401  case WRL2NODES::WRL2_BOX:
402 
403  if( !readBox( proc, aParent, aNode ) )
404  return false;
405 
406  break;
407 
409 
410  if( !readColor( proc, aParent, aNode ) )
411  return false;
412 
413  break;
414 
416  // XXX - IMPLEMENT
417  if( !proc.DiscardNode() )
418  {
419  wxLogTrace( traceVrmlPlugin, wxT( " * [INFO] failed to discard %s node %s." ),
420  glob, proc.GetFilePosition() );
421 
422  return false;
423  }
424  else
425  {
426  wxLogTrace( traceVrmlPlugin, wxT( " * [INFO] discarded %s node %s." ),
427  glob, proc.GetFilePosition() );
428  }
429 
430  break;
431 
433 
434  if( !readCoords( proc, aParent, aNode ) )
435  return false;
436 
437  break;
438 
440  // XXX - IMPLEMENT
441  if( !proc.DiscardNode() )
442  {
443  wxLogTrace( traceVrmlPlugin, wxT( " * [INFO] failed to discard %s node %s." ),
444  glob, proc.GetFilePosition() );
445 
446  return false;
447  }
448  else
449  {
450  wxLogTrace( traceVrmlPlugin, wxT( " * [INFO] discarded %s node %s." ),
451  glob, proc.GetFilePosition() );
452  }
453 
454  break;
455 
457  // XXX - IMPLEMENT
458  if( !proc.DiscardNode() )
459  {
460  wxLogTrace( traceVrmlPlugin, wxT( " * [INFO] failed to discard %s node %s." ),
461  glob, proc.GetFilePosition() );
462 
463  return false;
464  }
465  else
466  {
467  wxLogTrace( traceVrmlPlugin, wxT( " * [INFO] discarded %s node %s." ),
468  glob, proc.GetFilePosition() );
469  }
470 
471  break;
472 
474  // XXX - IMPLEMENT
475  if( !proc.DiscardNode() )
476  {
477  wxLogTrace( traceVrmlPlugin, wxT( " * [INFO] failed to discard %s node %s." ),
478  glob, proc.GetFilePosition() );
479 
480  return false;
481  }
482  else
483  {
484  wxLogTrace( traceVrmlPlugin, wxT( " * [INFO] discarded %s node %s." ),
485  glob, proc.GetFilePosition() );
486  }
487 
488  break;
489 
491 
492  if( !readFaceSet( proc, aParent, aNode ) )
493  return false;
494 
495  break;
496 
498 
499  if( !readLineSet( proc, aParent, aNode ) )
500  return false;
501 
502  break;
503 
505 
506  if( !readPointSet( proc, aParent, aNode ) )
507  return false;
508 
509  break;
510 
512 
513  if( !readMaterial( proc, aParent, aNode ) )
514  return false;
515 
516  break;
517 
519 
520  if( !readNorms( proc, aParent, aNode ) )
521  return false;
522 
523  break;
524 
526 
527  if( !readShape( proc, aParent, aNode ) )
528  return false;
529 
530  break;
531 
533  // XXX - IMPLEMENT
534  if( !proc.DiscardNode() )
535  {
536  wxLogTrace( traceVrmlPlugin, wxT( " * [INFO] failed to discard %s node %s." ),
537  glob, proc.GetFilePosition() );
538 
539  return false;
540  }
541  else
542  {
543  wxLogTrace( traceVrmlPlugin, wxT( " * [INFO] discarded %s node %s." ),
544  glob, proc.GetFilePosition() );
545  }
546 
547  break;
548 
550 
551  if( !readSwitch( proc, aParent, aNode ) )
552  return false;
553 
554  break;
555 
558 
559  if( !readTransform( proc, aParent, aNode ) )
560  return false;
561 
562  break;
563 
565 
566  if( !readInline( proc, aParent, aNode ) )
567  return false;
568 
569  break;
570 
571  //
572  // items not implemented or for optional future implementation:
573  //
583  case WRL2NODES::WRL2_FOG:
586  case WRL2NODES::WRL2_LOD:
610  default:
611 
612  if( !proc.DiscardNode() )
613  {
614  wxLogTrace( traceVrmlPlugin, wxT( " * [INFO] failed to discard %s node %s." ),
615  glob, proc.GetFilePosition() );
616 
617  return false;
618  }
619  else
620  {
621  wxLogTrace( traceVrmlPlugin, wxT( " * [INFO] discarded %s node %s." ),
622  glob, proc.GetFilePosition() );
623  }
624 
625  break;
626  }
627 
628  return true;
629 }
630 
631 
632 bool WRL2BASE::Read( WRLPROC& proc, WRL2BASE* aTopNode )
633 {
634  wxCHECK_MSG( false, false, wxT( "This method must never be invoked on a WRL2BASE object." ) );
635 }
636 
637 
638 bool WRL2BASE::readTransform( WRLPROC& proc, WRL2NODE* aParent, WRL2NODE** aNode )
639 {
640  if( nullptr != aNode )
641  *aNode = nullptr;
642 
643  WRL2TRANSFORM* np = new WRL2TRANSFORM( aParent );
644 
645  if( !np->Read( proc, this ) )
646  {
647  delete np;
648  return false;
649  }
650 
651  if( nullptr != aNode )
652  *aNode = (WRL2NODE*) np;
653 
654  return true;
655 }
656 
657 
658 bool WRL2BASE::readShape( WRLPROC& proc, WRL2NODE* aParent, WRL2NODE** aNode )
659 {
660  if( nullptr != aNode )
661  *aNode = nullptr;
662 
663  WRL2SHAPE* np = new WRL2SHAPE( aParent );
664 
665  if( !np->Read( proc, this ) )
666  {
667  delete np;
668  return false;
669  }
670 
671  if( nullptr != aNode )
672  *aNode = (WRL2NODE*) np;
673 
674  return true;
675 }
676 
677 
678 bool WRL2BASE::readAppearance( WRLPROC& proc, WRL2NODE* aParent, WRL2NODE** aNode )
679 {
680  if( nullptr != aNode )
681  *aNode = nullptr;
682 
683  WRL2APPEARANCE* np = new WRL2APPEARANCE( aParent );
684 
685  if( !np->Read( proc, this ) )
686  {
687  delete np;
688  return false;
689  }
690 
691  if( nullptr != aNode )
692  *aNode = (WRL2NODE*) np;
693 
694  return true;
695 }
696 
697 
698 bool WRL2BASE::readMaterial( WRLPROC& proc, WRL2NODE* aParent, WRL2NODE** aNode )
699 {
700  if( nullptr != aNode )
701  *aNode = nullptr;
702 
703  WRL2MATERIAL* np = new WRL2MATERIAL( aParent );
704 
705  if( !np->Read( proc, this ) )
706  {
707  delete np;
708  return false;
709  }
710 
711  if( nullptr != aNode )
712  *aNode = (WRL2NODE*) np;
713 
714  return true;
715 }
716 
717 
718 bool WRL2BASE::readFaceSet( WRLPROC& proc, WRL2NODE* aParent, WRL2NODE** aNode )
719 {
720  if( nullptr != aNode )
721  *aNode = nullptr;
722 
723  WRL2FACESET* np = new WRL2FACESET( aParent );
724 
725  if( !np->Read( proc, this ) )
726  {
727  delete np;
728  return false;
729  }
730 
731  if( nullptr != aNode )
732  *aNode = (WRL2NODE*) np;
733 
734  return true;
735 }
736 
737 
738 bool WRL2BASE::readLineSet( WRLPROC& proc, WRL2NODE* aParent, WRL2NODE** aNode )
739 {
740  if( nullptr != aNode )
741  *aNode = nullptr;
742 
743  WRL2LINESET* np = new WRL2LINESET( aParent );
744 
745  if( !np->Read( proc, this ) )
746  {
747  delete np;
748  return false;
749  }
750 
751  if( nullptr != aNode )
752  *aNode = (WRL2NODE*) np;
753 
754  return true;
755 }
756 
757 
758 bool WRL2BASE::readPointSet( WRLPROC& proc, WRL2NODE* aParent, WRL2NODE** aNode )
759 {
760  if( nullptr != aNode )
761  *aNode = nullptr;
762 
763  WRL2POINTSET* np = new WRL2POINTSET( aParent );
764 
765  if( !np->Read( proc, this ) )
766  {
767  delete np;
768  return false;
769  }
770 
771  if( nullptr != aNode )
772  *aNode = (WRL2NODE*) np;
773 
774  return true;
775 }
776 
777 
778 bool WRL2BASE::readCoords( WRLPROC& proc, WRL2NODE* aParent, WRL2NODE** aNode )
779 {
780  if( nullptr != aNode )
781  *aNode = nullptr;
782 
783  WRL2COORDS* np = new WRL2COORDS( aParent );
784 
785  if( !np->Read( proc, this ) )
786  {
787  delete np;
788  return false;
789  }
790 
791  if( nullptr != aNode )
792  *aNode = (WRL2NODE*) np;
793 
794  return true;
795 }
796 
797 
798 bool WRL2BASE::readNorms( WRLPROC& proc, WRL2NODE* aParent, WRL2NODE** aNode )
799 {
800  if( nullptr != aNode )
801  *aNode = nullptr;
802 
803  WRL2NORMS* np = new WRL2NORMS( aParent );
804 
805  if( !np->Read( proc, this ) )
806  {
807  delete np;
808  return false;
809  }
810 
811  if( nullptr != aNode )
812  *aNode = (WRL2NODE*) np;
813 
814  return true;
815 }
816 
817 
818 bool WRL2BASE::readColor( WRLPROC& proc, WRL2NODE* aParent, WRL2NODE** aNode )
819 {
820  if( nullptr != aNode )
821  *aNode = nullptr;
822 
823  WRL2COLOR* np = new WRL2COLOR( aParent );
824 
825  if( !np->Read( proc, this ) )
826  {
827  delete np;
828  return false;
829  }
830 
831  if( nullptr != aNode )
832  *aNode = (WRL2NODE*) np;
833 
834  return true;
835 }
836 
837 
838 bool WRL2BASE::readBox( WRLPROC& proc, WRL2NODE* aParent, WRL2NODE** aNode )
839 {
840  if( nullptr != aNode )
841  *aNode = nullptr;
842 
843  WRL2BOX* np = new WRL2BOX( aParent );
844 
845  if( !np->Read( proc, this ) )
846  {
847  delete np;
848  return false;
849  }
850 
851  if( nullptr != aNode )
852  *aNode = (WRL2NODE*) np;
853 
854  return true;
855 }
856 
857 
858 bool WRL2BASE::readSwitch( WRLPROC& proc, WRL2NODE* aParent, WRL2NODE** aNode )
859 {
860  if( nullptr != aNode )
861  *aNode = nullptr;
862 
863  WRL2SWITCH* np = new WRL2SWITCH( aParent );
864 
865  if( !np->Read( proc, this ) )
866  {
867  delete np;
868  return false;
869  }
870 
871  if( nullptr != aNode )
872  *aNode = (WRL2NODE*) np;
873 
874  return true;
875 }
876 
877 
878 bool WRL2BASE::readInline( WRLPROC& proc, WRL2NODE* aParent, WRL2NODE** aNode )
879 {
880  if( nullptr != aNode )
881  *aNode = nullptr;
882 
883  if( !m_useInline )
884  {
885  if( !proc.DiscardNode() )
886  {
887  wxLogTrace( traceVrmlPlugin, wxT( " * [INFO] failed to discard in line node %s." ),
888  proc.GetFilePosition() );
889 
890  return false;
891  }
892 
893  return true;
894  }
895 
896  WRL2INLINE* np = new WRL2INLINE( aParent );
897 
898  if( !np->Read( proc, this ) )
899  {
900  delete np;
901  return false;
902  }
903 
904  if( nullptr != aNode )
905  *aNode = (WRL2NODE*) np;
906 
907  return true;
908 }
909 
910 
912 {
913  if( m_Children.empty() )
914  return nullptr;
915 
916  if( m_sgNode )
917  {
918  if( nullptr != aParent )
919  {
920  if( nullptr == S3D::GetSGNodeParent( m_sgNode )
921  && !S3D::AddSGNodeChild( aParent, m_sgNode ) )
922  {
923  return nullptr;
924  }
925  else if( aParent != S3D::GetSGNodeParent( m_sgNode )
926  && !S3D::AddSGNodeRef( aParent, m_sgNode ) )
927  {
928  return nullptr;
929  }
930  }
931 
932  return m_sgNode;
933  }
934 
935  IFSG_TRANSFORM topNode( aParent );
936 
937  std::list< WRL2NODE* >::iterator sC = m_Children.begin();
938  std::list< WRL2NODE* >::iterator eC = m_Children.end();
939  WRL2NODES type;
940 
941  // Include only Shape and Transform nodes in the top node
942  bool test = false; // set to true if there are any subnodes for display
943 
944  while( sC != eC )
945  {
946  type = (*sC)->GetNodeType();
947 
948  switch( type )
949  {
951  // wrap the shape in a transform
952  do
953  {
954  IFSG_TRANSFORM wrapper( topNode.GetRawPtr() );
955  SGNODE* pshape = (*sC)->TranslateToSG( wrapper.GetRawPtr() );
956 
957  if( nullptr != pshape )
958  test = true;
959  else
960  wrapper.Destroy();
961 
962  } while( 0 );
963 
964  break;
965 
969 
970  if( nullptr != (*sC)->TranslateToSG( topNode.GetRawPtr() ) )
971  test = true;
972 
973  break;
974 
975  default:
976  break;
977  }
978 
979  ++ sC;
980  }
981 
982  if( false == test )
983  {
984  topNode.Destroy();
985  return nullptr;
986  }
987 
988  m_sgNode = topNode.GetRawPtr();
989 
990  return m_sgNode;
991 }
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:235
bool Read(WRLPROC &proc, WRL2BASE *aTopNode) override
virtual ~WRL2BASE()
Definition: vrml2_base.cpp:59
std::list< WRL2NODE * > m_Children
Definition: vrml2_node.h:174
bool readShape(WRLPROC &proc, WRL2NODE *aParent, WRL2NODE **aNode)
Definition: vrml2_base.cpp:658
bool readMaterial(WRLPROC &proc, WRL2NODE *aParent, WRL2NODE **aNode)
Definition: vrml2_base.cpp:698
bool Read(WRLPROC &proc, WRL2BASE *aTopNode) override
bool readLineSet(WRLPROC &proc, WRL2NODE *aParent, WRL2NODE **aNode)
Definition: vrml2_base.cpp:738
bool readCoords(WRLPROC &proc, WRL2NODE *aParent, WRL2NODE **aNode)
Definition: vrml2_base.cpp:778
bool Read(WRLPROC &proc, WRL2BASE *aTopNode) override
Definition: vrml2_norms.cpp:81
WRLVERSION GetVRMLType(void)
Definition: wrlproc.cpp:230
bool Read(WRLPROC &proc)
Definition: vrml2_base.cpp:163
SGLIB_API SGNODE * GetSGNodeParent(SGNODE *aNode)
Definition: ifsg_api.cpp:492
WRL2NODES m_Type
Definition: vrml2_node.h:170
The base class of all Scene Graph nodes.
Definition: sg_node.h:74
collects header files for all SG* wrappers and the API
bool readAppearance(WRLPROC &proc, WRL2NODE *aParent, WRL2NODE **aNode)
Definition: vrml2_base.cpp:678
SGNODE * GetRawPtr(void) noexcept
Function GetRawPtr() returns the raw internal SGNODE pointer.
Definition: ifsg_node.cpp:65
SGLIB_API bool AddSGNodeRef(SGNODE *aParent, SGNODE *aChild)
Definition: ifsg_api.cpp:501
bool ReadNode(WRLPROC &proc, WRL2NODE *aParent, WRL2NODE **aNode)
Definition: vrml2_base.cpp:276
virtual bool SetName(const std::string &aName)
Definition: vrml2_node.cpp:222
WRL2NODES getNodeTypeID(const std::string &aNodeName)
Definition: vrml2_node.cpp:288
SGNODE * GetInlineData(const std::string &aName)
Definition: vrml2_base.cpp:97
bool isDangling(void) override
Determine whether an object should be moved to a different parent during the VRML to SG* translation.
Definition: vrml2_base.cpp:180
bool ReadGlob(std::string &aGlob)
Definition: wrlproc.cpp:245
void SetEnableInline(bool enable)
Definition: vrml2_base.cpp:85
bool GetEnableInline(void)
Definition: vrml2_base.cpp:91
SGLIB_API void DestroyNode(SGNODE *aNode) noexcept
Function DestroyNode deletes the given SG* class node.
Definition: ifsg_api.cpp:148
bool Read(WRLPROC &proc, WRL2BASE *aTopNode) override
bool Read(WRLPROC &proc, WRL2BASE *aTopNode) override
bool readColor(WRLPROC &proc, WRL2NODE *aParent, WRL2NODE **aNode)
Definition: vrml2_base.cpp:818
bool DiscardNode(void)
Definition: wrlproc.cpp:368
bool readFaceSet(WRLPROC &proc, WRL2NODE *aParent, WRL2NODE **aNode)
Definition: vrml2_base.cpp:718
SGLIB_API bool AddSGNodeChild(SGNODE *aParent, SGNODE *aChild)
Definition: ifsg_api.cpp:510
std::string GetFilePosition() const
Definition: wrlproc.cpp:1982
SGNODE * m_sgNode
Definition: vrml2_node.h:178
std::map< std::string, SGNODE * > m_inlineModels
Definition: vrml2_base.h:108
WRL2NODES GetNodeType(void) const
Definition: vrml2_node.cpp:204
const char * GetParentDir(void)
Definition: wrlproc.cpp:236
The top node of a VRML2 model.
Definition: vrml2_base.h:59
const wxChar *const traceVrmlPlugin
Flag to enable VRML plugin trace output.
Definition: vrml.cpp:63
virtual bool SetName(const std::string &aName) override
Definition: vrml2_base.cpp:157
bool m_useInline
Definition: vrml2_base.h:106
bool Read(WRLPROC &proc, WRL2BASE *aTopNode) override
bool Read(WRLPROC &proc, WRL2BASE *aTopNode) override
bool Read(WRLPROC &proc, WRL2BASE *aTopNode) override
bool ReadName(std::string &aName)
Definition: wrlproc.cpp:289
bool readTransform(WRLPROC &proc, WRL2NODE *aParent, WRL2NODE **aNode)
Definition: vrml2_base.cpp:638
IFSG_TRANSFORM is the wrapper for the VRML compatible TRANSFORM block class SCENEGRAPH.
virtual std::string GetName(void) override
Definition: vrml2_base.cpp:151
bool SetParent(WRL2NODE *aParent, bool doUnlink=true) override
Set the parent WRL2NODE of this object.
Definition: vrml2_base.cpp:79
Define the basic data set required to represent a 3D model.
Definition: scenegraph.h:44
bool Read(WRLPROC &proc, WRL2BASE *aTopNode) override
SCENEGRAPH * LoadVRML(const wxString &aFileName, bool useInline)
Definition: vrml.cpp:170
WRL2NODES
Definition: wrltypes.h:124
bool Read(WRLPROC &proc, WRL2BASE *aTopNode) override
Definition: vrml2_color.cpp:80
bool readSwitch(WRLPROC &proc, WRL2NODE *aParent, WRL2NODE **aNode)
Definition: vrml2_base.cpp:858
bool readNorms(WRLPROC &proc, WRL2NODE *aParent, WRL2NODE **aNode)
Definition: vrml2_base.cpp:798
std::string GetError(void)
Definition: wrlproc.cpp:1960
bool readBox(WRLPROC &proc, WRL2NODE *aParent, WRL2NODE **aNode)
Definition: vrml2_base.cpp:838
void Destroy(void)
Function Destroy deletes the object held by this wrapper.
Definition: ifsg_node.cpp:55
virtual bool AddRefNode(WRL2NODE *aNode)
Definition: vrml2_node.cpp:383
bool DiscardList(void)
Definition: wrlproc.cpp:491
bool readPointSet(WRLPROC &proc, WRL2NODE *aParent, WRL2NODE **aNode)
Definition: vrml2_base.cpp:758
bool eof(void)
Definition: wrlproc.cpp:1954
bool Read(WRLPROC &proc, WRL2BASE *aTopNode) override
Definition: vrml2_box.cpp:74
virtual WRL2NODE * FindNode(const std::string &aNodeName, const WRL2NODE *aCaller)
Search the tree of linked nodes and returns a reference to the first node found with the given name.
Definition: vrml2_node.cpp:305
bool readInline(WRLPROC &proc, WRL2NODE *aParent, WRL2NODE **aNode)
Definition: vrml2_base.cpp:878
std::string m_dir
Definition: vrml2_base.h:107
SGNODE * TranslateToSG(SGNODE *aParent) override
Produce a representation of the data using the intermediate scenegraph structures of the kicad_3dsg l...
Definition: vrml2_base.cpp:911
bool implementUse(WRLPROC &proc, WRL2NODE *aParent, WRL2NODE **aNode)
Definition: vrml2_base.cpp:187