35 #include <wx/filename.h> 37 #include <wx/stdpaths.h> 38 #include <wx/string.h> 40 #include <wx/wfstream.h> 41 #include <wx/zipstrm.h> 43 #include <decompress.hpp> 45 #include <TDocStd_Document.hxx> 47 #include <TopoDS_Shape.hxx> 48 #include <Quantity_Color.hxx> 49 #include <XCAFApp_Application.hxx> 51 #include <AIS_Shape.hxx> 53 #include <IGESControl_Reader.hxx> 54 #include <IGESCAFControl_Reader.hxx> 55 #include <Interface_Static.hxx> 57 #include <STEPControl_Reader.hxx> 58 #include <STEPCAFControl_Reader.hxx> 60 #include <XCAFDoc_DocumentTool.hxx> 61 #include <XCAFDoc_ColorTool.hxx> 62 #include <XCAFDoc_ShapeTool.hxx> 64 #include <BRep_Tool.hxx> 65 #include <BRepMesh_IncrementalMesh.hxx> 68 #include <TopoDS_Shape.hxx> 69 #include <TopoDS_Face.hxx> 70 #include <TopoDS_Compound.hxx> 71 #include <TopExp_Explorer.hxx> 73 #include <Quantity_Color.hxx> 74 #include <Poly_Triangulation.hxx> 75 #include <Poly_PolygonOnTriangulation.hxx> 76 #include <Precision.hxx> 78 #include <TDF_LabelSequence.hxx> 79 #include <TDF_ChildIterator.hxx> 80 #include <TDF_Tool.hxx> 81 #include <TDataStd_Name.hxx> 87 #define MASK_OCE wxT( "PLUGIN_OCE" ) 88 #define MASK_OCE_EXTRA wxT( "PLUGIN_OCE_EXTRA" ) 91 #define USER_PREC (0.14) 97 #define USER_ANGLE (0.52359878) 99 typedef std::map< Standard_Real, SGNODE* >
COLORMAP;
100 typedef std::map< std::string, SGNODE* >
FACEMAP;
101 typedef std::map< std::string, std::vector< SGNODE* > >
NODEMAP;
102 typedef std::pair< std::string, std::vector< SGNODE* > >
NODEITEM;
107 std::vector< SGNODE* >* aItems );
111 std::vector< SGNODE* >* items, Quantity_Color*
color );
116 Handle( TDocStd_Document ) m_doc;
117 Handle( XCAFDoc_ColorTool ) m_color;
118 Handle( XCAFDoc_ShapeTool ) m_assy;
132 refColor.SetValues( Quantity_NOC_BLACK );
142 COLORMAP::iterator sC =
colors.begin();
143 COLORMAP::iterator eC =
colors.end();
162 FACEMAP::iterator sF =
faces.begin();
163 FACEMAP::iterator eF =
faces.end();
179 NODEMAP::iterator sS =
shapes.begin();
180 NODEMAP::iterator eS =
shapes.end();
184 std::vector< SGNODE* >::iterator sV = sS->second.begin();
185 std::vector< SGNODE* >::iterator eV = sS->second.end();
207 bool GetShape(
const std::string&
id, std::vector< SGNODE* >*& listPtr )
210 NODEMAP::iterator item;
213 if( item ==
shapes.end() )
216 listPtr = &item->second;
223 FACEMAP::iterator item;
224 item =
faces.find(
id );
226 if( item ==
faces.end() )
235 if(
nullptr == colorObj )
250 Standard_Real
id = colorObj->Distance(
refColor );
251 std::map< Standard_Real, SGNODE* >::iterator item;
254 if( item !=
colors.end() )
259 app.SetSpecular( 0.12f, 0.12f, 0.12f );
260 app.SetAmbient( 0.1f, 0.1f, 0.1f );
261 app.SetDiffuse( colorObj->Red(), colorObj->Green(), colorObj->Blue() );
262 colors.insert( std::pair< Standard_Real, SGNODE* >(
id, app.GetRawPtr() ) );
264 return app.GetRawPtr();
280 wxFileName fname( wxString::FromUTF8Unchecked( aFileName ) );
281 wxFFileInputStream ifile( fname.GetFullPath() );
286 if( fname.GetExt().MakeUpper().EndsWith( wxT(
"STPZ" ) )
287 || fname.GetExt().MakeUpper().EndsWith( wxT(
"GZ" ) ) )
293 memset( iline, 0, 82 );
294 ifile.Read( iline, 82 );
299 if( !strncmp( iline,
"ISO-10303-21;", 13 ) )
302 std::string fstr = iline;
306 if( fstr.find(
"urn:oid:1.0.10303." ) != std::string::npos )
312 if( iline[72] ==
'S' && ( iline[80] == 0 || iline[80] == 13 || iline[80] == 10 ) )
325 void getTag(
const TDF_Label& aLabel, std::string& aTag )
327 std::ostringstream ostr;
329 if( aLabel.IsNull() )
331 wxLogTrace(
MASK_OCE, wxT(
"Null label passed to getTag" ) );
335 TColStd_ListOfInteger tagList;
336 TDF_Tool::TagList( aLabel, tagList );
338 for( TColStd_ListOfInteger::Iterator it( tagList ); it.More(); it.Next() )
352 Handle( TDataStd_Name )
name;
353 if( !aLabel.IsNull() && aLabel.FindAttribute( TDataStd_Name::GetID(),
name ) )
355 TCollection_ExtendedString extstr =
name->Get();
356 char* str =
new char[extstr.LengthOfCString() + 1];
357 extstr.ToUTF8CString( str );
359 txt = wxString::FromUTF8( str );
376 case TopAbs_COMPOUND:
return "COMPOUND";
377 case TopAbs_COMPSOLID:
return "COMPSOLID";
378 case TopAbs_SOLID:
return "SOLID";
379 case TopAbs_SHELL:
return "SHELL";
380 case TopAbs_FACE:
return "FACE";
381 case TopAbs_WIRE:
return "WIRE";
382 case TopAbs_EDGE:
return "EDGE";
383 case TopAbs_VERTEX:
return "VERTEX";
384 case TopAbs_SHAPE:
return "SHAPE";
396 static inline std::ostream&
operator<<( std::ostream& aOStream,
const Quantity_ColorRGBA& aColor )
398 Quantity_Color rgb = aColor.GetRGB();
416 static void printLabel( TDF_Label aLabel, Handle( XCAFDoc_ShapeTool ) aShapeTool,
417 Handle( XCAFDoc_ColorTool ) aColorTool,
const char* aPreMsg =
nullptr )
419 if( aLabel.IsNull() )
425 TCollection_AsciiString entry;
426 TDF_Tool::Entry( aLabel, entry );
427 std::ostringstream ss;
428 ss << aPreMsg << entry <<
", " <<
getLabelName( aLabel )
429 << ( aShapeTool->IsShape( aLabel ) ?
", shape" :
"" )
430 << ( aShapeTool->IsTopLevel( aLabel ) ?
", topLevel" :
"" )
431 << ( aShapeTool->IsFree( aLabel ) ?
", free" :
"" )
432 << ( aShapeTool->IsAssembly( aLabel ) ?
", assembly" :
"" )
433 << ( aShapeTool->IsSimpleShape( aLabel ) ?
", simple" :
"" )
434 << ( aShapeTool->IsCompound( aLabel ) ?
", compound" :
"" )
435 << ( aShapeTool->IsReference( aLabel ) ?
", reference" :
"" )
436 << ( aShapeTool->IsComponent( aLabel ) ?
", component" :
"" )
437 << ( aShapeTool->IsSubShape( aLabel ) ?
", subshape" :
"" );
439 if( aShapeTool->IsSubShape( aLabel ) )
441 auto shape = aShapeTool->GetShape( aLabel );
442 if( !shape.IsNull() )
446 if( aShapeTool->IsShape( aLabel ) )
448 Quantity_ColorRGBA c;
449 if( aColorTool->GetColor( aLabel, XCAFDoc_ColorGen, c ) )
451 if( aColorTool->GetColor( aLabel, XCAFDoc_ColorSurf, c ) )
453 if( aColorTool->GetColor( aLabel, XCAFDoc_ColorCurv, c ) )
457 wxLogTrace(
MASK_OCE, ss.str().c_str() );
469 static void dumpLabels( TDF_Label aLabel, Handle( XCAFDoc_ShapeTool ) aShapeTool,
470 Handle( XCAFDoc_ColorTool ) aColorTool,
int aDepth = 0 )
472 std::string indent( aDepth * 2,
' ' );
473 printLabel( aLabel, aShapeTool, aColorTool, indent.c_str() );
474 TDF_ChildIterator it;
475 for( it.Initialize( aLabel ); it.More(); it.Next() )
476 dumpLabels( it.Value(), aShapeTool, aColorTool, aDepth + 1 );
484 if( data.m_color->
GetColor( label, XCAFDoc_ColorGen,
color ) )
486 else if( data.m_color->
GetColor( label, XCAFDoc_ColorSurf,
color ) )
488 else if( data.m_color->
GetColor( label, XCAFDoc_ColorCurv,
color ) )
491 label = label.Father();
506 std::vector< SGNODE* >::iterator sL = lp->begin();
507 std::vector< SGNODE* >::iterator eL = lp->end();
524 bool readIGES( Handle( TDocStd_Document ) & m_doc,
const char* fname )
526 IGESCAFControl_Reader reader;
527 IFSelect_ReturnStatus stat = reader.ReadFile( fname );
528 reader.PrintCheckLoad( Standard_False, IFSelect_ItemsByEntity );
530 if( stat != IFSelect_RetDone )
534 if( !Interface_Static::SetIVal(
"read.precision.mode", 0 ) )
538 reader.SetColorMode(
true);
539 reader.SetNameMode(
false);
540 reader.SetLayerMode(
false);
542 if ( !reader.Transfer( m_doc ) )
546 if( reader.NbShapes() < 1 )
553 bool readSTEP( Handle(TDocStd_Document)& m_doc,
const char* fname )
555 wxLogTrace(
MASK_OCE, wxT(
"Reading step file %s" ), fname );
557 STEPCAFControl_Reader reader;
558 IFSelect_ReturnStatus stat = reader.ReadFile( fname );
560 if( stat != IFSelect_RetDone )
564 if( !Interface_Static::SetIVal(
"read.precision.mode", 1 ) )
568 if( !Interface_Static::SetRVal(
"read.precision.val",
USER_PREC ) )
572 reader.SetColorMode(
true );
573 reader.SetNameMode(
false );
574 reader.SetLayerMode(
false );
576 if ( !reader.Transfer( m_doc ) )
583 if( reader.NbRootsForTransfer() < 1 )
590 bool readSTEPZ( Handle(TDocStd_Document)& m_doc,
const char* aFileName )
592 wxFileName fname( wxString::FromUTF8Unchecked( aFileName ) );
593 wxFFileInputStream ifile( fname.GetFullPath() );
595 wxFileName outFile( fname );
597 outFile.SetPath( wxStandardPaths::Get().GetTempDir() );
598 outFile.SetExt( wxT(
"STEP" ) );
600 wxFileOffset size = ifile.GetLength();
601 wxBusyCursor busycursor;
603 if( size == wxInvalidOffset )
607 bool success =
false;
608 wxFFileOutputStream ofile( outFile.GetFullPath() );
613 char *buffer =
new char[size];
615 ifile.Read( buffer, size);
616 std::string expanded;
620 expanded = gzip::decompress( buffer, size );
626 if( expanded.empty() )
630 wxZipInputStream izipfile( ifile );
631 std::unique_ptr<wxZipEntry> zip_file( izipfile.GetNextEntry() );
633 if( zip_file && !zip_file->IsDir() && izipfile.CanRead() )
635 izipfile.Read( ofile );
641 ofile.Write( expanded.data(), expanded.size() );
651 bool retval =
readSTEP( m_doc, outFile.GetFullPath().mb_str() );
654 wxRemoveFile( outFile.GetFullPath() );
664 Handle(XCAFApp_Application) m_app = XCAFApp_Application::GetApplication();
665 m_app->NewDocument(
"MDTV-XCAF", data.m_doc );
673 if( !
readIGES( data.m_doc, filename ) )
675 m_app->Close( data.m_doc );
682 if( !
readSTEP( data.m_doc, filename ) )
684 m_app->Close( data.m_doc );
693 m_app->Close( data.m_doc );
701 m_app->Close( data.m_doc );
706 data.m_assy = XCAFDoc_DocumentTool::ShapeTool( data.m_doc->Main() );
707 data.m_color = XCAFDoc_DocumentTool::ColorTool( data.m_doc->Main() );
710 if( wxLog::IsAllowedTraceMask(
MASK_OCE ) )
712 dumpLabels( data.m_doc->Main(), data.m_assy, data.m_color );
716 TDF_LabelSequence frshapes;
717 data.m_assy->GetFreeShapes( frshapes );
725 for( Standard_Integer i = 1; i <= frshapes.Length(); i++ )
727 const TDF_Label& label = frshapes.Value( i );
729 if( data.m_color->IsVisible( label ) )
738 m_app->Close( data.m_doc );
745 #if ( defined( DEBUG_OCE ) && DEBUG_OCE > 3 )
748 wxFileName fn( wxString::FromUTF8Unchecked( filename ) );
752 output = wxT(
"_step-" );
754 output = wxT(
"_iges-" );
756 output.append( fn.GetName() );
757 output.append( wxT(
".wrl" ) );
763 data.
scene =
nullptr;
765 m_app->Close( data.m_doc );
772 std::vector< SGNODE* >* items, Quantity_Color*
color )
777 wxLogTrace(
MASK_OCE, wxT(
"Processing shell" ) );
778 for( it.Initialize( shape,
false,
false ); it.More(); it.Next() )
780 const TopoDS_Face& face = TopoDS::Face( it.Value() );
791 std::vector< SGNODE* >* items )
797 Quantity_Color* lcolor =
nullptr;
799 wxLogTrace(
MASK_OCE, wxT(
"Processing solid" ) );
802 if( !data.m_assy->Search( shape, label ) )
805 std::ostringstream ostr;
806 ostr <<
"KMISC_" << i++;
811 bool found_color =
false;
822 if( data.m_assy->Search( shape, label, Standard_False, Standard_True, Standard_True ) &&
833 if( data.m_assy->Search( shape, label, Standard_False, Standard_False,
846 if( data.m_assy->Search( shape, label, Standard_False, Standard_False,
864 std::vector< SGNODE* >* component =
nullptr;
866 if( !partID.empty() )
873 if(
nullptr != items )
874 items->push_back( pptr );
878 std::vector< SGNODE* > itemList;
880 for( it.Initialize( shape,
false,
false ); it.More(); it.Next() )
882 const TopoDS_Shape& subShape = it.Value();
884 if( subShape.ShapeType() == TopAbs_SHELL )
886 if(
processShell( subShape, data, pptr, &itemList, lcolor ) )
891 wxLogTrace(
MASK_OCE, wxT(
"Unsupported subshape in solid" ) );
897 else if(
nullptr != items )
898 items->push_back( pptr );
905 std::vector<SGNODE*>* aItems )
907 std::string labelTag;
909 if( wxLog::IsAllowedTraceMask(
MASK_OCE ) )
912 getTag( aLabel, labelTag );
915 wxLogTrace(
MASK_OCE, wxT(
"Processing label %s" ), labelTag );
917 TopoDS_Shape originalShape;
918 TDF_Label shapeLabel = aLabel;
920 if( !aData.m_assy->
GetShape( shapeLabel, originalShape ) )
925 TopoDS_Shape shape = originalShape;
927 if( aData.m_assy->IsReference( aLabel ) )
929 wxLogTrace(
MASK_OCE, wxT(
"Label %s is ref, trying to pull up referred label" ),
932 if( !aData.m_assy->GetReferredShape( aLabel, shapeLabel ) )
937 labelTag = static_cast<int>( shapeLabel.Tag() );
940 if( !aData.m_assy->
GetShape( shapeLabel, shape ) )
950 const TopLoc_Location& loc = originalShape.Location();
952 if( !loc.IsIdentity() )
954 wxLogTrace(
MASK_OCE, wxT(
"Label %d has location" ), static_cast<int>( aLabel.Tag() ) );
955 gp_Trsf T = loc.Transformation();
956 gp_XYZ coord = T.TranslationPart();
958 wxLogTrace(
MASK_OCE, wxT(
"Translation %f, %f, %f" ), coord.X(), coord.Y(), coord.Z() );
962 if( T.GetRotation( axis,
angle ) )
965 wxLogTrace(
MASK_OCE, wxT(
"Rotation %f, %f, %f, angle %f" ),
966 axis.X(), axis.Y(), axis.Z(),
angle );
970 TopAbs_ShapeEnum stype = shape.ShapeType();
976 case TopAbs_COMPOUND:
980 if( !aData.m_assy->IsAssembly( shapeLabel ) )
984 for( xp.Init( shape, TopAbs_SOLID ); xp.More(); xp.Next() )
990 for( xp.Init( shape, TopAbs_SHELL, TopAbs_SOLID ); xp.More(); xp.Next() )
992 processShell( xp.Current(), aData, pptr, aItems, nullptr );
1006 if(
processShell( shape, aData, pptr, aItems,
nullptr ) )
1012 if(
processFace( TopoDS::Face( shape ), aData, pptr, aItems,
nullptr ) )
1021 if(
nullptr != aItems )
1022 aItems->push_back( pptr );
1024 if( !aData.m_assy->IsSimpleShape( shapeLabel ) && shapeLabel.HasChild() )
1026 wxLogTrace(
MASK_OCE, wxT(
"Label %s has children" ), labelTag );
1027 TDF_ChildIterator it;
1029 for( it.Initialize( shapeLabel ); it.More(); it.Next() )
1041 std::vector< SGNODE* >* items, Quantity_Color*
color )
1043 if( Standard_True == face.IsNull() )
1046 bool reverse = ( face.Orientation() == TopAbs_REVERSED );
1047 SGNODE* ashape =
nullptr;
1051 bool useBothSides =
false;
1056 useBothSides =
true;
1058 if( data.m_assy->FindShape( face, label, Standard_False ) )
1061 if( !partID.empty() )
1062 ashape = data.
GetFace( partID );
1071 if(
nullptr != items )
1072 items->push_back( ashape );
1076 std::string id2 = partID;
1085 if(
nullptr != items )
1086 items->push_back( shapeB );
1092 TopLoc_Location loc;
1093 Standard_Boolean isTessellate (Standard_False);
1094 Handle( Poly_Triangulation ) triangulation = BRep_Tool::Triangulation( face, loc );
1096 if( triangulation.IsNull() || triangulation->Deflection() >
USER_PREC + Precision::Confusion() )
1097 isTessellate = Standard_True;
1102 triangulation = BRep_Tool::Triangulation( face, loc );
1105 if( triangulation.IsNull() == Standard_True )
1108 Quantity_Color lcolor;
1115 if( data.m_color->ShapeTool()->Search( face, L ) )
1117 if( data.m_color->
GetColor( L, XCAFDoc_ColorGen, lcolor )
1118 || data.m_color->
GetColor( L, XCAFDoc_ColorCurv, lcolor )
1119 || data.m_color->
GetColor( L, XCAFDoc_ColorSurf, lcolor ) )
1138 std::vector< SGPOINT > vertices;
1139 std::vector< int > indices;
1140 std::vector< int > indices2;
1143 for(
int i = 1; i <= triangulation->NbNodes(); i++ )
1145 gp_XYZ v( triangulation->Node(i).Coord() );
1146 vertices.emplace_back( v.X(), v.Y(), v.Z() );
1149 for(
int i = 1; i <= triangulation->NbTriangles(); i++ )
1152 triangulation->Triangle(i).Get(a, b, c);
1167 indices.push_back( a );
1168 indices.push_back( b );
1169 indices.push_back( c );
1173 indices2.push_back( b );
1174 indices2.push_back( a );
1175 indices2.push_back( c );
1180 coordIdx.
SetIndices( indices.size(), &indices[0] );
1184 if( !partID.empty() )
1185 data.
faces.insert( std::pair< std::string, SGNODE* >( partID, vshape.
GetRawPtr() ) );
1191 std::string id2 = partID;
1200 coordIdx2.
SetIndices( indices2.size(), &indices2[0] );
1204 if( !partID.empty() )
1205 data.
faces.insert( std::pair< std::string, SGNODE* >( id2, vshape2.
GetRawPtr() ) );
void getTag(const TDF_Label &aLabel, std::string &aTag)
Gets the absolute tag string for a given label in the form of ##:##:##:##.
SGNODE * GetColor(Quantity_Color *colorObj)
bool readSTEPZ(Handle(TDocStd_Document)&m_doc, const char *aFileName)
IFSG_COORDS is the wrapper for SGCOORDS.
IFSG_COORDINDEX is the wrapper for SGCOORDINDEX.
SGNODE * GetFace(const std::string &id)
static void dumpLabels(TDF_Label aLabel, Handle(XCAFDoc_ShapeTool) aShapeTool, Handle(XCAFDoc_ColorTool) aColorTool, int aDepth=0)
Dumps a label and the entire tree underneath it.
static std::ostream & operator<<(std::ostream &aOStream, const Quantity_ColorRGBA &aColor)
static int colorFloatToDecimal(float aVal)
bool SetDiffuse(float aRVal, float aGVal, float aBVal)
SGLIB_API SGNODE * GetSGNodeParent(SGNODE *aNode)
bool processSolid(const TopoDS_Shape &shape, DATA &data, SGNODE *parent, std::vector< SGNODE * > *items)
bool SetParent(SGNODE *aParent)
Function SetParent sets the parent SGNODE of this object.
The base class of all Scene Graph nodes.
collects header files for all SG* wrappers and the API
bool readSTEP(Handle(TDocStd_Document)&m_doc, const char *fname)
std::pair< std::string, std::vector< SGNODE * > > NODEITEM
SGNODE * GetRawPtr(void) noexcept
Function GetRawPtr() returns the raw internal SGNODE pointer.
SGLIB_API bool AddSGNodeRef(SGNODE *aParent, SGNODE *aChild)
std::map< std::string, SGNODE * > FACEMAP
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.
std::map< std::string, std::vector< SGNODE * > > NODEMAP
SGLIB_API void DestroyNode(SGNODE *aNode) noexcept
Function DestroyNode deletes the given SG* class node.
bool SetAmbient(float aRVal, float aGVal, float aBVal)
bool processFace(const TopoDS_Face &face, DATA &data, SGNODE *parent, std::vector< SGNODE * > *items, Quantity_Color *color)
SGLIB_API bool AddSGNodeChild(SGNODE *aParent, SGNODE *aChild)
bool getColor(DATA &data, TDF_Label label, Quantity_Color &color)
FormatType fileType(const char *aFileName)
bool SetShininess(float aShininess) noexcept
static void printLabel(TDF_Label aLabel, Handle(XCAFDoc_ShapeTool) aShapeTool, Handle(XCAFDoc_ColorTool) aColorTool, const char *aPreMsg=nullptr)
Gets a string for a given TopAbs_ShapeEnum element.
bool CalcNormals(SGNODE **aPtr)
bool readIGES(Handle(TDocStd_Document) &m_doc, const char *fname)
bool SetIndices(size_t nIndices, int *aIndexList)
Function SetIndices sets the number of indices and creates a copy of the given index data.
SCENEGRAPH * LoadModel(char const *filename)
void addItems(SGNODE *parent, std::vector< SGNODE * > *lp)
bool SetSpecular(float aRVal, float aGVal, float aBVal)
static wxString getLabelName(const TDF_Label &aLabel)
bool SetCoordsList(size_t aListSize, const SGPOINT *aCoordsList)
bool processLabel(const TDF_Label &aLabel, DATA &aData, SGNODE *aParent, std::vector< SGNODE * > *aItems)
IFSG_FACESET is the wrapper for the SGFACESET class.
static DIRECTION_45::AngleType angle(const VECTOR2I &a, const VECTOR2I &b)
Define the basic data set required to represent a 3D model.
Handle(TDocStd_Document) m_doc
void Destroy(void)
Function Destroy deletes the object held by this wrapper.
std::map< Standard_Real, SGNODE * > COLORMAP
bool GetShape(const std::string &id, std::vector< SGNODE * > *&listPtr)
std::string getShapeName(TopAbs_ShapeEnum aShape)
Gets a string for a given TopAbs_ShapeEnum element.
IFSG_SHAPE is the wrapper for the SGSHAPE class.
bool processShell(const TopoDS_Shape &shape, DATA &data, SGNODE *parent, std::vector< SGNODE * > *items, Quantity_Color *color)