From b9c1e4400431e77e77fc5e9baffb52662a07f8e2 Mon Sep 17 00:00:00 2001 From: akz Date: Thu, 5 Feb 2015 14:38:59 +0300 Subject: [PATCH] 0025357: STL writer does not check the given shape for existing triangulation and remeshes shape using BRepMesh in force mode. StlTransfer.cxx, function StlTransfer::BuildIncrementalMesh(...) fills the StlMesh_Mesh. Before this fix the StlTransfer always force meshing of the passed shape. Now meshing is completely removed from the StlTransfer. StlWriter can return error status now, for example, if a mesh of the passed shape is empty. In this case file will be not created. Added test case bugs/xde/bug25357 Avoid the warning on gcc compiler. Test scripts were modified according to the fix. 1) bug23192, bug22670, bug23193: removed "isParallel" flag from the command arguments. Manually meshing of the shape (as far as meshing was removed from STL writer). 2) bug22898: before the fix writestl always remeshes the shape with a deflection, related to the boundery box of the shape. For "hammer" shape there is a 38.9076 deflection for mesh. Differences between before writing and after reading are dedicated to fact that stl writes triangulation as an elements of the spahe (like faces, edges etc.) --- src/QABugs/QABugs_2.cxx | 5 +-- src/StlAPI/StlAPI.cdl | 11 ++++++- src/StlAPI/StlAPI.cxx | 4 +-- src/StlAPI/StlAPI_Writer.cdl | 37 ++++------------------- src/StlAPI/StlAPI_Writer.cxx | 45 +++++++++------------------ src/StlTransfer/StlTransfer.cdl | 16 ++++------ src/StlTransfer/StlTransfer.cxx | 11 ++----- src/XSDRAWSTLVRML/XSDRAWSTLVRML.cxx | 18 ++++++----- tests/bugs/fclasses/bug23192_1 | 4 +-- tests/bugs/fclasses/bug23192_2 | 4 +-- tests/bugs/xde/bug22670_1 | 2 ++ tests/bugs/xde/bug22670_2 | 5 +-- tests/bugs/xde/bug22898 | 1 + tests/bugs/xde/bug23193 | 1 + tests/bugs/xde/bug25357 | 47 +++++++++++++++++++++++++++++ 15 files changed, 112 insertions(+), 99 deletions(-) create mode 100644 tests/bugs/xde/bug25357 diff --git a/src/QABugs/QABugs_2.cxx b/src/QABugs/QABugs_2.cxx index 1f5401ece7..ca5a272dab 100644 --- a/src/QABugs/QABugs_2.cxx +++ b/src/QABugs/QABugs_2.cxx @@ -33,6 +33,7 @@ #include #include #include +#include #include #include @@ -183,8 +184,8 @@ static Standard_Integer OCC1048 (Draw_Interpretor& di, Standard_Integer argc, co Standard_Real theDeflection = 0.006; Handle(StlMesh_Mesh) theStlMesh = new StlMesh_Mesh; - StlTransfer::BuildIncrementalMesh(aShape, theDeflection, Standard_False, theStlMesh); - + BRepMesh_IncrementalMesh aMesh(aShape, theDeflection); + StlTransfer::RetrieveMesh(aShape, theStlMesh); Standard_Integer NBTRIANGLES = theStlMesh->NbTriangles(); di<<"Info: Number of triangles = "< #include -void StlAPI::Write(const TopoDS_Shape& aShape, +StlAPI_ErrorStatus StlAPI::Write(const TopoDS_Shape& aShape, const Standard_CString aFile, const Standard_Boolean aAsciiMode) { StlAPI_Writer writer; writer.ASCIIMode() = aAsciiMode; - writer.Write (aShape, aFile); + return writer.Write (aShape, aFile); } diff --git a/src/StlAPI/StlAPI_Writer.cdl b/src/StlAPI/StlAPI_Writer.cdl index 38f468bcba..2264ec10cc 100644 --- a/src/StlAPI/StlAPI_Writer.cdl +++ b/src/StlAPI/StlAPI_Writer.cdl @@ -21,34 +21,12 @@ class Writer from StlAPI uses Shape from TopoDS, - Mesh from StlMesh + Mesh from StlMesh, + ErrorStatus from StlAPI is - Create; + Create; ---Purpose: Creates a writer object with - -- default parameters: ASCIIMode, RelativeMode, SetCoefficent, - -- SetDeflection. These parameters may be modified. - - SetDeflection(me: in out; aDeflection : in Real from Standard); - ---Purpose: Sets the deflection of the meshing algorithm. - -- Deflection is used, only if relative mode is false - - SetCoefficient(me: in out; aCoefficient : in Real from Standard); - ---Purpose: Sets the coeffiecient for computation of deflection through - -- relative size of shape. Default value = 0.001 - - RelativeMode(me: in out) returns Boolean; - ---C++: return & - ---Purpose: Returns the address to the - -- flag defining the relative mode for writing the file. - -- This address may be used to either read or change the flag. - -- If the mode returns True (default value), the - -- deflection is calculated from the relative size of the - -- shape. If the mode returns False, the user defined deflection is used. - -- Example - -- Read: - -- Standard_Boolean val = Writer.RelativeMode( ); - -- Modify: - -- Writer.RelativeMode( ) = Standard_True; + -- default parameters: ASCIIMode. ASCIIMode(me: in out) returns Boolean; ---C++: return & @@ -61,14 +39,11 @@ is Write(me : in out; aShape : Shape from TopoDS; - aFileName : CString from Standard; - InParallel : Boolean from Standard = Standard_False); + aFileName : CString from Standard) returns ErrorStatus from StlAPI; ---Purpose: Converts a given shape to STL format and writes it to file with a given filename. + --- \return the error state. fields - theRelativeMode : Boolean from Standard; theASCIIMode : Boolean from Standard; - theDeflection : Real from Standard; - theCoefficient : Real from Standard; theStlMesh : Mesh from StlMesh; end Writer; diff --git a/src/StlAPI/StlAPI_Writer.cxx b/src/StlAPI/StlAPI_Writer.cxx index 9037efae15..d0f365389d 100644 --- a/src/StlAPI/StlAPI_Writer.cxx +++ b/src/StlAPI/StlAPI_Writer.cxx @@ -19,30 +19,10 @@ #include #include -#define MAX2(X, Y) ( Abs(X) > Abs(Y)? Abs(X) : Abs(Y) ) -#define MAX3(X, Y, Z) ( MAX2 ( MAX2(X,Y) , Z) ) - StlAPI_Writer::StlAPI_Writer() { theStlMesh = new StlMesh_Mesh; theASCIIMode = Standard_True; - theDeflection = 0.01; - theRelativeMode = Standard_True; - theCoefficient = 0.001; -} - -void StlAPI_Writer::SetDeflection(const Standard_Real aDeflection) -{ - theDeflection = aDeflection; -} -void StlAPI_Writer::SetCoefficient(const Standard_Real aCoefficient) -{ - theCoefficient = aCoefficient; -} - -Standard_Boolean& StlAPI_Writer::RelativeMode() -{ - return theRelativeMode; } Standard_Boolean& StlAPI_Writer::ASCIIMode() @@ -50,23 +30,26 @@ Standard_Boolean& StlAPI_Writer::ASCIIMode() return theASCIIMode; } -void StlAPI_Writer::Write(const TopoDS_Shape& theShape, const Standard_CString theFileName, const Standard_Boolean theInParallel) +StlAPI_ErrorStatus StlAPI_Writer::Write(const TopoDS_Shape& theShape, const Standard_CString theFileName) { OSD_Path aFile(theFileName); - if (theRelativeMode) { - Standard_Real aXmin, aYmin, aZmin, aXmax, aYmax, aZmax; - Bnd_Box Total; - BRepBndLib::Add(theShape, Total); - Total.Get(aXmin, aYmin, aZmin, aXmax, aYmax, aZmax); - theDeflection = MAX3(aXmax-aXmin , aYmax-aYmin , aZmax-aZmin)*theCoefficient; - } - StlTransfer::BuildIncrementalMesh(theShape, theDeflection, theInParallel, theStlMesh); + StlTransfer::RetrieveMesh(theShape, theStlMesh); + + if (theStlMesh.IsNull() || theStlMesh->IsEmpty()) + return StlAPI_MeshIsEmpty; + // Write the built mesh + Standard_Boolean wasFileOpened = Standard_False; if (theASCIIMode) { - RWStl::WriteAscii(theStlMesh, aFile); + wasFileOpened = RWStl::WriteAscii(theStlMesh, aFile); } else { - RWStl::WriteBinary(theStlMesh, aFile); + wasFileOpened = RWStl::WriteBinary(theStlMesh, aFile); } + + if (!wasFileOpened) + return StlAPI_CannotOpenFile; + + return StlAPI_StatusOK; } diff --git a/src/StlTransfer/StlTransfer.cdl b/src/StlTransfer/StlTransfer.cdl index 40a3c2639f..2d3e66bc48 100644 --- a/src/StlTransfer/StlTransfer.cdl +++ b/src/StlTransfer/StlTransfer.cdl @@ -17,11 +17,9 @@ package StlTransfer ---Purpose: The package Algorithm for Meshing implements - -- facilities to compute the Mesh data-structure, as - -- defined in package StlMesh, from a shape of package - -- TopoDS. The triangulation is computed with the - -- Delaunay algorithm implemented in package - -- BRepMesh. The result is stored in the mesh + -- facilities to retrieve the Mesh data-structure from a shape of package + -- TopoDS. The triangulation should be computed before. + -- The result is stored in the mesh -- data-structure Mesh from package StlMesh. -- @@ -31,11 +29,9 @@ uses TopoDS is - BuildIncrementalMesh (Shape : in Shape from TopoDS; - Deflection : in Real from Standard; - InParallel : in Boolean from Standard; - Mesh : Mesh from StlMesh) - raises ConstructionError; + RetrieveMesh (Shape : in Shape from TopoDS; + Mesh : Mesh from StlMesh); + ---Purpose: Retrieve a Mesh data-structure from the Shape, convert and store it into the Mesh. end StlTransfer; diff --git a/src/StlTransfer/StlTransfer.cxx b/src/StlTransfer/StlTransfer.cxx index d440ecf070..e485a87962 100644 --- a/src/StlTransfer/StlTransfer.cxx +++ b/src/StlTransfer/StlTransfer.cxx @@ -108,16 +108,9 @@ static void Normal(const TopoDS_Face& aFace, } } -void StlTransfer::BuildIncrementalMesh (const TopoDS_Shape& Shape, - const Standard_Real Deflection, - const Standard_Boolean InParallel, +void StlTransfer::RetrieveMesh (const TopoDS_Shape& Shape, const Handle(StlMesh_Mesh)& Mesh) { - if (Deflection <= Precision::Confusion ()) { - Standard_ConstructionError::Raise ("StlTransfer::BuildIncrementalMesh"); - } - - BRepMesh_IncrementalMesh aMesher(Shape, Deflection, Standard_False, 0.5, InParallel); for (TopExp_Explorer itf(Shape,TopAbs_FACE); itf.More(); itf.Next()) { TopoDS_Face face = TopoDS::Face(itf.Current()); TopLoc_Location Loc, loc; @@ -125,7 +118,7 @@ void StlTransfer::BuildIncrementalMesh (const TopoDS_Shape& Shape, if (theTriangulation.IsNull()) continue; //Meshing was not done for this face! Poly_Array1OfTriangle theTriangles(1,theTriangulation->NbTriangles()); theTriangles.Assign(theTriangulation->Triangles()); - Mesh->AddDomain (Deflection); + Mesh->AddDomain (theTriangulation->Deflection()); TColgp_Array1OfPnt thePoints(1, theTriangulation->NbNodes()); thePoints.Assign(theTriangulation->Nodes()); diff --git a/src/XSDRAWSTLVRML/XSDRAWSTLVRML.cxx b/src/XSDRAWSTLVRML/XSDRAWSTLVRML.cxx index 6b658488c1..47f6f18fc2 100644 --- a/src/XSDRAWSTLVRML/XSDRAWSTLVRML.cxx +++ b/src/XSDRAWSTLVRML/XSDRAWSTLVRML.cxx @@ -92,21 +92,25 @@ extern Standard_Boolean VDisplayAISObject (const TCollection_AsciiString& theNam static Standard_Integer writestl (Draw_Interpretor& di, Standard_Integer argc, const char** argv) { - if (argc < 3 || argc > 5) { + if (argc < 3 || argc > 4) { di << "Use: " << argv[0] - << " shape file [ascii/binary (0/1) : 1 by default] [InParallel (0/1) : 0 by default]" << "\n"; + << " shape file [ascii/binary (0/1) : 1 by default]" << "\n"; } else { TopoDS_Shape aShape = DBRep::Get(argv[1]); Standard_Boolean isASCIIMode = Standard_False; - Standard_Boolean isInParallel = Standard_False; - if (argc > 3) { + if (argc == 4) { isASCIIMode = (Draw::Atoi(argv[3]) == 0); - if (argc > 4) - isInParallel = (Draw::Atoi(argv[4]) == 1); } StlAPI_Writer aWriter; aWriter.ASCIIMode() = isASCIIMode; - aWriter.Write (aShape, argv[2], isInParallel); + StlAPI_ErrorStatus aStatus = aWriter.Write (aShape, argv[2]); + + switch (aStatus) + { + case StlAPI_MeshIsEmpty: di << "** Error **: Mesh is empty. Please, compute triangulation before."; break; + case StlAPI_CannotOpenFile: di << "** Error **: Cannot create/open a file with the passed name."; break; + case StlAPI_StatusOK: default: break; + } } return 0; } diff --git a/tests/bugs/fclasses/bug23192_1 b/tests/bugs/fclasses/bug23192_1 index be5324df55..6b250902f5 100755 --- a/tests/bugs/fclasses/bug23192_1 +++ b/tests/bugs/fclasses/bug23192_1 @@ -14,11 +14,11 @@ set aFile $imagedir/${test_image}.stl file delete ${aFile} set anASCIImode 1 -set InParallel 0 box res 10 10 10 +incmesh res 0.1 -writestl res ${aFile} ${anASCIImode} ${InParallel} +writestl res ${aFile} ${anASCIImode} catch {exec chmod 777 ${aFile}} if { [file exists ${aFile}] } { diff --git a/tests/bugs/fclasses/bug23192_2 b/tests/bugs/fclasses/bug23192_2 index 7e54e964db..158cd5e356 100755 --- a/tests/bugs/fclasses/bug23192_2 +++ b/tests/bugs/fclasses/bug23192_2 @@ -14,11 +14,11 @@ set aFile $imagedir/${test_image}.stl file delete ${aFile} set anASCIImode 0 -set InParallel 0 box res 10 10 10 +incmesh res 0.1 -writestl res ${aFile} ${anASCIImode} ${InParallel} +writestl res ${aFile} ${anASCIImode} catch {exec chmod 777 ${aFile}} if { [file exists ${aFile}] } { diff --git a/tests/bugs/xde/bug22670_1 b/tests/bugs/xde/bug22670_1 index 9c74bea8df..ff3cb0591a 100755 --- a/tests/bugs/xde/bug22670_1 +++ b/tests/bugs/xde/bug22670_1 @@ -13,6 +13,8 @@ readstl res_mesh [locate_data_file OMF6391_box.stl] set aFile ${imagedir}/OCC22670.stl file delete ${aFile} +incmesh res_mesh 0.1 + set anASCIImode 0 writestl res_mesh ${aFile} ${anASCIImode} catch {exec chmod 777 ${aFile}} diff --git a/tests/bugs/xde/bug22670_2 b/tests/bugs/xde/bug22670_2 index b9077ad3f3..818b62a3cf 100755 --- a/tests/bugs/xde/bug22670_2 +++ b/tests/bugs/xde/bug22670_2 @@ -25,10 +25,11 @@ if { [catch { readstl res_mesh $filepath } catch_result] } { set aFile $imagedir/${test_image}.stl catch {exec rm -f ${aFile}} + + incmesh res_mesh 0.1 set anASCIImode 0 - set InParallel 1 - writestl res_mesh ${aFile} ${anASCIImode} ${InParallel} + writestl res_mesh ${aFile} ${anASCIImode} catch {exec chmod 777 ${aFile}} readstl result ${aFile} diff --git a/tests/bugs/xde/bug22898 b/tests/bugs/xde/bug22898 index 58c5b2561c..b1972c96ff 100644 --- a/tests/bugs/xde/bug22898 +++ b/tests/bugs/xde/bug22898 @@ -42,6 +42,7 @@ tolerance step_1 checkarea step_1 3.978e8 1e6 0.001 # STL +incmesh hammer 38.9076 writestl hammer $imagedir/hammer.stl readstl stl $imagedir/hammer.stl checkshape stl diff --git a/tests/bugs/xde/bug23193 b/tests/bugs/xde/bug23193 index 13578a17c6..73f0e0b8d5 100755 --- a/tests/bugs/xde/bug23193 +++ b/tests/bugs/xde/bug23193 @@ -12,6 +12,7 @@ set aFile $imagedir/bug23193_sample.stl vinit stepread [locate_data_file bug23193_sample.stp] a * +incmesh a_1 1 writestl a_1 ${aFile} 0 meshfromstl m1 ${aFile} diff --git a/tests/bugs/xde/bug25357 b/tests/bugs/xde/bug25357 new file mode 100644 index 0000000000..758bedc503 --- /dev/null +++ b/tests/bugs/xde/bug25357 @@ -0,0 +1,47 @@ +puts "==========" +puts "OCC25357" +puts "==========" +puts "" +####################################################################################### +# STL writer does not check the given shape for existing triangulation and remeshes +# shape using BRepMesh in force mode +####################################################################################### + +set aFile ${imagedir}/${test_image}.stl +file delete -force ${aFile} + +set anASCIImode 0 + +ptorus res 10 8 +incmesh res 0.5 + +#decho off +set LogBefore [trinfo res] +#decho on + +writestl res ${aFile} ${anASCIImode} + +#decho off +set LogAfter [trinfo res] +#decho on + +set status 1 +if { ![file exists ${aFile}] } { + set status 0 +} + +# Check file size +set filesize [ file size ${aFile} ] +if { ${filesize} == 0 } { + set status 0 +} + +if { $LogBefore != $LogAfter } { + set status 0 +} + +if {$status == 1} { + puts "OK: STL writer check given shape" +} else { + puts "Error: STL writer does not check given shape" +}