mirror of
https://git.dev.opencascade.org/repos/occt.git
synced 2025-04-10 18:51:21 +03:00
0031080: Data Exchange, STL reader - improve API for reading multi-domain STL files
reading of multidomain stl files into separate Poly_Triangulation objects
This commit is contained in:
parent
33c8a72788
commit
0bab2704ae
@ -99,11 +99,42 @@ namespace
|
|||||||
return aPoly;
|
return aPoly;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
protected:
|
||||||
|
void Clear()
|
||||||
|
{
|
||||||
|
myNodes.Clear();
|
||||||
|
myTriangles.Clear();
|
||||||
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
NCollection_Vector<gp_XYZ> myNodes;
|
NCollection_Vector<gp_XYZ> myNodes;
|
||||||
NCollection_Vector<Poly_Triangle> myTriangles;
|
NCollection_Vector<Poly_Triangle> myTriangles;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
class MultiDomainReader : public Reader
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
//! Add new solid
|
||||||
|
//! Add triangulation to triangulation list for multi-domain case
|
||||||
|
virtual void AddSolid() Standard_OVERRIDE
|
||||||
|
{
|
||||||
|
if (Handle(Poly_Triangulation) aCurrentTri = GetTriangulation())
|
||||||
|
{
|
||||||
|
myTriangulationList.Append(aCurrentTri);
|
||||||
|
}
|
||||||
|
Clear();
|
||||||
|
}
|
||||||
|
|
||||||
|
//! Returns triangulation list for multi-domain case
|
||||||
|
NCollection_Sequence<Handle(Poly_Triangulation)>& ChangeTriangulationList()
|
||||||
|
{
|
||||||
|
return myTriangulationList;
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
NCollection_Sequence<Handle(Poly_Triangulation)> myTriangulationList;
|
||||||
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
//=============================================================================
|
//=============================================================================
|
||||||
@ -122,6 +153,22 @@ Handle(Poly_Triangulation) RWStl::ReadFile (const Standard_CString theFile,
|
|||||||
return aReader.GetTriangulation();
|
return aReader.GetTriangulation();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//=============================================================================
|
||||||
|
//function : ReadFile
|
||||||
|
//purpose :
|
||||||
|
//=============================================================================
|
||||||
|
void RWStl::ReadFile(const Standard_CString theFile,
|
||||||
|
const Standard_Real theMergeAngle,
|
||||||
|
NCollection_Sequence<Handle(Poly_Triangulation)>& theTriangList,
|
||||||
|
const Message_ProgressRange& theProgress)
|
||||||
|
{
|
||||||
|
MultiDomainReader aReader;
|
||||||
|
aReader.SetMergeAngle (theMergeAngle);
|
||||||
|
aReader.Read (theFile, theProgress);
|
||||||
|
theTriangList.Clear();
|
||||||
|
theTriangList.Append (aReader.ChangeTriangulationList());
|
||||||
|
}
|
||||||
|
|
||||||
//=============================================================================
|
//=============================================================================
|
||||||
//function : ReadFile
|
//function : ReadFile
|
||||||
//purpose :
|
//purpose :
|
||||||
|
@ -20,6 +20,7 @@
|
|||||||
#include <Poly_Triangulation.hxx>
|
#include <Poly_Triangulation.hxx>
|
||||||
#include <Standard_Macro.hxx>
|
#include <Standard_Macro.hxx>
|
||||||
#include <Message_ProgressScope.hxx>
|
#include <Message_ProgressScope.hxx>
|
||||||
|
#include <NCollection_Sequence.hxx>
|
||||||
|
|
||||||
//! This class provides methods to read and write triangulation from / to the STL files.
|
//! This class provides methods to read and write triangulation from / to the STL files.
|
||||||
class RWStl
|
class RWStl
|
||||||
@ -61,7 +62,17 @@ public:
|
|||||||
Standard_EXPORT static Handle(Poly_Triangulation) ReadFile (const Standard_CString theFile,
|
Standard_EXPORT static Handle(Poly_Triangulation) ReadFile (const Standard_CString theFile,
|
||||||
const Standard_Real theMergeAngle,
|
const Standard_Real theMergeAngle,
|
||||||
const Message_ProgressRange& theProgress = Message_ProgressRange());
|
const Message_ProgressRange& theProgress = Message_ProgressRange());
|
||||||
|
|
||||||
|
//! Read specified STL file and fills triangulation list for multi-domain case.
|
||||||
|
//! @param[in] theFile file path to read
|
||||||
|
//! @param[in] theMergeAngle maximum angle in radians between triangles to merge equal nodes; M_PI/2 means ignore angle
|
||||||
|
//! @param[out] theTriangList triangulation list for multi-domain case
|
||||||
|
//! @param[in] theProgress progress indicator
|
||||||
|
Standard_EXPORT static void ReadFile(const Standard_CString theFile,
|
||||||
|
const Standard_Real theMergeAngle,
|
||||||
|
NCollection_Sequence<Handle(Poly_Triangulation)>& theTriangList,
|
||||||
|
const Message_ProgressRange& theProgress = Message_ProgressRange());
|
||||||
|
|
||||||
//! Read triangulation from a binary STL file
|
//! Read triangulation from a binary STL file
|
||||||
//! In case of error, returns Null handle.
|
//! In case of error, returns Null handle.
|
||||||
Standard_EXPORT static Handle(Poly_Triangulation) ReadBinary (const OSD_Path& thePath,
|
Standard_EXPORT static Handle(Poly_Triangulation) ReadBinary (const OSD_Path& thePath,
|
||||||
|
@ -180,6 +180,7 @@ Standard_Boolean RWStl_Reader::Read (const char* theFile,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
*aStream >> std::ws; // skip any white spaces
|
*aStream >> std::ws; // skip any white spaces
|
||||||
|
AddSolid();
|
||||||
}
|
}
|
||||||
return ! aStream->fail();
|
return ! aStream->fail();
|
||||||
}
|
}
|
||||||
@ -300,6 +301,11 @@ Standard_Boolean RWStl_Reader::ReadAscii (Standard_IStream& theStream,
|
|||||||
|
|
||||||
// skip header "solid ..."
|
// skip header "solid ..."
|
||||||
aLine = theBuffer.ReadLine (theStream, aLineLen);
|
aLine = theBuffer.ReadLine (theStream, aLineLen);
|
||||||
|
// skip empty lines
|
||||||
|
while (aLine && !*aLine)
|
||||||
|
{
|
||||||
|
aLine = theBuffer.ReadLine (theStream, aLineLen);
|
||||||
|
}
|
||||||
if (aLine == NULL)
|
if (aLine == NULL)
|
||||||
{
|
{
|
||||||
Message::SendFail ("Error: premature end of file");
|
Message::SendFail ("Error: premature end of file");
|
||||||
|
@ -39,7 +39,8 @@ public:
|
|||||||
Standard_EXPORT RWStl_Reader();
|
Standard_EXPORT RWStl_Reader();
|
||||||
|
|
||||||
//! Reads data from STL file (either binary or Ascii).
|
//! Reads data from STL file (either binary or Ascii).
|
||||||
//! This function supports reading multi-domain STL files formed by concatenation of several "plain" files.
|
//! This function supports reading multi-domain STL files formed by concatenation
|
||||||
|
//! of several "plain" files.
|
||||||
//! The mesh nodes are not merged between domains.
|
//! The mesh nodes are not merged between domains.
|
||||||
//! Unicode paths can be given in UTF-8 encoding.
|
//! Unicode paths can be given in UTF-8 encoding.
|
||||||
//! Format is recognized automatically by analysis of the file header.
|
//! Format is recognized automatically by analysis of the file header.
|
||||||
@ -84,6 +85,9 @@ public:
|
|||||||
//! Should create new triangle built on specified nodes in the target model.
|
//! Should create new triangle built on specified nodes in the target model.
|
||||||
virtual void AddTriangle (Standard_Integer theN1, Standard_Integer theN2, Standard_Integer theN3) = 0;
|
virtual void AddTriangle (Standard_Integer theN1, Standard_Integer theN2, Standard_Integer theN3) = 0;
|
||||||
|
|
||||||
|
//! Callback function to be implemented in descendant.
|
||||||
|
//! Should create a new triangulation for a solid in multi-domain case.
|
||||||
|
virtual void AddSolid() {}
|
||||||
public:
|
public:
|
||||||
|
|
||||||
//! Return merge tolerance; M_PI/2 by default - all nodes are merged regardless angle between triangles.
|
//! Return merge tolerance; M_PI/2 by default - all nodes are merged regardless angle between triangles.
|
||||||
|
@ -626,6 +626,7 @@ static Standard_Integer readstl(Draw_Interpretor& theDI,
|
|||||||
{
|
{
|
||||||
TCollection_AsciiString aShapeName, aFilePath;
|
TCollection_AsciiString aShapeName, aFilePath;
|
||||||
bool toCreateCompOfTris = false;
|
bool toCreateCompOfTris = false;
|
||||||
|
bool anIsMulti = false;
|
||||||
double aMergeAngle = M_PI / 2.0;
|
double aMergeAngle = M_PI / 2.0;
|
||||||
for (Standard_Integer anArgIter = 1; anArgIter < theArgc; ++anArgIter)
|
for (Standard_Integer anArgIter = 1; anArgIter < theArgc; ++anArgIter)
|
||||||
{
|
{
|
||||||
@ -648,6 +649,15 @@ static Standard_Integer readstl(Draw_Interpretor& theDI,
|
|||||||
++anArgIter;
|
++anArgIter;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
else if (anArg == "-multi")
|
||||||
|
{
|
||||||
|
anIsMulti = true;
|
||||||
|
if (anArgIter + 1 < theArgc
|
||||||
|
&& Draw::ParseOnOff (theArgv[anArgIter + 1], anIsMulti))
|
||||||
|
{
|
||||||
|
++anArgIter;
|
||||||
|
}
|
||||||
|
}
|
||||||
else if (anArg == "-mergeangle"
|
else if (anArg == "-mergeangle"
|
||||||
|| anArg == "-smoothangle"
|
|| anArg == "-smoothangle"
|
||||||
|| anArg == "-nomergeangle"
|
|| anArg == "-nomergeangle"
|
||||||
@ -689,15 +699,46 @@ static Standard_Integer readstl(Draw_Interpretor& theDI,
|
|||||||
TopoDS_Shape aShape;
|
TopoDS_Shape aShape;
|
||||||
if (!toCreateCompOfTris)
|
if (!toCreateCompOfTris)
|
||||||
{
|
{
|
||||||
// Read STL file to the triangulation.
|
Handle(Draw_ProgressIndicator) aProgress = new Draw_ProgressIndicator (theDI,1);
|
||||||
Handle(Draw_ProgressIndicator) aProgress = new Draw_ProgressIndicator (theDI, 1);
|
if(anIsMulti)
|
||||||
Handle(Poly_Triangulation) aTriangulation = RWStl::ReadFile (aFilePath.ToCString(), aMergeAngle, aProgress->Start());
|
{
|
||||||
|
NCollection_Sequence<Handle(Poly_Triangulation)> aTriangList;
|
||||||
|
// Read STL file to the triangulation list.
|
||||||
|
RWStl::ReadFile(aFilePath.ToCString(),aMergeAngle,aTriangList,aProgress->Start());
|
||||||
|
BRep_Builder aB;
|
||||||
|
TopoDS_Face aFace;
|
||||||
|
if (aTriangList.Size() == 1)
|
||||||
|
{
|
||||||
|
aB.MakeFace (aFace);
|
||||||
|
aB.UpdateFace (aFace,aTriangList.First());
|
||||||
|
aShape = aFace;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
TopoDS_Compound aCmp;
|
||||||
|
aB.MakeCompound (aCmp);
|
||||||
|
|
||||||
|
NCollection_Sequence<Handle(Poly_Triangulation)>::Iterator anIt (aTriangList);
|
||||||
|
for (; anIt.More(); anIt.Next())
|
||||||
|
{
|
||||||
|
aB.MakeFace (aFace);
|
||||||
|
aB.UpdateFace (aFace,anIt.Value());
|
||||||
|
aB.Add (aCmp,aFace);
|
||||||
|
}
|
||||||
|
aShape = aCmp;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// Read STL file to the triangulation.
|
||||||
|
Handle(Poly_Triangulation) aTriangulation = RWStl::ReadFile (aFilePath.ToCString(),aMergeAngle,aProgress->Start());
|
||||||
|
|
||||||
TopoDS_Face aFace;
|
TopoDS_Face aFace;
|
||||||
BRep_Builder aB;
|
BRep_Builder aB;
|
||||||
aB.MakeFace (aFace);
|
aB.MakeFace (aFace);
|
||||||
aB.UpdateFace (aFace, aTriangulation);
|
aB.UpdateFace (aFace,aTriangulation);
|
||||||
aShape = aFace;
|
aShape = aFace;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@ -2435,11 +2476,12 @@ void XSDRAWSTLVRML::InitCommands (Draw_Interpretor& theCommands)
|
|||||||
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 ("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 ("writestl", "shape file [ascii/binary (0/1) : 1 by default] [InParallel (0/1) : 0 by default]",__FILE__,writestl,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",
|
theCommands.Add ("readstl",
|
||||||
"readstl shape file [-brep] [-mergeAngle Angle]"
|
"readstl shape file [-brep] [-mergeAngle Angle] [-multi]"
|
||||||
"\n\t\t: Reads STL file and creates a new shape with specified name."
|
"\n\t\t: Reads STL file and creates a new shape with specified name."
|
||||||
"\n\t\t: When -brep is specified, creates a Compound of per-triangle Faces."
|
"\n\t\t: When -brep is specified, creates a Compound of per-triangle Faces."
|
||||||
"\n\t\t: Single triangulation-only Face is created otherwise (default)."
|
"\n\t\t: Single triangulation-only Face is created otherwise (default)."
|
||||||
"\n\t\t: -mergeAngle specifies maximum angle in degrees between triangles to merge equal nodes; disabled by default.",
|
"\n\t\t: -mergeAngle specifies maximum angle in degrees between triangles to merge equal nodes; disabled by default."
|
||||||
|
"\n\t\t: -multi creates a face per solid in multi-domain files; ignored when -brep is set.",
|
||||||
__FILE__, readstl, g);
|
__FILE__, readstl, g);
|
||||||
theCommands.Add ("loadvrml" , "shape file",__FILE__,loadvrml,g);
|
theCommands.Add ("loadvrml" , "shape file",__FILE__,loadvrml,g);
|
||||||
theCommands.Add ("ReadObj",
|
theCommands.Add ("ReadObj",
|
||||||
|
44
tests/bugs/stlvrml/bug31080
Normal file
44
tests/bugs/stlvrml/bug31080
Normal file
@ -0,0 +1,44 @@
|
|||||||
|
puts "========"
|
||||||
|
puts "0031080: Data Exchange, STL reader - improve API for reading multi-domain STL files"
|
||||||
|
puts "========"
|
||||||
|
puts ""
|
||||||
|
|
||||||
|
pload ALL
|
||||||
|
|
||||||
|
# create two boxes with mesh
|
||||||
|
box b1 5 5 5
|
||||||
|
box b2 5 5 5
|
||||||
|
ttranslate b2 10 10 10
|
||||||
|
incmesh b1 0.1
|
||||||
|
incmesh b2 0.1
|
||||||
|
|
||||||
|
# write each box to Ascii STL
|
||||||
|
writestl b1 $imagedir/${casename}_1.stl 0
|
||||||
|
writestl b2 $imagedir/${casename}_2.stl 0
|
||||||
|
|
||||||
|
set aTmpStl "${imagedir}/${casename}_cat.stl"
|
||||||
|
file delete $aTmpStl
|
||||||
|
set file_res [open $aTmpStl a+]
|
||||||
|
|
||||||
|
# cat each stl files content to file_res
|
||||||
|
set file_stl [open $imagedir/${casename}_1.stl r]
|
||||||
|
set buffer [read $file_stl];
|
||||||
|
puts $file_res $buffer
|
||||||
|
close $file_stl
|
||||||
|
|
||||||
|
set file_stl [open $imagedir/${casename}_2.stl r]
|
||||||
|
set buffer [read $file_stl];
|
||||||
|
puts $file_res $buffer
|
||||||
|
close $file_stl
|
||||||
|
close $file_res
|
||||||
|
|
||||||
|
# load multi-domain STL
|
||||||
|
readstl result ${imagedir}/${casename}_cat.stl -multi
|
||||||
|
|
||||||
|
vinit
|
||||||
|
vdisplay result -dispmode 1
|
||||||
|
vfit
|
||||||
|
|
||||||
|
checknbshapes result -face 2 -compound 1
|
||||||
|
checktrinfo result -tri 24 -nod 16
|
||||||
|
checkview -screenshot -3d -path ${imagedir}/${test_image}.png
|
Loading…
x
Reference in New Issue
Block a user