KiCad PCB EDA Suite
vrml1_group.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-2016 Cirilo Bernardo <cirilo.bernardo@gmail.com>
5  *
6  * This program is free software; you can redistribute it and/or
7  * modify it under the terms of the GNU General Public License
8  * as published by the Free Software Foundation; either version 2
9  * of the License, or (at your option) any later version.
10  *
11  * This program is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14  * GNU General Public License for more details.
15  *
16  * You should have received a copy of the GNU General Public License
17  * along with this program; if not, you may find one here:
18  * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
19  * or you may search the http://www.gnu.org website for the version 2 license,
20  * or you may write to the Free Software Foundation, Inc.,
21  * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
22  */
23 
24 // note: this was copied from the vrml1_separator class. the difference
25 // between a separator and a group is that a group propagates its
26 // current settings to its parent. While it would be possible to
27 // implement the separator as a derived class, it is easy enough to
28 // simply duplicate the code
29 
30 #include <iostream>
31 #include <sstream>
32 #include <wx/log.h>
33 
34 #include "vrml1_base.h"
35 #include "vrml1_group.h"
36 #include "plugins/3dapi/ifsg_all.h"
37 
38 
39 WRL1GROUP::WRL1GROUP( NAMEREGISTER* aDictionary ) : WRL1NODE( aDictionary )
40 {
42  return;
43 }
44 
45 
46 WRL1GROUP::WRL1GROUP( NAMEREGISTER* aDictionary, WRL1NODE* aParent ) :
47  WRL1NODE( aDictionary )
48 {
50  m_Parent = aParent;
51 
52  if( NULL != m_Parent )
53  m_Parent->AddChildNode( this );
54 
55  return;
56 }
57 
58 
60 {
61  #if defined( DEBUG_VRML1 ) && ( DEBUG_VRML1 > 2 )
62  do {
63  std::ostringstream ostr;
64  ostr << " * [INFO] Destroying Group with " << m_Children.size();
65  ostr << " children, " << m_Refs.size() << " references and ";
66  ostr << m_BackPointers.size() << " backpointers";
67  wxLogTrace( MASK_VRML, "%s\n", ostr.str().c_str() );
68  } while( 0 );
69  #endif
70 
71  return;
72 }
73 
74 
75 // functions inherited from WRL1NODE
76 bool WRL1GROUP::Read( WRLPROC& proc, WRL1BASE* aTopNode )
77 {
78  if( NULL == aTopNode )
79  {
80  #ifdef DEBUG_VRML1
81  do {
82  std::ostringstream ostr;
83  ostr << __FILE__ << ": " << __FUNCTION__ << ": " << __LINE__ << "\n";
84  ostr << " * [BUG] aTopNode is NULL";
85  wxLogTrace( MASK_VRML, "%s\n", ostr.str().c_str() );
86  } while( 0 );
87  #endif
88 
89  return false;
90  }
91 
92  size_t line, column;
93  proc.GetFilePosData( line, column );
94 
95  char tok = proc.Peek();
96 
97  if( proc.eof() )
98  {
99  #if defined( DEBUG_VRML1 ) && ( DEBUG_VRML1 > 1 )
100  do {
101  std::ostringstream ostr;
102  ostr << __FILE__ << ": " << __FUNCTION__ << ": " << __LINE__ << "\n";
103  ostr << " * [INFO] bad file format; unexpected eof at line ";
104  ostr << line << ", column " << column;
105  wxLogTrace( MASK_VRML, "%s\n", ostr.str().c_str() );
106  } while( 0 );
107  #endif
108 
109  return false;
110  }
111 
112  if( '{' != tok )
113  {
114  #if defined( DEBUG_VRML1 ) && ( DEBUG_VRML1 > 1 )
115  do {
116  std::ostringstream ostr;
117  ostr << proc.GetError() << "\n";
118  ostr << __FILE__ << ": " << __FUNCTION__ << ": " << __LINE__ << "\n";
119  ostr << " * [INFO] bad file format; expecting '{' but got '" << tok;
120  ostr << "' at line " << line << ", column " << column;
121  wxLogTrace( MASK_VRML, "%s\n", ostr.str().c_str() );
122  } while( 0 );
123  #endif
124 
125  return false;
126  }
127 
128  proc.Pop();
129 
130  while( true )
131  {
132  if( proc.Peek() == '}' )
133  {
134  proc.Pop();
135  break;
136  }
137 
138  proc.GetFilePosData( line, column );
139 
140  if( !aTopNode->ReadNode( proc, this, NULL ) )
141  {
142  #if defined( DEBUG_VRML1 ) && ( DEBUG_VRML1 > 1 )
143  do {
144  std::ostringstream ostr;
145  ostr << __FILE__ << ": " << __FUNCTION__ << ": " << __LINE__ << "\n";
146  ostr << " * [INFO] bad file format; unexpected eof at line ";
147  ostr << line << ", column " << column;
148  wxLogTrace( MASK_VRML, "%s\n", ostr.str().c_str() );
149  } while( 0 );
150  #endif
151 
152  return false;
153  }
154 
155  if( proc.Peek() == ',' )
156  proc.Pop();
157 
158  } // while( true ) -- reading contents of Group{}
159 
160  return true;
161 }
162 
163 
165 {
166  #if defined( DEBUG_VRML1 ) && ( DEBUG_VRML1 > 2 )
167  do {
168  std::ostringstream ostr;
169  ostr << " * [INFO] Translating Group with " << m_Children.size();
170  ostr << " children, " << m_Refs.size() << " references and ";
171  ostr << m_BackPointers.size() << " backpointers (total ";
172  ostr << m_Items.size() << " items)";
173  wxLogTrace( MASK_VRML, "%s\n", ostr.str().c_str() );
174  } while( 0 );
175  #endif
176 
177  if( !m_Parent )
178  {
179  #ifdef DEBUG
180  do {
181  std::ostringstream ostr;
182  ostr << __FILE__ << ": " << __FUNCTION__ << ": " << __LINE__ << "\n";
183  ostr << " * [BUG] Group has no parent";
184  wxLogTrace( MASK_VRML, "%s\n", ostr.str().c_str() );
185  } while( 0 );
186  #endif
187 
188  return NULL;
189  }
190 
191  if( WRL1_BASE != m_Parent->GetNodeType() )
192  {
193  if( NULL == sp )
194  {
195  #if defined( DEBUG_VRML1 ) && ( DEBUG_VRML1 > 1 )
196  wxLogTrace( MASK_VRML, " * [INFO] bad model: no base data given\n" );
197  #endif
198 
199  return NULL;
200  }
201  }
202  else if( NULL == sp )
203  {
204  m_current.Init();
205  sp = &m_current;
206  }
207 
208  S3D::SGTYPES ptype = S3D::GetSGNodeType( aParent );
209 
210  if( NULL != aParent && ptype != S3D::SGTYPE_TRANSFORM )
211  {
212  #ifdef DEBUG_VRML1
213  do {
214  std::ostringstream ostr;
215  ostr << __FILE__ << ": " << __FUNCTION__ << ": " << __LINE__ << "\n";
216  ostr << " * [BUG] Group does not have a Transform parent (parent ID: ";
217  ostr << ptype << ")";
218  wxLogTrace( MASK_VRML, "%s\n", ostr.str().c_str() );
219  } while( 0 );
220  #endif
221 
222  return NULL;
223  }
224 
225  IFSG_TRANSFORM txNode( aParent );
226  bool hasContent = false;
227 
228  std::list< WRL1NODE* >::iterator sI = m_Items.begin();
229  std::list< WRL1NODE* >::iterator eI = m_Items.end();
230 
231  SGNODE* node = txNode.GetRawPtr();
232 
233  while( sI != eI )
234  {
235  if( NULL != (*sI)->TranslateToSG( node, sp ) )
236  hasContent = true;
237 
238  ++sI;
239  }
240 
241  if( !hasContent )
242  {
243  txNode.Destroy();
244  return NULL;
245  }
246 
247  return node;
248 }
WRL1BASE represents the top node of a VRML1 model.
Definition: vrml1_base.h:45
void Pop(void)
Definition: wrlproc.cpp:2007
bool GetFilePosData(size_t &line, size_t &column)
Definition: wrlproc.cpp:1951
#define MASK_VRML
Definition: wrltypes.h:37
WRL1STATUS m_current
Definition: vrml1_node.h:128
SGNODE * TranslateToSG(SGNODE *aParent, WRL1STATUS *sp) override
Function TranslateToSG produces a representation of the data using the intermediate scenegraph struct...
SGNODE represents the base class of all Scene Graph nodes.
Definition: sg_node.h:76
collects header files for all SG* wrappers and the API
void Init()
Definition: vrml1_node.h:92
SGNODE * GetRawPtr(void) noexcept
Function GetRawPtr() returns the raw internal SGNODE pointer.
Definition: ifsg_node.cpp:66
std::list< WRL1NODE * > m_BackPointers
Definition: vrml1_node.h:122
virtual ~WRL1GROUP()
Definition: vrml1_group.cpp:59
#define NULL
std::list< WRL1NODE * > m_Refs
Definition: vrml1_node.h:124
bool ReadNode(WRLPROC &proc, WRL1NODE *aParent, WRL1NODE **aNode)
Definition: vrml1_base.cpp:314
WRL1NODE represents the base class of all VRML1 nodes.
Definition: vrml1_node.h:111
char Peek(void)
Definition: wrlproc.cpp:1979
bool Read(WRLPROC &proc, WRL1BASE *aTopNode) override
Definition: vrml1_group.cpp:76
virtual bool AddChildNode(WRL1NODE *aNode)
Definition: vrml1_node.cpp:442
SGTYPES
Definition: sg_types.h:34
SGLIB_API S3D::SGTYPES GetSGNodeType(SGNODE *aNode)
Definition: ifsg_api.cpp:627
WRL1NODES GetNodeType(void) const
Function GetNodeType returns the type of this node instance.
Definition: vrml1_node.cpp:310
WRL1NODES m_Type
Definition: vrml1_node.h:119
std::list< WRL1NODE * > m_Items
Definition: vrml1_node.h:125
IFSG_TRANSFORM is the wrapper for the VRML compatible TRANSFORM block class SCENEGRAPH.
WRL1NODE * m_Parent
Definition: vrml1_node.h:118
std::string GetError(void)
Definition: wrlproc.cpp:1945
WRL1GROUP(NAMEREGISTER *aDictionary)
Definition: vrml1_group.cpp:39
void Destroy(void)
Function Destroy deletes the object held by this wrapper.
Definition: ifsg_node.cpp:54
bool eof(void)
Definition: wrlproc.cpp:1939
std::list< WRL1NODE * > m_Children
Definition: vrml1_node.h:123