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