KiCad PCB EDA Suite
loadmodel.cpp File Reference
#include <iostream>
#include <fstream>
#include <sstream>
#include <string>
#include <cstring>
#include <map>
#include <vector>
#include <wx/filename.h>
#include <wx/stdpaths.h>
#include <wx/string.h>
#include <wx/utils.h>
#include <wx/wfstream.h>
#include <wx/zipstrm.h>
#include <decompress.hpp>
#include <TDocStd_Document.hxx>
#include <TopoDS.hxx>
#include <TopoDS_Shape.hxx>
#include <Quantity_Color.hxx>
#include <XCAFApp_Application.hxx>
#include <AIS_Shape.hxx>
#include <IGESControl_Reader.hxx>
#include <IGESCAFControl_Reader.hxx>
#include <Interface_Static.hxx>
#include <STEPControl_Reader.hxx>
#include <STEPCAFControl_Reader.hxx>
#include <XCAFDoc_DocumentTool.hxx>
#include <XCAFDoc_ColorTool.hxx>
#include <XCAFDoc_ShapeTool.hxx>
#include <BRep_Tool.hxx>
#include <BRepMesh_IncrementalMesh.hxx>
#include <TopoDS_Face.hxx>
#include <TopoDS_Compound.hxx>
#include <TopExp_Explorer.hxx>
#include <Poly_Triangulation.hxx>
#include <Poly_PolygonOnTriangulation.hxx>
#include <Precision.hxx>
#include <TDF_LabelSequence.hxx>
#include <TDF_ChildIterator.hxx>
#include "plugins/3dapi/ifsg_all.h"

Go to the source code of this file.

Classes

struct  DATA
 

Macros

#define MASK_OCE   "PLUGIN_OCE"
 
#define USER_PREC   (0.14)
 
#define USER_ANGLE   (0.52359878)
 

Typedefs

typedef std::map< Standard_Real, SGNODE * > COLORMAP
 
typedef std::map< std::string, SGNODE * > FACEMAP
 
typedef std::map< std::string, std::vector< SGNODE * > > NODEMAP
 
typedef std::pair< std::string, std::vector< SGNODE * > > NODEITEM
 

Enumerations

enum  FormatType { FMT_NONE = 0, FMT_STEP, FMT_STPZ, FMT_IGES }
 

Functions

bool processNode (const TopoDS_Shape &shape, DATA &data, SGNODE *parent, std::vector< SGNODE * > *items)
 
bool processComp (const TopoDS_Shape &shape, DATA &data, SGNODE *parent, std::vector< SGNODE * > *items)
 
bool processFace (const TopoDS_Face &face, DATA &data, SGNODE *parent, std::vector< SGNODE * > *items, Quantity_Color *color)
 
FormatType fileType (const char *aFileName)
 
void getTag (TDF_Label &label, std::string &aTag)
 
bool getColor (DATA &data, TDF_Label label, Quantity_Color &color)
 
void addItems (SGNODE *parent, std::vector< SGNODE * > *lp)
 
bool readIGES (Handle(TDocStd_Document)&m_doc, const char *fname)
 
bool readSTEP (Handle(TDocStd_Document)&m_doc, const char *fname)
 
bool readSTEPZ (Handle(TDocStd_Document)&m_doc, const char *aFileName)
 
SCENEGRAPHLoadModel (char const *filename)
 
bool processShell (const TopoDS_Shape &shape, DATA &data, SGNODE *parent, std::vector< SGNODE * > *items, Quantity_Color *color)
 
bool processSolid (const TopoDS_Shape &shape, DATA &data, SGNODE *parent, std::vector< SGNODE * > *items)
 

Macro Definition Documentation

◆ MASK_OCE

#define MASK_OCE   "PLUGIN_OCE"

Definition at line 80 of file loadmodel.cpp.

◆ USER_ANGLE

#define USER_ANGLE   (0.52359878)

Definition at line 89 of file loadmodel.cpp.

◆ USER_PREC

#define USER_PREC   (0.14)

Definition at line 83 of file loadmodel.cpp.

Typedef Documentation

◆ COLORMAP

typedef std::map< Standard_Real, SGNODE* > COLORMAP

Definition at line 91 of file loadmodel.cpp.

◆ FACEMAP

typedef std::map< std::string, SGNODE* > FACEMAP

Definition at line 92 of file loadmodel.cpp.

◆ NODEITEM

typedef std::pair< std::string, std::vector< SGNODE* > > NODEITEM

Definition at line 94 of file loadmodel.cpp.

◆ NODEMAP

typedef std::map< std::string, std::vector< SGNODE* > > NODEMAP

Definition at line 93 of file loadmodel.cpp.

Enumeration Type Documentation

◆ FormatType

enum FormatType
Enumerator
FMT_NONE 
FMT_STEP 
FMT_STPZ 
FMT_IGES 

Definition at line 264 of file loadmodel.cpp.

