KiCad PCB EDA Suite
vrml2_base.cpp File Reference
#include <iostream>
#include <sstream>
#include <utility>
#include <wx/string.h>
#include <wx/filename.h>
#include <wx/log.h>
#include "vrml2_base.h"
#include "vrml2_transform.h"
#include "vrml2_shape.h"
#include "vrml2_appearance.h"
#include "vrml2_material.h"
#include "vrml2_faceset.h"
#include "vrml2_lineset.h"
#include "vrml2_pointset.h"
#include "vrml2_coords.h"
#include "vrml2_norms.h"
#include "vrml2_color.h"
#include "vrml2_box.h"
#include "vrml2_switch.h"
#include "vrml2_inline.h"
#include "plugins/3dapi/ifsg_all.h"

Go to the source code of this file.

Functions

SCENEGRAPHLoadVRML (const wxString &aFileName, bool useInline)
 

Function Documentation

◆ LoadVRML()

SCENEGRAPH* LoadVRML ( const wxString &  aFileName,
bool  useInline 
)

Definition at line 170 of file vrml.cpp.

171 {
172  FILE_LINE_READER* modelFile = nullptr;
173  SCENEGRAPH* scene = nullptr;
174  wxString filename = aFileName;
175  wxFileName tmpfilename;
176 
177  if( aFileName.Upper().EndsWith( wxT( "WRZ" ) ) )
178  {
179  wxFFileInputStream ifile( aFileName );
180  tmpfilename = wxFileName( aFileName );
181 
182  tmpfilename.SetPath( wxStandardPaths::Get().GetTempDir() );
183  tmpfilename.SetExt( wxT( "WRL" ) );
184 
185  wxFileOffset size = ifile.GetLength();
186 
187  if( size == wxInvalidOffset )
188  return nullptr;
189 
190  {
191  wxFFileOutputStream ofile( tmpfilename.GetFullPath() );
192 
193  if( !ofile.IsOk() )
194  return nullptr;
195 
196  char *buffer = new char[size];
197 
198  ifile.Read( buffer, size);
199  std::string expanded;
200 
201  try
202  {
203  expanded = gzip::decompress( buffer, size );
204  }
205  catch(...)
206  {
207  delete[] buffer;
208  return nullptr;
209  }
210 
211  delete[] buffer;
212 
213  ofile.Write( expanded.data(), expanded.size() );
214  ofile.Close();
215  }
216 
217  filename = tmpfilename.GetFullPath();
218  }
219 
220  try
221  {
222  // set the max char limit to 8MB; if a VRML file contains
223  // longer lines then perhaps it shouldn't be used
224  modelFile = new FILE_LINE_READER( filename, 0, 8388608 );
225  }
226  catch( IO_ERROR & )
227  {
228  wxLogError( wxS( " * " ) + _( "[INFO] load failed: input line too long\n" ) );
229  return nullptr;
230  }
231 
232 
233  // VRML file processor
234  WRLPROC proc( modelFile );
235 
236  // Cleanup our temporary file
237  if( tmpfilename.IsOk() )
238  wxRemoveFile( tmpfilename.GetFullPath() );
239 
240  if( proc.GetVRMLType() == WRLVERSION::VRML_V1 )
241  {
242  wxLogTrace( traceVrmlPlugin, wxT( " * [INFO] Processing VRML 1.0 file" ) );
243 
244  WRL1BASE* bp = new WRL1BASE;
245 
246  if( !bp->Read( proc ) )
247  {
248  wxLogTrace( traceVrmlPlugin, wxT( " * [INFO] load failed" ) );
249  }
250  else
251  {
252  wxLogTrace( traceVrmlPlugin, wxT( " * [INFO] load completed" ) );
253 
254  scene = (SCENEGRAPH*)bp->TranslateToSG( nullptr, nullptr );
255  }
256 
257  delete bp;
258  }
259  else
260  {
261  wxLogTrace( traceVrmlPlugin, wxT( " * [INFO] Processing VRML 2.0 file" ) );
262 
263  WRL2BASE* bp = new WRL2BASE;
264 
265  // allow Inline{} files to be included
266  bp->SetEnableInline( true );
267 
268  if( !bp->Read( proc ) )
269  {
270  wxLogTrace( traceVrmlPlugin, wxT( " * [INFO] load failed" ) );
271  }
272  else
273  {
274  wxLogTrace( traceVrmlPlugin, wxT( " * [INFO] load completed" ) );
275 
276  // for now we recalculate all normals per-vertex per-face
277  scene = (SCENEGRAPH*)bp->TranslateToSG( nullptr );
278  }
279 
280  delete bp;
281  }
282 
283  if( nullptr != modelFile )
284  delete modelFile;
285 
286  // DEBUG: WRITE OUT VRML2 FILE TO CONFIRM STRUCTURE
287 #if ( defined( DEBUG_VRML1 ) && DEBUG_VRML1 > 3 ) \
288  || ( defined( DEBUG_VRML2 ) && DEBUG_VRML2 > 3 )
289  if( scene )
290  {
291  wxFileName fn( wxString::FromUTF8Unchecked( aFileName ) );
292  wxString output;
293 
294  if( proc.GetVRMLType() == VRML_V1 )
295  output = wxT( "_vrml1-" );
296  else
297  output = wxT( "_vrml2-" );
298 
299  output.append( fn.GetName() );
300  output.append( wxT(".wrl") );
301  S3D::WriteVRML( output.ToUTF8(), true, (SGNODE*)(scene), true, true );
302  }
303 #endif
304 
305  return scene;
306 }
Represent the top node of a VRML1 model.
Definition: vrml1_base.h:45
bool Read(WRLPROC &proc)
Definition: vrml2_base.cpp:163
bool Read(WRLPROC &proc)
Definition: vrml1_base.cpp:77
The base class of all Scene Graph nodes.
Definition: sg_node.h:74
SGLIB_API bool WriteVRML(const char *filename, bool overwrite, SGNODE *aTopNode, bool reuse, bool renameNodes)
Function WriteVRML writes out the given node and its subnodes to a VRML2 file.
Definition: ifsg_api.cpp:77
void SetEnableInline(bool enable)
Definition: vrml2_base.cpp:85
A LINE_READER that reads from an open file.
Definition: richio.h:172
SGNODE * TranslateToSG(SGNODE *aParent, WRL1STATUS *sp) override
Produce a representation of the data using the intermediate scenegraph structures of the kicad_3dsg l...
Definition: vrml1_base.cpp:529
#define _(s)
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
Define the basic data set required to represent a 3D model.
Definition: scenegraph.h:44
Hold an error message and may be used when throwing exceptions containing meaningful error messages.
Definition: ki_exception.h:75
SGNODE * TranslateToSG(SGNODE *aParent) override
Produce a representation of the data using the intermediate scenegraph structures of the kicad_3dsg l...
Definition: vrml2_base.cpp:911

References _, WRLPROC::GetVRMLType(), WRL1BASE::Read(), WRL2BASE::Read(), WRL2BASE::SetEnableInline(), traceVrmlPlugin, WRL1BASE::TranslateToSG(), WRL2BASE::TranslateToSG(), VRML_V1, and S3D::WriteVRML().

Referenced by WRL2BASE::GetInlineData(), and Load().