diff --git a/src/BinTools/BinTools_ShapeSet.cxx b/src/BinTools/BinTools_ShapeSet.cxx index 3f0d45bf1b..532f9cb5f3 100644 --- a/src/BinTools/BinTools_ShapeSet.cxx +++ b/src/BinTools/BinTools_ShapeSet.cxx @@ -74,8 +74,8 @@ static Standard_OStream& operator <<(Standard_OStream& OS, const gp_Pnt P) //purpose : //======================================================================= -BinTools_ShapeSet::BinTools_ShapeSet(const Standard_Boolean isWithTriangles) - :myFormatNb(3), myWithTriangles(isWithTriangles) +BinTools_ShapeSet::BinTools_ShapeSet(const Standard_Boolean /*isWithTriangles*/) + :myFormatNb(3), myWithTriangles(Standard_True/*isWithTriangles*/) {} //======================================================================= @@ -517,6 +517,12 @@ void BinTools_ShapeSet::Read(TopoDS_Shape& S, Standard_IStream& IS, anOrient = (TopAbs_Orientation)aChar; Standard_Integer anIndx; BinTools::GetInteger(IS, anIndx); + Standard_Integer anInd = nbshapes - anIndx + 1; + if (anInd < 1 || anInd > myShapes.Extent()) + { + S = TopoDS_Shape(); + return; + } S = myShapes(nbshapes - anIndx + 1); S.Orientation(anOrient); diff --git a/src/BinTools/BinTools_SurfaceSet.cxx b/src/BinTools/BinTools_SurfaceSet.cxx index 6dd2fa23b6..1d893ef9e9 100644 --- a/src/BinTools/BinTools_SurfaceSet.cxx +++ b/src/BinTools/BinTools_SurfaceSet.cxx @@ -95,6 +95,8 @@ Standard_Integer BinTools_SurfaceSet::Add(const Handle(Geom_Surface)& S) Handle(Geom_Surface) BinTools_SurfaceSet::Surface (const Standard_Integer I)const { + if (I < 1 || I > myMap.Extent()) + return Handle(Geom_Surface)(); return Handle(Geom_Surface)::DownCast(myMap(I)); } diff --git a/src/TKVRML/EXTERNLIB b/src/TKVRML/EXTERNLIB index 6f521bbafa..ed69fdfbd8 100755 --- a/src/TKVRML/EXTERNLIB +++ b/src/TKVRML/EXTERNLIB @@ -11,3 +11,4 @@ TKHLR TKService TKGeomAlgo TKV3d +TKSTL \ No newline at end of file diff --git a/src/VrmlData/VrmlData_Geometry.cxx b/src/VrmlData/VrmlData_Geometry.cxx index 5fc4b5c10f..6b6a714b05 100644 --- a/src/VrmlData/VrmlData_Geometry.cxx +++ b/src/VrmlData/VrmlData_Geometry.cxx @@ -650,7 +650,15 @@ VrmlData_ErrorStatus VrmlData_ArrayVec3d::ReadArray // Read the body of the data node (list of triplets) if (OK(aStatus) && OK(aStatus, VrmlData_Scene::ReadLine(theBuffer))) { if (theBuffer.LinePtr[0] != '[') // opening bracket - aStatus = VrmlData_VrmlFormatError; + { + // Handle case when brackets are ommited for single element of array + gp_XYZ anXYZ; + // Read three numbers (XYZ value) + if (!OK(aStatus, Scene().ReadXYZ(theBuffer, anXYZ, + isScale, Standard_False))) + aStatus = VrmlData_VrmlFormatError; + vecValues.Append(anXYZ); + } else { theBuffer.LinePtr++; for(;;) { diff --git a/src/VrmlData/VrmlData_Group.cxx b/src/VrmlData/VrmlData_Group.cxx index f1d989a661..685b04523f 100644 --- a/src/VrmlData/VrmlData_Group.cxx +++ b/src/VrmlData/VrmlData_Group.cxx @@ -203,6 +203,10 @@ VrmlData_ErrorStatus VrmlData_Group::Read (VrmlData_InBuffer& theBuffer) break; } } + else if (VRMLDATA_LCOMPARE(theBuffer.LinePtr, "collide")) { + TCollection_AsciiString aDummy; + aStatus = Scene().ReadWord (theBuffer, aDummy); + } else if (VRMLDATA_LCOMPARE (theBuffer.LinePtr, "Separator") || VRMLDATA_LCOMPARE (theBuffer.LinePtr, "Switch")) { Standard_Boolean isBracketed (Standard_False); diff --git a/src/VrmlData/VrmlData_IndexedFaceSet.cxx b/src/VrmlData/VrmlData_IndexedFaceSet.cxx index 0e5f8c4fe8..94a5d687ab 100644 --- a/src/VrmlData/VrmlData_IndexedFaceSet.cxx +++ b/src/VrmlData/VrmlData_IndexedFaceSet.cxx @@ -29,6 +29,26 @@ #include #include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + IMPLEMENT_STANDARD_RTTIEXT(VrmlData_IndexedFaceSet,VrmlData_Faceted) #ifdef _MSC_VER @@ -36,8 +56,239 @@ IMPLEMENT_STANDARD_RTTIEXT(VrmlData_IndexedFaceSet,VrmlData_Faceted) #pragma warning (disable:4996) #endif +// Auxiliary tools +namespace +{ + // Tool to get triangles from triangulation taking into account face + // orientation and location + class TriangleAccessor + { + public: + TriangleAccessor (const TopoDS_Face& aFace) + { + TopLoc_Location aLoc; + myPoly = BRep_Tool::Triangulation (aFace, aLoc); + myTrsf = aLoc.Transformation(); + myNbTriangles = (myPoly.IsNull() ? 0 : myPoly->Triangles().Length()); + myInvert = (aFace.Orientation() == TopAbs_REVERSED); + if (myTrsf.IsNegative()) + myInvert = ! myInvert; + } + int NbTriangles () const { return myNbTriangles; } + // get i-th triangle and outward normal + void GetTriangle (int iTri, gp_Vec &theNormal, gp_Pnt &thePnt1, gp_Pnt &thePnt2, gp_Pnt &thePnt3) + { + // get positions of nodes + int iNode1, iNode2, iNode3; + myPoly->Triangles()(iTri).Get (iNode1, iNode2, iNode3); + thePnt1 = myPoly->Nodes()(iNode1); + thePnt2 = myPoly->Nodes()(myInvert ? iNode3 : iNode2); + thePnt3 = myPoly->Nodes()(myInvert ? iNode2 : iNode3); + + // apply transormation if not identity + if (myTrsf.Form() != gp_Identity) + { + thePnt1.Transform (myTrsf); + thePnt2.Transform (myTrsf); + thePnt3.Transform (myTrsf); + } + + // calculate normal + theNormal = (thePnt2.XYZ() - thePnt1.XYZ()) ^ (thePnt3.XYZ() - thePnt1.XYZ()); + Standard_Real aNorm = theNormal.Magnitude(); + if (aNorm > gp::Resolution()) + theNormal /= aNorm; + } + + private: + Handle(Poly_Triangulation) myPoly; + gp_Trsf myTrsf; + int myNbTriangles; + bool myInvert; + }; + + // convert to float and, on big-endian platform, to little-endian representation + inline float convertFloat (Standard_Real aValue) + { +#ifdef OCCT_BINARY_FILE_DO_INVERSE + return OSD_BinaryFile::InverseShortReal ((float)aValue); +#else + return (float)aValue; +#endif + } + + // A static method adding nodes to a mesh and keeping coincident (sharing) nodes. + static Standard_Integer AddVertex(Handle(StlMesh_Mesh)& mesh, + BRepBuilderAPI_CellFilter& filter, + BRepBuilderAPI_VertexInspector& inspector, + const gp_XYZ& p) + { + Standard_Integer index; + inspector.SetCurrent(p); + gp_XYZ minp = inspector.Shift(p, -Precision::Confusion()); + gp_XYZ maxp = inspector.Shift(p, +Precision::Confusion()); + filter.Inspect(minp, maxp, inspector); + const TColStd_ListOfInteger& indices = inspector.ResInd(); + if (indices.IsEmpty() == Standard_False) + { + index = indices.First(); // it should be only one + inspector.ClearResList(); + } + else + { + index = mesh->AddVertex(p.X(), p.Y(), p.Z()); + filter.Add(index, p); + inspector.Add(p); + } + return index; + } + + void createFromMesh(Handle(TopoDS_TShape)& theShapeWithMesh) + { + TopoDS_Shape aShape; + //aShape.Orientation(TopAbs_FORWARD); + + aShape.TShape(theShapeWithMesh); + if (aShape.IsNull()) + return; + + // Write to STL and then read again to get BRep model (vrml fills only triangulation) + //StlAPI::Write(aShape, "D:/Temp/tempfile"); + //StlAPI::Read(aShape, "D:/Temp/tempfile"); + + gp_XYZ p1, p2, p3; + TopoDS_Vertex Vertex1, Vertex2, Vertex3; + TopoDS_Face AktFace; + TopoDS_Wire AktWire; + BRepBuilderAPI_Sewing aSewingTool; + Standard_Real x1, y1, z1; + Standard_Real x2, y2, z2; + Standard_Real x3, y3, z3; + Standard_Integer i1,i2,i3; + + aSewingTool.Init(1.0e-06,Standard_True); + + TopoDS_Compound aComp; + BRep_Builder BuildTool; + BuildTool.MakeCompound( aComp ); + + Handle(StlMesh_Mesh) aSTLMesh = new StlMesh_Mesh(); + aSTLMesh->AddDomain(); + + // Filter unique vertices to share the nodes of the mesh. + BRepBuilderAPI_CellFilter uniqueVertices(Precision::Confusion()); + BRepBuilderAPI_VertexInspector inspector(Precision::Confusion()); + + // Read mesh + for (TopExp_Explorer exp (aShape, TopAbs_FACE); exp.More(); exp.Next()) + { + TriangleAccessor aTool (TopoDS::Face (exp.Current())); + for (int iTri = 1; iTri <= aTool.NbTriangles(); iTri++) + { + gp_Vec aNorm; + gp_Pnt aPnt1, aPnt2, aPnt3; + aTool.GetTriangle(iTri, aNorm, aPnt1, aPnt2, aPnt3); + + i1 = AddVertex(aSTLMesh, uniqueVertices, inspector, aPnt1.XYZ()); + i2 = AddVertex(aSTLMesh, uniqueVertices, inspector, aPnt2.XYZ()); + i3 = AddVertex(aSTLMesh, uniqueVertices, inspector, aPnt3.XYZ()); + aSTLMesh->AddTriangle(i1, i2, i3, aNorm.X(), aNorm.Y(), aNorm.Z()); + } + } + + StlMesh_MeshExplorer aMExp (aSTLMesh); + Standard_Integer NumberDomains = aSTLMesh->NbDomains(); + Standard_Integer iND; + for (iND=1;iND<=NumberDomains;iND++) + { + for (aMExp.InitTriangle (iND); aMExp.MoreTriangle (); aMExp.NextTriangle ()) + { + aMExp.TriangleVertices (x1,y1,z1,x2,y2,z2,x3,y3,z3); + p1.SetCoord(x1,y1,z1); + p2.SetCoord(x2,y2,z2); + p3.SetCoord(x3,y3,z3); + + if ((!(p1.IsEqual(p2,0.0))) && (!(p1.IsEqual(p3,0.0)))) + { + Vertex1 = BRepBuilderAPI_MakeVertex(p1); + Vertex2 = BRepBuilderAPI_MakeVertex(p2); + Vertex3 = BRepBuilderAPI_MakeVertex(p3); + + AktWire = BRepBuilderAPI_MakePolygon( Vertex1, Vertex2, Vertex3, Standard_True); + + if( !AktWire.IsNull()) + { + AktFace = BRepBuilderAPI_MakeFace( AktWire); + if(!AktFace.IsNull()) + BuildTool.Add( aComp, AktFace ); + } + } + } + } + aSTLMesh->Clear(); + + aSewingTool.Init(); + aSewingTool.Load( aComp ); + aSewingTool.Perform(); + aShape = aSewingTool.SewedShape(); + if ( aShape.IsNull() ) + aShape = aComp; + + ShapeUpgrade_UnifySameDomain anUSD(aShape); + anUSD.SetLinearTolerance(1e-5); + anUSD.Build(); + aShape = anUSD.Shape(); + + if (aShape.ShapeType() == TopAbs_SHELL && TopoDS::Shell(aShape).Closed()) + { + TopoDS_Solid aSolid; + TopoDS_Shell aShell = TopoDS::Shell (aShape); + if (!aShell.Free ()) { + aShell.Free(Standard_True); + } + BRep_Builder aBuilder; + aBuilder.MakeSolid (aSolid); + aBuilder.Add (aSolid, aShell); + + Standard_Boolean isOk = Standard_True; + try { + OCC_CATCH_SIGNALS + BRepClass3d_SolidClassifier bsc3d (aSolid); + Standard_Real t = Precision::Confusion(); + bsc3d.PerformInfinitePoint(t); + + if (bsc3d.State() == TopAbs_IN) { + TopoDS_Solid aSolid2; + aBuilder.MakeSolid (aSolid2); + aShell.Reverse(); + aBuilder.Add (aSolid2, aShell); + aSolid = aSolid2; + } + } + catch (Standard_Failure) { isOk = Standard_False; } + if (isOk) aShape = aSolid; + } + + // Trying to apply "Combine to Cylinder" + + //ShapeUpgrade_CombineToCylinder cmb2Cyl; + //Standard_Boolean isOk = Standard_True; + //try { + // OCC_CATCH_SIGNALS + // cmb2Cyl.SetShape(aShape); + // cmb2Cyl.SetAngularTolerance(20); + // cmb2Cyl.SetLinearTolerance(3); + // cmb2Cyl.Build(); + //} + //catch (Standard_Failure) { isOk = Standard_False; } + //if (isOk && cmb2Cyl.IsDone()) + // aShape = cmb2Cyl.Shape(); + + theShapeWithMesh = aShape.TShape(); + } +} //======================================================================= //function : readData @@ -210,6 +461,7 @@ const Handle(TopoDS_TShape)& VrmlData_IndexedFaceSet::TShape () myIsModified = Standard_False; } + //createFromMesh(myTShape); return myTShape; } diff --git a/src/VrmlData/VrmlData_IndexedLineSet.cxx b/src/VrmlData/VrmlData_IndexedLineSet.cxx index 7f15d7a66d..bd2642ab5f 100644 --- a/src/VrmlData/VrmlData_IndexedLineSet.cxx +++ b/src/VrmlData/VrmlData_IndexedLineSet.cxx @@ -55,34 +55,34 @@ Quantity_Color VrmlData_IndexedLineSet::GetColor const Handle(TopoDS_TShape)& VrmlData_IndexedLineSet::TShape () { - if (myNbPolygons == 0) - myTShape.Nullify(); - else if (myIsModified) { - Standard_Integer i; - BRep_Builder aBuilder; - const gp_XYZ * arrNodes = myCoords->Values(); + //if (myNbPolygons == 0) + // myTShape.Nullify(); + //else if (myIsModified) { + // Standard_Integer i; + // BRep_Builder aBuilder; + // const gp_XYZ * arrNodes = myCoords->Values(); - // Create the Wire - TopoDS_Wire aWire; - aBuilder.MakeWire(aWire); - for (i = 0; i < (int)myNbPolygons; i++) { - const Standard_Integer * arrIndice; - const Standard_Integer nNodes = Polygon(i, arrIndice); - TColgp_Array1OfPnt arrPoint (1, nNodes); - TColStd_Array1OfReal arrParam (1, nNodes); - for (Standard_Integer j = 0; j < nNodes; j++) { - arrPoint(j+1).SetXYZ (arrNodes[arrIndice[j]]); - arrParam(j+1) = j; - } - const Handle(Poly_Polygon3D) aPolyPolygon = - new Poly_Polygon3D (arrPoint, arrParam); - TopoDS_Edge anEdge; - aBuilder.MakeEdge (anEdge, aPolyPolygon); - aBuilder.Add (aWire, anEdge); - } - myTShape = aWire.TShape(); - } - return myTShape; + // // Create the Wire + // TopoDS_Wire aWire; + // aBuilder.MakeWire(aWire); + // for (i = 0; i < (int)myNbPolygons; i++) { + // const Standard_Integer * arrIndice; + // const Standard_Integer nNodes = Polygon(i, arrIndice); + // TColgp_Array1OfPnt arrPoint (1, nNodes); + // TColStd_Array1OfReal arrParam (1, nNodes); + // for (Standard_Integer j = 0; j < nNodes; j++) { + // arrPoint(j+1).SetXYZ (arrNodes[arrIndice[j]]); + // arrParam(j+1) = j; + // } + // const Handle(Poly_Polygon3D) aPolyPolygon = + // new Poly_Polygon3D (arrPoint, arrParam); + // TopoDS_Edge anEdge; + // aBuilder.MakeEdge (anEdge, aPolyPolygon); + // aBuilder.Add (aWire, anEdge); + // } + // myTShape = aWire.TShape(); + //} + return Handle(TopoDS_TShape)(); } //======================================================================= diff --git a/src/VrmlData/VrmlData_Scene.cxx b/src/VrmlData/VrmlData_Scene.cxx index c1862caf45..9128cd3fbd 100644 --- a/src/VrmlData/VrmlData_Scene.cxx +++ b/src/VrmlData/VrmlData_Scene.cxx @@ -497,6 +497,9 @@ VrmlData_ErrorStatus VrmlData_Scene::createNode else if (VRMLDATA_LCOMPARE(theBuffer.LinePtr, "Separator")) aNode = new VrmlData_Group (* this, strName, Standard_False); + else if (VRMLDATA_LCOMPARE(theBuffer.LinePtr, "Collision")) + aNode = new VrmlData_Group (* this, strName, + Standard_False); else if (VRMLDATA_LCOMPARE(theBuffer.LinePtr, "Switch")) aNode = new VrmlData_Group (* this, strName, Standard_False); diff --git a/src/XDEDRAW/XDEDRAW_Common.cxx b/src/XDEDRAW/XDEDRAW_Common.cxx index 9b347cc8cc..b19e320ba4 100644 --- a/src/XDEDRAW/XDEDRAW_Common.cxx +++ b/src/XDEDRAW/XDEDRAW_Common.cxx @@ -48,6 +48,23 @@ #include #include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include + #include //============================================================ // Support for several models in DRAW @@ -513,6 +530,339 @@ static Standard_Integer Expand (Draw_Interpretor& di, Standard_Integer argc, con return 0; } +//======================================================================= +//function : ReadVrml +//purpose : Read VRML file to DECAF document +//======================================================================= + +TDF_Label ReadVrmlRec(const OSD_Path& thePath, const Handle(TDocStd_Document)& theDoc, const TDF_Label& theLabel) +{ + TDF_Label aNewLabel; + Handle(XCAFDoc_ShapeTool) aShapeTool = XCAFDoc_DocumentTool::ShapeTool( theDoc->Main() ); + Handle(XCAFDoc_ColorTool) aColorTool = XCAFDoc_DocumentTool::ColorTool( theDoc->Main() ); + + // Get path of the VRML file. + TCollection_AsciiString aVrmlDir("."); + TCollection_AsciiString aDisk = thePath.Disk(); + TCollection_AsciiString aTrek = thePath.Trek(); + TCollection_AsciiString aName = thePath.Name(); + TCollection_AsciiString anExt = thePath.Extension(); + + cout << "==============================================================" << endl; + + if (!aTrek.IsEmpty()) + { + if (!aDisk.IsEmpty()) + aVrmlDir = aDisk; + else + aVrmlDir.Clear(); + aTrek.ChangeAll('|', '/'); + aTrek.ChangeAll('\\', '/'); + aVrmlDir += aTrek; + + if (!aName.IsEmpty()) + aVrmlDir += aName; + + if (!anExt.IsEmpty()) + aVrmlDir += anExt; + } + + // Analize the passed Path + if (thePath.Extension() == ".wrl") + { + // Read shape from vrml and add to parent as component + TopoDS_Shape aShape ; + VrmlData_DataMapOfShapeAppearance aShapeAppMap; + filebuf aFic; + istream aStream (&aFic); + if (aFic.open(aVrmlDir.ToCString(), ios::in)) + { + cout << "Reading file " << aVrmlDir.ToCString() << "..." << endl; + + VrmlData_Scene aScene; + aScene.SetVrmlDir(aVrmlDir); + aScene << aStream; + aFic.close(); + if (aScene.Status() == VrmlData_StatusOK) + { + aShape = aScene.GetShape(aShapeAppMap); + + if (aShape.IsNull()) + { + cout << "Shape was not extracted from file " << aVrmlDir.ToCString() << "..." << endl; + return aNewLabel; + } + + TopExp_Explorer anExp; + Quantity_Color aFaceColor; + Quantity_Color anEdgeColor(Quantity_NOC_BLACK); + for (anExp.Init(aShape, TopAbs_FACE); anExp.More(); anExp.Next()) + { + if (aShapeAppMap.IsBound(anExp.Current().TShape())) + { + Handle(VrmlData_Appearance) anAppearance = aShapeAppMap.Find(anExp.Current().TShape()); + if (!anAppearance.IsNull() && !anAppearance->Material().IsNull()) + { + aFaceColor = anAppearance->Material()->DiffuseColor(); + break; + } + } + } + + //Standard_Boolean isSingleShell = Standard_False; + //TopoDS_Shell aShell; + //for (anExp.Init(aShape, TopAbs_SHELL); anExp.More(); anExp.Next()) + //{ + // if (!anExp.Current().IsNull() && anExp.Current().ShapeType() == TopAbs_SHELL) + // { + // if (!isSingleShell) + // { + // aShell = TopoDS::Shell(anExp.Current()); + // isSingleShell = Standard_True; + // } + // else + // { + // isSingleShell = Standard_False; + // break; + // } + // } + //} + + //Standard_Boolean hasCylindrical = Standard_False; + //if (!aShell.IsNull() && isSingleShell) + //{ + // for (anExp.Init(aShell, TopAbs_FACE); anExp.More(); anExp.Next()) + // { + // if (!anExp.Current().IsNull()) + // { + // const TopoDS_Face& aFace = TopoDS::Face(anExp.Current()); + // Handle(Geom_CylindricalSurface) aSurf = Handle(Geom_CylindricalSurface)::DownCast(BRep_Tool::Surface(aFace)); + // if (!aSurf.IsNull()) + // hasCylindrical = Standard_True; + // } + // } + //} + //if (hasCylindrical) + // aShape = aShell; + //else + // isSingleShell = Standard_False; + + //if (!isSingleShell) + //{ + // Standard_Boolean doTriangulation = Standard_False; + // for (anExp.Init(aShape, TopAbs_FACE); anExp.More(); anExp.Next()) + // { + // TopLoc_Location aDummy; + // if (BRep_Tool::Triangulation(TopoDS::Face(anExp.Current()), aDummy).IsNull()) + // { + // doTriangulation = Standard_True; + // break; + // } + // } + + // if (doTriangulation) + // { + // BRepMesh_IncrementalMesh aMesh(aShape, 1); + // aMesh.Perform(); + // if (aMesh.IsDone()) + // aShape = aMesh.Shape(); + // } + + // // Write to STL and then read again to get BRep model (vrml fills only triangulation) + // StlAPI::Write(aShape, vrmlTempFile); + // StlAPI::Read(aShape, vrmlTempFile); + //} + + /*if (aShape.IsNull()) + return aNewLabel;*/ + + /*ShapeUpgrade_UnifySameDomain anUSD(aShape); + anUSD.SetLinearTolerance(1e-5); + anUSD.Build(); + aShape = anUSD.Shape(); + + if (aShape.ShapeType() == TopAbs_SHELL && TopoDS::Shell(aShape).Closed()) + { + TopoDS_Solid aSolid; + TopoDS_Shell aShell = TopoDS::Shell (aShape); + if (!aShell.Free ()) { + aShell.Free(Standard_True); + } + BRep_Builder aBuilder; + aBuilder.MakeSolid (aSolid); + aBuilder.Add (aSolid, aShell); + + Standard_Boolean isOk = Standard_True; + try { + OCC_CATCH_SIGNALS + BRepClass3d_SolidClassifier bsc3d (aSolid); + Standard_Real t = Precision::Confusion(); + bsc3d.PerformInfinitePoint(t); + + if (bsc3d.State() == TopAbs_IN) { + TopoDS_Solid aSolid2; + aBuilder.MakeSolid (aSolid2); + aShell.Reverse(); + aBuilder.Add (aSolid2, aShell); + aSolid = aSolid2; + } + } + catch (Standard_Failure) { isOk = Standard_False; } + if (isOk) aShape = aSolid; + }*/ + + if (theLabel.IsNull() || !aShapeTool->IsAssembly(theLabel)) + { + // Add new shape + aNewLabel = aShapeTool->AddShape(aShape, Standard_False); + cout << "Created new shape " << thePath.Name() << " (free)" << endl; + } + else if (!theLabel.IsNull() && aShapeTool->IsAssembly(theLabel)) + { + // Add shape as component + aNewLabel = aShapeTool->AddComponent(theLabel, aShape); + Handle(TDataStd_Name) anAttrName; + theLabel.FindAttribute(TDataStd_Name::GetID(), anAttrName); + cout << "Created new shape " << thePath.Name() << " as part of " << (anAttrName.IsNull()? "(noname)" : TCollection_AsciiString(anAttrName->Get())) << endl; + + if ( aShapeTool->IsReference(aNewLabel) ) + { + TDF_Label RefLabel; + if ( aShapeTool->GetReferredShape(aNewLabel, RefLabel) ) + aNewLabel = RefLabel; + } + } + + if (!aNewLabel.IsNull()) + TDataStd_Name::Set(aNewLabel, thePath.Name()); + + aColorTool->SetColor(aNewLabel, aFaceColor, XCAFDoc_ColorSurf); + aColorTool->SetColor(aNewLabel, anEdgeColor, XCAFDoc_ColorCurv); + return aNewLabel; + } + else + { + cout << "Error during reading of vrml file " << aVrmlDir.ToCString() << endl; + } + } + else + { + cout << "Cannot open file " << aVrmlDir.ToCString() << endl; + } + } + else if (thePath.Extension().IsEmpty()) + { + cout << "Scaning root " << aVrmlDir.ToCString() << "..." << endl; + + OSD_DirectoryIterator aDirIt(thePath, "*"); + OSD_FileIterator aFileIt(thePath, "*.wrl"); + + // Check real dircetories + OSD_Path aSubDirPath; + TCollection_AsciiString aTempName; + Standard_Boolean isSubDirExist = Standard_False; + for (; aDirIt.More(); aDirIt.Next()) + { + aDirIt.Values().Path(aSubDirPath); + aTempName = aSubDirPath.Name() + aSubDirPath.Extension(); + if (aTempName != "." && aTempName != "..") + { + isSubDirExist = Standard_True; + break; + } + } + aDirIt.Initialize(thePath, "*"); // Re-initialize + + if (!isSubDirExist && !aFileIt.More()) + { + cout << "No files or directories detected in " << aVrmlDir.ToCString() << endl; + } + else + { + // Create assembly + TopoDS_Compound aComp; + BRep_Builder aBuilder; + aBuilder.MakeCompound(aComp); + + if (theLabel.IsNull() || !aShapeTool->IsAssembly(theLabel)) + { + // Add new shape + aNewLabel = aShapeTool->AddShape(aComp); + cout << "Created new assembly " << thePath.Name() << " (free)" << endl; + } + else if (!theLabel.IsNull() && aShapeTool->IsAssembly(theLabel)) + { + // Add shape as component + aNewLabel = aShapeTool->AddComponent(theLabel, aComp, Standard_True); + Handle(TDataStd_Name) anAttrName; + theLabel.FindAttribute(TDataStd_Name::GetID(), anAttrName); + cout << "Created new assembly " << thePath.Name() << " as part of " << (anAttrName.IsNull()? "(noname)" : TCollection_AsciiString(anAttrName->Get())) << endl; + + if ( aShapeTool->IsReference(aNewLabel) ) + { + TDF_Label RefLabel; + if ( aShapeTool->GetReferredShape(aNewLabel, RefLabel) ) + aNewLabel = RefLabel; + } + } + + if (!aNewLabel.IsNull()) + TDataStd_Name::Set(aNewLabel, thePath.Name()); + + // Add components + for (; aDirIt.More(); aDirIt.Next()) + { + aDirIt.Values().Path(aSubDirPath); + aTempName = aSubDirPath.Name() + aSubDirPath.Extension(); + if (aTempName == "." || aTempName == "..") + continue; + aSubDirPath.SetDisk(thePath.Disk()); + aSubDirPath.SetTrek(thePath.Trek() + thePath.Name()); + ReadVrmlRec(aSubDirPath, theDoc, aNewLabel); + } + + for (; aFileIt.More(); aFileIt.Next()) + { + aFileIt.Values().Path(aSubDirPath); + aSubDirPath.SetDisk(thePath.Disk()); + aSubDirPath.SetTrek(thePath.Trek() + thePath.Name()); + ReadVrmlRec(aSubDirPath, theDoc, aNewLabel); + } + + aShapeTool->UpdateAssembly(aNewLabel); + } + // At the end of operation update assemblies + } + else + { + cout << "Unknown file format: " << thePath.Extension() << endl; + } + + return aNewLabel; +} + +static Standard_Integer ReadVrml (Draw_Interpretor& di, Standard_Integer argc, const char** argv) +{ + if ( argc != 3 ) { + di << "Use: " << argv[0] << " Doc Path: Read VRML assembly to DECAF document\n"; + return 0; + } + + Handle(TDocStd_Document) doc; + if (!DDocStd::GetDocument(argv[1],doc,Standard_False)) + { + Handle(TDocStd_Application) A = DDocStd::GetApplication(); + A->NewDocument("BinXCAF",doc); + TDataStd_Name::Set(doc->GetData()->Root(),argv[1]); + Handle(DDocStd_DrawDocument) DD = new DDocStd_DrawDocument(doc); + Draw::Set(argv[1], DD); + } + + ReadVrmlRec(OSD_Path(argv[2]), doc, TDF_Label()); + + return 0; +} + void XDEDRAW_Common::InitCommands(Draw_Interpretor& di) { static Standard_Boolean initactor = Standard_False; @@ -533,4 +883,5 @@ void XDEDRAW_Common::InitCommands(Draw_Interpretor& di) { di.Add("XExpand", "XExpand Doc recursively(0/1) or XExpand Doc recursively(0/1) label1 abel2 ..." "or XExpand Doc recursively(0/1) shape1 shape2 ...",__FILE__, Expand, g); + di.Add("ReadVrml" , "Doc Path: Read VRML assembly to DECAF document" ,__FILE__, ReadVrml, g); } diff --git a/src/XDEDRAW/XDEDRAW_Shapes.cxx b/src/XDEDRAW/XDEDRAW_Shapes.cxx index 51e53551ae..2ada53c938 100644 --- a/src/XDEDRAW/XDEDRAW_Shapes.cxx +++ b/src/XDEDRAW/XDEDRAW_Shapes.cxx @@ -273,14 +273,15 @@ static Standard_Integer nbComponents (Draw_Interpretor& di, Standard_Integer arg static Standard_Integer addComponent (Draw_Interpretor& di, Standard_Integer argc, const char** argv) { - if (argc!=4) { - di<<"Use: "<GetData(), argv[2], aLabel); TopoDS_Shape aShape; @@ -288,7 +289,7 @@ static Standard_Integer addComponent (Draw_Interpretor& di, Standard_Integer arg Handle(XCAFDoc_ShapeTool) myAssembly = XCAFDoc_DocumentTool::ShapeTool(Doc->Main()); // XCAFDoc_ShapeTool myAssembly-> // myAssembly->Init(Doc); - myAssembly->AddComponent(aLabel, aShape); + myAssembly->AddComponent(aLabel, aShape, makeAssembly); TCollection_AsciiString Entry; TDF_Tool::Entry(aLabel, Entry); di << Entry.ToCString();