KiCad PCB EDA Suite
Loading...
Searching...
No Matches
sg_index.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#include <iostream>
22#include <sstream>
23#include <wx/log.h>
24
26
27
28SGINDEX::SGINDEX( SGNODE* aParent ) : SGNODE( aParent )
29{
30 if( nullptr != aParent && S3D::SGTYPE_FACESET != aParent->GetNodeType() )
31 {
32 m_Parent = nullptr;
33
34 wxLogTrace( MASK_3D_SG, wxT( "%s:%s:%d * [BUG] inappropriate parent to SGINDEX (type "
35 "'%d')" ),
36 __FILE__, __FUNCTION__, __LINE__,
37 aParent->GetNodeType() );
38 }
39}
40
41
43{
44 index.clear();
45}
46
47
48bool SGINDEX::SetParent( SGNODE* aParent, bool notify )
49{
50 if( nullptr != m_Parent )
51 {
52 if( aParent == m_Parent )
53 return true;
54
55 // handle the change in parents
56 if( notify )
57 m_Parent->unlinkChildNode( this );
58
59 m_Parent = nullptr;
60
61 if( nullptr == aParent )
62 return true;
63 }
64
65 // only a SGFACESET may be parent to a SGINDEX and derived types
66 if( nullptr != aParent && S3D::SGTYPE_FACESET != aParent->GetNodeType() )
67 return false;
68
69 m_Parent = aParent;
70
71 if( m_Parent )
72 m_Parent->AddChildNode( this );
73
74 return true;
75}
76
77
78SGNODE* SGINDEX::FindNode(const char *aNodeName, const SGNODE *aCaller) noexcept
79{
80 if( nullptr == aNodeName || 0 == aNodeName[0] )
81 return nullptr;
82
83 if( !m_Name.compare( aNodeName ) )
84 return this;
85
86 return nullptr;
87}
88
89
90void SGINDEX::unlinkChildNode( const SGNODE* aCaller ) noexcept
91{
92 // Node should have no children or refs.
93 wxCHECK( false, /* void */ );
94}
95
96
97void SGINDEX::unlinkRefNode( const SGNODE* aCaller ) noexcept
98{
99 // Node should have no children or refs.
100 wxCHECK( false, /* void */ );
101}
102
103
104bool SGINDEX::AddRefNode( SGNODE* aNode ) noexcept
105{
106 // Node should have no children or refs.
107 wxCHECK( false, false );
108
109 return false;
110}
111
112
113bool SGINDEX::AddChildNode( SGNODE* aNode ) noexcept
114{
115 // Node should have no children or refs.
116 wxCHECK( false, false );
117
118 return false;
119}
120
121
122bool SGINDEX::GetIndices( size_t& nIndices, int*& aIndexList )
123{
124 if( index.empty() )
125 {
126 nIndices = 0;
127 aIndexList = nullptr;
128 return false;
129 }
130
131 nIndices = index.size();
132 aIndexList = & index[0];
133 return true;
134}
135
136
137void SGINDEX::SetIndices( size_t nIndices, int* aIndexList )
138{
139 index.clear();
140
141 if( 0 == nIndices || nullptr == aIndexList )
142 return;
143
144 for( size_t i = 0; i < nIndices; ++i )
145 index.push_back( aIndexList[i] );
146
147 return;
148}
149
150
151void SGINDEX::AddIndex( int aIndex )
152{
153 index.push_back( aIndex );
154}
155
156
158{
159 m_written = false;
160
161 // rename this node
162 m_Name.clear();
163 GetName();
164}
165
166
167bool SGINDEX::WriteVRML( std::ostream& aFile, bool aReuseFlag )
168{
169 if( index.empty() )
170 return false;
171
173 return writeCoordIndex( aFile );
174
175 return writeColorIndex( aFile );
176}
177
178
179bool SGINDEX::writeCoordIndex( std::ostream& aFile )
180{
181 size_t n = index.size();
182
183 wxCHECK_MSG( n % 3 == 0, false, wxT( "Coordinate index is not divisible by three (violates "
184 "triangle constraint)" ) );
185
186 aFile << " coordIndex [\n ";
187
188 // indices to control formatting
189 int nv0 = 0;
190 int nv1 = 0;
191
192 for( size_t i = 0; i < n; )
193 {
194 aFile << index[i];
195 ++i;
196
197 if( ++nv0 == 3 )
198 {
199 aFile << ",-1";
200 ++nv1;
201 nv0 = 0;
202 }
203
204 if( i < n )
205 {
206 aFile << ",";
207
208 if( nv1 == 8 )
209 {
210 nv1 = 0;
211 aFile << "\n ";
212 }
213 }
214 }
215
216 aFile << "]\n";
217
218 return true;
219}
220
221
222bool SGINDEX::writeColorIndex( std::ostream& aFile )
223{
224 aFile << " colorIndex [\n ";
225 return writeIndexList( aFile );
226}
227
228
229bool SGINDEX::writeIndexList( std::ostream& aFile )
230{
231 // index to control formatting
232 int nv = 0;
233 size_t n = index.size();
234
235 for( size_t i = 0; i < n; )
236 {
237 aFile << index[i];
238 ++i;
239
240 if( i < n )
241 {
242 aFile << ",";
243
244 if( ++nv == 20 )
245 {
246 aFile << "\n ";
247 nv = 0;
248 }
249 }
250 }
251
252 aFile << "]\n";
253
254 return true;
255}
256
257
258bool SGINDEX::WriteCache( std::ostream& aFile, SGNODE* parentNode )
259{
260 if( nullptr == parentNode )
261 {
262 wxCHECK( m_Parent, false );
263
264 SGNODE* np = m_Parent;
265
266 while( nullptr != np->GetParent() )
267 np = np->GetParent();
268
269 if( np->WriteCache( aFile, nullptr ) )
270 {
271 m_written = true;
272 return true;
273 }
274
275 return false;
276 }
277
278 wxCHECK( parentNode == m_Parent, false );
279
280 if( !aFile.good() )
281 {
282 wxLogTrace( MASK_3D_SG, wxT( "%s:%s:%d * [INFO] bad stream" ),
283 __FILE__, __FUNCTION__, __LINE__ );
284
285 return false;
286 }
287
288 aFile << "[" << GetName() << "]";
289 size_t npts = index.size();
290 aFile.write( (char*)&npts, sizeof(size_t) );
291
292 for( size_t i = 0; i < npts; ++i )
293 aFile.write( (char*)&index[i], sizeof(int) );
294
295 if( aFile.fail() )
296 return false;
297
298 m_written = true;
299 return true;
300}
301
302
303bool SGINDEX::ReadCache( std::istream& aFile, SGNODE* parentNode )
304{
305 wxCHECK( index.empty(), false );
306
307 size_t npts;
308 aFile.read( (char*)&npts, sizeof(size_t) );
309 int tmp;
310
311 if( aFile.fail() )
312 return false;
313
314 for( size_t i = 0; i < npts; ++i )
315 {
316 aFile.read( (char*) &tmp, sizeof( int ) );
317
318 if( aFile.fail() )
319 return false;
320
321 index.push_back( tmp );
322 }
323
324 return true;
325}
bool AddChildNode(SGNODE *aNode) noexcept override
Definition sg_index.cpp:113
void unlinkChildNode(const SGNODE *aCaller) noexcept override
Remove references to an owned child.
Definition sg_index.cpp:90
void unlinkRefNode(const SGNODE *aCaller) noexcept override
Remove pointers to a referenced node.
Definition sg_index.cpp:97
SGINDEX(SGNODE *aParent)
Definition sg_index.cpp:28
bool writeCoordIndex(std::ostream &aFile)
Definition sg_index.cpp:179
bool GetIndices(size_t &nIndices, int *&aIndexList)
Retrieve the number of indices and a pointer to the list.
Definition sg_index.cpp:122
std::vector< int > index
Definition sg_index.h:91
bool WriteVRML(std::ostream &aFile, bool aReuseFlag) override
Writes this node's data to a VRML file.
Definition sg_index.cpp:167
bool ReadCache(std::istream &aFile, SGNODE *parentNode) override
Reads binary format data from a cache file.
Definition sg_index.cpp:303
void AddIndex(int aIndex)
Add a single index to the list.
Definition sg_index.cpp:151
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.
Definition sg_index.cpp:78
bool writeColorIndex(std::ostream &aFile)
Definition sg_index.cpp:222
void ReNameNodes(void) override
Rename a node and all its child nodes in preparation for write operations.
Definition sg_index.cpp:157
void SetIndices(size_t nIndices, int *aIndexList)
Set the number of indices and creates a copy of the given index data.
Definition sg_index.cpp:137
virtual ~SGINDEX()
Definition sg_index.cpp:42
virtual bool SetParent(SGNODE *aParent, bool notify=true) override
Set the parent SGNODE of this object.
Definition sg_index.cpp:48
bool WriteCache(std::ostream &aFile, SGNODE *parentNode) override
Write this node's data to a binary cache file.
Definition sg_index.cpp:258
bool writeIndexList(std::ostream &aFile)
Definition sg_index.cpp:229
bool AddRefNode(SGNODE *aNode) noexcept override
Definition sg_index.cpp:104
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
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
@ SGTYPE_FACESET
Definition sg_types.h:37
@ SGTYPE_COORDINDEX
Definition sg_types.h:39