From f5fa6b335c42a62583a22e769bd24842d206de6d Mon Sep 17 00:00:00 2001 From: akz Date: Thu, 5 Feb 2015 15:02:01 +0300 Subject: [PATCH] 0025279: OCCT fails to read VRML file created by OCCT 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 --- src/VrmlAPI/VrmlAPI.cdl | 4 +- src/VrmlAPI/VrmlAPI.cxx | 4 +- src/VrmlAPI/VrmlAPI_Writer.cdl | 14 ++- src/VrmlAPI/VrmlAPI_Writer.cxx | 60 +++++++++++- src/VrmlConverter/VrmlConverter.cdl | 1 + .../VrmlConverter_DeflectionCurve.cdl | 12 ++- .../VrmlConverter_DeflectionCurve.cxx | 97 ++++++++++++++----- .../VrmlConverter_ShadedShape.cxx | 43 -------- .../VrmlConverter_WFDeflectionShape.cxx | 30 ++++-- src/VrmlData/VrmlData_Scene.cxx | 4 +- src/VrmlData/VrmlData_ShapeConvert.cxx | 88 ++++++----------- src/XSDRAWSTLVRML/XSDRAWSTLVRML.cxx | 90 +++++++---------- tests/bugs/stlvrml/bug25279 | 41 ++++++++ 13 files changed, 289 insertions(+), 199 deletions(-) create mode 100755 tests/bugs/stlvrml/bug25279 diff --git a/src/VrmlAPI/VrmlAPI.cdl b/src/VrmlAPI/VrmlAPI.cdl index c131d9f4a9..a02610befd 100644 --- a/src/VrmlAPI/VrmlAPI.cdl +++ b/src/VrmlAPI/VrmlAPI.cdl @@ -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; diff --git a/src/VrmlAPI/VrmlAPI.cxx b/src/VrmlAPI/VrmlAPI.cxx index 74bd6c47d5..557d92c123 100644 --- a/src/VrmlAPI/VrmlAPI.cxx +++ b/src/VrmlAPI/VrmlAPI.cxx @@ -17,7 +17,7 @@ #include #include -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); } diff --git a/src/VrmlAPI/VrmlAPI_Writer.cdl b/src/VrmlAPI/VrmlAPI_Writer.cdl index 8d1d8e5199..51238704b3 100644 --- a/src/VrmlAPI/VrmlAPI_Writer.cdl +++ b/src/VrmlAPI/VrmlAPI_Writer.cdl @@ -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; diff --git a/src/VrmlAPI/VrmlAPI_Writer.cxx b/src/VrmlAPI/VrmlAPI_Writer.cxx index a31c9d203f..19437b98fc 100644 --- a/src/VrmlAPI/VrmlAPI_Writer.cxx +++ b/src/VrmlAPI/VrmlAPI_Writer.cxx @@ -30,7 +30,15 @@ #include #include #include +#include +#include #include +#include +#include +#include +#include +#include +#include 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; +} diff --git a/src/VrmlConverter/VrmlConverter.cdl b/src/VrmlConverter/VrmlConverter.cdl index 427a1eb91a..a6e81c12c8 100644 --- a/src/VrmlConverter/VrmlConverter.cdl +++ b/src/VrmlConverter/VrmlConverter.cdl @@ -40,6 +40,7 @@ uses Poly, TColgp, MMgt, + TColStd, Adaptor3d, BRepAdaptor, TopoDS, diff --git a/src/VrmlConverter/VrmlConverter_DeflectionCurve.cdl b/src/VrmlConverter/VrmlConverter_DeflectionCurve.cdl index dd69b21edb..dedd27f32f 100644 --- a/src/VrmlConverter/VrmlConverter_DeflectionCurve.cdl +++ b/src/VrmlConverter/VrmlConverter_DeflectionCurve.cdl @@ -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; diff --git a/src/VrmlConverter/VrmlConverter_DeflectionCurve.cxx b/src/VrmlConverter/VrmlConverter_DeflectionCurve.cxx index e55208b06d..eb01dae9ee 100644 --- a/src/VrmlConverter/VrmlConverter_DeflectionCurve.cxx +++ b/src/VrmlConverter/VrmlConverter_DeflectionCurve.cxx @@ -75,6 +75,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); +} diff --git a/src/VrmlConverter/VrmlConverter_ShadedShape.cxx b/src/VrmlConverter/VrmlConverter_ShadedShape.cxx index be90081174..fcfe879fff 100644 --- a/src/VrmlConverter/VrmlConverter_ShadedShape.cxx +++ b/src/VrmlConverter/VrmlConverter_ShadedShape.cxx @@ -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; diff --git a/src/VrmlConverter/VrmlConverter_WFDeflectionShape.cxx b/src/VrmlConverter/VrmlConverter_WFDeflectionShape.cxx index 71091c6d64..4b1f6846a5 100644 --- a/src/VrmlConverter/VrmlConverter_WFDeflectionShape.cxx +++ b/src/VrmlConverter/VrmlConverter_WFDeflectionShape.cxx @@ -30,7 +30,7 @@ #include #include #include - +#include //========================================================================= // 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); } } } diff --git a/src/VrmlData/VrmlData_Scene.cxx b/src/VrmlData/VrmlData_Scene.cxx index a8fbd536e4..5a83eca28c 100644 --- a/src/VrmlData/VrmlData_Scene.cxx +++ b/src/VrmlData/VrmlData_Scene.cxx @@ -42,6 +42,7 @@ #include #include #include +#include #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); } diff --git a/src/VrmlData/VrmlData_ShapeConvert.cxx b/src/VrmlData/VrmlData_ShapeConvert.cxx index 25abb08060..58baf5fc05 100644 --- a/src/VrmlData/VrmlData_ShapeConvert.cxx +++ b/src/VrmlData/VrmlData_ShapeConvert.cxx @@ -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 diff --git a/src/XSDRAWSTLVRML/XSDRAWSTLVRML.cxx b/src/XSDRAWSTLVRML/XSDRAWSTLVRML.cxx index 47f6f18fc2..548e029b11 100644 --- a/src/XSDRAWSTLVRML/XSDRAWSTLVRML.cxx +++ b/src/XSDRAWSTLVRML/XSDRAWSTLVRML.cxx @@ -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 index 0000000000..02cf7ca40f --- /dev/null +++ b/tests/bugs/stlvrml/bug25279 @@ -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}" +} -- 2.20.1