KiCad PCB EDA Suite
Loading...
Searching...
No Matches
sg_helpers.h
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
28
29#ifndef SG_HELPERS_H
30#define SG_HELPERS_H
31
32#include <iostream>
33#include <string>
34#include <algorithm>
35#include <vector>
38#include <glm/fwd.hpp>
39
40class SGNORMALS;
41class SGCOORDS;
42class SGCOORDINDEX;
43
44
45// Function to drop references within an SGNODE
46// The node being destroyed must remove itself from the object reference's
47// backpointer list in order to avoid a segfault.
48#define DROP_REFS( aType, aList ) \
49 do \
50 { \
51 std::vector<aType*>::iterator sL = aList.begin(); \
52 std::vector<aType*>::iterator eL = aList.end(); \
53 while( sL != eL ) \
54 { \
55 ( (SGNODE*) *sL )->delNodeRef( this ); \
56 ++sL; \
57 } \
58 aList.clear(); \
59 } while( 0 )
60
61
62// Function to delete owned objects within an SGNODE
63// The owned object's parent is set to NULL before
64// deletion to avoid a redundant 'unlinkChildNode' call.
65#define DEL_OBJS( aType, aList ) \
66 do \
67 { \
68 std::vector<aType*>::iterator sL = aList.begin(); \
69 std::vector<aType*>::iterator eL = aList.end(); \
70 while( sL != eL ) \
71 { \
72 ( (SGNODE*) *sL )->SetParent( nullptr, false ); \
73 delete *sL; \
74 ++sL; \
75 } \
76 aList.clear(); \
77 } while( 0 )
78
79
80// Function to unlink a child or reference node when that child or
81// reference node is being destroyed.
82#define UNLINK_NODE( aNodeID, aType, aNode, aOwnedList, aRefList, isChild ) \
83 do \
84 { \
85 if( aNodeID == aNode->GetNodeType() ) \
86 { \
87 std::vector<aType*>* oSL; \
88 std::vector<aType*>::iterator sL; \
89 std::vector<aType*>::iterator eL; \
90 if( isChild ) \
91 { \
92 oSL = &aOwnedList; \
93 sL = oSL->begin(); \
94 eL = oSL->end(); \
95 while( sL != eL ) \
96 { \
97 if( (SGNODE*) *sL == aNode ) \
98 { \
99 oSL->erase( sL ); \
100 return; \
101 } \
102 ++sL; \
103 } \
104 } \
105 else \
106 { \
107 oSL = &aRefList; \
108 sL = oSL->begin(); \
109 eL = oSL->end(); \
110 while( sL != eL ) \
111 { \
112 if( (SGNODE*) *sL == aNode ) \
113 { \
114 delNodeRef( this ); \
115 oSL->erase( sL ); \
116 return; \
117 } \
118 ++sL; \
119 } \
120 } \
121 return; \
122 } \
123 } while( 0 )
124
125
126// Function to check a node type, check for an existing reference,
127// and add the node type to the reference list if applicable
128#define ADD_NODE( aNodeID, aType, aNode, aOwnedList, aRefList, isChild ) \
129 do \
130 { \
131 if( aNodeID == aNode->GetNodeType() ) \
132 { \
133 std::vector<aType*>::iterator sL; \
134 sL = std::find( aOwnedList.begin(), aOwnedList.end(), aNode ); \
135 if( sL != aOwnedList.end() ) \
136 return true; \
137 sL = std::find( aRefList.begin(), aRefList.end(), aNode ); \
138 if( sL != aRefList.end() ) \
139 return true; \
140 if( isChild ) \
141 { \
142 SGNODE* ppn = (SGNODE*) aNode->GetParent(); \
143 if( nullptr != ppn ) \
144 { \
145 if( this != ppn ) \
146 { \
147 std::cerr << __FILE__ << ": " << __FUNCTION__ << ": " << __LINE__ << "\n"; \
148 std::cerr << " * [BUG] object '" << aNode->GetName(); \
149 std::cerr << "' has multiple parents '" << ppn->GetName() << "', '"; \
150 std::cerr << m_Name << "'\n"; \
151 return false; \
152 } \
153 } \
154 aOwnedList.push_back( (aType*) aNode ); \
155 aNode->SetParent( this, false ); \
156 } \
157 else \
158 { \
159 /*if( nullptr == aNode->GetParent() ) { \
160 std::cerr << __FILE__ << ": " << __FUNCTION__ << ": " << __LINE__ << "\n"; \
161 std::cerr << " * [BUG] object '" << aNode->GetName(); \
162 std::cerr << "' has no parent\n"; \
163 std::cerr << " * [INFO] possible copy assignment or copy constructor bug\n"; \
164 return false; \
165 } */ \
166 aRefList.push_back( (aType*) aNode ); \
167 aNode->addNodeRef( this ); \
168 } \
169 return true; \
170 } \
171 } while( 0 )
172
173
174// Function to find a node object given a (non-unique) node name
175#define FIND_NODE( aType, aName, aNodeList, aCallingNode ) \
176 do \
177 { \
178 std::vector<aType*>::iterator sLA = aNodeList.begin(); \
179 std::vector<aType*>::iterator eLA = aNodeList.end(); \
180 SGNODE* psg = nullptr; \
181 while( sLA != eLA ) \
182 { \
183 if( (SGNODE*) *sLA != aCallingNode ) \
184 { \
185 psg = (SGNODE*) ( *sLA )->FindNode( aName, this ); \
186 if( nullptr != psg ) \
187 return psg; \
188 } \
189 ++sLA; \
190 } \
191 } while( 0 )
192
193
194namespace S3D
195{
196 bool degenerate( glm::dvec3* pts ) noexcept;
197
198 //
199 // Normals calculations from triangles
200 //
201
202 /*
203 * Take an array of 3D coordinates and its corresponding index set and calculates
204 * the normals assuming that indices are given in CCW order.
205 *
206 * Care must be taken in using this function to ensure that:
207 * -# All coordinates are indexed; unindexed coordinates are assigned normal(0,0,1);
208 * when dealing with VRML models which may list and reuse one large coordinate set it
209 * is necessary to gather all index sets and perform this operation only once.
210 * -# Index sets must represent triangles (multiple of 3 indices) and must not be
211 * degenerate, that is all indices and coordinates in a triad must be unique.
212 *
213 * @param coords is the array of 3D vertices.
214 * @param index is the array of 3x vertex indices (triads).
215 * @param norms is an empty array which holds the normals corresponding to each vector.
216 * @return true on success; otherwise false.
217 */
218 bool CalcTriangleNormals( std::vector< SGPOINT > coords, std::vector< int >& index,
219 std::vector< SGVECTOR >& norms );
220
221 // formats a floating point number for text output to a VRML file
222 void FormatFloat( std::string& result, double value );
223
224 // format orientation data for VRML output
225 void FormatOrientation( std::string& result, const SGVECTOR& axis, double rotation );
226
227 // format point data for VRML output
228 void FormatPoint( std::string& result, const SGPOINT& point );
229
230 // format vector data for VRML output
231 void FormatVector( std::string& result, const SGVECTOR& aVector );
232
233 // format Color data for VRML output
234 void FormatColor( std::string& result, const SGCOLOR& aColor );
235
236 //
237 // Cache related WRITE functions
238 //
239
240 // write out an XYZ vertex
241 bool WritePoint( std::ostream& aFile, const SGPOINT& aPoint );
242
243 // write out a unit vector
244 bool WriteVector( std::ostream& aFile, const SGVECTOR& aVector );
245
246 // write out an RGB color
247 bool WriteColor( std::ostream& aFile, const SGCOLOR& aColor );
248
257 S3D::SGTYPES ReadTag( std::istream& aFile, std::string& aName );
258
259 // read an XYZ vertex
260 bool ReadPoint( std::istream& aFile, SGPOINT& aPoint );
261
262 // read a unit vector
263 bool ReadVector( std::istream& aFile, SGVECTOR& aVector );
264
265 // read an RGB color
266 bool ReadColor( std::istream& aFile, SGCOLOR& aColor );
267}
268
269#endif // SG_HELPERS_H
int index
An object to maintain a coordinate index list.
Define a vertex coordinate set for a scenegraph object.
Definition sg_coords.h:37
Define a set of vertex normals for a scene graph object.
Definition sg_normals.h:35
bool ReadVector(std::istream &aFile, SGVECTOR &aVector)
bool ReadPoint(std::istream &aFile, SGPOINT &aPoint)
bool WritePoint(std::ostream &aFile, const SGPOINT &aPoint)
bool WriteColor(std::ostream &aFile, const SGCOLOR &aColor)
bool CalcTriangleNormals(std::vector< SGPOINT > coords, std::vector< int > &index, std::vector< SGVECTOR > &norms)
void FormatColor(std::string &result, const SGCOLOR &aColor)
void FormatFloat(std::string &result, double value)
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.
bool WriteVector(std::ostream &aFile, const SGVECTOR &aVector)
void FormatVector(std::string &result, const SGVECTOR &aVector)
void FormatPoint(std::string &result, const SGPOINT &point)
bool degenerate(glm::dvec3 *pts) noexcept
SGTYPES
Definition sg_types.h:32
bool ReadColor(std::istream &aFile, SGCOLOR &aColor)
void FormatOrientation(std::string &result, const SGVECTOR &axis, double rotation)
defines the low level classes common to scene graph nodes
defines the types of intermediate scene graph objects
wxString result
Test unit parsing edge cases and error handling.