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