KiCad PCB EDA Suite
vrml2_pointset.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) 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 
26 #include <iostream>
27 #include <sstream>
28 #include <wx/log.h>
29 
30 #include "vrml2_base.h"
31 #include "vrml2_pointset.h"
32 #include "vrml2_coords.h"
33 #include "vrml2_color.h"
34 #include "plugins/3dapi/ifsg_all.h"
35 
36 
38 {
39  setDefaults();
41 }
42 
43 
45 {
46  setDefaults();
48  m_Parent = aParent;
49 
50  if( nullptr != m_Parent )
51  m_Parent->AddChildNode( this );
52 }
53 
54 
56 {
57  wxLogTrace( traceVrmlPlugin,
58  wxT( " * [INFO] Destroying PointSet node with %zu children, %zu"
59  "references, and %zu back pointers." ),
60  m_Children.size(), m_Refs.size(), m_BackPointers.size() );
61 }
62 
63 
65 {
66  color = nullptr;
67  coord = nullptr;
68 }
69 
70 
72 {
73  // nodes must be one of:
74  // Color
75  // Coordinate
76 
77  switch( aType )
78  {
81  break;
82 
83  default:
84  return false;
85  break;
86  }
87 
88  return true;
89 }
90 
91 
93 {
94  // this node is dangling unless it has a parent of type WRL2_SHAPE
95  if( nullptr == m_Parent || m_Parent->GetNodeType() != WRL2NODES::WRL2_SHAPE )
96  return true;
97 
98  return false;
99 }
100 
101 
103 {
104  wxCHECK_MSG( aNode, false, wxT( "Invalid node." ) );
105 
106  WRL2NODES type = aNode->GetNodeType();
107 
108  if( !checkNodeType( type ) )
109  {
110  wxLogTrace( traceVrmlPlugin,
111  wxT( "%s:%s:%d\n"
112  " * [INFO] bad file format; unexpected child node '%s'." ),
113  __FILE__, __FUNCTION__, __LINE__, aNode->GetNodeTypeName( type ) );
114 
115  return false;
116  }
117 
118  if( WRL2NODES::WRL2_COLOR == type )
119  {
120  if( nullptr != color )
121  {
122  wxLogTrace( traceVrmlPlugin,
123  wxT( "%s:%s:%d\n"
124  " * [INFO] bad file format; multiple color nodes." ),
125  __FILE__, __FUNCTION__, __LINE__ );
126 
127  return false;
128  }
129 
130  color = aNode;
131  return WRL2NODE::AddRefNode( aNode );
132  }
133 
134  if( WRL2NODES::WRL2_COORDINATE == type )
135  {
136  if( nullptr != coord )
137  {
138  wxLogTrace( traceVrmlPlugin,
139  wxT( "%s:%s:%d\n"
140  " * [INFO] bad file format; multiple coord nodes." ),
141  __FILE__, __FUNCTION__, __LINE__ );
142 
143  return false;
144  }
145 
146  coord = aNode;
147  return WRL2NODE::AddRefNode( aNode );
148  }
149 
150  return WRL2NODE::AddRefNode( aNode );
151 }
152 
153 
155 {
156  wxCHECK_MSG( aNode, false, wxT( "Invalid node." ) );
157 
158  WRL2NODES type = aNode->GetNodeType();
159 
160  if( !checkNodeType( type ) )
161  {
162  wxLogTrace( traceVrmlPlugin,
163  wxT( "%s:%s:%d\n"
164  " * [INFO] bad file format; unexpected child node '%s'." ),
165  __FILE__, __FUNCTION__, __LINE__, aNode->GetNodeTypeName( type ) );
166 
167  return false;
168  }
169 
170  if( WRL2NODES::WRL2_COLOR == type )
171  {
172  if( nullptr != color )
173  {
174  wxLogTrace( traceVrmlPlugin,
175  wxT( "%s:%s:%d\n"
176  " * [INFO] bad file format; multiple color nodes." ),
177  __FILE__, __FUNCTION__, __LINE__ );
178 
179  return false;
180  }
181 
182  color = aNode;
183  return WRL2NODE::AddChildNode( aNode );
184  }
185 
186  if( WRL2NODES::WRL2_COORDINATE == type )
187  {
188  if( nullptr != coord )
189  {
190  wxLogTrace( traceVrmlPlugin,
191  wxT( "%s:%s:%d\n"
192  " * [INFO] bad file format; multiple coord nodes." ),
193  __FILE__, __FUNCTION__, __LINE__ );
194 
195  return false;
196  }
197 
198  coord = aNode;
199  return WRL2NODE::AddChildNode( aNode );
200  }
201 
202  return WRL2NODE::AddChildNode( aNode );
203 }
204 
205 
206 
207 bool WRL2POINTSET::Read( WRLPROC& proc, WRL2BASE* aTopNode )
208 {
209  char tok = proc.Peek();
210 
211  if( proc.eof() )
212  {
213  wxLogTrace( traceVrmlPlugin, wxT( "%s:%s:%d\n"
214  " * [INFO] bad file format; unexpected eof %s." ),
215  __FILE__, __FUNCTION__, __LINE__, proc.GetFilePosition() );
216 
217  return false;
218  }
219 
220  if( '{' != tok )
221  {
222  wxLogTrace( traceVrmlPlugin,
223  wxT( "%s:%s:%d\n"
224  " * [INFO] bad file format; expecting '{' but got '%s' %s." ),
225  __FILE__, __FUNCTION__, __LINE__, tok, proc.GetFilePosition() );
226 
227  return false;
228  }
229 
230  proc.Pop();
231  std::string glob;
232 
233  while( true )
234  {
235  if( proc.Peek() == '}' )
236  {
237  proc.Pop();
238  break;
239  }
240 
241  if( !proc.ReadName( glob ) )
242  {
243  wxLogTrace( traceVrmlPlugin, wxT( "%s:%s:%d\n"
244  "%s" ),
245  __FILE__, __FUNCTION__, __LINE__ , proc.GetError() );
246 
247  return false;
248  }
249 
250  // expecting one of:
251  // color
252  // coord
253  if( !glob.compare( "color" ) )
254  {
255  if( !aTopNode->ReadNode( proc, this, nullptr ) )
256  {
257  wxLogTrace( traceVrmlPlugin,
258  wxT( "%s:%s:%d\n"
259  " * [INFO] could not read color node information." ),
260  __FILE__, __FUNCTION__, __LINE__ );
261 
262  return false;
263  }
264  }
265  else if( !glob.compare( "coord" ) )
266  {
267  if( !aTopNode->ReadNode( proc, this, nullptr ) )
268  {
269  wxLogTrace( traceVrmlPlugin,
270  wxT( "%s:%s:%d\n"
271  " * [INFO] could not read coord node information." ),
272  __FILE__, __FUNCTION__, __LINE__ );
273 
274  return false;
275  }
276  }
277  else
278  {
279  wxLogTrace( traceVrmlPlugin,
280  wxT( "%s:%s:%d\n"
281  " * [INFO] invalid PointSet %s (no closing brace)\n"
282  " * [INFO] file: '%s'\n" ),
283  __FILE__, __FUNCTION__, __LINE__, proc.GetFilePosition(),
284  proc.GetFileName() );
285 
286  return false;
287  }
288  } // while( true ) -- reading contents of PointSet{}
289 
290  return true;
291 }
292 
293 
295 {
296  // note: there are no plans to support drawing of points
297  return nullptr;
298 }
299 
300 
302 {
303  if( nullptr == aNode )
304  return;
305 
306  if( aNode->GetParent() == this )
307  {
308  if( aNode == color )
309  color = nullptr;
310  else if( aNode == coord )
311  coord = nullptr;
312  }
313 
314  WRL2NODE::unlinkChildNode( aNode );
315 }
316 
317 
319 {
320  if( nullptr == aNode )
321  return;
322 
323  if( aNode->GetParent() != this )
324  {
325  if( aNode == color )
326  color = nullptr;
327  else if( aNode == coord )
328  coord = nullptr;
329 
330  }
331 
332  WRL2NODE::unlinkRefNode( aNode );
333 }
334 
335 
337 {
338  if( nullptr == color )
339  return false;
340 
341  return ( (WRL2COLOR*) color )->HasColors();
342 }
bool Read(WRLPROC &proc, WRL2BASE *aTopNode) override
void Pop(void)
Definition: wrlproc.cpp:2035
std::list< WRL2NODE * > m_Children
Definition: vrml2_node.h:174
bool isDangling(void) override
Determine whether an object should be moved to a different parent during the VRML to SG* translation.
virtual ~WRL2POINTSET()
bool AddChildNode(WRL2NODE *aNode) override
std::list< WRL2NODE * > m_Refs
Definition: vrml2_node.h:175
WRL2NODE * coord
WRL2NODES m_Type
Definition: vrml2_node.h:170
The base class of all Scene Graph nodes.
Definition: sg_node.h:74
collects header files for all SG* wrappers and the API
bool ReadNode(WRLPROC &proc, WRL2NODE *aParent, WRL2NODE **aNode)
Definition: vrml2_base.cpp:276
bool HasColors(void)
bool checkNodeType(WRL2NODES aType)
void unlinkRefNode(const WRL2NODE *aNode) override
Remove pointers to a referenced node.
WRL2NODE * m_Parent
Definition: vrml2_node.h:169
std::string GetFilePosition() const
Definition: wrlproc.cpp:1982
std::list< WRL2NODE * > m_BackPointers
Definition: vrml2_node.h:173
WRL2NODE * color
WRL2NODES GetNodeType(void) const
Definition: vrml2_node.cpp:204
char Peek(void)
Definition: wrlproc.cpp:2007
std::string GetFileName(void)
Definition: wrlproc.cpp:1995
The top node of a VRML2 model.
Definition: vrml2_base.h:59
const wxChar *const traceVrmlPlugin
Flag to enable VRML plugin trace output.
Definition: vrml.cpp:63
SGNODE * TranslateToSG(SGNODE *aParent) override
Produce a representation of the data using the intermediate scenegraph structures of the kicad_3dsg l...
const char * GetNodeTypeName(WRL2NODES aNodeType) const
Definition: vrml2_node.cpp:273
virtual bool AddChildNode(WRL2NODE *aNode)
Definition: vrml2_node.cpp:356
bool ReadName(std::string &aName)
Definition: wrlproc.cpp:289
virtual void unlinkRefNode(const WRL2NODE *aNode)
Remove pointers to a referenced node.
Definition: vrml2_node.cpp:425
WRL2NODE * GetParent(void) const
Definition: vrml2_node.cpp:210
bool AddRefNode(WRL2NODE *aNode) override
WRL2NODES
Definition: wrltypes.h:124
void setDefaults(void)
std::string GetError(void)
Definition: wrlproc.cpp:1960
virtual void unlinkChildNode(const WRL2NODE *aNode)
Remove references to an owned child.
Definition: vrml2_node.cpp:407
virtual bool AddRefNode(WRL2NODE *aNode)
Definition: vrml2_node.cpp:383
bool eof(void)
Definition: wrlproc.cpp:1954
void unlinkChildNode(const WRL2NODE *aNode) override
Remove references to an owned child.