265 {
266  FMT_NONE = 0,
267  FMT_STEP,
268  FMT_STPZ,
269  FMT_IGES
270 };

Function Documentation

◆ addItems()

void addItems ( SGNODE parent,
std::vector< SGNODE * > *  lp 
)

Definition at line 373 of file loadmodel.cpp.

374 {
375  if( NULL == lp )
376  return;
377 
378  std::vector< SGNODE* >::iterator sL = lp->begin();
379  std::vector< SGNODE* >::iterator eL = lp->end();
380  SGNODE* item;
381 
382  while( sL != eL )
383  {
384  item = *sL;
385 
386  if( NULL == S3D::GetSGNodeParent( item ) )
387  S3D::AddSGNodeChild( parent, item );
388  else
389  S3D::AddSGNodeRef( parent, item );
390 
391  ++sL;
392  }
393 
394  return;
395 }
SGLIB_API SGNODE * GetSGNodeParent(SGNODE *aNode)
Definition: ifsg_api.cpp:492
The base class of all Scene Graph nodes.
Definition: sg_node.h:74
SGLIB_API bool AddSGNodeRef(SGNODE *aParent, SGNODE *aChild)
Definition: ifsg_api.cpp:501
#define NULL
SGLIB_API bool AddSGNodeChild(SGNODE *aParent, SGNODE *aChild)
Definition: ifsg_api.cpp:510

References S3D::AddSGNodeChild(), S3D::AddSGNodeRef(), S3D::GetSGNodeParent(), and NULL.

Referenced by processSolid().

◆ fileType()

FormatType fileType ( const char *  aFileName)

Definition at line 273 of file loadmodel.cpp.

274 {
275  wxFileName fname( wxString::FromUTF8Unchecked( aFileName ) );
276  wxFFileInputStream ifile( fname.GetFullPath() );
277 
278  if( !ifile.IsOk() )
279  return FMT_NONE;
280 
281  if( fname.GetExt().MakeUpper().EndsWith( "STPZ" ) ||
282  fname.GetExt().MakeUpper().EndsWith( "GZ" ) )
283  return FMT_STPZ;
284 
285  char iline[82];
286  memset( iline, 0, 82 );
287  ifile.Read( iline, 82 );
288  iline[81] = 0; // ensure NULL termination when string is too long
289 
290  // check for STEP in Part 21 format
291  // (this can give false positives since Part 21 is not exclusively STEP)
292  if( !strncmp( iline, "ISO-10303-21;", 13 ) )
293  return FMT_STEP;
294 
295  std::string fstr = iline;
296 
297  // check for STEP in XML format
298  // (this can give both false positive and false negatives)
299  if( fstr.find( "urn:oid:1.0.10303." ) != std::string::npos )
300  return FMT_STEP;
301 
302  // Note: this is a very simple test which can yield false positives; the only
303  // sure method for determining if a file *not* an IGES model is to attempt
304  // to load it.
305  if( iline[72] == 'S' && ( iline[80] == 0 || iline[80] == 13 || iline[80] == 10 ) )
306  return FMT_IGES;
307 
308  return FMT_NONE;
309 }

References FMT_IGES, FMT_NONE, FMT_STEP, and FMT_STPZ.

Referenced by PANEL_FP_LIB_TABLE::browseLibrariesHandler(), GRAPHICS_IMPORT_MGR::GetPluginByExt(), SCH_EDIT_FRAME::importFile(), FOOTPRINT_EDIT_FRAME::ImportFootprint(), LoadModel(), PANEL_FP_LIB_TABLE::PANEL_FP_LIB_TABLE(), GERBVIEW_CONTROL::ReloadAllLayers(), and SYMBOL_EDIT_FRAME::saveLibrary().

◆ getColor()

bool getColor ( DATA data,
TDF_Label  label,
Quantity_Color &  color 
)

Definition at line 352 of file loadmodel.cpp.

353 {
354  while( true )
355  {
356  if( data.m_color->GetColor( label, XCAFDoc_ColorGen, color ) )
357  return true;
358  else if( data.m_color->GetColor( label, XCAFDoc_ColorSurf, color ) )
359  return true;
360  else if( data.m_color->GetColor( label, XCAFDoc_ColorCurv, color ) )
361  return true;
362 
363  label = label.Father();
364 
365  if( label.IsNull() )
366  break;
367  };
368 
369  return false;
370 }
SGNODE * GetColor(Quantity_Color *colorObj)
Definition: loadmodel.cpp:228
int color
Definition: DXF_plotter.cpp:60

References color, and DATA::GetColor().

Referenced by processSolid().

◆ getTag()

void getTag ( TDF_Label &  label,
std::string &  aTag 
)

Definition at line 312 of file loadmodel.cpp.

