return aPoly;
}
+ protected:
+ void Clear()
+ {
+ myNodes.Clear();
+ myTriangles.Clear();
+ }
+
private:
NCollection_Vector<gp_XYZ> myNodes;
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;
+ };
+
}
//=============================================================================
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
//purpose :
#include <Poly_Triangulation.hxx>
#include <Standard_Macro.hxx>
#include <Message_ProgressScope.hxx>
+#include <NCollection_Sequence.hxx>
//! This class provides methods to read and write triangulation from / to the STL files.
class RWStl
Standard_EXPORT static Handle(Poly_Triangulation) ReadFile (const Standard_CString theFile,
const Standard_Real theMergeAngle,
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
//! In case of error, returns Null handle.
Standard_EXPORT static Handle(Poly_Triangulation) ReadBinary (const OSD_Path& thePath,
}
}
*aStream >> std::ws; // skip any white spaces
+ AddSolid();
}
return ! aStream->fail();
}
// skip header "solid ..."
aLine = theBuffer.ReadLine (theStream, aLineLen);
+ // skip empty lines
+ while (aLine && !*aLine)
+ {
+ aLine = theBuffer.ReadLine (theStream, aLineLen);
+ }
if (aLine == NULL)
{
Message::SendFail ("Error: premature end of file");
Standard_EXPORT RWStl_Reader();
//! 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.
//! Unicode paths can be given in UTF-8 encoding.
//! Format is recognized automatically by analysis of the file header.
//! 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;
+ //! Callback function to be implemented in descendant.
+ //! Should create a new triangulation for a solid in multi-domain case.
+ virtual void AddSolid() {}
public:
//! Return merge tolerance; M_PI/2 by default - all nodes are merged regardless angle between triangles.
{
TCollection_AsciiString aShapeName, aFilePath;
bool toCreateCompOfTris = false;
+ bool anIsMulti = false;
double aMergeAngle = M_PI / 2.0;
for (Standard_Integer anArgIter = 1; anArgIter < theArgc; ++anArgIter)
{
++anArgIter;
}
}
+ else if (anArg == "-multi")
+ {
+ anIsMulti = true;
+ if (anArgIter + 1 < theArgc
+ && Draw::ParseOnOff (theArgv[anArgIter + 1], anIsMulti))
+ {
+ ++anArgIter;
+ }
+ }
else if (anArg == "-mergeangle"
|| anArg == "-smoothangle"
|| anArg == "-nomergeangle"
TopoDS_Shape aShape;
if (!toCreateCompOfTris)
{
- // Read STL file to the triangulation.
- Handle(Draw_ProgressIndicator) aProgress = new Draw_ProgressIndicator (theDI, 1);
- Handle(Poly_Triangulation) aTriangulation = RWStl::ReadFile (aFilePath.ToCString(), aMergeAngle, aProgress->Start());
+ Handle(Draw_ProgressIndicator) aProgress = new Draw_ProgressIndicator (theDI,1);
+ if(anIsMulti)
+ {
+ 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;
- BRep_Builder aB;
- aB.MakeFace (aFace);
- aB.UpdateFace (aFace, aTriangulation);
- aShape = aFace;
+ TopoDS_Face aFace;
+ BRep_Builder aB;
+ aB.MakeFace (aFace);
+ aB.UpdateFace (aFace,aTriangulation);
+ aShape = aFace;
+ }
}
else
{
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 ("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: 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: -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);
theCommands.Add ("loadvrml" , "shape file",__FILE__,loadvrml,g);
theCommands.Add ("ReadObj",
--- /dev/null
+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