]> OCCT Git - occt-copy.git/commitdiff
Implement reading of vrml assembly into OCAF
authorakz <akz@opencascade.com>
Fri, 5 Aug 2016 08:24:58 +0000 (11:24 +0300)
committerakz <akz@opencascade.com>
Fri, 12 Aug 2016 14:55:13 +0000 (17:55 +0300)
15 files changed:
src/BRepAdaptor/BRepAdaptor_Surface.cxx
src/BRepTools/BRepTools.cxx
src/BinTools/BinTools_ShapeSet.cxx
src/BinTools/BinTools_SurfaceSet.cxx
src/Prs3d/Prs3d_ShapeTool.cxx
src/StdPrs/StdPrs_Isolines.cxx
src/StdPrs/StdPrs_WFShape.cxx
src/TKVRML/EXTERNLIB
src/VrmlData/VrmlData_Geometry.cxx
src/VrmlData/VrmlData_Group.cxx
src/VrmlData/VrmlData_IndexedFaceSet.cxx
src/VrmlData/VrmlData_IndexedLineSet.cxx
src/VrmlData/VrmlData_Scene.cxx
src/XDEDRAW/XDEDRAW_Common.cxx
src/XDEDRAW/XDEDRAW_Shapes.cxx

index ff31f8a3538fece3aadda49f0db37237b969cc42..850facead96db0221981727a0997a9f048dbec2d 100644 (file)
@@ -72,13 +72,17 @@ void BRepAdaptor_Surface::Initialize(const TopoDS_Face& F,
 {
   myFace = F;
   TopLoc_Location L;
+  const Handle(Geom_Surface)& aSurface = BRep_Tool::Surface(F, L);
+  if (aSurface.IsNull())
+    return;
+
   if (Restriction) {
     Standard_Real umin,umax,vmin,vmax;
     BRepTools::UVBounds(F,umin,umax,vmin,vmax);
-    mySurf.Load(BRep_Tool::Surface(F,L),umin,umax,vmin,vmax);
+    mySurf.Load(aSurface,umin,umax,vmin,vmax);
   }
   else 
-    mySurf.Load(BRep_Tool::Surface(F,L));
+    mySurf.Load(aSurface);
   myTrsf = L.Transformation();
 }
 
index 706708a77ed4c12e78889c14a0ffd18891894606..daaba168efc8f4055622e0ff9cab4d16e760d8a5 100644 (file)
@@ -74,7 +74,8 @@ void  BRepTools::UVBounds(const TopoDS_Face& F,
 {
   Bnd_Box2d B;
   AddUVBounds(F,B);
-  B.Get(UMin,VMin,UMax,VMax);
+  if (!B.IsVoid())
+    B.Get(UMin,VMin,UMax,VMax);
 }
 
 //=======================================================================
@@ -130,7 +131,11 @@ void  BRepTools::AddUVBounds(const TopoDS_Face& FF, Bnd_Box2d& B)
   if (aBox.IsVoid()) {
     Standard_Real UMin,UMax,VMin,VMax;
     TopLoc_Location L;
-    BRep_Tool::Surface(F,L)->Bounds(UMin,UMax,VMin,VMax);
+    const Handle(Geom_Surface)& aSurf = BRep_Tool::Surface(F, L);
+    if (aSurf.IsNull())
+      return;
+
+    aSurf->Bounds(UMin,UMax,VMin,VMax);
     aBox.Update(UMin,VMin,UMax,VMax);
   }
   
index 5ab0c6b2bab5e0e07eef15e59437f1588fce0a9d..18fc63f96f2b17560a68a708974341cafb3c257e 100644 (file)
@@ -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*/)
 {}
 
 //=======================================================================
@@ -90,9 +90,9 @@ BinTools_ShapeSet::~BinTools_ShapeSet()
 //function : SetWithTriangles
 //purpose  : 
 //=======================================================================
-void BinTools_ShapeSet::SetWithTriangles(const Standard_Boolean isWithTriangles)
+void BinTools_ShapeSet::SetWithTriangles(const Standard_Boolean /*isWithTriangles*/)
 {
-  myWithTriangles = isWithTriangles;
+  myWithTriangles = Standard_True;//isWithTriangles;
 }
 
 //=======================================================================
@@ -524,6 +524,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);
 