313 {
314  if( label.IsNull() )
315  return;
316 
317  std::string rtag; // tag in reverse
318  aTag.clear();
319  int id = label.Tag();
320  std::ostringstream ostr;
321  ostr << id;
322  rtag = ostr.str();
323  ostr.str( "" );
324  ostr.clear();
325 
326  TDF_Label nlab = label.Father();
327 
328  while( !nlab.IsNull() )
329  {
330  rtag.append( 1, ':' );
331  id = nlab.Tag();
332  ostr << id;
333  rtag.append( ostr.str() );
334  ostr.str( "" );
335  ostr.clear();
336  nlab = nlab.Father();
337  };
338 
339  std::string::reverse_iterator bI = rtag.rbegin();
340  std::string::reverse_iterator eI = rtag.rend();
341 
342  while( bI != eI )
343  {
344  aTag.append( 1, *bI );
345  ++bI;
346  }
347 
348  return;
349 }

Referenced by processFace(), and processSolid().

◆ LoadModel()

SCENEGRAPH* LoadModel ( char const *  filename)

Definition at line 532 of file loadmodel.cpp.

533 {
534  DATA data;
535 
536  Handle(XCAFApp_Application) m_app = XCAFApp_Application::GetApplication();
537  m_app->NewDocument( "MDTV-XCAF", data.m_doc );
538  FormatType modelFmt = fileType( filename );
539 
540  switch( modelFmt )
541  {
542  case FMT_IGES:
543  data.renderBoth = true;
544 
545  if( !readIGES( data.m_doc, filename ) )
546  return NULL;
547  break;
548 
549  case FMT_STEP:
550  if( !readSTEP( data.m_doc, filename ) )
551  return NULL;
552  break;
553 
554  case FMT_STPZ:
555  if( !readSTEPZ( data.m_doc, filename ) )
556  return NULL;
557  break;
558 
559 
560  default:
561  return NULL;
562  break;
563  }
564 
565  data.m_assy = XCAFDoc_DocumentTool::ShapeTool( data.m_doc->Main() );
566  data.m_color = XCAFDoc_DocumentTool::ColorTool( data.m_doc->Main() );
567 
568  // retrieve all free shapes
569  TDF_LabelSequence frshapes;
570  data.m_assy->GetFreeShapes( frshapes );
571 
572  int nshapes = frshapes.Length();
573  int id = 1;
574  bool ret = false;
575 
576  // create the top level SG node
577  IFSG_TRANSFORM topNode( true );
578  data.scene = topNode.GetRawPtr();
579 
580  while( id <= nshapes )
581  {
582  TopoDS_Shape shape = data.m_assy->GetShape( frshapes.Value(id) );
583 
584  if ( !shape.IsNull() && processNode( shape, data, data.scene, NULL ) )
585  ret = true;
586 
587  ++id;
588  };
589 
590  if( !ret )
591  return NULL;
592 
593  SCENEGRAPH* scene = (SCENEGRAPH*)data.scene;
594 
595  // DEBUG: WRITE OUT VRML2 FILE TO CONFIRM STRUCTURE
596  #if ( defined( DEBUG_OCE ) && DEBUG_OCE > 3 )
597  if( data.scene )
598  {
599  wxFileName fn( wxString::FromUTF8Unchecked( filename ) );
600  wxString output;
601 
602  if( FMT_STEP == modelFmt )
603  output = wxT( "_step-" );
604  else
605  output = wxT( "_iges-" );
606 
607  output.append( fn.GetName() );
608  output.append( wxT(".wrl") );
609  S3D::WriteVRML( output.ToUTF8(), true, data.scene, true, true );
610  }
611  #endif
612 
613  // set to NULL to prevent automatic destruction of the scene data
614  data.scene = NULL;
615 
616  return scene;
617 }
bool readSTEPZ(Handle(TDocStd_Document)&m_doc, const char *aFileName)
Definition: loadmodel.cpp:462
bool readSTEP(Handle(TDocStd_Document)&m_doc, const char *fname)
Definition: loadmodel.cpp:427
bool processNode(const TopoDS_Shape &shape, DATA &data, SGNODE *parent, std::vector< SGNODE * > *items)
Definition: loadmodel.cpp:816
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:76
#define NULL
bool readIGES(Handle(TDocStd_Document)&m_doc, const char *fname)
Definition: loadmodel.cpp:398
FormatType fileType(const char *aFileName)
Definition: loadmodel.cpp:273
FormatType
Definition: loadmodel.cpp:264
SGNODE * scene
Definition: loadmodel.cpp:112
IFSG_TRANSFORM is the wrapper for the VRML compatible TRANSFORM block class SCENEGRAPH.
Define the basic data set required to represent a 3D model.
Definition: scenegraph.h:44
bool renderBoth
Definition: loadmodel.cpp:118
bool GetShape(const std::string &id, std::vector< SGNODE * > *&listPtr)
Definition: loadmodel.cpp:202

References fileType(), FMT_IGES, FMT_STEP, FMT_STPZ, IFSG_NODE::GetRawPtr(), DATA::GetShape(), NULL, processNode(), readIGES(), readSTEP(), readSTEPZ(), DATA::renderBoth, DATA::scene, and S3D::WriteVRML().

