0025279: OCCT fails to read VRML file created by OCCT
authorakz <akz@opencascade.com>
Thu, 5 Feb 2015 12:02:01 +0000 (15:02 +0300)
committerbugmaster <bugmaster@opencascade.com>
Thu, 5 Feb 2015 12:02:52 +0000 (15:02 +0300)
1) Version of VRML format is added to VrmlAPI_Writer::Write() and VrmlAPI::Write() to allow use the both versions of the VRML by one writer.
2) Unification of the command to write VRML of both versions. Now "writevrml" command can write VRLM files of v1.0 and v2.0, with wireframe/shaded/both representations. Parameter "Deflection" was removed (next commit will remove meshing, so parameter will be useless).
3) Meshing is removed from writers of both (v1.0 and v2.0) versions. Shaded representation is skipped in case when a mesh does not exist.
Wireframe representation checks the existence of a mesh before. If the mesh exists, a deflected edges are taken from the mesh, otherwise - are generated with the default deflection.
4) Drawing of redundant edges is removed in wireframe representation of VRML version 1.0 (a grid on non-plane surfaces does not match a real edges of TopoDS_Shape and does not match representation in version 2.0).

Test case for issue CR25279

13 files changed:
src/VrmlAPI/VrmlAPI.cdl
src/VrmlAPI/VrmlAPI.cxx
src/VrmlAPI/VrmlAPI_Writer.cdl
src/VrmlAPI/VrmlAPI_Writer.cxx
src/VrmlConverter/VrmlConverter.cdl
src/VrmlConverter/VrmlConverter_DeflectionCurve.cdl
src/VrmlConverter/VrmlConverter_DeflectionCurve.cxx
src/VrmlConverter/VrmlConverter_ShadedShape.cxx
src/VrmlConverter/VrmlConverter_WFDeflectionShape.cxx
src/VrmlData/VrmlData_Scene.cxx
src/VrmlData/VrmlData_ShapeConvert.cxx
src/XSDRAWSTLVRML/XSDRAWSTLVRML.cxx
tests/bugs/stlvrml/bug25279 [new file with mode: 0755]

index c131d9f..a02610b 100644 (file)
@@ -41,8 +41,8 @@ is
     class Writer;
        ---Purpose: With help of this class user can change parameters of writing.
     
-    Write(aShape: Shape from TopoDS; aFileName: CString from Standard);
-       ---Purpose: Converts the shape aShape to VRML format and writes it
+    Write(aShape: Shape from TopoDS; aFileName: CString from Standard; aVersion: Integer = 2);
+       ---Purpose: Converts the shape aShape to VRML format of the passed version and writes it
        -- to the file identified by aFileName using default parameters.
     
 end VrmlAPI;
index 74bd6c4..557d92c 100644 (file)
@@ -17,7 +17,7 @@
 #include <VrmlAPI_Writer.hxx>
 #include <TopoDS_Shape.hxx>
 
