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.)
#include <BRep_Tool.hxx>
#include <BRepAlgoAPI_Section.hxx>
#include <BRepAlgo_Section.hxx>
+#include <BRepMesh_IncrementalMesh.hxx>
#include <Precision.hxx>
#include <Standard_ErrorHandler.hxx>
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 = "<<NBTRIANGLES<<"\n";
StlMesh
is
+ enumeration ErrorStatus is
+ ---Purpose: Set of statuses to indicate a type of the error
+ -- occurred during data retrieving and writing operations.
+ StatusOK,
+ MeshIsEmpty,
+ CannotOpenFile
+
+ end ErrorStatus;
+
class Writer;
class Reader;
Write(aShape : in Shape from TopoDS;
aFile : in CString from Standard;
- aAsciiMode : in Boolean from Standard = Standard_True);
+ aAsciiMode : in Boolean from Standard = Standard_True) returns ErrorStatus from StlAPI;
---Purpose : Convert and write shape to STL format.
-- file is written in binary if aAsciiMode is False
-- otherwise it is written in Ascii (by default)
#include <StlAPI_Writer.hxx>
#include <StlAPI_Reader.hxx>
-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);
}
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 &
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;
#include <BRepBndLib.hxx>
#include <OSD_Path.hxx>
-#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()
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;
}
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.
--
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;
}
}
-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;
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());
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;
}
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}] } {
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}] } {
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}}
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}
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
vinit
stepread [locate_data_file bug23193_sample.stp] a *
+incmesh a_1 1
writestl a_1 ${aFile} 0
meshfromstl m1 ${aFile}
--- /dev/null
+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"
+}