Referenced by Load().

◆ processComp()

bool processComp ( const TopoDS_Shape &  shape,
DATA data,
SGNODE parent,
std::vector< SGNODE * > *  items 
)

Definition at line 752 of file loadmodel.cpp.

754 {
755  TopoDS_Iterator it;
756  IFSG_TRANSFORM childNode( parent );
757  SGNODE* pptr = childNode.GetRawPtr();
758  const TopLoc_Location& loc = shape.Location();
759  bool ret = false;
760 
761  if( !loc.IsIdentity() )
762  {
763  gp_Trsf T = loc.Transformation();
764  gp_XYZ coord = T.TranslationPart();
765  childNode.SetTranslation( SGPOINT( coord.X(), coord.Y(), coord.Z() ) );
766  gp_XYZ axis;
767  Standard_Real angle;
768 
769  if( T.GetRotation( axis, angle ) )
770  childNode.SetRotation( SGVECTOR( axis.X(), axis.Y(), axis.Z() ), angle );
771  }
772 
773  for( it.Initialize( shape, false, false ); it.More(); it.Next() )
774  {
775  const TopoDS_Shape& subShape = it.Value();
776  TopAbs_ShapeEnum stype = subShape.ShapeType();
777  data.hasSolid = false;
778 
779  switch( stype )
780  {
781  case TopAbs_COMPOUND:
782  case TopAbs_COMPSOLID:
783  if( processComp( subShape, data, pptr, items ) )
784  ret = true;
785  break;
786 
787  case TopAbs_SOLID:
788  if( processSolid( subShape, data, pptr, items ) )
789  ret = true;
790  break;
791 
792  case TopAbs_SHELL:
793  if( processShell( subShape, data, pptr, items, NULL ) )
794  ret = true;
795  break;
796 
797  case TopAbs_FACE:
798  if( processFace( TopoDS::Face( subShape ), data, pptr, items, NULL ) )
799  ret = true;
800  break;
801 
802  default:
803  break;
804  }
805  }
806 
807  if( !ret )
808  childNode.Destroy();
809  else if( NULL != items )
810  items->push_back( pptr );
811 
812  return ret;
813 }
bool processSolid(const TopoDS_Shape &shape, DATA &data, SGNODE *parent, std::vector< SGNODE * > *items)
Definition: loadmodel.cpp:638
The base class of all Scene Graph nodes.
Definition: sg_node.h:74
#define NULL
bool processFace(const TopoDS_Face &face, DATA &data, SGNODE *parent, std::vector< SGNODE * > *items, Quantity_Color *color)
Definition: loadmodel.cpp:854
bool hasSolid
Definition: loadmodel.cpp:119
static DIRECTION_45::AngleType angle(const VECTOR2I &a, const VECTOR2I &b)
IFSG_TRANSFORM is the wrapper for the VRML compatible TRANSFORM block class SCENEGRAPH.
bool processComp(const TopoDS_Shape &shape, DATA &data, SGNODE *parent, std::vector< SGNODE * > *items)
Definition: loadmodel.cpp:752
bool processShell(const TopoDS_Shape &shape, DATA &data, SGNODE *parent, std::vector< SGNODE * > *items, Quantity_Color *color)
Definition: loadmodel.cpp:620

References PNS::angle(), IFSG_NODE::Destroy(), IFSG_NODE::GetRawPtr(), DATA::hasSolid, NULL, processFace(), processShell(), processSolid(), IFSG_TRANSFORM::SetRotation(), and IFSG_TRANSFORM::SetTranslation().

Referenced by processNode().

◆ processFace()

bool processFace ( const TopoDS_Face &  face,
DATA data,
SGNODE parent,
std::vector< SGNODE * > *  items,
Quantity_Color *  color 
)

Definition at line 854 of file loadmodel.cpp.