@@ -732,6 +738,7 @@ void  BinTools_ShapeSet::WriteGeometry(const TopoDS_Shape& S,
       const TopoDS_Face& F = TopoDS::Face(S);
       
       if (!(TF->Surface()).IsNull()) {
+        //OS << (Standard_Byte) 1;
        Standard_Boolean aNatRes = (BRep_Tool::NaturalRestriction(F)) ? Standard_True : Standard_False;
        BinTools::PutBool(OS, aNatRes);
 
@@ -740,6 +747,8 @@ void  BinTools_ShapeSet::WriteGeometry(const TopoDS_Shape& S,
        BinTools::PutInteger(OS, mySurfaces.Index(TF->Surface()));
        BinTools::PutInteger(OS, Locations().Index(TF->Location()));
       }
+      //else
+       // OS << (Standard_Byte) 0;
       if (myWithTriangles) {
        if (!(TF->Triangulation()).IsNull()) {
          OS << (Standard_Byte) 2;
@@ -1099,17 +1108,26 @@ void  BinTools_ShapeSet::ReadGeometry(const TopAbs_ShapeEnum T,
     // create a face :
        TopoDS_Face& F = TopoDS::Face(S);
        myBuilder.MakeFace(F);
-       BinTools::GetBool(IS, bval); //NaturalRestriction flag
-       BinTools::GetReal(IS, tol);
-       BinTools::GetInteger(IS, s); //surface indx
-       BinTools::GetInteger(IS, l); //location indx
-       if (!mySurfaces.Surface(s).IsNull()) {
-         myBuilder.UpdateFace(TopoDS::Face(S),
-                              mySurfaces.Surface(s),
-                              Locations().Location(l),tol);
-         myBuilder.NaturalRestriction(TopoDS::Face(S),bval );
-       }
-    
+  //Standard_Byte aByte = (Standard_Byte)IS.get();
+  //if (aByte == 1)
+  //{
+    BinTools::GetBool(IS, bval); //NaturalRestriction flag
+    BinTools::GetReal(IS, tol);
+    BinTools::GetInteger(IS, s); //surface indx
+    BinTools::GetInteger(IS, l); //location indx
+    if (!mySurfaces.Surface(s).IsNull()) {
+      myBuilder.UpdateFace(TopoDS::Face(S),
+                           mySurfaces.Surface(s),
+                           Locations().Location(l), tol);
+      myBuilder.NaturalRestriction(TopoDS::Face(S), bval);
+    }
+    else
+    {
+      // Compute offset and return back to position before reading surface parameters
+      size_t offset = sizeof(Standard_Integer) * 2 + sizeof(Standard_Real) + sizeof(Standard_Byte);
+      IS.seekg(-offset, IS.cur);
+    }
+  //}
        Standard_Byte aByte = (Standard_Byte)IS.get();
       // cas triangulation
        if(aByte == 2) {
index 6dd2fa23b6c02888c5db34d742285f84f75c77dd..1d893ef9e9db2a4f62c7389fbc8d7a295d22430d 100644 (file)
@@ -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));
 }
 
index cf47f649b51a6cc727b1cc388686ef0e37b2e0fc..c924e7a2f182d88070b08c6362982267dd9c6714 100644 (file)
@@ -147,6 +147,8 @@ Standard_Boolean Prs3d_ShapeTool::IsPlanarFace() const
   TopLoc_Location l;
   const TopoDS_Face& F = TopoDS::Face(myFaceExplorer.Current());
   const Handle(Geom_Surface)& S = BRep_Tool::Surface(F, l);
+  if (S.IsNull())
+    return Standard_False;
   Handle(Standard_Type) TheType = S->DynamicType();
 
   if (TheType == STANDARD_TYPE(Geom_RectangularTrimmedSurface)) {
index ad2b1017d7a9700ada6ced7817d0cecdfabb37c3..93e0ad63cb047b85bf587f5e553a543ed840e7ae 100644 (file)
@@ -611,7 +611,10 @@ void StdPrs_Isolines::UVIsoParameters (const TopoDS_Face&      theFace,
   aVmax = Min (aVmax,  theUVLimit);
 
   TopLoc_Location aLocation;
-  Handle(Geom_Surface) aSurface = BRep_Tool::Surface (theFace, aLocation);
+  const Handle(Geom_Surface)& aSurface = BRep_Tool::Surface (theFace, aLocation);
+
+  if (aSurface.IsNull())
+    return;
 
   const Standard_Boolean isUClosed = aSurface->IsUClosed();
   const Standard_Boolean isVClosed = aSurface->IsVClosed();
index 878c4c38280d0f1cae37eae354cfbc2e6e6aaea4..6aecad35fbe2f6d9c67dce158d26f100b17c55ab 100644 (file)
@@ -304,6 +304,9 @@ void StdPrs_WFShape::addEdgesOnTriangulation (const Handle(Prs3d_Presentation)&
       }
     }
 
+    if (aNbFree == 0)
+      continue;
+
     // Allocate the arrays.
     TColStd_Array1OfInteger aFree (1, 2 * aNbFree);
     Standard_Integer aNbInternal = (3 * aNbTriangles - aNbFree) / 2;
index 6f521bbafa11e1913f515b66aa2191139414c423..ed69fdfbd84c945fbc6ea285ecb1b0f2346d4d2a 100755 (executable)
@@ -11,3 +11,4 @@ TKHLR
 TKService
 TKGeomAlgo
 TKV3d
+TKSTL
\ No newline at end of file
index 5fc4b5c10fdfa8091e929c763ec897697af5ddbe..6b6a714b05a6b3642bf4a13c135528bb4e4d8546 100644 (file)
@@ -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(;;) {
index f1d989a661fa92ef0b77d0ee05f4e835fcfdda46..685b04523f967d6fb6b8b80607724c4fd035b193 100644 (file)
@@ -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);
index 0e5f8c4fe8358e58b1cacf2f05814c1d7f734343..94a5d687ab32b251923ea0b667a188e1d2cd2801 100644 (file)
 #include <Poly.hxx>
 #include <TShort_HArray1OfShortReal.hxx>
 
+#include <TopoDS_Face.hxx>
+#include <BRep_Tool.hxx>
+#include <TopoDS_Vertex.hxx>
+#include <TopoDS_Wire.hxx>
+#include <BRepBuilderAPI_Sewing.hxx>
+#include <TopoDS_Compound.hxx>
+#include <BRep_Builder.hxx>
+#include <TopExp_Explorer.hxx>
+#include <TopoDS.hxx>
+#include <BRepBuilderAPI_CellFilter.hxx>
+#include <StlMesh_Mesh.hxx>
+#include <StlMesh_MeshExplorer.hxx>
+#include <BRepBuilderAPI_MakeVertex.hxx>
+#include <BRepBuilderAPI_MakePolygon.hxx>
+#include <BRepBuilderAPI_MakeFace.hxx>
+#include <StlAPI.hxx>
+#include <ShapeUpgrade_UnifySameDomain.hxx>
+#include <BRepClass3d_SolidClassifier.hxx>
+#include <ShapeUpgrade_CombineToCylinder.hxx>
+
 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;
 }
 
index 7f15d7a66d0af3c0630ec70ee3ade30a3db314bd..bd2642ab5f2be155418eeb0ca5f082c890c89d33 100644 (file)
@@ -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();
-
-    // 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;
+  //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 Handle(TopoDS_TShape)();
 }
 
 //=======================================================================
index c1862caf4554147f9812c1c7991b662829b7420c..9128cd3fbd9e8536775fb4109d6897acaafd43ac 100644 (file)
@@ -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);
index 5c1a5f8f836fdf8f715b07402200556f822e4c28..3b84a4065200b857193f46ab5347168e97cd089c 100644 (file)
 #include <TDF_Tool.hxx>
 #include <TopoDS_Shape.hxx>
 
+#include <BRep_Builder.hxx>
+#include <OSD_Path.hxx>
+#include <OSD_DirectoryIterator.hxx>
+#include <OSD_FileIterator.hxx>
+#include <TopoDS_Compound.hxx>
+#include <VrmlData_Scene.hxx>
+#include <ShapeUpgrade_UnifySameDomain.hxx>
+#include <TopExp_Explorer.hxx>
+#include <TopoDS.hxx>
+#include <XCAFDoc_ColorTool.hxx>
+#include <BRepClass3d_SolidClassifier.hxx>
+#include <Poly_Triangulation.hxx>
+#include <BRepMesh_IncrementalMesh.hxx>
+#include <Geom_CylindricalSurface.hxx>
+
+#include <StlAPI.hxx>
+
 #include <stdio.h>
 //============================================================
 // Support for several models in DRAW
@@ -517,6 +534,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;
@@ -537,4 +887,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);
 }
index 20bfb0ca9e623f9e4b14b10f08e0ddda1e4dd3b9..1736233b38b70cdd3c8549924eee50a880aa2489 100644 (file)
@@ -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: "<<argv[0]<<" DocName Label Shape \n";
+  if (argc<4) {
+    di<<"Use: "<<argv[0]<<" DocName Label Shape [int makeAssembly (1/0)]\n";
     return 1;
   }
   Handle(TDocStd_Document) Doc;   
   DDocStd::GetDocument(argv[1], Doc);
   if ( Doc.IsNull() ) { di << argv[1] << " is not a document\n"; return 1; }
-
+  Standard_Boolean makeAssembly = Standard_True;
+  if ( argc==5 && Draw::Atoi(argv[4]) == 0 ) makeAssembly = Standard_False;
   TDF_Label aLabel;
   TDF_Tool::Label(Doc->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();