KiCad PCB EDA Suite
sg_shape.cpp
Go to the documentation of this file.
1/*
2 * This program source code file is part of KiCad, a free EDA CAD application.
3 *
4 * Copyright (C) 2015-2017 Cirilo Bernardo <[email protected]>
5 * Copyright (C) 2020 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
26#include <iostream>
27#include <sstream>
28#include <wx/log.h>
29
38
39
40SGSHAPE::SGSHAPE( SGNODE* aParent ) : SGNODE( aParent )
41{
43 m_Appearance = nullptr;
44 m_RAppearance = nullptr;
45 m_FaceSet = nullptr;
46 m_RFaceSet = nullptr;
47
48 if( nullptr != aParent && S3D::SGTYPE_TRANSFORM != aParent->GetNodeType() )
49 {
50 m_Parent = nullptr;
51
52 wxLogTrace( MASK_3D_SG, wxT( "%s:%s:%d * [BUG] inappropriate parent to SGSHAPE (type %d)" ),
53 __FILE__, __FUNCTION__, __LINE__, aParent->GetNodeType() );
54 }
55 else if( nullptr != aParent && S3D::SGTYPE_TRANSFORM == aParent->GetNodeType() )
56 {
57 m_Parent->AddChildNode( this );
58 }
59}
60
61
63{
64 // drop references
65 if( m_RAppearance )
66 {
68 m_RAppearance = nullptr;
69 }
70
71 if( m_RFaceSet )
72 {
73 m_RFaceSet->delNodeRef( this );
74 m_RFaceSet = nullptr;
75 }
76
77 // delete objects
78 if( m_Appearance )
79 {
80 m_Appearance->SetParent( nullptr, false );
81 delete m_Appearance;
82 m_Appearance = nullptr;
83 }
84
85 if( m_FaceSet )
86 {
87 m_FaceSet->SetParent( nullptr, false );
88 delete m_FaceSet;
89 m_FaceSet = nullptr;
90 }
91}
92
93
94bool SGSHAPE::SetParent( SGNODE* aParent, bool notify )
95{
96 if( nullptr != m_Parent )
97 {
98 if( aParent == m_Parent )
99 return true;
100
101 // handle the change in parents
102 if( notify )
103 m_Parent->unlinkChildNode( this );
104
105 m_Parent = nullptr;
106
107 if( nullptr == aParent )
108 return true;
109 }
110
111 // only a SGTRANSFORM may be parent to a SGSHAPE
112 if( nullptr != aParent && S3D::SGTYPE_TRANSFORM != aParent->GetNodeType() )
113 return false;
114
115 m_Parent = aParent;
116
117 if( m_Parent )
118 m_Parent->AddChildNode( this );
119
120 return true;
121}
122
123
124SGNODE* SGSHAPE::FindNode( const char* aNodeName, const SGNODE* aCaller )
125{
126 if( nullptr == aNodeName || 0 == aNodeName[0] )
127 return nullptr;
128
129 if( !m_Name.compare( aNodeName ) )
130 return this;
131
132 SGNODE* tmp = nullptr;
133
134 if( nullptr != m_Appearance )
135 {
136 tmp = m_Appearance->FindNode( aNodeName, this );
137
138 if( tmp )
139 {
140 return tmp;
141 }
142 }
143
144 if( nullptr != m_FaceSet )
145 {
146 tmp = m_FaceSet->FindNode( aNodeName, this );
147
148 if( tmp )
149 {
150 return tmp;
151 }
152 }
153
154 // query the parent if appropriate
155 if( aCaller == m_Parent || nullptr == m_Parent )
156 return nullptr;
157
158 return m_Parent->FindNode( aNodeName, this );
159}
160
161
162void SGSHAPE::unlinkNode( const SGNODE* aNode, bool isChild )
163{
164 if( nullptr == aNode )
165 return;
166
167 if( isChild )
168 {
169 if( aNode == m_Appearance )
170 {
171 m_Appearance = nullptr;
172 return;
173 }
174
175 if( aNode == m_FaceSet )
176 {
177 m_FaceSet = nullptr;
178 return;
179 }
180 }
181 else
182 {
183 if( aNode == m_RAppearance )
184 {
185 delNodeRef( this );
186 m_RAppearance = nullptr;
187 return;
188 }
189
190 if( aNode == m_RFaceSet )
191 {
192 delNodeRef( this );
193 m_RFaceSet = nullptr;
194 return;
195 }
196 }
197
198 wxLogTrace( MASK_3D_SG, wxT( "%s:%s:%d * [BUG] unlinkNode() did not find its target" ),
199 __FILE__, __FUNCTION__, __LINE__ );
200}
201
202
204{
205 unlinkNode( aNode, true );
206}
207
208
209void SGSHAPE::unlinkRefNode( const SGNODE* aNode )
210{
211 unlinkNode( aNode, false );
212}
213
214
215bool SGSHAPE::addNode( SGNODE* aNode, bool isChild )
216{
217 wxCHECK( aNode, false );
218
219 if( S3D::SGTYPE_APPEARANCE == aNode->GetNodeType() )
220 {
222 {
223 if( aNode != m_Appearance && aNode != m_RAppearance )
224 {
225 wxLogTrace( MASK_3D_SG, wxT( "%s:%s:%d * [BUG] assigning multiple Appearance "
226 "nodes" ),
227 __FILE__, __FUNCTION__, __LINE__ );
228
229 return false;
230 }
231
232 return true;
233 }
234
235 if( isChild )
236 {
237 m_Appearance = (SGAPPEARANCE*)aNode;
238 m_Appearance->SetParent( this );
239 }
240 else
241 {
242 m_RAppearance = (SGAPPEARANCE*)aNode;
243 m_RAppearance->addNodeRef( this );
244 }
245
246 return true;
247 }
248
249 if( S3D::SGTYPE_FACESET == aNode->GetNodeType() )
250 {
251 if( m_FaceSet || m_RFaceSet )
252 {
253 if( aNode != m_FaceSet && aNode != m_RFaceSet )
254 {
255 wxLogTrace( MASK_3D_SG, wxT( "%s:%s:%d * [BUG] assigning multiple FaceSet nodes" ),
256 __FILE__, __FUNCTION__, __LINE__ );
257
258 return false;
259 }
260
261 return true;
262 }
263
264 if( isChild )
265 {
266 m_FaceSet = (SGFACESET*)aNode;
267 m_FaceSet->SetParent( this );
268 }
269 else
270 {
271 m_RFaceSet = (SGFACESET*)aNode;
272 m_RFaceSet->addNodeRef( this );
273 }
274
275 return true;
276 }
277
278 wxLogTrace( MASK_3D_SG, wxT( "%s:%s:%d * [BUG] object %s is not a valid type for this "
279 "object (%d)" ),
280 __FILE__, __FUNCTION__, __LINE__, aNode->GetName(), aNode->GetNodeType() );
281
282 return false;
283}
284
285
287{
288 return addNode( aNode, false );
289}
290
291
293{
294 return addNode( aNode, true );
295}
296
297
299{
300 m_written = false;
301
302 // rename this node
303 m_Name.clear();
304 GetName();
305
306 // rename Appearance
307 if( m_Appearance )
309
310 // rename FaceSet
311 if( m_FaceSet )
313}
314
315
316bool SGSHAPE::WriteVRML( std::ostream& aFile, bool aReuseFlag )
317{
319 {
320 return false;
321 }
322
323 if( aReuseFlag )
324 {
325 if( !m_written )
326 {
327 aFile << "DEF " << GetName() << " Shape {\n";
328 m_written = true;
329 }
330 else
331 {
332 aFile << " USE " << GetName() << "\n";
333 return true;
334 }
335 }
336 else
337 {
338 aFile << " Shape {\n";
339 }
340
341 if( m_Appearance )
342 m_Appearance->WriteVRML( aFile, aReuseFlag );
343
344 if( m_RAppearance )
345 m_RAppearance->WriteVRML( aFile, aReuseFlag );
346
347 if( m_FaceSet )
348 m_FaceSet->WriteVRML( aFile, aReuseFlag );
349
350 if( m_RFaceSet )
351 m_RFaceSet->WriteVRML( aFile, aReuseFlag );
352
353 aFile << "}\n";
354
355 return true;
356}
357
358
359bool SGSHAPE::WriteCache( std::ostream& aFile, SGNODE* parentNode )
360{
361 if( nullptr == parentNode )
362 {
363 wxCHECK( m_Parent, false );
364
365 SGNODE* np = m_Parent;
366
367 while( nullptr != np->GetParent() )
368 np = np->GetParent();
369
370 if( np->WriteCache( aFile, nullptr ) )
371 {
372 m_written = true;
373 return true;
374 }
375
376 return false;
377 }
378
379 wxCHECK( parentNode == m_Parent, false );
380
381 if( !aFile.good() )
382 {
383 wxLogTrace( MASK_3D_SG, wxT( "%s:%s:%d * [BUG] bad stream" ),
384 __FILE__, __FUNCTION__, __LINE__ );
385
386 return false;
387 }
388
389 // check if any references are unwritten and swap parents if so
390 if( nullptr != m_RAppearance && !m_RAppearance->isWritten() )
392
393 if( nullptr != m_RFaceSet && !m_RFaceSet->isWritten() )
394 m_RFaceSet->SwapParent( this );
395
396 aFile << "[" << GetName() << "]";
397 #define NITEMS 4
398 bool items[NITEMS];
399 int i;
400
401 for( i = 0; i < NITEMS; ++i )
402 items[i] = 0;
403
404 i = 0;
405
406 if( nullptr != m_Appearance )
407 items[i] = true;
408
409 ++i;
410
411 if( nullptr != m_RAppearance )
412 items[i] = true;
413
414 ++i;
415
416 if( nullptr != m_FaceSet )
417 items[i] = true;
418
419 ++i;
420
421 if( nullptr != m_RFaceSet )
422 items[i] = true;
423
424 for( int jj = 0; jj < NITEMS; ++jj )
425 aFile.write( (char*)&items[jj], sizeof(bool) );
426
427 if( items[0] )
428 m_Appearance->WriteCache( aFile, this );
429
430 if( items[1] )
431 aFile << "[" << m_RAppearance->GetName() << "]";
432
433 if( items[2] )
434 m_FaceSet->WriteCache( aFile, this );
435
436 if( items[3] )
437 aFile << "[" << m_RFaceSet->GetName() << "]";
438
439 if( aFile.fail() )
440 return false;
441
442 m_written = true;
443 return true;
444}
445
446
447bool SGSHAPE::ReadCache( std::istream& aFile, SGNODE* parentNode )
448{
449 wxCHECK( m_Appearance == nullptr && m_RAppearance == nullptr && m_FaceSet == nullptr &&
450 m_RFaceSet == nullptr, false );
451
452 #define NITEMS 4
453 bool items[NITEMS];
454
455 for( int i = 0; i < NITEMS; ++i )
456 aFile.read( (char*)&items[i], sizeof(bool) );
457
458 if( ( items[0] && items[1] ) || ( items[2] && items[3] ) )
459 {
460 wxLogTrace( MASK_3D_SG, wxT( "%s:%s:%d * [INFO] corrupt data; multiple item definitions "
461 "at position %ul" ),
462 __FILE__, __FUNCTION__, __LINE__,
463 static_cast<unsigned long>( aFile.tellg() ) );
464
465 return false;
466 }
467
468 std::string name;
469
470 if( items[0] )
471 {
472 if( S3D::SGTYPE_APPEARANCE != S3D::ReadTag( aFile, name ) )
473 {
474 wxLogTrace( MASK_3D_SG, wxT( "%s:%s:%d * [INFO] corrupt data; bad child appearance "
475 "tag at position %ul" ),
476 __FILE__, __FUNCTION__, __LINE__,
477 static_cast<unsigned long>( aFile.tellg() ) );
478
479 return false;
480 }
481
482 m_Appearance = new SGAPPEARANCE( this );
483 m_Appearance->SetName( name.c_str() );
484
485 if( !m_Appearance->ReadCache( aFile, this ) )
486 {
487 wxLogTrace( MASK_3D_SG, wxT( "%s:%s:%d * [INFO] corrupt data while reading appearance "
488 "'%s'" ),
489 __FILE__, __FUNCTION__, __LINE__, name );
490
491 return false;
492 }
493 }
494
495 if( items[1] )
496 {
497 if( S3D::SGTYPE_APPEARANCE != S3D::ReadTag( aFile, name ) )
498 {
499 wxLogTrace( MASK_3D_SG, wxT( "%s:%s:%d * [INFO] corrupt data; bad ref appearance tag "
500 "at position %ul" ),
501 __FILE__, __FUNCTION__, __LINE__,
502 static_cast<unsigned long>( aFile.tellg() ) );
503
504 return false;
505 }
506
507 SGNODE* np = FindNode( name.c_str(), this );
508
509 if( !np )
510 {
511 wxLogTrace( MASK_3D_SG, wxT( "%s:%s:%d * [INFO] corrupt data: cannot find ref "
512 "appearance '%s'" ),
513 __FILE__, __FUNCTION__, __LINE__,
514 name );
515
516 return false;
517 }
518
520 {
521 wxLogTrace( MASK_3D_SG, wxT( "%s:%s:%d * [INFO] corrupt data: type is not "
522 "SGAPPEARANCE '%s'" ),
523 __FILE__, __FUNCTION__, __LINE__,
524 name );
525
526 return false;
527 }
528
530 m_RAppearance->addNodeRef( this );
531 }
532
533 if( items[2] )
534 {
535 if( S3D::SGTYPE_FACESET != S3D::ReadTag( aFile, name ) )
536 {
537 wxLogTrace( MASK_3D_SG, wxT( "%s:%s:%d * [INFO] corrupt data; bad child face set tag "
538 "at position %ul" ),
539 __FILE__, __FUNCTION__, __LINE__,
540 static_cast<unsigned long>( aFile.tellg() ) );
541
542 return false;
543 }
544
545 m_FaceSet = new SGFACESET( this );
546 m_FaceSet->SetName( name.c_str() );
547
548 if( !m_FaceSet->ReadCache( aFile, this ) )
549 {
550 wxLogTrace( MASK_3D_SG, wxT( "%s:%s:%d * [INFO] corrupt data while reading face set "
551 "'%s'" ),
552 __FILE__, __FUNCTION__, __LINE__, name );
553
554 return false;
555 }
556 }
557
558 if( items[3] )
559 {
560 if( S3D::SGTYPE_FACESET != S3D::ReadTag( aFile, name ) )
561 {
562 wxLogTrace( MASK_3D_SG, wxT( "%s:%s:%d * [INFO] corrupt data; bad ref face set tag at "
563 "position %ul" ),
564 __FILE__, __FUNCTION__, __LINE__,
565 static_cast<unsigned long>( aFile.tellg() ) );
566
567 return false;
568 }
569
570 SGNODE* np = FindNode( name.c_str(), this );
571
572 if( !np )
573 {
574 wxLogTrace( MASK_3D_SG, wxT( "%s:%s:%d * [INFO] corrupt data: cannot find ref face "
575 "set '%s'" ),
576 __FILE__, __FUNCTION__, __LINE__,
577 name );
578
579 return false;
580 }
581
582 if( S3D::SGTYPE_FACESET != np->GetNodeType() )
583 {
584 wxLogTrace( MASK_3D_SG, wxT( "%s:%s:%d * [INFO] corrupt data: type is not SGFACESET "
585 "'%s'" ),
586 __FILE__, __FUNCTION__, __LINE__,
587 name );
588
589 return false;
590 }
591
592 m_RFaceSet = (SGFACESET*)np;
593 m_RFaceSet->addNodeRef( this );
594 }
595
596 if( aFile.fail() )
597 return false;
598
599 return true;
600}
601
602
603bool SGSHAPE::Prepare( const glm::dmat4* aTransform, S3D::MATLIST& materials,
604 std::vector< SMESH >& meshes )
605{
606 SMESH m;
607 S3D::INIT_SMESH( m );
608
610 SGFACESET* pf = m_FaceSet;
611
612 if( nullptr == pa )
613 pa = m_RAppearance;
614
615 if( nullptr == pf )
616 pf = m_RFaceSet;
617
618 // no face sets = nothing to render, which is valid though pointless
619 if( nullptr == pf )
620 return true;
621
622 if( !pf->validate() )
623 {
624 wxLogTrace( MASK_3D_SG, wxT( "%s:%s:%d * [INFO] bad model; inconsistent data" ),
625 __FILE__, __FUNCTION__, __LINE__ );
626
627 return true;
628 }
629
630 if( nullptr == pa )
631 {
632 m.m_MaterialIdx = 0;
633 }
634 else
635 {
636 int idx;
637
638 if( !S3D::GetMatIndex( materials, pa, idx ) )
639 {
640 m.m_MaterialIdx = 0;
641 }
642 else
643 {
644 m.m_MaterialIdx = idx;
645 }
646 }
647
648 SGCOLORS* pc = pf->m_Colors;
649 SGCOORDS* pv = pf->m_Coords;
650 SGCOORDINDEX* vidx = pf->m_CoordIndices;
651 SGNORMALS* pn = pf->m_Normals;
652
653 if( nullptr == pc )
654 pc = pf->m_RColors;
655
656 if( nullptr == pv )
657 pv = pf->m_RCoords;
658
659 if( nullptr == pn )
660 pn = pf->m_RNormals;
661
662 // set the vertex points and indices
663 size_t nCoords = 0;
664 SGPOINT* pCoords = nullptr;
665 pv->GetCoordsList( nCoords, pCoords );
666
667 size_t nColors = 0;
668 SGCOLOR* pColors = nullptr;
669
670 if( pc )
671 {
672 // check the vertex colors
673 pc->GetColorList( nColors, pColors );
674
675 if( nColors < nCoords )
676 {
677 wxLogTrace( MASK_3D_SG, wxT( "%s:%s:%d * [INFO] bad model; not enough colors per "
678 "vertex (%ul vs %ul)" ),
679 __FILE__, __FUNCTION__, __LINE__, static_cast<unsigned long>( nColors ),
680 static_cast<unsigned long>( nCoords ) );
681
682 return true;
683 }
684 }
685
686 // set the vertex indices
687 size_t nvidx = 0;
688 int* lv = nullptr;
689 vidx->GetIndices( nvidx, lv );
690
691 // note: reduce the vertex set to include only the referenced vertices
692 std::vector< int > vertices; // store the list of temp vertex indices
693 std::map< int, unsigned int > indexmap; // map temp vertex to true vertex
694 std::map< int, unsigned int >::iterator mit;
695
696 for( unsigned int i = 0; i < nvidx; ++i )
697 {
698 mit = indexmap.find( lv[i] );
699
700 if( mit == indexmap.end() )
701 {
702 indexmap.emplace( lv[i], vertices.size() );
703 vertices.push_back( lv[i] );
704 }
705 }
706
707 if( vertices.size() < 3 )
708 {
709 wxLogTrace( MASK_3D_SG, wxT( "%s:%s:%d * [INFO] bad model; not enough vertices" ),
710 __FILE__, __FUNCTION__, __LINE__ );
711
712 return true;
713 }
714
715 // construct the final vertex/color list
716 SFVEC3F* lColors = nullptr;
717 SFVEC3F* lCoords = new SFVEC3F[ vertices.size() ];
718 int ti;
719
720 if( pc )
721 {
722 lColors = new SFVEC3F[vertices.size()];
723 m.m_Color = lColors;
724 }
725
726 if( pc )
727 {
728 for( size_t i = 0; i < vertices.size(); ++i )
729 {
730 ti = vertices[i];
731 glm::dvec4 pt( pCoords[ti].x, pCoords[ti].y, pCoords[ti].z, 1.0 );
732 pt = (*aTransform) * pt;
733 pColors[ti].GetColor( lColors[i].x, lColors[i].y, lColors[i].z );
734 lCoords[i] = SFVEC3F( pt.x, pt.y, pt.z );
735 }
736 }
737 else
738 {
739 for( size_t i = 0; i < vertices.size(); ++i )
740 {
741 ti = vertices[i];
742 glm::dvec4 pt( pCoords[ti].x, pCoords[ti].y, pCoords[ti].z, 1.0 );
743 pt = (*aTransform) * pt;
744 lCoords[i] = SFVEC3F( pt.x, pt.y, pt.z );
745 }
746 }
747
748 m.m_VertexSize = (unsigned int) vertices.size();
749 m.m_Positions = lCoords;
750 unsigned int* lvidx = new unsigned int[ nvidx ];
751
752 for( unsigned int i = 0; i < nvidx; ++i )
753 {
754 mit = indexmap.find( lv[i] );
755 lvidx[i] = mit->second;
756 }
757
758 m.m_FaceIdxSize = (unsigned int )nvidx;
759 m.m_FaceIdx = lvidx;
760
761 // set the per-vertex normals
762 size_t nNorms = 0;
763 SGVECTOR* pNorms = nullptr;
764 double x, y, z;
765
766 pn->GetNormalList( nNorms, pNorms );
767 SFVEC3F* lNorms = new SFVEC3F[ vertices.size() ];
768
769 for( size_t i = 0; i < vertices.size(); ++i )
770 {
771 ti = vertices[i];
772 pNorms[ti].GetVector( x, y, z );
773 glm::dvec4 pt( x, y, z, 0.0 );
774 pt = (*aTransform) * pt;
775
776 lNorms[i] = SFVEC3F( pt.x, pt.y, pt.z );
777 }
778
779 m.m_Normals = lNorms;
780 meshes.push_back( m );
781
782 return true;
783}
const char * name
Definition: DXF_plotter.cpp:56
Defines the generic material appearance of a scenegraph object.
Definition: sg_appearance.h:38
SGNODE * FindNode(const char *aNodeName, const SGNODE *aCaller) noexcept override
Search the tree of linked nodes and return a reference to the first node found with the given name.
bool WriteVRML(std::ostream &aFile, bool aReuseFlag) override
Writes this node's data to a VRML file.
bool ReadCache(std::istream &aFile, SGNODE *parentNode) override
Reads binary format data from a cache file.
bool WriteCache(std::ostream &aFile, SGNODE *parentNode) override
Write this node's data to a binary cache file.
void ReNameNodes(void) override
Rename a node and all its child nodes in preparation for write operations.
virtual bool SetParent(SGNODE *aParent, bool notify=true) override
Set the parent SGNODE of this object.
Define an RGB color set for a scenegraph object.
Definition: sg_colors.h:39
bool GetColorList(size_t &aListSize, SGCOLOR *&aColorList)
Definition: sg_colors.cpp:128
void GetColor(float &aRedVal, float &aGreenVal, float &aBlueVal) const noexcept
Definition: sg_base.cpp:59
An object to maintain a coordinate index list.
Definition: sg_coordindex.h:43
Define a vertex coordinate set for a scenegraph object.
Definition: sg_coords.h:41
bool GetCoordsList(size_t &aListSize, SGPOINT *&aCoordsList)
Definition: sg_coords.cpp:130
Define an indexed face set for a scenegraph.
Definition: sg_faceset.h:47
SGCOORDS * m_RCoords
Definition: sg_faceset.h:86
SGCOORDINDEX * m_CoordIndices
Definition: sg_faceset.h:81
SGNODE * FindNode(const char *aNodeName, const SGNODE *aCaller) override
Search the tree of linked nodes and return a reference to the first node found with the given name.
Definition: sg_faceset.cpp:149
SGCOORDS * m_Coords
Definition: sg_faceset.h:80
void ReNameNodes(void) override
Rename a node and all its child nodes in preparation for write operations.
Definition: sg_faceset.cpp:413
SGNORMALS * m_Normals
Definition: sg_faceset.h:82
virtual bool SetParent(SGNODE *aParent, bool notify=true) override
Set the parent SGNODE of this object.
Definition: sg_faceset.cpp:119
SGCOLORS * m_RColors
Definition: sg_faceset.h:85
SGNORMALS * m_RNormals
Definition: sg_faceset.h:87
bool validate(void)
Definition: sg_faceset.cpp:854
SGCOLORS * m_Colors
Definition: sg_faceset.h:79
bool WriteCache(std::ostream &aFile, SGNODE *parentNode) override
Write this node's data to a binary cache file.
Definition: sg_faceset.cpp:493
bool WriteVRML(std::ostream &aFile, bool aReuseFlag) override
Writes this node's data to a VRML file.
Definition: sg_faceset.cpp:438
bool ReadCache(std::istream &aFile, SGNODE *parentNode) override
Reads binary format data from a cache file.
Definition: sg_faceset.cpp:601
bool GetIndices(size_t &nIndices, int *&aIndexList)
Retrieve the number of indices and a pointer to the list.
Definition: sg_index.cpp:126
The base class of all Scene Graph nodes.
Definition: sg_node.h:75
void SetName(const char *aName)
Definition: sg_node.cpp:155
virtual bool WriteCache(std::ostream &aFile, SGNODE *parentNode)=0
Write this node's data to a binary cache file.
const char * GetName(void)
Definition: sg_node.cpp:146
virtual SGNODE * FindNode(const char *aNodeName, const SGNODE *aCaller)=0
Search the tree of linked nodes and return a reference to the first node found with the given name.
bool isWritten(void) noexcept
Return true if the object had already been written to a cache file or VRML file.
Definition: sg_node.h:220
SGNODE * GetParent(void) const noexcept
Returns a pointer to the parent SGNODE of this object or NULL if the object has no parent (ie.
Definition: sg_node.cpp:110
S3D::SGTYPES GetNodeType(void) const noexcept
Return the type of this node instance.
Definition: sg_node.cpp:104
virtual bool AddChildNode(SGNODE *aNode)=0
SGNODE * m_Parent
Pointer to parent node; may be NULL for top level transform.
Definition: sg_node.h:227
std::string m_Name
name to use for referencing the entity by name.
Definition: sg_node.h:229
void addNodeRef(SGNODE *aNode)
Add a pointer to a node which references this node, but does not own.
Definition: sg_node.cpp:170
virtual void unlinkChildNode(const SGNODE *aNode)=0
Remove references to an owned child.
void delNodeRef(const SGNODE *aNode)
Remove a pointer to a node which references this node, but does not own.
Definition: sg_node.cpp:185
bool m_written
Set to true when the object has been written after a ReNameNodes().
Definition: sg_node.h:230
S3D::SGTYPES m_SGtype
Type of Scene Graph node.
Definition: sg_node.h:228
bool SwapParent(SGNODE *aNewParent)
Swap the ownership with the given parent.
Definition: sg_node.cpp:116
Define a set of vertex normals for a scene graph object.
Definition: sg_normals.h:39
bool GetNormalList(size_t &aListSize, SGVECTOR *&aNormalList)
Definition: sg_normals.cpp:129
SGNODE * FindNode(const char *aNodeName, const SGNODE *aCaller) override
Search the tree of linked nodes and return a reference to the first node found with the given name.
Definition: sg_shape.cpp:124
bool WriteVRML(std::ostream &aFile, bool aReuseFlag) override
Writes this node's data to a VRML file.
Definition: sg_shape.cpp:316
virtual bool SetParent(SGNODE *aParent, bool notify=true) override
Set the parent SGNODE of this object.
Definition: sg_shape.cpp:94
bool AddChildNode(SGNODE *aNode) override
Definition: sg_shape.cpp:292
void unlinkRefNode(const SGNODE *aNode) override
Remove pointers to a referenced node.
Definition: sg_shape.cpp:209
void unlinkNode(const SGNODE *aNode, bool isChild)
Definition: sg_shape.cpp:162
bool Prepare(const glm::dmat4 *aTransform, S3D::MATLIST &materials, std::vector< SMESH > &meshes)
Definition: sg_shape.cpp:603
virtual ~SGSHAPE()
Definition: sg_shape.cpp:62
SGFACESET * m_RFaceSet
Definition: sg_shape.h:77
bool AddRefNode(SGNODE *aNode) override
Definition: sg_shape.cpp:286
SGSHAPE(SGNODE *aParent)
Definition: sg_shape.cpp:40
SGFACESET * m_FaceSet
Definition: sg_shape.h:73
void ReNameNodes(void) override
Rename a node and all its child nodes in preparation for write operations.
Definition: sg_shape.cpp:298
bool addNode(SGNODE *aNode, bool isChild)
Definition: sg_shape.cpp:215
void unlinkChildNode(const SGNODE *aNode) override
Remove references to an owned child.
Definition: sg_shape.cpp:203
bool WriteCache(std::ostream &aFile, SGNODE *parentNode) override
Write this node's data to a binary cache file.
Definition: sg_shape.cpp:359
SGAPPEARANCE * m_RAppearance
Definition: sg_shape.h:76
bool ReadCache(std::istream &aFile, SGNODE *parentNode) override
Reads binary format data from a cache file.
Definition: sg_shape.cpp:447
SGAPPEARANCE * m_Appearance
Definition: sg_shape.h:72
void GetVector(double &aXVal, double &aYVal, double &aZVal) const noexcept
Definition: sg_base.cpp:225
void INIT_SMESH(SMESH &aMesh) noexcept
Definition: sg_node.cpp:276
bool GetMatIndex(MATLIST &aList, SGNODE *aNode, int &aIndex)
Definition: sg_node.cpp:245
S3D::SGTYPES ReadTag(std::istream &aFile, std::string &aName)
Read the text tag of a binary cache file which is the NodeTag and unique ID number combined.
Definition: sg_helpers.cpp:195
@ SGTYPE_SHAPE
Definition: sg_types.h:44
@ SGTYPE_FACESET
Definition: sg_types.h:40
@ SGTYPE_APPEARANCE
Definition: sg_types.h:37
@ SGTYPE_TRANSFORM
Definition: sg_types.h:36
Define a number of macros to aid in repetitious code which is probably best expressed as a preprocess...
#define NITEMS
Per-vertex normal/color/texcoors structure.
Definition: c3dmodel.h:77
unsigned int * m_FaceIdx
Triangle Face Indexes.
Definition: c3dmodel.h:84
SFVEC3F * m_Normals
Vertex normals array.
Definition: c3dmodel.h:80
unsigned int m_MaterialIdx
Material Index to be used in this mesh (must be < m_MaterialsSize )
Definition: c3dmodel.h:85
unsigned int m_VertexSize
Number of vertex in the arrays.
Definition: c3dmodel.h:78
unsigned int m_FaceIdxSize
Number of elements of the m_FaceIdx array.
Definition: c3dmodel.h:83
SFVEC3F * m_Color
Vertex color array, can be NULL.
Definition: c3dmodel.h:82
SFVEC3F * m_Positions
Vertex position array.
Definition: c3dmodel.h:79
glm::vec3 SFVEC3F
Definition: xv3d_types.h:44