856 {
857  if( Standard_True == face.IsNull() )
858  return false;
859 
860  bool reverse = ( face.Orientation() == TopAbs_REVERSED );
861  SGNODE* ashape = NULL;
862  std::string partID;
863  TDF_Label label;
864 
865  bool useBothSides = false;
866 
867  // for IGES renderBoth = TRUE; for STEP if a shell or face is not a descendant
868  // of a SOLID then hasSolid = false and we must render both sides
869  if( data.renderBoth || !data.hasSolid )
870  useBothSides = true;
871 
872  if( data.m_assy->FindShape( face, label, Standard_False ) )
873  getTag( label, partID );
874 
875  if( !partID.empty() )
876  ashape = data.GetFace( partID );
877 
878  if( ashape )
879  {
880  if( NULL == S3D::GetSGNodeParent( ashape ) )
881  S3D::AddSGNodeChild( parent, ashape );
882  else
883  S3D::AddSGNodeRef( parent, ashape );
884 
885  if( NULL != items )
886  items->push_back( ashape );
887 
888  if( useBothSides )
889  {
890  std::string id2 = partID;
891  id2.append( "b" );
892  SGNODE* shapeB = data.GetFace( id2 );
893 
894  if( NULL == S3D::GetSGNodeParent( shapeB ) )
895  S3D::AddSGNodeChild( parent, shapeB );
896  else
897  S3D::AddSGNodeRef( parent, shapeB );
898 
899  if( NULL != items )
900  items->push_back( shapeB );
901  }
902 
903  return true;
904  }
905 
906  TopLoc_Location loc;
907  Standard_Boolean isTessellate (Standard_False);
908  Handle(Poly_Triangulation) triangulation = BRep_Tool::Triangulation( face, loc );
909 
910  if( triangulation.IsNull() || triangulation->Deflection() > USER_PREC + Precision::Confusion() )
911  isTessellate = Standard_True;
912 
913  if (isTessellate)
914  {
915  BRepMesh_IncrementalMesh IM(face, USER_PREC, Standard_False, USER_ANGLE );
916  triangulation = BRep_Tool::Triangulation( face, loc );
917  }
918 
919  if( triangulation.IsNull() == Standard_True )
920  return false;
921 
922  Quantity_Color lcolor;
923 
924  // check for a face color; this has precedence over SOLID colors
925  do
926  {
927  TDF_Label L;
928 
929  if( data.m_color->ShapeTool()->Search( face, L ) )
930  {
931  if( data.m_color->GetColor( L, XCAFDoc_ColorGen, lcolor )
932  || data.m_color->GetColor( L, XCAFDoc_ColorCurv, lcolor )
933  || data.m_color->GetColor( L, XCAFDoc_ColorSurf, lcolor ) )
934  color = &lcolor;
935  }
936  } while( 0 );
937 
938  SGNODE* ocolor = data.GetColor( color );
939 
940  // create a SHAPE and attach the color and data,
941  // then attach the shape to the parent and return TRUE
942  IFSG_SHAPE vshape( true );
943  IFSG_FACESET vface( vshape );
944  IFSG_COORDS vcoords( vface );
945  IFSG_COORDINDEX coordIdx( vface );
946 
947  if( NULL == S3D::GetSGNodeParent( ocolor ) )
948  S3D::AddSGNodeChild( vshape.GetRawPtr(), ocolor );
949  else
950  S3D::AddSGNodeRef( vshape.GetRawPtr(), ocolor );
951 
952  const TColgp_Array1OfPnt& arrPolyNodes = triangulation->Nodes();
953  const Poly_Array1OfTriangle& arrTriangles = triangulation->Triangles();
954 
955  std::vector< SGPOINT > vertices;
956  std::vector< int > indices;
957  std::vector< int > indices2;
958  gp_Trsf tx;
959 
960  for(int i = 1; i <= triangulation->NbNodes(); i++)
961  {
962  gp_XYZ v( arrPolyNodes(i).Coord() );
963  vertices.emplace_back( v.X(), v.Y(), v.Z() );
964  }
965 
966  for(int i = 1; i <= triangulation->NbTriangles(); i++)
967  {
968  int a, b, c;
969  arrTriangles( i ).Get( a, b, c );
970  a--;
971 
972  if( reverse )
973  {
974  int tmp = b - 1;
975  b = c - 1;
976  c = tmp;
977  } else {
978  b--;
979  c--;
980  }
981 
982  indices.push_back( a );
983  indices.push_back( b );
984  indices.push_back( c );
985 
986  if( useBothSides )
987  {
988  indices2.push_back( b );
989  indices2.push_back( a );
990  indices2.push_back( c );
991  }
992  }
993 
994  vcoords.SetCoordsList( vertices.size(), &vertices[0] );
995  coordIdx.SetIndices( indices.size(), &indices[0] );
996  vface.CalcNormals( NULL );
997  vshape.SetParent( parent );
998 
999  if( !partID.empty() )
1000  data.faces.insert( std::pair< std::string,
1001  SGNODE* >( partID, vshape.GetRawPtr() ) );
1002 
1003  // The outer surface of an IGES model is indeterminate so
1004  // we must render both sides of a surface.
1005  if( useBothSides )
1006  {
1007  std::string id2 = partID;
1008  id2.append( "b" );
1009  IFSG_SHAPE vshape2( true );
1010  IFSG_FACESET vface2( vshape2 );
1011  IFSG_COORDS vcoords2( vface2 );
1012  IFSG_COORDINDEX coordIdx2( vface2 );
1013  S3D::AddSGNodeRef( vshape2.GetRawPtr(), ocolor );
1014 
1015  vcoords2.SetCoordsList( vertices.size(), &vertices[0] );
1016  coordIdx2.SetIndices( indices2.size(), &indices2[0] );
1017  vface2.CalcNormals( NULL );
1018  vshape2.SetParent( parent );
1019 
1020  if( !partID.empty() )
1021  data.faces.insert( std::pair< std::string,
1022  SGNODE* >( id2, vshape2.GetRawPtr() ) );
1023  }
1024 
1025  return true;
1026 }
SGNODE * GetColor(Quantity_Color *colorObj)
Definition: loadmodel.cpp:228
IFSG_COORDS is the wrapper for SGCOORDS.
Definition: ifsg_coords.h:40
IFSG_COORDINDEX is the wrapper for SGCOORDINDEX.
SGNODE * GetFace(const std::string &id)
Definition: loadmodel.cpp:216
FACEMAP faces
Definition: loadmodel.cpp:117
int color
Definition: DXF_plotter.cpp:60
SGLIB_API SGNODE * GetSGNodeParent(SGNODE *aNode)
Definition: ifsg_api.cpp:492
The base class of all Scene Graph nodes.
Definition: sg_node.h:74
SGLIB_API bool AddSGNodeRef(SGNODE *aParent, SGNODE *aChild)
Definition: ifsg_api.cpp:501
#define NULL
void getTag(TDF_Label &label, std::string &aTag)
Definition: loadmodel.cpp:312
#define USER_ANGLE
Definition: loadmodel.cpp:89
SGLIB_API bool AddSGNodeChild(SGNODE *aParent, SGNODE *aChild)
Definition: ifsg_api.cpp:510
#define USER_PREC
Definition: loadmodel.cpp:83
bool hasSolid
Definition: loadmodel.cpp:119
IFSG_FACESET is the wrapper for the SGFACESET class.
Definition: ifsg_faceset.h:40
bool renderBoth
Definition: loadmodel.cpp:118
IFSG_SHAPE is the wrapper for the SGSHAPE class.
Definition: ifsg_shape.h:40

