KiCad PCB EDA Suite
vrml2_lineset.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_lineset.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 IndexedLineSet 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  colorPerVertex = true;
69 }
70 
71 
73 {
74  // nodes must be one of:
75  // Color
76  // Coordinate
77 
78  switch( aType )
79  {
82  break;
83 
84  default:
85  return false;
86  break;
87  }
88 
89  return true;
90 }
91 
92 
94 {
95  // this node is dangling unless it has a parent of type WRL2_SHAPE
96 
97  if( nullptr == m_Parent || m_Parent->GetNodeType() != WRL2NODES::WRL2_SHAPE )
98  return true;
99 
100  return false;
101 }
102 
103 
105 {
106  wxCHECK_MSG( aNode, false, wxT( "Invalid node." ) );
107 
108  WRL2NODES type = aNode->GetNodeType();
109 
110  if( !checkNodeType( type ) )
111  {
112  wxLogTrace( traceVrmlPlugin,
113  wxT( "%s:%s:%d\n"
114  " * [INFO] bad file format; unexpected child node '%s'." ),
115  __FILE__, __FUNCTION__, __LINE__, aNode->GetNodeTypeName( type ) );
116 
117  return false;
118  }
119 
120  if( WRL2NODES::WRL2_COLOR == type )
121  {
122  if( nullptr != color )
123  {
124  wxLogTrace( traceVrmlPlugin,
125  wxT( "%s:%s:%d\n"
126  " * [INFO] bad file format; multiple color nodes." ),
127  __FILE__, __FUNCTION__, __LINE__ );
128 
129  return false;
130  }
131 
132  color = aNode;
133  return WRL2NODE::AddRefNode( aNode );
134  }
135 
136  if( WRL2NODES::WRL2_COORDINATE == type )
137  {
138  if( nullptr != coord )
139  {
140  wxLogTrace( traceVrmlPlugin,
141  wxT( "%s:%s:%d\n"
142  " * [INFO] bad file format; multiple coord nodes." ),
143  __FILE__, __FUNCTION__, __LINE__ );
144 
145  return false;
146  }
147 
148  coord = aNode;
149  return WRL2NODE::AddRefNode( aNode );
150  }
151 
152  return WRL2NODE::AddRefNode( aNode );
153 }
154 
155 
157 {
158  wxCHECK_MSG( aNode, false, wxT( "Invalid node." ) );
159 
160  WRL2NODES type = aNode->GetNodeType();
161 
162  if( !checkNodeType( type ) )
163  {
164  wxLogTrace( traceVrmlPlugin,
165  wxT( "%s:%s:%d\n"
166  " * [INFO] bad file format; unexpected child node '%s'." ),
167  __FILE__, __FUNCTION__, __LINE__, aNode->GetNodeTypeName( type ) );
168 
169  return false;
170  }
171 
172  if( WRL2NODES::WRL2_COLOR == type )
173  {
174  if( nullptr != color )
175  {
176  wxLogTrace( traceVrmlPlugin,
177  wxT( "%s:%s:%d\n"
178  " * [INFO] bad file format; multiple color nodes." ),
179  __FILE__, __FUNCTION__, __LINE__ );
180 
181  return false;
182  }
183 
184  color = aNode;
185  return WRL2NODE::AddChildNode( aNode );
186  }
187 
188  if( WRL2NODES::WRL2_COORDINATE == type )
189  {
190  if( nullptr != coord )
191  {
192  wxLogTrace( traceVrmlPlugin,
193  wxT( "%s:%s:%d\n"
194  " * [INFO] bad file format; multiple coord nodes." ),
195  __FILE__, __FUNCTION__, __LINE__ );
196 
197  return false;
198  }
199 
200  coord = aNode;
201  return WRL2NODE::AddChildNode( aNode );
202  }
203 
204  return WRL2NODE::AddChildNode( aNode );
205 }
206 
207 
208 
209 bool WRL2LINESET::Read( WRLPROC& proc, WRL2BASE* aTopNode )
210 {
211  char tok = proc.Peek();
212 
213  if( proc.eof() )
214  {
215  wxLogTrace( traceVrmlPlugin, wxT( "%s:%s:%d\n"
216  " * [INFO] bad file format; unexpected eof %s." ),
217  __FILE__, __FUNCTION__, __LINE__, proc.GetFilePosition() );
218 
219  return false;
220  }
221 
222  if( '{' != tok )
223  {
224  wxLogTrace( traceVrmlPlugin,
225  wxT( "%s:%s:%d\n"
226  " * [INFO] bad file format; expecting '{' but got '%s' %s." ),
227  __FILE__, __FUNCTION__, __LINE__, tok, proc.GetFilePosition() );
228 
229  return false;
230  }
231 
232  proc.Pop();
233  std::string glob;
234 
235  while( true )
236  {
237  if( proc.Peek() == '}' )
238  {
239  proc.Pop();
240  break;
241  }
242 
243  if( !proc.ReadName( glob ) )
244  {
245  wxLogTrace( traceVrmlPlugin, wxT( "%s:%s:%d\n"
246  "%s" ),
247  __FILE__, __FUNCTION__, __LINE__ , proc.GetError() );
248 
249  return false;
250  }
251 
252  // expecting one of:
253  // [node]
254  // color
255  // coord
256  // [bool]
257  // colorPerVertex
258  // [ vector<int> ]
259  // colorIndex
260  // coordIndex
261 
262  if( !glob.compare( "colorPerVertex" ) )
263  {
264  if( !proc.ReadSFBool( colorPerVertex ) )
265  {
266  wxLogTrace( traceVrmlPlugin, wxT( "%s:%s:%d\n"
267  " * [INFO] invalid colorPerVertex %s\n"
268  " * [INFO] file: '%s'\n"
269  "%s" ),
270  __FILE__, __FUNCTION__, __LINE__, proc.GetFilePosition(),
271  proc.GetFileName(), proc.GetError() );
272 
273  return false;
274  }
275  }
276  else if( !glob.compare( "colorIndex" ) )
277  {
278  if( !proc.ReadMFInt( colorIndex ) )
279  {
280  wxLogTrace( traceVrmlPlugin, wxT( "%s:%s:%d\n"
281  " * [INFO] invalid colorIndex %s\n"
282  " * [INFO] file: '%s'\n"
283  "%s" ),
284  __FILE__, __FUNCTION__, __LINE__, proc.GetFilePosition(),
285  proc.GetFileName(), proc.GetError() );
286 
287  return false;
288  }
289  }
290  else if( !glob.compare( "coordIndex" ) )
291  {
292  if( !proc.ReadMFInt( coordIndex ) )
293  {
294  wxLogTrace( traceVrmlPlugin, wxT( "%s:%s:%d\n"
295  " * [INFO] invalid coordIndex %s\n"
296  " * [INFO] file: '%s'\n"
297  "%s" ),
298  __FILE__, __FUNCTION__, __LINE__, proc.GetFilePosition(),
299  proc.GetFileName(), proc.GetError() );
300 
301  return false;
302  }
303  }
304  else if( !glob.compare( "color" ) )
305  {
306  if( !aTopNode->ReadNode( proc, this, nullptr ) )
307  {
308  wxLogTrace( traceVrmlPlugin,
309  wxT( "%s:%s:%d\n"
310  " * [INFO] could not read color node information." ),
311  __FILE__, __FUNCTION__, __LINE__ );
312 
313  return false;
314  }
315  }
316  else if( !glob.compare( "coord" ) )
317  {
318  if( !aTopNode->ReadNode( proc, this, nullptr ) )
319  {
320  wxLogTrace( traceVrmlPlugin,
321  wxT( "%s:%s:%d\n"
322  " * [INFO] could not read coord node information." ),
323  __FILE__, __FUNCTION__, __LINE__ );
324 
325  return false;
326  }
327  }
328  else
329  {
330  wxLogTrace( traceVrmlPlugin,
331  wxT( "%s:%s:%d\n"
332  " * [INFO] invalid IndexedFaceSet %s\n"
333  " * [INFO] file: '%s'\n" ),
334  __FILE__, __FUNCTION__, __LINE__, proc.GetFilePosition(),
335  proc.GetFileName() );
336 
337  return false;
338  }
339  } // while( true ) -- reading contents of IndexedLineSet{}
340 
341  return true;
342 }
343 
344 
346 {
347  // note: there are no plans to support drawing of lines
348  return nullptr;
349 }
350 
351 
353 {
354  if( nullptr == aNode )
355  return;
356 
357  if( aNode->GetParent() == this )
358  {
359  if( aNode == color )
360  color = nullptr;
361  else if( aNode == coord )
362  coord = nullptr;
363  }
364 
365  WRL2NODE::unlinkChildNode( aNode );
366 }
367 
368 
370 {
371  if( nullptr == aNode )
372  return;
373 
374  if( aNode->GetParent() != this )
375  {
376  if( aNode == color )
377  color = nullptr;
378  else if( aNode == coord )
379  coord = nullptr;
380  }
381 
382  WRL2NODE::unlinkRefNode( aNode );
383 }
384 
385 
387 {
388  if( nullptr == color )
389  return false;
390 
391  return ((WRL2COLOR*) color)->HasColors();
392 }
bool colorPerVertex
Definition: vrml2_lineset.h:73
void Pop(void)
Definition: wrlproc.cpp:2035
std::vector< int > colorIndex
Definition: vrml2_lineset.h:75
std::list< WRL2NODE * > m_Children
Definition: vrml2_node.h:174
void unlinkChildNode(const WRL2NODE *aNode) override
Remove references to an owned child.
std::list< WRL2NODE * > m_Refs
Definition: vrml2_node.h:175
bool isDangling(void) override
Determine whether an object should be moved to a different parent during the VRML to SG* translation.
bool ReadMFInt(std::vector< int > &aMFInt32)
Definition: wrlproc.cpp:1504
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
virtual ~WRL2LINESET()
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
bool HasColors(void)
bool AddChildNode(WRL2NODE *aNode) override
std::vector< int > coordIndex
Definition: vrml2_lineset.h:76
bool ReadSFBool(bool &aSFBool)
Definition: wrlproc.cpp:729
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
void setDefaults(void)
const char * GetNodeTypeName(WRL2NODES aNodeType) const
Definition: vrml2_node.cpp:273
WRL2NODE * coord
Definition: vrml2_lineset.h:71
virtual bool AddChildNode(WRL2NODE *aNode)
Definition: vrml2_node.cpp:356
bool Read(WRLPROC &proc, WRL2BASE *aTopNode) override
bool ReadName(std::string &aName)
Definition: wrlproc.cpp:289
SGNODE * TranslateToSG(SGNODE *aParent) override
Produce a representation of the data using the intermediate scenegraph structures of the kicad_3dsg l...
void unlinkRefNode(const WRL2NODE *aNode) override
Remove pointers to a referenced node.
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
WRL2NODES
Definition: wrltypes.h:124
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 AddRefNode(WRL2NODE *aNode) override
WRL2NODE * color
Definition: vrml2_lineset.h:70
bool eof(void)
Definition: wrlproc.cpp:1954
bool checkNodeType(WRL2NODES aType)