-void VrmlAPI::Write(const TopoDS_Shape& aShape, const Standard_CString aFileName)  {
+void VrmlAPI::Write(const TopoDS_Shape& aShape, const Standard_CString aFileName, const Standard_Integer aVersion)  {
   VrmlAPI_Writer writer;
-  writer.Write(aShape, aFileName);
+  writer.Write(aShape, aFileName, aVersion);
 }
index 8d1d8e5..5123870 100644 (file)
@@ -81,9 +81,19 @@ is
     GetFreeBoundsMaterial(me) returns Material from Vrml;
     GetUnfreeBoundsMaterial(me) returns Material from Vrml;
     
-    Write(me; aShape : Shape from TopoDS; aFile : CString from Standard);
+    Write(me; aShape : Shape from TopoDS; aFile : CString from Standard; aVersion: Integer = 2);
        ---Purpose: Converts the shape aShape to
-       -- VRML format and writes it to the file identified by aFile.
+       -- VRML format of the passed version and writes it to the file identified by aFile.
+               
+       write_v1(me; aShape: Shape from TopoDS; aFileName: CString from Standard)
+       is protected;
+               ---Purpose: Converts the shape aShape to VRML format of version 1.0 and writes it
+       -- to the file identified by aFileName using default parameters.
+               
+       write_v2(me; aShape: Shape from TopoDS; aFileName: CString from Standard)
+       is protected;
+               ---Purpose: Converts the shape aShape to VRML format of version 2.0 and writes it
+       -- to the file identified by aFileName using default parameters.
         
 fields
     myRepresentation : RepresentationOfShape from VrmlAPI;
index a31c9d2..19437b9 100644 (file)
 #include <Vrml_Instancing.hxx>
 #include <Vrml_Separator.hxx>
 #include <VrmlConverter_WFDeflectionShape.hxx>
+#include <VrmlData_Scene.hxx>
+#include <VrmlData_ShapeConvert.hxx>
 #include <OSD_OpenFile.hxx>
+#include <TopExp_Explorer.hxx>
+#include <TopAbs_ShapeEnum.hxx>
+#include <TopoDS.hxx>
+#include <TopoDS_Face.hxx>
+#include <Poly_Triangulation.hxx>
+#include <BRep_Tool.hxx>
 
 VrmlAPI_Writer::VrmlAPI_Writer()
 {
@@ -212,7 +220,15 @@ Handle(Vrml_Material) VrmlAPI_Writer::GetUnfreeBoundsMaterial() const
   return myUnfreeBoundsMaterial;
 }
 
-void VrmlAPI_Writer::Write(const TopoDS_Shape& aShape,const Standard_CString aFile) const
+void VrmlAPI_Writer::Write(const TopoDS_Shape& aShape,const Standard_CString aFile, const Standard_Integer aVersion) const
+{
+  if (aVersion == 1)
+    write_v1(aShape, aFile);
+  else if (aVersion == 2)
+    write_v2(aShape, aFile);
+}
+
+void VrmlAPI_Writer::write_v1(const TopoDS_Shape& aShape,const Standard_CString aFile) const
 {
   OSD_Path thePath(aFile);
   TCollection_AsciiString theFile;thePath.SystemName(theFile);
@@ -263,6 +279,26 @@ void VrmlAPI_Writer::Write(const TopoDS_Shape& aShape,const Standard_CString aFi
   TopTools_Array1OfShape Shapes(1,1);
   Shapes.SetValue(1,aShape);
 
+  // Check shape tesselation
+  TopExp_Explorer anExp (aShape, TopAbs_FACE);
+  TopLoc_Location aLoc;
+  Standard_Boolean hasTriangles = Standard_False;
+  for (; anExp.More(); anExp.Next())
+  {
+    const TopoDS_Face& aFace = TopoDS::Face (anExp.Current());
+    if (!aFace.IsNull()) 
+    {
+      Handle(Poly_Triangulation) aTri =
+        BRep_Tool::Triangulation (aFace, aLoc);
+
+      if (!aTri.IsNull())
+      {
+        hasTriangles = Standard_True;
+        break;
+      }
+    }
+  }
+
 //=========================================
 //----  Definition of data for Projector
 //=========================================
@@ -296,7 +332,7 @@ void VrmlAPI_Writer::Write(const TopoDS_Shape& aShape,const Standard_CString aFi
   projector1->Add(outfile);
   Vrml_Separator S2;
   S2.Print(outfile); 
-  if (myRepresentation == VrmlAPI_ShadedRepresentation || myRepresentation == VrmlAPI_BothRepresentation)
+  if ( (myRepresentation == VrmlAPI_ShadedRepresentation || myRepresentation == VrmlAPI_BothRepresentation) && hasTriangles)
     {
       Vrml_Group Group1;
       Group1.Print(outfile);
@@ -318,3 +354,23 @@ void VrmlAPI_Writer::Write(const TopoDS_Shape& aShape,const Standard_CString aFi
   S1.Print(outfile); 
 }
 
+void VrmlAPI_Writer::write_v2(const TopoDS_Shape& aShape,const Standard_CString aFile) const
+{
+  Standard_Boolean anExtFace = Standard_False;
+  if(myRepresentation == VrmlAPI_ShadedRepresentation || myRepresentation == VrmlAPI_BothRepresentation) 
+    anExtFace = Standard_True;
+
+  Standard_Boolean anExtEdge = Standard_False;
+  if(myRepresentation == VrmlAPI_WireFrameRepresentation|| myRepresentation == VrmlAPI_BothRepresentation)
+    anExtEdge = Standard_True;
+
+  VrmlData_Scene aScene;
+  VrmlData_ShapeConvert aConv(aScene);
+  aConv.AddShape(aShape);
+  aConv.Convert(anExtFace, anExtEdge);
+
+  filebuf aFoc;
+  ostream outStream (&aFoc);
+  if (aFoc.open (aFile, ios::out))
+    outStream << aScene;
+}
index 427a1eb..a6e81c1 100644 (file)
@@ -40,6 +40,7 @@ uses
        Poly, 
         TColgp, 
        MMgt,
+               TColStd,
        Adaptor3d,
         BRepAdaptor,
        TopoDS,
index dd69b21..dedd27f 100644 (file)
@@ -30,7 +30,8 @@ uses
  
     Length       from Quantity,
     Curve        from Adaptor3d,
-    Drawer       from VrmlConverter
+    Drawer       from VrmlConverter,
+       HArray1OfReal from TColStd
 
 is
 
@@ -88,6 +89,15 @@ is
     --          The aspect is the current aspect
     --          The drawing will be limited between the points of parameter
     --          U1 and U2.
+       
+       Add(myclass; anOStream: in out OStream from Standard; 
+                aCurve   : Curve          from Adaptor3d;
+                 aParams  : HArray1OfReal  from TColStd;
+                                aNbNodes : Integer;
+                                aDrawer  : Drawer         from VrmlConverter);
+                
+    ---Purpose: adds to the OStream the drawing of the curve aCurve with  
+    --          the array of parameters to retrieve points on curve.
 
 
 end DeflectionCurve;
index e55208b..eb01dae 100644 (file)
@@ -76,6 +76,41 @@ static void FindLimits(const Adaptor3d_Curve& aCurve,
 
 
 //==================================================================
+// function: PrintPoints
+// purpose:
+//==================================================================
+static void PrintPoints (Handle(TColgp_HArray1OfVec)& aHAV1,
+                         Handle(TColStd_HArray1OfInteger)& aHAI1,
+                         const Handle(VrmlConverter_Drawer)& aDrawer,
+                         Standard_OStream&             anOStream)
+{
+// creation of Vrml objects
+    Handle(VrmlConverter_LineAspect) LA = new VrmlConverter_LineAspect;
+    LA = aDrawer->LineAspect();
+
+// Separator 1 {
+    Vrml_Separator SE1;
+    SE1.Print(anOStream);
+// Material
+    if (LA->HasMaterial()){
+
+      Handle(Vrml_Material) M;
+      M = LA->Material();
+    
+      M->Print(anOStream);
+    }
+// Coordinate3
+    Handle(Vrml_Coordinate3)  C3 = new Vrml_Coordinate3(aHAV1);
+    C3->Print(anOStream);
+// IndexedLineSet
+    Vrml_IndexedLineSet  ILS;
+    ILS.SetCoordIndex(aHAI1);
+    ILS.Print(anOStream);
+// Separator 1 }
+    SE1.Print(anOStream);
+}
+
+//==================================================================
 // function: DrawCurve
 // purpose:
 //==================================================================
@@ -196,33 +231,10 @@ static void DrawCurve (Adaptor3d_Curve&          aCurve,
 
 
   if (key) {
-
-// creation of Vrml objects
-    Handle(VrmlConverter_LineAspect) LA = new VrmlConverter_LineAspect;
-    LA = aDrawer->LineAspect();
-
-// Separator 1 {
-    Vrml_Separator SE1;
-    SE1.Print(anOStream);
-// Material
-    if (LA->HasMaterial()){
-
-      Handle(Vrml_Material) M;
-      M = LA->Material();
-    
-      M->Print(anOStream);
-    }
-// Coordinate3
-    Handle(Vrml_Coordinate3)  C3 = new Vrml_Coordinate3(HAV1);
-    C3->Print(anOStream);
-// IndexedLineSet
-    Vrml_IndexedLineSet  ILS;
-    ILS.SetCoordIndex(HAI1);
-    ILS.Print(anOStream);
-// Separator 1 }
-    SE1.Print(anOStream);
+    PrintPoints(HAV1, HAI1, aDrawer, anOStream);
   }
 }
+
 //==================================================================
 // function: GetDeflection
 // purpose:
@@ -363,3 +375,38 @@ void VrmlConverter_DeflectionCurve::Add(Standard_OStream&    anOStream,
             U1 , U2, aDrawer, anOStream);
 }
 
+//==================================================================
+// function: Add
+// purpose: 6
+//==================================================================
+
+void VrmlConverter_DeflectionCurve::Add(Standard_OStream& anOStream,
+                                        const Adaptor3d_Curve& aCurve,
+                                        const Handle(TColStd_HArray1OfReal)& aParams,
+                                        const Standard_Integer aNbNodes,
+                                        const Handle(VrmlConverter_Drawer)& aDrawer)
+{
+  Handle(TColgp_HArray1OfVec) aHAV1 = new TColgp_HArray1OfVec(1, aNbNodes);
+  Handle(TColStd_HArray1OfInteger) aHAI1 = new TColStd_HArray1OfInteger(1, aNbNodes + 1);
+
+  Standard_Integer i;
+  gp_Pnt aPoint;
+  gp_Vec aVec;
+  for (i = 1; i<=aNbNodes; i++)
+  {
+    Standard_Real aParam = aParams->Value(aParams->Lower() + i - 1);
+    aPoint = aCurve.Value(aParam);
+    aVec.SetX(aPoint.X());
+    aVec.SetY(aPoint.Y());
+    aVec.SetZ(aPoint.Z());
+    aHAV1->SetValue(i, aVec);
+  }
+
+  for (i = aHAI1->Lower(); i < aHAI1->Upper(); i++)
+  {
+    aHAI1->SetValue(i,i-1);
+  }
+  aHAI1->SetValue(aHAI1->Upper(),-1);
+
+  PrintPoints(aHAV1, aHAI1, aDrawer, anOStream);
+}
index be90081..fcfe879 100644 (file)
@@ -61,49 +61,6 @@ void VrmlConverter_ShadedShape::Add( Standard_OStream& anOStream,
                                      const TopoDS_Shape& aShape,
                                      const Handle(VrmlConverter_Drawer)& aDrawer )
   {
-
-  // here the triangulation is computed on the whole shape
-  //  if it does not yet exist
-
-
-    Standard_Real theRequestedDeflection;
-    if(aDrawer->TypeOfDeflection() == Aspect_TOD_RELATIVE)   // TOD_RELATIVE, TOD_ABSOLUTE
-      {
-       Bnd_Box box;
-       BRepBndLib::AddClose(aShape, box);
-
-       Standard_Real  Xmin, Xmax, Ymin, Ymax, Zmin, Zmax, diagonal;
-       box.Get( Xmin, Ymin, Zmin, Xmax, Ymax, Zmax );
-       if (!(box.IsOpenXmin() || box.IsOpenXmax() ||
-             box.IsOpenYmin() || box.IsOpenYmax() ||
-             box.IsOpenZmin() || box.IsOpenZmax()))
-           {
-
-           diagonal = Sqrt ((Xmax - Xmin)*( Xmax - Xmin) + ( Ymax - Ymin)*( Ymax - Ymin) + ( Zmax - Zmin)*( Zmax - Zmin));
-           diagonal = Max(diagonal, Precision::Confusion());
-           theRequestedDeflection = aDrawer->DeviationCoefficient() * diagonal;      
-         }
-       else
-         {
-           diagonal =1000000.;
-           theRequestedDeflection = aDrawer->DeviationCoefficient() * diagonal;  
-         }
-//     cout << "diagonal = "<< diagonal << endl;
-//     cout << "theRequestedDeflection = "<< theRequestedDeflection << endl;
-
-      }
-    else 
-      {
-       theRequestedDeflection = aDrawer->MaximalChordialDeviation(); 
-      }
-
-    if (!BRepTools::Triangulation(aShape,theRequestedDeflection))
-    {
-      // computes and save the triangulation in the face.
-      BRepMesh_IncrementalMesh(aShape,theRequestedDeflection);
-    }
-  
-  
   Handle(Poly_Triangulation) T;
   TopLoc_Location theLocation;
   Standard_Integer i, j, k, decal, nnv, EI;
index 71091c6..4b1f684 100644 (file)
@@ -30,7 +30,7 @@
 #include <Vrml_Material.hxx>
 #include <Vrml_PointSet.hxx>
 #include <Precision.hxx>
-
+#include <Poly_PolygonOnTriangulation.hxx>
 
 //=========================================================================
 // function: Add
@@ -71,8 +71,8 @@ void VrmlConverter_WFDeflectionShape::Add( Standard_OStream&                   a
       {
        theRequestedDeflection = aDrawer->MaximalChordialDeviation(); 
       }
-//==
-    if (aDrawer->UIsoAspect()->Number() != 0 ||
+//== Is not used to reach the same wireframe representation with VRML#2.0
+    /*if (aDrawer->UIsoAspect()->Number() != 0 ||
        aDrawer->VIsoAspect()->Number() != 0 ) {
 
       BRepAdaptor_Surface S;
@@ -142,7 +142,7 @@ void VrmlConverter_WFDeflectionShape::Add( Standard_OStream&                   a
        }
       }
     }
-  }
+  }*/
 
 //====
     Standard_Integer qnt=0;
@@ -151,6 +151,10 @@ void VrmlConverter_WFDeflectionShape::Add( Standard_OStream&                   a
        qnt++;
       }
 
+  Handle(Poly_PolygonOnTriangulation) aPT;
+  Handle(Poly_Triangulation) aT;
+  TopLoc_Location aL;
+
 //   cout << "Quantity of Curves  = " << qnt << endl;
 
 // Wire (without any neighbour)
@@ -168,7 +172,11 @@ void VrmlConverter_WFDeflectionShape::Add( Standard_OStream&                   a
            if (Tool.Neighbours() == 0) {
              if (Tool.HasCurve()) {
                BRepAdaptor_Curve C(Tool.GetCurve());
-               VrmlConverter_DeflectionCurve::Add(anOStream, C, theRequestedDeflection, aDrawer);
+    BRep_Tool::PolygonOnTriangulation(Tool.GetCurve(), aPT, aT, aL);
+    if (!aPT.IsNull() && !aT.IsNull() && aPT->HasParameters())
+      VrmlConverter_DeflectionCurve::Add(anOStream, C, aPT->Parameters(), aPT->NbNodes(), aDrawer);
+    else
+      VrmlConverter_DeflectionCurve::Add(anOStream, C, theRequestedDeflection, aDrawer);
              }
            }
          }
@@ -191,7 +199,11 @@ void VrmlConverter_WFDeflectionShape::Add( Standard_OStream&                   a
            if (Tool.Neighbours() == 1) {
              if (Tool.HasCurve()) {
                BRepAdaptor_Curve C(Tool.GetCurve());
-               VrmlConverter_DeflectionCurve::Add(anOStream, C, theRequestedDeflection, aDrawer);
+    BRep_Tool::PolygonOnTriangulation(Tool.GetCurve(), aPT, aT, aL);
+    if (!aPT.IsNull() && !aT.IsNull() && aPT->HasParameters())
+      VrmlConverter_DeflectionCurve::Add(anOStream, C, aPT->Parameters(), aPT->NbNodes(), aDrawer);
+    else
+      VrmlConverter_DeflectionCurve::Add(anOStream, C, theRequestedDeflection, aDrawer);
              }
            }
          }
@@ -214,7 +226,11 @@ void VrmlConverter_WFDeflectionShape::Add( Standard_OStream&                   a
          if (Tool.Neighbours() >= 2) {
            if (Tool.HasCurve()) {
              BRepAdaptor_Curve C(Tool.GetCurve());
-             VrmlConverter_DeflectionCurve::Add(anOStream, C, theRequestedDeflection, aDrawer);
+        BRep_Tool::PolygonOnTriangulation(Tool.GetCurve(), aPT, aT, aL);
+        if (!aPT.IsNull() && !aT.IsNull() && aPT->HasParameters())
+          VrmlConverter_DeflectionCurve::Add(anOStream, C, aPT->Parameters(), aPT->NbNodes(), aDrawer);
+        else
+          VrmlConverter_DeflectionCurve::Add(anOStream, C, theRequestedDeflection, aDrawer);
            }
          }
        }
index a8fbd53..5a83eca 100644 (file)
@@ -42,6 +42,7 @@
 #include <TopExp_Explorer.hxx>
 #include <BRep_Builder.hxx>
 #include <Precision.hxx>
+#include <Standard_Version.hxx>
 
 #ifdef WNT
 #define _CRT_SECURE_NO_DEPRECATE
@@ -75,7 +76,8 @@ VrmlData_Scene::VrmlData_Scene
     myAutoNameCounter (0)
 {
   myWorldInfo = new VrmlData_WorldInfo (* this);
-  myWorldInfo->AddInfo ("Created by OPEN CASCADE (tm) VrmlData API");
+  Standard_CString anInfo = "Generated by Open CASCADE Technology " OCC_VERSION_STRING;
+  myWorldInfo->AddInfo (anInfo);
   myLstNodes.Append (myWorldInfo);
   myAllNodes.Append (myWorldInfo);
 }
index 25abb08..58baf5f 100644 (file)
@@ -144,7 +144,6 @@ void VrmlData_ShapeConvert::Convert (const Standard_Boolean theExtractFaces,
         TopoDS_Shape aTestedShape;
         aTestedShape.TShape (aShape.TShape());
         aTestedShape.Orientation (isReverse ? TopAbs_REVERSED : TopAbs_FORWARD);
-        Standard_Boolean isTessellate (Standard_False);
         switch (ShapeType[i]) {
         case TopAbs_FACE:
           {
@@ -158,16 +157,6 @@ void VrmlData_ShapeConvert::Convert (const Standard_Boolean theExtractFaces,
                 break;
               }
 
-              if (aTri.IsNull())
-                isTessellate = Standard_True;
-              // Check the existing deflection
-              else if (aTri->Deflection() > aDeflection+ Precision::Confusion())
-                isTessellate = Standard_True;
-              if (isTessellate) {
-                // Triangulate the face by the standard OCC mesher
-                BRepMesh_IncrementalMesh IM(aFace, aDeflection, Standard_False, theDeflAngle);
-                aTri = BRep_Tool::Triangulation (aFace, aLoc);
-              }
               if (aTri.IsNull() == Standard_False) {
                 TopoDS_Shape aTestedShapeRev = aTestedShape;
                 aTestedShapeRev.Orientation (isReverse ?
@@ -200,8 +189,6 @@ void VrmlData_ShapeConvert::Convert (const Standard_Boolean theExtractFaces,
          {
            const TopoDS_Edge& aEdge = TopoDS::Edge (aShape);
             if (aEdge.IsNull() == Standard_False) {
-              Handle(Poly_Polygon3D) aPol = BRep_Tool::Polygon3D (aEdge, aLoc);
-              
               if (aRelMap.IsBound (aTestedShape)) {
                 aTShapeNode = aRelMap(aTestedShape);
                 break;
@@ -214,52 +201,34 @@ void VrmlData_ShapeConvert::Convert (const Standard_Boolean theExtractFaces,
                 aTShapeNode = aRelMap(aTestedShape);
                 break;
               }
-              
-              if (aPol.IsNull())
-                isTessellate = Standard_True;
-              // Check the existing deflection
-              else if (aPol->Deflection() > aDeflection+ Precision::Confusion()
-                       && BRep_Tool::IsGeometric(aEdge))
-                isTessellate = Standard_True;
-              
-              if (isTessellate && BRep_Tool::IsGeometric(aEdge)) {
-                //try to find PolygonOnTriangulation
-                Handle(Poly_PolygonOnTriangulation) aPT;
-                Handle(Poly_Triangulation) aT;
-                TopLoc_Location aL;
-
-                Standard_Boolean found = Standard_False;
-                for(i = 1; ; i++) {
-                  
-                  BRep_Tool::PolygonOnTriangulation(aEdge, aPT, aT, aL, i);
-
-                  if(aPT.IsNull() || aT.IsNull()) break;
-
-                  if(aPT->Deflection() <= aDeflection + Precision::Confusion() &&
-                     aPT->HasParameters()) {
-                    found = Standard_True;
-                    break;
-                  }
 
+              //try to find PolygonOnTriangulation
+              Handle(Poly_PolygonOnTriangulation) aPT;
+              Handle(Poly_Triangulation) aT;
+              TopLoc_Location aL;
+              BRep_Tool::PolygonOnTriangulation(aEdge, aPT, aT, aL);
+
+              // If PolygonOnTriangulation was found -> get the Polygon3D
+              Handle(Poly_Polygon3D) aPol;
+              if(!aPT.IsNull() && !aT.IsNull() && aPT->HasParameters()) {
+                BRepAdaptor_Curve aCurve(aEdge);
+                Handle(TColStd_HArray1OfReal) aPrs = aPT->Parameters();
+                Standard_Integer nbNodes = aPT->NbNodes();
+                TColgp_Array1OfPnt arrNodes(1, nbNodes);
+                TColStd_Array1OfReal arrUVNodes(1, nbNodes);
+
+                for(Standard_Integer j = 1; j <= nbNodes; j++) {
+                  arrUVNodes(j) = aPrs->Value(aPrs->Lower() + j - 1);
+                  arrNodes(j) = aCurve.Value(arrUVNodes(j));
                 }
-                
-                if(found) {
-
-                  BRepAdaptor_Curve aCurve(aEdge);
-                  Handle(TColStd_HArray1OfReal) aPrs = aPT->Parameters();
-                  Standard_Integer nbNodes = aPT->NbNodes();
-                  TColgp_Array1OfPnt arrNodes(1, nbNodes);
-                  TColStd_Array1OfReal arrUVNodes(1, nbNodes);
+                aPol = new Poly_Polygon3D(arrNodes, arrUVNodes);
+                aPol->Deflection (aPT->Deflection());
+              }
+              else {
+                aPol = BRep_Tool::Polygon3D(aEdge, aL);
 
-                  for(Standard_Integer j = 1; j <= nbNodes; j++) {
-                    arrUVNodes(j) = aPrs->Value(aPrs->Lower() + j - 1);
-                    arrNodes(j) = aCurve.Value(arrUVNodes(j));
-                  }
-                  aPol = new Poly_Polygon3D(arrNodes, arrUVNodes);
-                  aPol->Deflection (aPT->Deflection());
-                }
-                else{
-                  
+                // If polygon was not found -> generate it
+                if (aPol.IsNull()) {
                   BRepAdaptor_Curve aCurve(aEdge);
                   const Standard_Real aFirst = aCurve.FirstParameter();
                   const Standard_Real aLast  = aCurve.LastParameter();
@@ -277,10 +246,11 @@ void VrmlData_ShapeConvert::Convert (const Standard_Boolean theExtractFaces,
                   aPol = new Poly_Polygon3D(arrNodes, arrUVNodes);
                   aPol->Deflection (aDeflection);
                 }
-                
-                BRep_Builder aBld;
-                aBld.UpdateEdge (aEdge, aPol);
               }
+
+              if (aPol.IsNull())
+                continue;
+
               aTShapeNode = polToIndexedLineSet (aPol);
               myScene.AddNode (aTShapeNode, Standard_False);
               // Bind the converted face
index 47f6f18..548e029 100644 (file)
@@ -130,21 +130,41 @@ static Standard_Integer readstl
 static Standard_Integer writevrml
 (Draw_Interpretor& di, Standard_Integer argc, const char** argv)
 {
-  if (argc<3) di << "wrong number of parameters"    << "\n";
-  else {
-    TopoDS_Shape aShape = DBRep::Get(argv[1]);
-    //     VrmlAPI_Writer writer;
-    //     writer.SetTransparencyToMaterial(writer.GetFrontMaterial(),0.0);
-    //      Quantity_Color color;
-    //      color.SetValues(Quantity_NOC_GOLD);
-    //      Handle(Quantity_HArray1OfColor) Col = new Quantity_HArray1OfColor(1,1);
-    //      Col->SetValue(1,color);
-    //      writer.SetDiffuseColorToMaterial(writer.GetFrontMaterial(),Col);
-    //      writer.SetRepresentation(VrmlAPI_ShadedRepresentation);
-    //      writer.SetDeflection(0.01);
-    //      writer.Write(shape, argv[2]);
-    VrmlAPI::Write(aShape, argv[2]);
+  if (argc < 3 || argc > 5) 
+  {
+    di << "wrong number of parameters" << "\n";
+    return 0;
   }
+
+  TopoDS_Shape aShape = DBRep::Get(argv[1]);
+
+  // Get the optional parameters
+  Standard_Integer aVersion = 2;
+  Standard_Integer aType = 1;
+  if (argc >= 4)
+  {
+    aVersion = Draw::Atoi(argv[3]);
+    if (argc == 5)
+      aType = Draw::Atoi(argv[4]);
+  }
+
+  // Bound parameters
+  aVersion = Max(1, aVersion);
+  aVersion = Min(2, aVersion);
+  aType = Max(0, aType);
+  aType = Min(2, aType);
+
+  VrmlAPI_Writer writer;
+
+  switch (aType)
+  {
+  case 0: writer.SetRepresentation(VrmlAPI_ShadedRepresentation); break;
+  case 1: writer.SetRepresentation(VrmlAPI_WireFrameRepresentation); break;
+  case 2: writer.SetRepresentation(VrmlAPI_BothRepresentation); break;
+  }
+
+  writer.Write(aShape, argv[2], aVersion);
+
   return 0;
 }
 
@@ -232,45 +252,6 @@ static Standard_Integer loadvrml
   return 0;
 }
 
-//=======================================================================
-//function : storevrml
-//purpose  :
-//=======================================================================
-
-static Standard_Integer storevrml
-(Draw_Interpretor& di, Standard_Integer argc, const char** argv)
-{
-  if (argc < 4) {
-    di << "wrong number of parameters"    << "\n";
-    di << "use: storevrml shape file defl type_of_conversion (0, 1, 2)"    << "\n";
-  }
-  else {
-    TopoDS_Shape aShape = DBRep::Get(argv[1]);
-    Standard_Real aDefl = Draw::Atof(argv[3]);
-    Standard_Integer aType = 1;
-    if(argc > 4) aType = Draw::Atoi(argv[4]);
-    aType = Max(0, aType);
-    aType = Min(2, aType);
-
-    Standard_Boolean anExtFace = Standard_False;
-    if(aType == 0 || aType == 2) anExtFace = Standard_True;
-    Standard_Boolean anExtEdge = Standard_False;
-    if(aType == 1 || aType == 2) anExtEdge = Standard_True;
-
-    VrmlData_Scene aScene;
-    VrmlData_ShapeConvert aConv(aScene);
-    aConv.AddShape(aShape);
-    aConv.Convert(anExtFace, anExtEdge, aDefl);
-
-    filebuf aFoc;
-    ostream outStream (&aFoc);
-    if (aFoc.open (argv[2], ios::out))
-      outStream << aScene;
-  }
-  return 0;
-}
-
-
 //-----------------------------------------------------------------------------
 static Standard_Integer createmesh
 (Draw_Interpretor& di, Standard_Integer argc, const char** argv )
@@ -1226,12 +1207,11 @@ void  XSDRAWSTLVRML::InitCommands (Draw_Interpretor& theCommands)
   const char* g = "XSTEP-STL/VRML";  // Step transfer file commands
   //XSDRAW::LoadDraw(theCommands);
 
-  theCommands.Add ("writevrml", "shape file",__FILE__,writevrml,g);
+  theCommands.Add ("writevrml", "shape file [version VRML#1.0/VRML#2.0 (1/2): 2 by default] [representation shaded/wireframe/both (0/1/2): 1 by default]",__FILE__,writevrml,g);
   theCommands.Add ("tovrml",    "shape file",__FILE__, tovrml, g);
   theCommands.Add ("writestl",  "shape file [ascii/binary (0/1) : 1 by default] [InParallel (0/1) : 0 by default]",__FILE__,writestl,g);
   theCommands.Add ("readstl",   "shape file",__FILE__,readstl,g);
   theCommands.Add ("loadvrml" , "shape file",__FILE__,loadvrml,g);
-  theCommands.Add ("storevrml" , "shape file defl [type]",__FILE__,storevrml,g);
 
   theCommands.Add ("meshfromstl",     "creates MeshVS_Mesh from STL file",            __FILE__, createmesh,      g );
   theCommands.Add ("mesh3delem",      "creates 3d element mesh to test",              __FILE__, create3d,        g );
diff --git a/tests/bugs/stlvrml/bug25279 b/tests/bugs/stlvrml/bug25279
new file mode 100755 (executable)
index 0000000..02cf7ca
--- /dev/null
@@ -0,0 +1,41 @@
+puts "================"
+puts "OCC25279"
+puts "================"
+puts ""
+#######################################################################################
+# OCCT fails to read VRML file created by OCCT
+#######################################################################################
+
+set BugNumber OCC25279
+
+set aFile ${imagedir}/${test_image}.vrml
+file delete ${aFile}
+
+ptorus res 10 8 0 90 270
+incmesh res 0.1
+
+set TrinfoBefore [trinfo res]
+
+set version 2
+set mode 2
+
+writevrml res ${aFile} ${version} ${mode}
+
+set TrinfoAfter [trinfo res]
+set Log [loadvrml test ${aFile}]
+
+set status 1
+
+if { $TrinfoBefore != $TrinfoAfter } {
+  set status 0 
+}
+
+if { [string length $Log] != 0 } {
+  set status 0 
+}
+
+if {$status == 1} {
+  puts "OK ${BugNumber}"
+} else {
+  puts "Faulty ${BugNumber}"
+}