References S3D::AddSGNodeChild(), S3D::AddSGNodeRef(), IFSG_FACESET::CalcNormals(), color, DATA::faces, DATA::GetColor(), DATA::GetFace(), IFSG_NODE::GetRawPtr(), S3D::GetSGNodeParent(), getTag(), DATA::hasSolid, NULL, DATA::renderBoth, IFSG_COORDS::SetCoordsList(), IFSG_INDEX::SetIndices(), IFSG_NODE::SetParent(), USER_ANGLE, and USER_PREC.

Referenced by processComp(), processNode(), and processShell().

◆ processNode()

bool processNode ( const TopoDS_Shape &  shape,
DATA data,
SGNODE parent,
std::vector< SGNODE * > *  items 
)

Definition at line 816 of file loadmodel.cpp.

818 {
819  TopAbs_ShapeEnum stype = shape.ShapeType();
820  bool ret = false;
821  data.hasSolid = false;
822 
823  switch( stype )
824  {
825  case TopAbs_COMPOUND:
826  case TopAbs_COMPSOLID:
827  if( processComp( shape, data, parent, items ) )
828  ret = true;
829  break;
830 
831  case TopAbs_SOLID:
832  if( processSolid( shape, data, parent, items ) )
833  ret = true;
834  break;
835 
836  case TopAbs_SHELL:
837  if( processShell( shape, data, parent, items, NULL ) )
838  ret = true;
839  break;
840 
841  case TopAbs_FACE:
842  if( processFace( TopoDS::Face( shape ), data, parent, items, NULL ) )
843  ret = true;
844  break;
845 
846  default:
847  break;
848  }
849 
850  return ret;
851 }
bool processSolid(const TopoDS_Shape &shape, DATA &data, SGNODE *parent, std::vector< SGNODE * > *items)
Definition: loadmodel.cpp:638
#define NULL
bool processFace(const TopoDS_Face &face, DATA &data, SGNODE *parent, std::vector< SGNODE * > *items, Quantity_Color *color)
Definition: loadmodel.cpp:854
bool hasSolid
Definition: loadmodel.cpp:119
bool processComp(const TopoDS_Shape &shape, DATA &data, SGNODE *parent, std::vector< SGNODE * > *items)
Definition: loadmodel.cpp:752
bool processShell(const TopoDS_Shape &shape, DATA &data, SGNODE *parent, std::vector< SGNODE * > *items, Quantity_Color *color)
Definition: loadmodel.cpp:620

References DATA::hasSolid, NULL, processComp(), processFace(), processShell(), and processSolid().

Referenced by LoadModel().

◆ processShell()

bool processShell ( const TopoDS_Shape &  shape,
DATA data,
SGNODE parent,
std::vector< SGNODE * > *  items,
Quantity_Color *  color 
)

Definition at line 620 of file loadmodel.cpp.

622 {
623  TopoDS_Iterator it;
624  bool ret = false;
625 
626  for( it.Initialize( shape, false, false ); it.More(); it.Next() )
627  {
628  const TopoDS_Face& face = TopoDS::Face( it.Value() );
629 
630  if( processFace( face, data, parent, items, color ) )
631  ret = true;
632  }
633 
634  return ret;
635 }
int color
Definition: DXF_plotter.cpp:60
bool processFace(const TopoDS_Face &face, DATA &data, SGNODE *parent, std::vector< SGNODE * > *items, Quantity_Color *color)
Definition: loadmodel.cpp:854

References color, and processFace().

Referenced by processComp(), processNode(), and processSolid().

◆ processSolid()

bool processSolid ( const TopoDS_Shape &  shape,
DATA data,
SGNODE parent,
std::vector< SGNODE * > *  items 
)

Definition at line 638 of file loadmodel.cpp.

640 {
641  TDF_Label label;
642  data.hasSolid = true;
643  std::string partID;
644  Quantity_Color col;
645  Quantity_Color* lcolor = NULL;
646 
647  // Search the whole model first to make sure something exists (may or may not have color)
648  if( !data.m_assy->Search( shape, label ) )
649  {
650  static int i = 0;
651  std::ostringstream ostr;
652  ostr << "KMISC_" << i++;
653  partID = ostr.str();
654  }
655  else
656  {
657  bool found_color = false;
658 
659  if( getColor( data, label, col ) )
660  {
661  found_color = true;
662  lcolor = &col;
663  }
664 
665  // If the top-level label doesn't have the color information, search components
666  if( !found_color )
667  {
668  if( data.m_assy->Search( shape, label, Standard_False, Standard_True, Standard_True ) &&
669  getColor( data, label, col ) )
670  {
671  found_color = true;
672  lcolor = &col;
673  }
674  }
675 
676  // If the components do not have color information, search all components without location
677  if( !found_color )
678  {
679  if( data.m_assy->Search( shape, label, Standard_False, Standard_False, Standard_True ) &&
680  getColor( data, label, col ) )
681  {
682  found_color = true;
683  lcolor = &col;
684  }
685  }
686 
687  // Our last chance to find the color looks for color as a subshape of top-level simple shapes
688  if( !found_color )
689  {
690  if( data.m_assy->Search( shape, label, Standard_False, Standard_False, Standard_False ) &&
691  getColor( data, label, col ) )
692  {
693  found_color = true;
694  lcolor = &col;
695  }
696  }
697 
698  getTag( label, partID );
699  }
700 
701  TopoDS_Iterator it;
702  IFSG_TRANSFORM childNode( parent );
703  SGNODE* pptr = childNode.GetRawPtr();
704  const TopLoc_Location& loc = shape.Location();
705  bool ret = false;
706 
707  if( !loc.IsIdentity() )
708  {
709  gp_Trsf T = loc.Transformation();
710  gp_XYZ coord = T.TranslationPart();
711  childNode.SetTranslation( SGPOINT( coord.X(), coord.Y(), coord.Z() ) );
712  gp_XYZ axis;
713  Standard_Real angle;
714 
715  if( T.GetRotation( axis, angle ) )
716  childNode.SetRotation( SGVECTOR( axis.X(), axis.Y(), axis.Z() ), angle );
717  }
718 
719  std::vector< SGNODE* >* component = NULL;
720 
721  if( !partID.empty() )
722  data.GetShape( partID, component );
723 
724  if( component )
725  {
726  addItems( pptr, component );
727 
728  if( NULL != items )
729  items->push_back( pptr );
730  }
731 
732  // instantiate the solid
733  std::vector< SGNODE* > itemList;
734 
735  for( it.Initialize( shape, false, false ); it.More(); it.Next() )
736  {
737  const TopoDS_Shape& subShape = it.Value();
738 
739  if( processShell( subShape, data, pptr, &itemList, lcolor ) )
740  ret = true;
741  }
742 
743  if( !ret )
744  childNode.Destroy();
745  else if( NULL != items )
746  items->push_back( pptr );
747 
748  return ret;
749 }
The base class of all Scene Graph nodes.
Definition: sg_node.h:74
#define NULL
void getTag(TDF_Label &label, std::string &aTag)
Definition: loadmodel.cpp:312
bool getColor(DATA &data, TDF_Label label, Quantity_Color &color)
Definition: loadmodel.cpp:352
bool hasSolid
Definition: loadmodel.cpp:119
void addItems(SGNODE *parent, std::vector< SGNODE * > *lp)
Definition: loadmodel.cpp:373
static DIRECTION_45::AngleType angle(const VECTOR2I &a, const VECTOR2I &b)
IFSG_TRANSFORM is the wrapper for the VRML compatible TRANSFORM block class SCENEGRAPH.
bool GetShape(const std::string &id, std::vector< SGNODE * > *&listPtr)
Definition: loadmodel.cpp:202
bool processShell(const TopoDS_Shape &shape, DATA &data, SGNODE *parent, std::vector< SGNODE * > *items, Quantity_Color *color)
Definition: loadmodel.cpp:620

References addItems(), PNS::angle(), IFSG_NODE::Destroy(), getColor(), IFSG_NODE::GetRawPtr(), DATA::GetShape(), getTag(), DATA::hasSolid, NULL, processShell(), IFSG_TRANSFORM::SetRotation(), and IFSG_TRANSFORM::SetTranslation().

Referenced by processComp(), and processNode().

◆ readIGES()

bool readIGES ( Handle(TDocStd_Document)&  m_doc,
const char *  fname 
)

Definition at line 398 of file loadmodel.cpp.

399 {
400  IGESCAFControl_Reader reader;
401  IFSelect_ReturnStatus stat = reader.ReadFile( fname );
402  reader.PrintCheckLoad( Standard_False, IFSelect_ItemsByEntity );
403 
404  if( stat != IFSelect_RetDone )
405  return false;
406 
407  // Enable file-defined shape precision
408  if( !Interface_Static::SetIVal( "read.precision.mode", 0 ) )
409  return false;
410 
411  // set other translation options
412  reader.SetColorMode(true); // use model colors
413  reader.SetNameMode(false); // don't use IGES label names
414  reader.SetLayerMode(false); // ignore LAYER data
415 
416  if ( !reader.Transfer( m_doc ) )
417  return false;
418 
419  // are there any shapes to translate?
420  if( reader.NbShapes() < 1 )
421  return false;
422 
423  return true;
424 }

Referenced by LoadModel().

◆ readSTEP()

bool readSTEP ( Handle(TDocStd_Document)&  m_doc,
const char *  fname 
)

Definition at line 427 of file loadmodel.cpp.

428 {
429  STEPCAFControl_Reader reader;
430  IFSelect_ReturnStatus stat = reader.ReadFile( fname );
431 
432  if( stat != IFSelect_RetDone )
433  return false;
434 
435  // Enable user-defined shape precision
436  if( !Interface_Static::SetIVal( "read.precision.mode", 1 ) )
437  return false;
438 
439  // Set the shape conversion precision to USER_PREC (default 0.0001 has too many triangles)
440  if( !Interface_Static::SetRVal( "read.precision.val", USER_PREC ) )
441  return false;
442 
443  // set other translation options
444  reader.SetColorMode(true); // use model colors
445  reader.SetNameMode(false); // don't use label names
446  reader.SetLayerMode(false); // ignore LAYER data
447 
448  if ( !reader.Transfer( m_doc ) )
449  {
450  m_doc->Close();
451  return false;
452  }
453 
454  // are there any shapes to translate?
455  if( reader.NbRootsForTransfer() < 1 )
456  return false;
457 
458  return true;
459 }
#define USER_PREC
Definition: loadmodel.cpp:83

References USER_PREC.

Referenced by LoadModel(), and readSTEPZ().

◆ readSTEPZ()

bool readSTEPZ ( Handle(TDocStd_Document)&  m_doc,
const char *  aFileName 
)

Definition at line 462 of file loadmodel.cpp.

463 {
464  wxFileName fname( wxString::FromUTF8Unchecked( aFileName ) );
465  wxFFileInputStream ifile( fname.GetFullPath() );
466 
467  wxFileName outFile( fname );
468 
469  outFile.SetPath( wxStandardPaths::Get().GetTempDir() );
470  outFile.SetExt( "STEP" );
471 
472  wxFileOffset size = ifile.GetLength();
473  wxBusyCursor busycursor;
474 
475  if( size == wxInvalidOffset )
476  return false;
477 
478  {
479  bool success = false;
480  wxFFileOutputStream ofile( outFile.GetFullPath() );
481 
482  if( !ofile.IsOk() )
483  return false;
484 
485  char *buffer = new char[size];
486 
487  ifile.Read( buffer, size);
488  std::string expanded;
489 
490  try
491  {
492  expanded = gzip::decompress( buffer, size );
493  success = true;
494  }
495  catch(...)
496  {}
497 
498  if( expanded.empty() )
499  {
500  ifile.Reset();
501  ifile.SeekI( 0 );
502  wxZipInputStream izipfile( ifile );
503  std::unique_ptr<wxZipEntry> zip_file( izipfile.GetNextEntry() );
504 
505  if( zip_file && !zip_file->IsDir() && izipfile.CanRead() )
506  {
507  izipfile.Read( ofile );
508  success = true;
509  }
510  }
511  else
512  {
513  ofile.Write( expanded.data(), expanded.size() );
514  }
515 
516  delete[] buffer;
517  ofile.Close();
518 
519  if( !success )
520  return false;
521  }
522 
523  bool retval = readSTEP( m_doc, outFile.GetFullPath().mb_str() );
524 
525  // Cleanup our temporary file
526  wxRemoveFile( outFile.GetFullPath() );
527 
528  return retval;
529 }
bool readSTEP(Handle(TDocStd_Document)&m_doc, const char *fname)
Definition: loadmodel.cpp:427

References readSTEP().

Referenced by LoadModel().