From: aml Date: Wed, 14 Jun 2017 05:07:26 +0000 (+0300) Subject: 0028840: Data Exchange - rewrite the STL Reader/Writer X-Git-Tag: V7_2_0_beta~2 X-Git-Url: http://git.dev.opencascade.org/gitweb/?p=occt.git;a=commitdiff_plain;h=4178b3531b9c3b3d3aff6a6e900a941e259fe068 0028840: Data Exchange - rewrite the STL Reader/Writer STL Reader and Writer tools have been refactored to improve performance and usability: - Basic reading of STL file is separated to abstract class RWStl_Reader which is not bound to particular data structures; the target data model can be bound via inheritance. - RWStl package uses class Poly_Triangulation to represent triangular mesh. - Obsolete data structures and tools (packages StlMesh and StlTransfer) are removed. --- diff --git a/adm/UDLIST b/adm/UDLIST index 279ecd3afa..39ffb0ba8a 100644 --- a/adm/UDLIST +++ b/adm/UDLIST @@ -347,8 +347,6 @@ n StepToGeom n StepToTopoDS n StepVisual n StlAPI -n StlMesh -n StlTransfer n TopoDSToStep n Transfer n TransferBRep diff --git a/dox/dev_guides/upgrade/upgrade.md b/dox/dev_guides/upgrade/upgrade.md index 2c6fd9456b..320059c8ff 100644 --- a/dox/dev_guides/upgrade/upgrade.md +++ b/dox/dev_guides/upgrade/upgrade.md @@ -1406,3 +1406,7 @@ In previous versions, *IsPeriodic()* always returned false if *IsClosed()* retur The history of the changing of the initial shape was corrected: * all shapes created by the algorithm are considered as modified shapes instead of generated ones; * method Generated was removed and its calls should be replaced by calls of method History()->Modified. + +@subsection upgrade_720_Change_In_RWStl Changes in STL Reader / Writer + +Class RWStl now uses class Poly_Triangulation for storing triangular mesh instead of StlMesh data classes; the latter have been removed. diff --git a/dox/user_guides/visualization/visualization.md b/dox/user_guides/visualization/visualization.md index b085f1d50d..5e9cfcd815 100644 --- a/dox/user_guides/visualization/visualization.md +++ b/dox/user_guides/visualization/visualization.md @@ -1508,8 +1508,8 @@ Such an object, for example, can be used for displaying the object and stored in ~~~~~ // read the data and create a data source -Handle (StlMesh_Mesh) aSTLMesh = RWStl::ReadFile (aFileName); -Handle (XSDRAWSTLVRML_DataSource) aDataSource = new XSDRAWSTLVRML_DataSource (aSTLMesh); +Handle(Poly_Triangulation) aSTLMesh = RWStl::ReadFile (aFileName); +Handle(XSDRAWSTLVRML_DataSource) aDataSource = new XSDRAWSTLVRML_DataSource (aSTLMesh); // create mesh Handle (MeshVS_Mesh) aMesh = new MeshVS(); diff --git a/samples/xaml/MainPage.xaml.cpp b/samples/xaml/MainPage.xaml.cpp index 5466e3b11c..9915da53d7 100644 --- a/samples/xaml/MainPage.xaml.cpp +++ b/samples/xaml/MainPage.xaml.cpp @@ -331,10 +331,8 @@ Standard_Boolean MainPage::SaveSTEP(const wchar_t* theFilePath, const TopoDS_Sha return Standard_False; } - char theFilePathA[MAX_PATH]; - WideCharToMultiByte(CP_UTF8, 0, theFilePath, -1, theFilePathA, sizeof(theFilePathA), NULL, NULL); - - switch (aWriter.Write(theFilePathA)) + const TCollection_AsciiString aFilePath (theFilePath); + switch (aWriter.Write (aFilePath.ToCString())) { case IFSelect_RetError: Output_TextBlock->Text += L"Error: Incorrect Data\n"; @@ -358,11 +356,8 @@ Standard_Boolean MainPage::SaveSTEP(const wchar_t* theFilePath, const TopoDS_Sha Standard_Boolean MainPage::SaveSTL(const wchar_t* theFilePath, const TopoDS_Shape& theShape) { StlAPI_Writer myStlWriter; - - char theFilePathA[MAX_PATH]; - WideCharToMultiByte(CP_UTF8, 0, theFilePath, -1, theFilePathA, sizeof(theFilePathA), NULL, NULL); - - return myStlWriter.Write(theShape, theFilePathA) == StlAPI_StatusOK; + const TCollection_AsciiString aFilePath (theFilePath); + return myStlWriter.Write (theShape, aFilePath.ToCString()); } //======================================================================= @@ -372,12 +367,8 @@ Standard_Boolean MainPage::SaveSTL(const wchar_t* theFilePath, const TopoDS_Shap Standard_Boolean MainPage::SaveVRML(const wchar_t* theFilePath, const TopoDS_Shape& theShape) { VrmlAPI_Writer aWriter; - - char theFilePathA[MAX_PATH]; - WideCharToMultiByte(CP_UTF8, 0, theFilePath, -1, theFilePathA, sizeof(theFilePathA), NULL, NULL); - - aWriter.Write(theShape, theFilePathA); - + const TCollection_AsciiString aFilePath (theFilePath); + aWriter.Write (theShape, aFilePath.ToCString()); return Standard_True; } @@ -390,11 +381,8 @@ Standard_Boolean MainPage::ReadBREP(const wchar_t* theFilePath, TopoDS_Shape& th theShape.Nullify(); BRep_Builder aBuilder; - - char theFilePathA[MAX_PATH]; - WideCharToMultiByte(CP_UTF8, 0, theFilePath, -1, theFilePathA, sizeof(theFilePathA), NULL, NULL); - - if (!BRepTools::Read(theShape, theFilePathA, aBuilder)) + const TCollection_AsciiString aFilePath (theFilePath); + if (!BRepTools::Read(theShape, aFilePath.ToCString(), aBuilder)) return Standard_False; return !theShape.IsNull() && BRepAlgo::IsValid(theShape); @@ -410,10 +398,8 @@ Standard_Boolean MainPage::ReadIGES(const wchar_t* theFilePath, TopoDS_Shape& th IGESControl_Reader Reader; - char theFilePathA[MAX_PATH]; - WideCharToMultiByte(CP_UTF8, 0, theFilePath, -1, theFilePathA, sizeof(theFilePathA), NULL, NULL); - - if (Reader.ReadFile(theFilePathA) != IFSelect_RetDone) + const TCollection_AsciiString aFilePath (theFilePath); + if (Reader.ReadFile (aFilePath.ToCString()) != IFSelect_RetDone) return Standard_False; Reader.TransferRoots(); @@ -431,11 +417,8 @@ Standard_Boolean MainPage::ReadSTEP(const wchar_t* theFilePath, TopoDS_Shape& th theShape.Nullify(); STEPControl_Reader aReader; - - char theFilePathA[MAX_PATH]; - WideCharToMultiByte(CP_UTF8, 0, theFilePath, -1, theFilePathA, sizeof(theFilePathA), NULL, NULL); - - switch (aReader.ReadFile(theFilePathA)) + const TCollection_AsciiString aFilePath (theFilePath); + switch (aReader.ReadFile (aFilePath.ToCString())) { case IFSelect_RetError: Output_TextBlock->Text += L"Error: Not a valid Step file\n"; diff --git a/src/QABugs/QABugs_2.cxx b/src/QABugs/QABugs_2.cxx index c5cb0d7602..757b54d606 100644 --- a/src/QABugs/QABugs_2.cxx +++ b/src/QABugs/QABugs_2.cxx @@ -128,33 +128,9 @@ static Standard_Integer OCC527(Draw_Interpretor& di, Standard_Integer argc, cons return 0; } -#include -#include -//======================================================================= -//function : OCC1048 -//purpose : -//======================================================================= -static Standard_Integer OCC1048 (Draw_Interpretor& di, Standard_Integer argc, const char ** argv) -{ - // Verify amount of arguments of the command - if (argc < 2) { di << "Usage : " << argv[0] <<" shape"; return 1;} - - TopoDS_Shape aShape = DBRep::Get(argv[1]); - - Standard_Real theDeflection = 0.006; - Handle(StlMesh_Mesh) theStlMesh = new StlMesh_Mesh; - BRepMesh_IncrementalMesh aMesh(aShape, theDeflection); - StlTransfer::RetrieveMesh(aShape, theStlMesh); - Standard_Integer NBTRIANGLES = theStlMesh->NbTriangles(); - di<<"Info: Number of triangles = "< -#include -#include -#include -#include -#include -#include -#include -#include #include -#include +#include #include -#include #include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -// A static method adding nodes to a mesh and keeping coincident (sharing) nodes. -static Standard_Integer AddVertex(Handle(StlMesh_Mesh)& mesh, - BRepBuilderAPI_CellFilter& filter, - BRepBuilderAPI_VertexInspector& inspector, - const gp_XYZ& p) +#include + +namespace { - Standard_Integer index; - inspector.SetCurrent(p); - gp_XYZ minp = inspector.Shift(p, -Precision::Confusion()); - gp_XYZ maxp = inspector.Shift(p, +Precision::Confusion()); - filter.Inspect(minp, maxp, inspector); - const TColStd_ListOfInteger& indices = inspector.ResInd(); - if (indices.IsEmpty() == Standard_False) + + static const Standard_Integer THE_STL_SIZEOF_FACET = 50; + static const Standard_Integer IND_THRESHOLD = 1000; // increment the indicator every 1k triangles + + //! Writing a Little Endian 32 bits integer + inline static void convertInteger (const Standard_Integer theValue, + Standard_Character* theResult) { - index = indices.First(); // it should be only one - inspector.ClearResList(); + union + { + Standard_Integer i; + Standard_Character c[4]; + } anUnion; + anUnion.i = theValue; + + theResult[0] = anUnion.c[0]; + theResult[1] = anUnion.c[1]; + theResult[2] = anUnion.c[2]; + theResult[3] = anUnion.c[3]; } - else + + //! Writing a Little Endian 32 bits float + inline static void convertDouble (const Standard_Real theValue, + Standard_Character* theResult) { - index = mesh->AddVertex(p.X(), p.Y(), p.Z()); - filter.Add(index, p); - inspector.Add(p); + union + { + Standard_ShortReal i; + Standard_Character c[4]; + } anUnion; + anUnion.i = (Standard_ShortReal)theValue; + + theResult[0] = anUnion.c[0]; + theResult[1] = anUnion.c[1]; + theResult[2] = anUnion.c[2]; + theResult[3] = anUnion.c[3]; } - return index; -} -// constants -static const size_t HEADER_SIZE = 84; -static const size_t SIZEOF_STL_FACET = 50; -static const size_t ASCII_LINES_PER_FACET = 7; + class Reader : public RWStl_Reader + { + public: + //! Add new node + virtual Standard_Integer AddNode (const gp_XYZ& thePnt) Standard_OVERRIDE + { + myNodes.Append (thePnt); + return myNodes.Size(); + } -static const int IND_THRESHOLD = 1000; // increment the indicator every 1k triangles + //! Add new triangle + virtual void AddTriangle (Standard_Integer theNode1, Standard_Integer theNode2, Standard_Integer theNode3) Standard_OVERRIDE + { + myTriangles.Append (Poly_Triangle (theNode1, theNode2, theNode3)); + } -//======================================================================= -//function : WriteInteger -//purpose : writing a Little Endian 32 bits integer -//======================================================================= + //! Creates Poly_Triangulation from collected data + Handle(Poly_Triangulation) GetTriangulation() + { + Handle(Poly_Triangulation) aPoly = new Poly_Triangulation (myNodes.Length(), myTriangles.Length(), Standard_False); + for (Standard_Integer aNodeIter = 0; aNodeIter < myNodes.Size(); ++aNodeIter) + { + aPoly->ChangeNode (aNodeIter + 1) = myNodes (aNodeIter); + } -inline static void WriteInteger(OSD_File& ofile,const Standard_Integer value) -{ - union { - Standard_Integer i;// don't be afraid, this is just an unsigned int - char c[4]; - } bidargum; + for (Standard_Integer aTriIter = 0; aTriIter < myTriangles.Size(); ++aTriIter) + { + aPoly->ChangeTriangle (aTriIter + 1) = myTriangles (aTriIter); + } - bidargum.i = value; + return aPoly; + } - Standard_Integer entier; + private: + NCollection_Vector myNodes; + NCollection_Vector myTriangles; + }; - entier = bidargum.c[0] & 0xFF; - entier |= (bidargum.c[1] & 0xFF) << 0x08; - entier |= (bidargum.c[2] & 0xFF) << 0x10; - entier |= (bidargum.c[3] & 0xFF) << 0x18; +} - ofile.Write((char *)&entier,sizeof(bidargum.c)); +//============================================================================= +//function : Read +//purpose : +//============================================================================= +Handle(Poly_Triangulation) RWStl::ReadFile (const Standard_CString theFile, + const Handle(Message_ProgressIndicator)& theProgress) +{ + Reader aReader; + if (!aReader.Read (theFile, theProgress)) + { + return Handle(Poly_Triangulation)(); + } + return aReader.GetTriangulation(); } -//======================================================================= -//function : WriteDouble2Float -//purpose : writing a Little Endian 32 bits float -//======================================================================= +//============================================================================= +//function : ReadFile +//purpose : +//============================================================================= +Handle(Poly_Triangulation) RWStl::ReadFile (const OSD_Path& theFile, + const Handle(Message_ProgressIndicator)& theProgress) +{ + OSD_File aFile(theFile); + if (!aFile.Exists()) + { + return Handle(Poly_Triangulation)(); + } + + TCollection_AsciiString aPath; + theFile.SystemName (aPath); + return ReadFile (aPath.ToCString(), theProgress); +} -inline static void WriteDouble2Float(OSD_File& ofile,Standard_Real value) +//============================================================================= +//function : ReadBinary +//purpose : +//============================================================================= +Handle(Poly_Triangulation) RWStl::ReadBinary (const OSD_Path& theFile, + const Handle(Message_ProgressIndicator)& theProgress) { - union { - Standard_ShortReal f; - char c[4]; - } bidargum; + OSD_File aFile(theFile); + if (!aFile.Exists()) + { + return Handle(Poly_Triangulation)(); + } - bidargum.f = (Standard_ShortReal)value; + TCollection_AsciiString aPath; + theFile.SystemName (aPath); - Standard_Integer entier; + std::filebuf aBuf; + OSD_OpenStream (aBuf, aPath, std::ios::in | std::ios::binary); + if (!aBuf.is_open()) + { + return Handle(Poly_Triangulation)(); + } + Standard_IStream aStream (&aBuf); - entier = bidargum.c[0] & 0xFF; - entier |= (bidargum.c[1] & 0xFF) << 0x08; - entier |= (bidargum.c[2] & 0xFF) << 0x10; - entier |= (bidargum.c[3] & 0xFF) << 0x18; + Reader aReader; + if (!aReader.ReadBinary (aStream, theProgress)) + { + return Handle(Poly_Triangulation)(); + } - ofile.Write((char *)&entier,sizeof(bidargum.c)); + return aReader.GetTriangulation(); } +//============================================================================= +//function : ReadAscii +//purpose : +//============================================================================= +Handle(Poly_Triangulation) RWStl::ReadAscii (const OSD_Path& theFile, + const Handle(Message_ProgressIndicator)& theProgress) +{ + OSD_File aFile (theFile); + if (!aFile.Exists()) + { + return Handle(Poly_Triangulation)(); + } -//======================================================================= -//function : readFloat2Double -//purpose : reading a Little Endian 32 bits float -//======================================================================= + TCollection_AsciiString aPath; + theFile.SystemName (aPath); -inline static Standard_Real ReadFloat2Double(OSD_File &aFile) -{ - union { - uint32_t i; - float f; - }bidargum; - - char c[4]; - Standard_Address adr; - adr = (Standard_Address)c; - Standard_Integer lread; - aFile.Read(adr,4,lread); - bidargum.i = c[0] & 0xFF; - bidargum.i |= (c[1] & 0xFF) << 0x08; - bidargum.i |= (c[2] & 0xFF) << 0x10; - bidargum.i |= (c[3] & 0xFF) << 0x18; - - return (Standard_Real)(bidargum.f); -} + std::filebuf aBuf; + OSD_OpenStream (aBuf, aPath, std::ios::in | std::ios::binary); + if (!aBuf.is_open()) + { + return Handle(Poly_Triangulation)(); + } + Standard_IStream aStream (&aBuf); + // get length of file to feed progress indicator + aStream.seekg (0, aStream.end); + std::streampos theEnd = aStream.tellg(); + aStream.seekg (0, aStream.beg); + Reader aReader; + if (!aReader.ReadAscii (aStream, theEnd, theProgress)) + { + return Handle(Poly_Triangulation)(); + } -//======================================================================= -//function : WriteBinary -//purpose : write a binary STL file in Little Endian format -//======================================================================= + return aReader.GetTriangulation(); +} -Standard_Boolean RWStl::WriteBinary (const Handle(StlMesh_Mesh)& theMesh, +//============================================================================= +//function : Write +//purpose : +//============================================================================= +Standard_Boolean RWStl::WriteBinary (const Handle(Poly_Triangulation)& aMesh, const OSD_Path& thePath, const Handle(Message_ProgressIndicator)& theProgInd) { - OSD_File aFile (thePath); - aFile.Build (OSD_WriteOnly, OSD_Protection()); - - Standard_Real x1, y1, z1; - Standard_Real x2, y2, z2; - Standard_Real x3, y3, z3; - - // writing 80 bytes of the trash? - char sval[80]; - aFile.Write ((Standard_Address)sval,80); - WriteInteger (aFile, theMesh->NbTriangles()); + TCollection_AsciiString aPath; + thePath.SystemName (aPath); - int dum=0; - StlMesh_MeshExplorer aMexp (theMesh); - - // create progress sentry for domains - Standard_Integer aNbDomains = theMesh->NbDomains(); - Message_ProgressSentry aDPS (theProgInd, "Mesh domains", 0, aNbDomains, 1); - for (Standard_Integer nbd = 1; nbd <= aNbDomains && aDPS.More(); nbd++, aDPS.Next()) + FILE* aFile = OSD_OpenFile (aPath, "wb"); + if (aFile == NULL) { - // create progress sentry for triangles in domain - Message_ProgressSentry aTPS (theProgInd, "Triangles", 0, - theMesh->NbTriangles (nbd), IND_THRESHOLD); - Standard_Integer aTriangleInd = 0; - for (aMexp.InitTriangle (nbd); aMexp.MoreTriangle(); aMexp.NextTriangle()) - { - aMexp.TriangleVertices (x1,y1,z1,x2,y2,z2,x3,y3,z3); - //pgo aMexp.TriangleOrientation (x,y,z); - gp_XYZ Vect12 ((x2-x1), (y2-y1), (z2-z1)); - gp_XYZ Vect13 ((x3-x1), (y3-y1), (z3-z1)); - gp_XYZ Vnorm = Vect12 ^ Vect13; - Standard_Real Vmodul = Vnorm.Modulus (); - if (Vmodul > gp::Resolution()) - { - Vnorm.Divide(Vmodul); - } - else - { - // si Vnorm est quasi-nul, on le charge a 0 explicitement - Vnorm.SetCoord (0., 0., 0.); - } - - WriteDouble2Float (aFile, Vnorm.X()); - WriteDouble2Float (aFile, Vnorm.Y()); - WriteDouble2Float (aFile, Vnorm.Z()); - - WriteDouble2Float (aFile, x1); - WriteDouble2Float (aFile, y1); - WriteDouble2Float (aFile, z1); + return Standard_False; + } - WriteDouble2Float (aFile, x2); - WriteDouble2Float (aFile, y2); - WriteDouble2Float (aFile, z2); + Standard_Boolean isOK = writeBinary (aMesh, aFile, theProgInd); - WriteDouble2Float (aFile, x3); - WriteDouble2Float (aFile, y3); - WriteDouble2Float (aFile, z3); + fclose (aFile); + return isOK; +} - aFile.Write (&dum, 2); +//============================================================================= +//function : Write +//purpose : +//============================================================================= +Standard_Boolean RWStl::WriteAscii (const Handle(Poly_Triangulation)& theMesh, + const OSD_Path& thePath, + const Handle(Message_ProgressIndicator)& theProgInd) +{ + TCollection_AsciiString aPath; + thePath.SystemName (aPath); - // update progress only per 1k triangles - if (++aTriangleInd % IND_THRESHOLD == 0) - { - if (!aTPS.More()) - break; - aTPS.Next(); - } - } + FILE* aFile = OSD_OpenFile (aPath, "w"); + if (aFile == NULL) + { + return Standard_False; } - aFile.Close(); - Standard_Boolean isInterrupted = !aDPS.More(); - return !isInterrupted; + + Standard_Boolean isOK = writeASCII (theMesh, aFile, theProgInd); + fclose (aFile); + return isOK; } -//======================================================================= -//function : WriteAscii -//purpose : write an ASCII STL file -//======================================================================= -Standard_Boolean RWStl::WriteAscii (const Handle(StlMesh_Mesh)& theMesh, - const OSD_Path& thePath, +//============================================================================= +//function : writeASCII +//purpose : +//============================================================================= +Standard_Boolean RWStl::writeASCII (const Handle(Poly_Triangulation)& theMesh, + FILE* theFile, const Handle(Message_ProgressIndicator)& theProgInd) { - OSD_File theFile (thePath); - theFile.Build(OSD_WriteOnly,OSD_Protection()); - TCollection_AsciiString buf ("solid\n"); - theFile.Write (buf,buf.Length());buf.Clear(); - - Standard_Real x1, y1, z1; - Standard_Real x2, y2, z2; - Standard_Real x3, y3, z3; - char sval[512]; - - // create progress sentry for domains - Standard_Integer aNbDomains = theMesh->NbDomains(); - Message_ProgressSentry aDPS (theProgInd, "Mesh domains", 0, aNbDomains, 1); - StlMesh_MeshExplorer aMexp (theMesh); - for (Standard_Integer nbd = 1; nbd <= aNbDomains && aDPS.More(); nbd++, aDPS.Next()) + // note that space after 'solid' is necessary for many systems + if (fwrite ("solid \n", 1, 7, theFile) != 7) { - // create progress sentry for triangles in domain - Message_ProgressSentry aTPS (theProgInd, "Triangles", 0, - theMesh->NbTriangles (nbd), IND_THRESHOLD); - Standard_Integer aTriangleInd = 0; - for (aMexp.InitTriangle (nbd); aMexp.MoreTriangle(); aMexp.NextTriangle()) - { - aMexp.TriangleVertices (x1,y1,z1,x2,y2,z2,x3,y3,z3); + return Standard_False; + } -// Standard_Real x, y, z; -// aMexp.TriangleOrientation (x,y,z); + char aBuffer[512]; + memset (aBuffer, 0, sizeof(aBuffer)); - gp_XYZ Vect12 ((x2-x1), (y2-y1), (z2-z1)); - gp_XYZ Vect23 ((x3-x2), (y3-y2), (z3-z2)); - gp_XYZ Vnorm = Vect12 ^ Vect23; - Standard_Real Vmodul = Vnorm.Modulus (); - if (Vmodul > gp::Resolution()) - { - Vnorm.Divide (Vmodul); - } - else - { - // si Vnorm est quasi-nul, on le charge a 0 explicitement - Vnorm.SetCoord (0., 0., 0.); - } - Sprintf (sval, + Message_ProgressSentry aPS (theProgInd, "Triangles", 0, + theMesh->NbTriangles(), IND_THRESHOLD); + + const TColgp_Array1OfPnt& aNodes = theMesh->Nodes(); + const Poly_Array1OfTriangle& aTriangles = theMesh->Triangles(); + const Standard_Integer NBTriangles = theMesh->NbTriangles(); + Standard_Integer anElem[3] = {0, 0, 0}; + for (Standard_Integer aTriIter = 1; aTriIter <= NBTriangles; ++aTriIter) + { + const Poly_Triangle& aTriangle = aTriangles (aTriIter); + aTriangle.Get (anElem[0], anElem[1], anElem[2]); + + const gp_Pnt aP1 = aNodes (anElem[0]); + const gp_Pnt aP2 = aNodes (anElem[1]); + const gp_Pnt aP3 = aNodes (anElem[2]); + + const gp_Vec aVec1 (aP1, aP2); + const gp_Vec aVec2 (aP1, aP3); + gp_Vec aVNorm = aVec1.Crossed (aVec2); + if (aVNorm.SquareMagnitude() > gp::Resolution()) + { + aVNorm.Normalize(); + } + else + { + aVNorm.SetCoord (0.0, 0.0, 0.0); + } + + Sprintf (aBuffer, " facet normal % 12e % 12e % 12e\n" " outer loop\n" " vertex % 12e % 12e % 12e\n" @@ -287,270 +303,132 @@ Standard_Boolean RWStl::WriteAscii (const Handle(StlMesh_Mesh)& theMesh, " vertex % 12e % 12e % 12e\n" " endloop\n" " endfacet\n", - Vnorm.X(), Vnorm.Y(), Vnorm.Z(), - x1, y1, z1, - x2, y2, z2, - x3, y3, z3); - buf += sval; - theFile.Write (buf, buf.Length()); buf.Clear(); - - // update progress only per 1k triangles - if (++aTriangleInd % IND_THRESHOLD == 0) - { - if (!aTPS.More()) - break; - aTPS.Next(); - } + aVNorm.X(), aVNorm.Y(), aVNorm.Z(), + aP1.X(), aP1.Y(), aP1.Z(), + aP2.X(), aP2.Y(), aP2.Z(), + aP3.X(), aP3.Y(), aP3.Z()); + + if (fprintf (theFile, "%s", aBuffer) < 0) + { + return Standard_False; + } + + // update progress only per 1k triangles + if ((aTriIter % IND_THRESHOLD) == 0) + { + aPS.Next(); } } - buf += "endsolid\n"; - theFile.Write (buf, buf.Length()); buf.Clear(); - theFile.Close(); - Standard_Boolean isInterrupted = !aDPS.More(); - return !isInterrupted; + if (fwrite ("endsolid\n", 1, 9, theFile) != 9) + { + return Standard_False; + } + + return Standard_True; } -//======================================================================= -//function : ReadFile -//Design : -//Warning : -//======================================================================= -Handle(StlMesh_Mesh) RWStl::ReadFile (const OSD_Path& thePath, +//============================================================================= +//function : writeBinary +//purpose : +//============================================================================= +Standard_Boolean RWStl::writeBinary (const Handle(Poly_Triangulation)& theMesh, + FILE* theFile, const Handle(Message_ProgressIndicator)& theProgInd) { - OSD_File file (thePath); - file.Open(OSD_ReadOnly,OSD_Protection(OSD_RWD,OSD_RWD,OSD_RWD,OSD_RWD)); - Standard_Boolean IsAscii; - unsigned char str[128]; - Standard_Integer lread,i; - Standard_Address ach; - ach = (Standard_Address)str; - - // we skip the header which is in Ascii for both modes - file.Read(ach,HEADER_SIZE,lread); - - // we read 128 characters to detect if we have a non-ascii char - file.Read(ach,sizeof(str),lread); - - IsAscii = Standard_True; - for (i = 0; i< lread && IsAscii; ++i) { - if (str[i] > '~') { - IsAscii = Standard_False; - } + char aHeader[80] = "STL Exported by OpenCASCADE [www.opencascade.com]"; + if (fwrite (aHeader, 1, 80, theFile) != 80) + { + return Standard_False; } -#ifdef OCCT_DEBUG - cout << (IsAscii ? "ascii\n" : "binary\n"); -#endif - file.Close(); - return IsAscii ? RWStl::ReadAscii (thePath, theProgInd) - : RWStl::ReadBinary (thePath, theProgInd); -} + Message_ProgressSentry aPS (theProgInd, "Triangles", 0, + theMesh->NbTriangles(), IND_THRESHOLD); -//======================================================================= -//function : ReadBinary -//Design : -//Warning : -//======================================================================= + const Standard_Size aNbChunkTriangles = 4096; + const Standard_Size aChunkSize = aNbChunkTriangles * THE_STL_SIZEOF_FACET; + NCollection_Array1 aData (1, aChunkSize); + Standard_Character* aDataChunk = &aData.ChangeFirst(); -Handle(StlMesh_Mesh) RWStl::ReadBinary (const OSD_Path& thePath, - const Handle(Message_ProgressIndicator)& /*theProgInd*/) -{ - Standard_Integer ifacet; - Standard_Real fx,fy,fz,fx1,fy1,fz1,fx2,fy2,fz2,fx3,fy3,fz3; - Standard_Integer i1,i2,i3,lread; - char buftest[5]; - Standard_Address adr; - adr = (Standard_Address)buftest; - - // Open the file - OSD_File theFile (thePath); - theFile.Open(OSD_ReadOnly,OSD_Protection(OSD_RWD,OSD_RWD,OSD_RWD,OSD_RWD)); - - // the size of the file (minus the header size) - // must be a multiple of SIZEOF_STL_FACET - - // compute file size - Standard_Size filesize = theFile.Size(); - - // don't trust the number of triangles which is coded in the file sometimes it is wrong - Standard_Integer NBFACET = (Standard_Integer)((filesize - HEADER_SIZE) / SIZEOF_STL_FACET); - if (NBFACET < 1) - { - throw Standard_NoMoreObject("RWStl::ReadBinary (wrong file size)"); - } + const TColgp_Array1OfPnt& aNodes = theMesh->Nodes(); + const Poly_Array1OfTriangle& aTriangles = theMesh->Triangles(); + const Standard_Integer aNBTriangles = theMesh->NbTriangles(); - theFile.Seek (80, OSD_FromBeginning); - theFile.Read (adr, 4, lread); - Standard_Integer aNbTrisInHeader = (((char* )buftest)[3] << 24) | (((Standard_Byte* )buftest)[2] << 16) - | (((Standard_Byte* )buftest)[1] << 8 ) | (((Standard_Byte* )buftest)[0] << 0 ); - if (NBFACET < aNbTrisInHeader) + Standard_Character aConv[4]; + convertInteger (aNBTriangles, aConv); + if (fwrite (aConv, 1, 4, theFile) != 4) { - Message::DefaultMessenger()->Send (TCollection_AsciiString ("RWStl - Binary STL file defines more triangles (") + aNbTrisInHeader - + ") that can be read (" + NBFACET + ") - probably corrupted file", - Message_Warning); + return Standard_False; } - else if (NBFACET > aNbTrisInHeader) - { - Message::DefaultMessenger()->Send (TCollection_AsciiString ("RWStl - Binary STL file defines less triangles (") + aNbTrisInHeader - + ") that can be read (" + NBFACET + ") - probably corrupted file", - Message_Warning); - } - else if ((filesize - HEADER_SIZE) % SIZEOF_STL_FACET != 0) + + Standard_Size aByteCount = 0; + for (Standard_Integer aTriIter = 1; aTriIter <= aNBTriangles; ++aTriIter) { - Message::DefaultMessenger()->Send (TCollection_AsciiString ("RWStl - Binary STL file has unidentified tail"), - Message_Warning); - } + Standard_Integer id[3]; + const Poly_Triangle& aTriangle = aTriangles (aTriIter); + aTriangle.Get (id[0], id[1], id[2]); + + const gp_Pnt aP1 = aNodes (id[0]); + const gp_Pnt aP2 = aNodes (id[1]); + const gp_Pnt aP3 = aNodes (id[2]); + + gp_Vec aVec1 (aP1, aP2); + gp_Vec aVec2 (aP1, aP3); + gp_Vec aVNorm = aVec1.Crossed(aVec2); + if (aVNorm.SquareMagnitude() > gp::Resolution()) + { + aVNorm.Normalize(); + } + else + { + aVNorm.SetCoord (0.0, 0.0, 0.0); + } - // skip the header - theFile.Seek(HEADER_SIZE,OSD_FromBeginning); - - // create the StlMesh_Mesh object - Handle(StlMesh_Mesh) ReadMesh = new StlMesh_Mesh (); - ReadMesh->AddDomain (); - - // Filter unique vertices to share the nodes of the mesh. - BRepBuilderAPI_CellFilter uniqueVertices(Precision::Confusion()); - BRepBuilderAPI_VertexInspector inspector(Precision::Confusion()); - - for (ifacet=1; ifacet<=NBFACET; ++ifacet) { - // read normal coordinates - fx = ReadFloat2Double(theFile); - fy = ReadFloat2Double(theFile); - fz = ReadFloat2Double(theFile); - - // read vertex 1 - fx1 = ReadFloat2Double(theFile); - fy1 = ReadFloat2Double(theFile); - fz1 = ReadFloat2Double(theFile); - - // read vertex 2 - fx2 = ReadFloat2Double(theFile); - fy2 = ReadFloat2Double(theFile); - fz2 = ReadFloat2Double(theFile); - - // read vertex 3 - fx3 = ReadFloat2Double(theFile); - fy3 = ReadFloat2Double(theFile); - fz3 = ReadFloat2Double(theFile); - - // Add vertices. - i1 = AddVertex(ReadMesh, uniqueVertices, inspector, gp_XYZ(fx1, fy1, fz1)); - i2 = AddVertex(ReadMesh, uniqueVertices, inspector, gp_XYZ(fx2, fy2, fz2)); - i3 = AddVertex(ReadMesh, uniqueVertices, inspector, gp_XYZ(fx3, fy3, fz3)); - - // Add triangle. - ReadMesh->AddTriangle (i1,i2,i3,fx,fy,fz); - - // skip extra bytes - theFile.Read(adr,2,lread); - } + convertDouble (aVNorm.X(), &aDataChunk[aByteCount]); aByteCount += 4; + convertDouble (aVNorm.Y(), &aDataChunk[aByteCount]); aByteCount += 4; + convertDouble (aVNorm.Z(), &aDataChunk[aByteCount]); aByteCount += 4; - theFile.Close (); - return ReadMesh; -} + convertDouble (aP1.X(), &aDataChunk[aByteCount]); aByteCount += 4; + convertDouble (aP1.Y(), &aDataChunk[aByteCount]); aByteCount += 4; + convertDouble (aP1.Z(), &aDataChunk[aByteCount]); aByteCount += 4; -//======================================================================= -//function : ReadAscii -//Design : -//Warning : -//======================================================================= + convertDouble (aP2.X(), &aDataChunk[aByteCount]); aByteCount += 4; + convertDouble (aP2.Y(), &aDataChunk[aByteCount]); aByteCount += 4; + convertDouble (aP2.Z(), &aDataChunk[aByteCount]); aByteCount += 4; -Handle(StlMesh_Mesh) RWStl::ReadAscii (const OSD_Path& thePath, - const Handle(Message_ProgressIndicator)& theProgInd) -{ - TCollection_AsciiString filename; - long ipos; - Standard_Integer nbLines = 0; - Standard_Integer nbTris = 0; - Standard_Integer iTri; - Standard_Integer i1,i2,i3; - Handle(StlMesh_Mesh) ReadMesh; + convertDouble (aP3.X(), &aDataChunk[aByteCount]); aByteCount += 4; + convertDouble (aP3.Y(), &aDataChunk[aByteCount]); aByteCount += 4; + convertDouble (aP3.Z(), &aDataChunk[aByteCount]); aByteCount += 4; - thePath.SystemName (filename); + aDataChunk[aByteCount] = 0; aByteCount += 1; + aDataChunk[aByteCount] = 0; aByteCount += 1; - // Open the file - FILE* file = OSD_OpenFile(filename.ToCString(),"r"); - - fseek(file,0L,SEEK_END); - - long filesize = ftell(file); + // Chunk is filled. Dump it to the file. + if (aByteCount == aChunkSize) + { + if (fwrite (aDataChunk, 1, aChunkSize, theFile) != aChunkSize) + { + return Standard_False; + } - rewind(file); + aByteCount = 0; + } - // count the number of lines - for (ipos = 0; ipos < filesize; ++ipos) { - if (getc(file) == '\n') - nbLines++; + // update progress only per 1k triangles + if ((aTriIter % IND_THRESHOLD) == 0) + { + aPS.Next(); + } } - // compute number of triangles - nbTris = (nbLines / ASCII_LINES_PER_FACET); - - // go back to the beginning of the file - rewind(file); - - // skip header - while (getc(file) != '\n'); -#ifdef OCCT_DEBUG - cout << "start mesh\n"; -#endif - ReadMesh = new StlMesh_Mesh(); - ReadMesh->AddDomain(); - - // Filter unique vertices to share the nodes of the mesh. - BRepBuilderAPI_CellFilter uniqueVertices(Precision::Confusion()); - BRepBuilderAPI_VertexInspector inspector(Precision::Confusion()); - - // main reading - Message_ProgressSentry aPS (theProgInd, "Triangles", 0, (nbTris - 1) * 1.0 / IND_THRESHOLD, 1); - for (iTri = 0; iTri < nbTris && aPS.More();) + // Write last part if necessary. + if (aByteCount != aChunkSize) { - char x[256]="", y[256]="", z[256]=""; - - // reading the facet normal - if (3 != fscanf(file,"%*s %*s %80s %80s %80s\n", x, y, z)) - break; // error should be properly reported - gp_XYZ aN (Atof(x), Atof(y), Atof(z)); - - // skip the keywords "outer loop" - if (fscanf(file,"%*s %*s") < 0) - break; - - // reading vertex - if (3 != fscanf(file,"%*s %80s %80s %80s\n", x, y, z)) - break; // error should be properly reported - gp_XYZ aV1 (Atof(x), Atof(y), Atof(z)); - if (3 != fscanf(file,"%*s %80s %80s %80s\n", x, y, z)) - break; // error should be properly reported - gp_XYZ aV2 (Atof(x), Atof(y), Atof(z)); - if (3 != fscanf(file,"%*s %80s %80s %80s\n", x, y, z)) - break; // error should be properly reported - gp_XYZ aV3 (Atof(x), Atof(y), Atof(z)); - - // here the facet must be built and put in the mesh datastructure - - i1 = AddVertex(ReadMesh, uniqueVertices, inspector, aV1); - i2 = AddVertex(ReadMesh, uniqueVertices, inspector, aV2); - i3 = AddVertex(ReadMesh, uniqueVertices, inspector, aV3); - ReadMesh->AddTriangle (i1, i2, i3, aN.X(), aN.Y(), aN.Z()); - - // skip the keywords "endloop" - if (fscanf(file,"%*s") < 0) - break; - - // skip the keywords "endfacet" - if (fscanf(file,"%*s") < 0) - break; - - // update progress only per 1k triangles - if (++iTri % IND_THRESHOLD == 0) - aPS.Next(); + if (fwrite (aDataChunk, 1, aByteCount, theFile) != aByteCount) + { + return Standard_False; + } } -#ifdef OCCT_DEBUG - cout << "end mesh\n"; -#endif - fclose(file); - return ReadMesh; + + return Standard_True; } diff --git a/src/RWStl/RWStl.hxx b/src/RWStl/RWStl.hxx index cbbbcf3289..bea270f6fe 100644 --- a/src/RWStl/RWStl.hxx +++ b/src/RWStl/RWStl.hxx @@ -1,7 +1,6 @@ -// Created on: 1994-10-13 -// Created by: Marc LEGAY -// Copyright (c) 1994-1999 Matra Datavision -// Copyright (c) 1999-2014 OPEN CASCADE SAS +// Created on: 2017-06-13 +// Created by: Alexander MALYSHEV +// Copyright (c) 2017 OPEN CASCADE SAS // // This file is part of Open CASCADE Technology software library. // @@ -17,85 +16,61 @@ #ifndef _RWStl_HeaderFile #define _RWStl_HeaderFile -#include -#include -#include #include +#include +#include +#include -class StlMesh_Mesh; -class OSD_Path; - -//! This package contains the methods to be used in -//! the Stereo Lithograpy Application. The main -//! features of this application are ,starting from a -//! Shape : -//! - mesh this shape with a maximun tolerance, -//! - display the meshing, -//! - write the meshing in a file (binary or ascii), -//! - read of file (binary or ascii) and display it, -//! - translate a binary file to an ascii file, -//! - translate an ascii file to an binary file. -class RWStl +//! This class provides methods to read and write triangulation from / to the STL files. +class RWStl { public: - DEFINE_STANDARD_ALLOC - - - //! write the meshing in a file following the + //! Write triangulation to binary STL file. //! binary format of an STL file. //! Returns false if the cannot be opened; - Standard_EXPORT static Standard_Boolean WriteBinary (const Handle(StlMesh_Mesh)& aMesh, const OSD_Path& aPath, const Handle(Message_ProgressIndicator)& aProgInd = NULL); + Standard_EXPORT static Standard_Boolean WriteBinary (const Handle(Poly_Triangulation)& theMesh, + const OSD_Path& thePath, + const Handle(Message_ProgressIndicator)& theProgInd = Handle(Message_ProgressIndicator)()); //! write the meshing in a file following the //! Ascii format of an STL file. //! Returns false if the cannot be opened; - Standard_EXPORT static Standard_Boolean WriteAscii (const Handle(StlMesh_Mesh)& aMesh, const OSD_Path& aPath, const Handle(Message_ProgressIndicator)& aProgInd = NULL); - - //! This method will chwck if the file is a binary - //! file or an AsciiFile testing the 5 first - //! characters of the file wich are :"solid" in an - //! ascii file. If we do not find that word we assume - //! that it is a binary file. - Standard_EXPORT static Handle(StlMesh_Mesh) ReadFile (const OSD_Path& aPath, const Handle(Message_ProgressIndicator)& aProgInd = NULL); + Standard_EXPORT static Standard_Boolean WriteAscii (const Handle(Poly_Triangulation)& theMesh, + const OSD_Path& thePath, + const Handle(Message_ProgressIndicator)& theProgInd = Handle(Message_ProgressIndicator)()); - //! Read a meshing from a binary file - //! Raises NoMoreObject from Standard if a statement - //! does not contain the right number of tokens - //! Raises TypeMisMatch if a token has not the good - //! type (often real) - Standard_EXPORT static Handle(StlMesh_Mesh) ReadBinary (const OSD_Path& aPath, const Handle(Message_ProgressIndicator)& aProgInd = NULL); + //! Read specified STL file and returns its content as triangulation. + //! In case of error, returns Null handle. + Standard_EXPORT static Handle(Poly_Triangulation) ReadFile (const OSD_Path& theFile, + const Handle(Message_ProgressIndicator)& aProgInd = Handle(Message_ProgressIndicator)()); + + //! Read specified STL file and returns its content as triangulation. + //! In case of error, returns Null handle. + Standard_EXPORT static Handle(Poly_Triangulation) ReadFile (const Standard_CString theFile, + const Handle(Message_ProgressIndicator)& aProgInd = Handle(Message_ProgressIndicator)()); + + //! 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, + const Handle(Message_ProgressIndicator)& theProgInd = Handle(Message_ProgressIndicator)()); - //! Read a meshing from a binary file - //! Raises NoMoreObject from Standard if a statement - //! does not contain the right number of tokens - //! Raises TypeMisMatch if a token has not the good - //! type (often real) - //! Raises MoMoreObject if a file is finished before - //! having found the word endsolid; - Standard_EXPORT static Handle(StlMesh_Mesh) ReadAscii (const OSD_Path& aPath, const Handle(Message_ProgressIndicator)& aProgInd = NULL); - - - - -protected: - - - - + //! Read triangulation from an Ascii STL file + //! In case of error, returns Null handle. + Standard_EXPORT static Handle(Poly_Triangulation) ReadAscii (const OSD_Path& thePath, + const Handle(Message_ProgressIndicator)& theProgInd = Handle(Message_ProgressIndicator)()); private: + //! Write ASCII version. + static Standard_Boolean writeASCII (const Handle(Poly_Triangulation)& theMesh, + FILE *theFile, + const Handle(Message_ProgressIndicator)& theProgInd); - - - + //! Write binary version. + static Standard_Boolean writeBinary (const Handle(Poly_Triangulation)& theMesh, + FILE *theFile, + const Handle(Message_ProgressIndicator)& theProgInd); }; - - - - - - -#endif // _RWStl_HeaderFile +#endif diff --git a/src/RWStl/RWStl_Reader.cxx b/src/RWStl/RWStl_Reader.cxx new file mode 100644 index 0000000000..84082bc4cf --- /dev/null +++ b/src/RWStl/RWStl_Reader.cxx @@ -0,0 +1,407 @@ +// Created: 2016-05-01 +// Author: Andrey Betenev +// Copyright: Open CASCADE 2016 +// +// This file is part of Open CASCADE Technology software library. +// +// This library is free software; you can redistribute it and/or modify it under +// the terms of the GNU Lesser General Public License version 2.1 as published +// by the Free Software Foundation, with special exception defined in the file +// OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT +// distribution for complete text of the license and disclaimer of any warranty. +// +// Alternatively, this file may be used under the terms of Open CASCADE +// commercial license or contractual agreement. + +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include + +IMPLEMENT_STANDARD_RTTIEXT(RWStl_Reader, Standard_Transient) + +namespace +{ + // Binary STL sizes + static const size_t THE_STL_HEADER_SIZE = 84; + static const size_t THE_STL_SIZEOF_FACET = 50; + static const size_t THE_STL_MIN_FILE_SIZE = THE_STL_HEADER_SIZE + THE_STL_SIZEOF_FACET; + + //! Auxiliary tool for merging nodes during STL reading. + class MergeNodeTool + { + public: + + //! Constructor + MergeNodeTool (RWStl_Reader* theReader) + : myReader (theReader), + myMap (1024, new NCollection_IncAllocator (1024 * 1024)) + { + } + + //! Add new triangle + int AddNode (double theX, double theY, double theZ) + { + // use existing node if found at the same point + gp_XYZ aPnt (theX, theY, theZ); + + Standard_Integer anIndex = -1; + if (myMap.Find (aPnt, anIndex)) + { + return anIndex; + } + + anIndex = myReader->AddNode (aPnt); + myMap.Bind (aPnt, anIndex); + return anIndex; + } + + public: + + static Standard_Boolean IsEqual (const gp_XYZ& thePnt1, const gp_XYZ& thePnt2) + { + return (thePnt1 - thePnt2).SquareModulus() < Precision::SquareConfusion(); + } + + static Standard_Integer HashCode (const gp_XYZ& thePnt, Standard_Integer theUpper) + { + return ::HashCode (thePnt.X() * M_LN10 + thePnt.Y() * M_PI + thePnt.Z() * M_E, theUpper); + } + + private: + RWStl_Reader* myReader; + NCollection_DataMap myMap; + }; + + //! Read a Little Endian 32 bits float + inline static float readStlFloat (const char* theData) + { + #if OCCT_BINARY_FILE_DO_INVERSE + // on big-endian platform, map values byte-per-byte + union + { + uint32_t i; + float f; + } bidargum; + bidargum.i = theData[0] & 0xFF; + bidargum.i |= (theData[1] & 0xFF) << 0x08; + bidargum.i |= (theData[2] & 0xFF) << 0x10; + bidargum.i |= (theData[3] & 0xFF) << 0x18; + return bidargum.f; + #else + // on little-endian platform, use plain cast + return *reinterpret_cast(theData); + #endif + } + + //! Read a Little Endian 32 bits float + inline static gp_XYZ readStlFloatVec3 (const char* theData) + { + return gp_XYZ (readStlFloat (theData), + readStlFloat (theData + sizeof(float)), + readStlFloat (theData + sizeof(float) * 2)); + } + +} + +//============================================================================== +//function : Read +//purpose : +//============================================================================== + +Standard_Boolean RWStl_Reader::Read (const char* theFile, + const Handle(Message_ProgressIndicator)& theProgress) +{ + std::filebuf aBuf; + OSD_OpenStream (aBuf, theFile, std::ios::in | std::ios::binary); + if (!aBuf.is_open()) + { + return Standard_False; + } + + Standard_IStream aStream (&aBuf); + if (IsAscii (aStream)) + { + // get length of file to feed progress indicator + aStream.seekg (0, aStream.end); + std::streampos theEnd = aStream.tellg(); + aStream.seekg (0, aStream.beg); + return ReadAscii (aStream, theEnd, theProgress); + } + else + { + return ReadBinary (aStream, theProgress); + } +} + +//============================================================================== +//function : IsAscii +//purpose : +//============================================================================== + +Standard_Boolean RWStl_Reader::IsAscii (Standard_IStream& theStream) +{ + // read first 134 bytes to detect file format + char aBuffer[THE_STL_MIN_FILE_SIZE]; + std::streamsize aNbRead = theStream.read (aBuffer, THE_STL_MIN_FILE_SIZE).gcount(); + if (!theStream) + { + Message::DefaultMessenger()->Send ("Error: Cannot read file", Message_Fail); + return false; + } + + // put back the read symbols + for (std::streamsize aByteIter = aNbRead; aByteIter > 0; --aByteIter) + { + theStream.unget(); + } + + // if file is shorter than size of binary file with 1 facet, it must be ascii + if (aNbRead < std::streamsize(THE_STL_MIN_FILE_SIZE)) + { + return true; + } + + // otherwise, detect binary format by presence of non-ascii symbols in first 128 bytes + // (note that binary STL file may start with the same bytes "solid " as Ascii one) + for (Standard_Integer aByteIter = 0; aByteIter < aNbRead; ++aByteIter) + { + if ((unsigned char )aBuffer[aByteIter] > (unsigned char )'~') + { + return false; + } + } + return true; +} + +// adapted from Standard_CString.cxx +#ifdef __APPLE__ + // There are a lot of *_l functions availalbe on Mac OS X - we use them + #define SAVE_TL() +#elif defined(_MSC_VER) + // MSVCRT has equivalents with slightly different syntax + #define SAVE_TL() + #define sscanf_l(theBuffer, theLocale, theFormat, ...) _sscanf_s_l(theBuffer, theFormat, theLocale, __VA_ARGS__) +#else + // glibc provides only limited xlocale implementation: + // strtod_l/strtol_l/strtoll_l functions with explicitly specified locale + // and newlocale/uselocale/freelocale to switch locale within current thread only. + // So we switch to C locale temporarily + #define SAVE_TL() Standard_CLocaleSentry aLocaleSentry; + #define sscanf_l(theBuffer, theLocale, theFormat, ...) sscanf(theBuffer, theFormat, __VA_ARGS__) +#endif + +// Macro to get 64-bit position of the file from streampos +#if defined(_MSC_VER) + #define GETPOS(aPos) aPos.seekpos() +#else + #define GETPOS(aPos) ((int64_t)aPos) +#endif + +static inline bool str_starts_with (const char* theStr, const char* theWord, int theN) +{ + while (isspace (*theStr) && *theStr != '\0') theStr++; + return !strncmp (theStr, theWord, theN); +} + +//============================================================================== +//function : ReadAscii +//purpose : +//============================================================================== +Standard_Boolean RWStl_Reader::ReadAscii (Standard_IStream& theStream, + const std::streampos theUntilPos, + const Handle(Message_ProgressIndicator)& theProgress) +{ + // use method seekpos() to get true 64-bit offset to enable + // handling of large files (VS 2010 64-bit) + const int64_t aStartPos = GETPOS(theStream.tellg()); + const int64_t aEndPos = (theUntilPos > 0 ? GETPOS(theUntilPos) : std::numeric_limits::max()); + + // skip header "solid ..." + theStream.ignore (aEndPos - aStartPos, '\n'); + if (!theStream) + { + Message::DefaultMessenger()->Send ("Error: premature end of file", Message_Fail); + return false; + } + + MergeNodeTool aMergeTool (this); + Standard_CLocaleSentry::clocale_t aLocale = Standard_CLocaleSentry::GetCLocale(); + (void)aLocale; // to avoid warning on GCC where it is actually not used + SAVE_TL() // for GCC only, set C locale globally + + // report progress every 1 MiB of read data + const int aStepB = 1024 * 1024; + const Standard_Integer aNbSteps = 1 + Standard_Integer((theUntilPos - aStartPos) / aStepB); + Message_ProgressSentry aPSentry (theProgress, "Reading text STL file", 0, aNbSteps, 1); + + int64_t aProgressPos = aStartPos + aStepB; + const int64_t LINELEN = 1024; + int aNbLine = 1; + char aLine1[LINELEN], aLine2[LINELEN], aLine3[LINELEN]; + while (aPSentry.More()) + { + if (GETPOS(theStream.tellg()) > aProgressPos) + { + aPSentry.Next(); + aProgressPos += aStepB; + } + + char facet[LINELEN], outer[LINELEN]; + theStream.getline (facet, std::min (LINELEN, aEndPos - GETPOS(theStream.tellg()))); // "facet normal nx ny nz" + if (str_starts_with (facet, "endsolid", 8)) + { + // end of STL code + break; + } + theStream.getline (outer, std::min (LINELEN, aEndPos - GETPOS(theStream.tellg()))); // "outer loop" + if (!str_starts_with (facet, "facet", 5) || !str_starts_with (outer, "outer", 5)) + { + TCollection_AsciiString aStr ("Error: unexpected format of facet at line "); + aStr += aNbLine + 1; + Message::DefaultMessenger()->Send (aStr, Message_Fail); + return false; + } + + theStream.getline (aLine1, std::min (LINELEN, aEndPos - GETPOS(theStream.tellg()))); + theStream.getline (aLine2, std::min (LINELEN, aEndPos - GETPOS(theStream.tellg()))); + theStream.getline (aLine3, std::min (LINELEN, aEndPos - GETPOS(theStream.tellg()))); + + // stop reading if end of file is reached; + // note that well-formatted file never ends by the vertex line + if (theStream.eof() || GETPOS(theStream.tellg()) >= aEndPos) + { + break; + } + + if (!theStream) + { + Message::DefaultMessenger()->Send ("Error: premature end of file", Message_Fail); + return false; + } + aNbLine += 5; + + Standard_Real x1, y1, z1, x2, y2, z2, x3, y3, z3; + Standard_Integer aReadCount = // read 3 lines "vertex x y z" + sscanf_l (aLine1, aLocale, "%*s %lf %lf %lf", &x1, &y1, &z1) + + sscanf_l (aLine2, aLocale, "%*s %lf %lf %lf", &x2, &y2, &z2) + + sscanf_l (aLine3, aLocale, "%*s %lf %lf %lf", &x3, &y3, &z3); + if (aReadCount != 9) + { + TCollection_AsciiString aStr ("Error: cannot read vertex co-ordinates at line "); + aStr += aNbLine; + Message::DefaultMessenger()->Send(aStr, Message_Fail); + return false; + } + + // add triangle + int n1 = aMergeTool.AddNode (x1, y1, z1); + int n2 = aMergeTool.AddNode (x2, y2, z2); + int n3 = aMergeTool.AddNode (x3, y3, z3); + if (n1 != n2 && n2 != n3 && n3 != n1) + { + AddTriangle (n1, n2, n3); + } + + theStream.ignore (aEndPos - GETPOS(theStream.tellg()), '\n'); // skip "endloop" + theStream.ignore (aEndPos - GETPOS(theStream.tellg()), '\n'); // skip "endfacet" + + aNbLine += 2; + } + + return aPSentry.More(); +} + +//============================================================================== +//function : readStlBinary +//purpose : +//============================================================================== + +Standard_Boolean RWStl_Reader::ReadBinary (Standard_IStream& theStream, + const Handle(Message_ProgressIndicator)& theProgress) +{ +/* + // the size of the file (minus the header size) + // must be a multiple of SIZEOF_STL_FACET + if ((theFileLen - THE_STL_HEADER_SIZE) % THE_STL_SIZEOF_FACET != 0 + || (theFileLen < THE_STL_MIN_FILE_SIZE)) + { + Message::DefaultMessenger()->Send ("Error: Corrupted binary STL file (inconsistent file size)!", Message_Fail); + return Standard_False; + } + const Standard_Integer aNbFacets = Standard_Integer((theFileLen - THE_STL_HEADER_SIZE) / THE_STL_SIZEOF_FACET); +*/ + + // read file header at first + char aHeader[THE_STL_HEADER_SIZE + 1]; + if (theStream.read (aHeader, THE_STL_HEADER_SIZE).gcount() != std::streamsize(THE_STL_HEADER_SIZE)) + { + Message::DefaultMessenger()->Send ("Error: Corrupted binary STL file!", Message_Fail); + return false; + } + + // number of facets is stored as 32-bit integer at position 80 + const Standard_Integer aNbFacets = *(int32_t*)(aHeader + 80); + + MergeNodeTool aMergeTool (this); + + // don't trust the number of triangles which is coded in the file + // sometimes it is wrong, and with this technique we don't need to swap endians for integer + Message_ProgressSentry aPSentry (theProgress, "Reading binary STL file", 0, aNbFacets, 1); + Standard_Integer aNbRead = 0; + + // allocate buffer for 80 triangles + const int THE_CHUNK_NBFACETS = 80; + char aBuffer[THE_STL_SIZEOF_FACET * THE_CHUNK_NBFACETS]; + + // normal + 3 nodes + 2 extra bytes + const size_t aVec3Size = sizeof(float) * 3; + const size_t aFaceDataLen = aVec3Size * 4 + 2; + const char* aBufferPtr = aBuffer; + Standard_Integer aNbFacesInBuffer = 0; + for (Standard_Integer aNbFacetRead = 0; aNbFacetRead < aNbFacets && aPSentry.More(); + ++aNbFacetRead, ++aNbRead, --aNbFacesInBuffer, aBufferPtr += aFaceDataLen, aPSentry.Next()) + { + // read more data + if (aNbFacesInBuffer <= 0) + { + aNbFacesInBuffer = Min (THE_CHUNK_NBFACETS, aNbFacets - aNbFacetRead); + const std::streamsize aDataToRead = aNbFacesInBuffer * aFaceDataLen; + if (theStream.read (aBuffer, aDataToRead).gcount() != aDataToRead) + { + Message::DefaultMessenger()->Send ("Error: read filed", Message_Fail); + return false; + } + aBufferPtr = aBuffer; + } + + // get points from buffer +// readStlFloatVec3 (aBufferPtr); // skip normal + gp_XYZ aP1 = readStlFloatVec3 (aBufferPtr + aVec3Size); + gp_XYZ aP2 = readStlFloatVec3 (aBufferPtr + aVec3Size * 2); + gp_XYZ aP3 = readStlFloatVec3 (aBufferPtr + aVec3Size * 3); + + // add triangle + int n1 = aMergeTool.AddNode (aP1.X(), aP1.Y(), aP1.Z()); + int n2 = aMergeTool.AddNode (aP2.X(), aP2.Y(), aP2.Z()); + int n3 = aMergeTool.AddNode (aP3.X(), aP3.Y(), aP3.Z()); + if (n1 != n2 && n2 != n3 && n3 != n1) + { + AddTriangle (n1, n2, n3); + } + } + + return true; +} diff --git a/src/RWStl/RWStl_Reader.hxx b/src/RWStl/RWStl_Reader.hxx new file mode 100644 index 0000000000..c8f3cc5476 --- /dev/null +++ b/src/RWStl/RWStl_Reader.hxx @@ -0,0 +1,77 @@ +// Created: 2016-05-01 +// Author: Andrey Betenev +// Copyright: Open CASCADE 2016 +// +// This file is part of Open CASCADE Technology software library. +// +// This library is free software; you can redistribute it and/or modify it under +// the terms of the GNU Lesser General Public License version 2.1 as published +// by the Free Software Foundation, with special exception defined in the file +// OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT +// distribution for complete text of the license and disclaimer of any warranty. +// +// Alternatively, this file may be used under the terms of Open CASCADE +// commercial license or contractual agreement. + +#ifndef _RWStl_Reader_HeaderFile +#define _RWStl_Reader_HeaderFile + +#include +#include + +//! An abstract class implementing procedure to read STL file. +//! +//! This class is not bound to particular data structure and can be used to read the file directly into arbitrary data model. +//! To use it, create descendant class and implement methods addNode() and addTriangle(). +//! +//! Call method Read() to read the file. In the process of reading, the tool will call methods addNode() and addTriangle() to fill the mesh data structure. +//! +//! The nodes with equal coordinates are merged automatically on the fly. +class RWStl_Reader : public Standard_Transient +{ + DEFINE_STANDARD_RTTIEXT(RWStl_Reader, Standard_Transient) +public: + + //! Reads data from STL file (either binary or Ascii). + //! Unicode paths can be given in UTF-8 encoding. + //! Format is recognized automatically by analysis of the file header. + //! Returns true if success, false on error or user break. + Standard_EXPORT Standard_Boolean Read (const char* theFile, + const Handle(Message_ProgressIndicator)& theProgress); + + //! Guess whether the stream is an Ascii STL file, by analysis of the first bytes (~200). + //! The function attempts to put back the read symbols to the stream which thus must support ungetc(). + //! Returns true if the stream seems to contain Ascii STL. + Standard_EXPORT Standard_Boolean IsAscii (Standard_IStream& theStream); + + //! Reads STL data from binary stream. + //! The stream must be opened in binary mode. + //! Stops after reading the number of triangles recorded in the file header. + //! Returns true if success, false on error or user break. + Standard_EXPORT Standard_Boolean ReadBinary (Standard_IStream& theStream, + const Handle(Message_ProgressIndicator)& theProgress); + + //! Reads data from the stream assumed to contain Ascii STL data. + //! The stream can be opened either in binary or in Ascii mode. + //! Reading stops at the position specified by theUntilPos, + //! or end of file is reached, or when keyword "endsolid" is found. + //! Empty lines are not supported and will read to reading failure. + //! If theUntilPos is non-zero, reads not more than until that position. + //! Returns true if success, false on error or user break. + Standard_EXPORT Standard_Boolean ReadAscii (Standard_IStream& theStream, + const std::streampos theUntilPos, + const Handle(Message_ProgressIndicator)& theProgress); + +public: + + //! Callback function to be implemented in descendant. + //! Should create new node with specified coordinates in the target model, and return its ID as integer. + virtual Standard_Integer AddNode (const gp_XYZ& thePnt) = 0; + + //! Callback function to be implemented in descendant. + //! 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; + +}; + +#endif diff --git a/src/StlAPI/FILES b/src/StlAPI/FILES index bcffca9030..4762d58710 100644 --- a/src/StlAPI/FILES +++ b/src/StlAPI/FILES @@ -1,6 +1,5 @@ StlAPI.cxx StlAPI.hxx -StlAPI_ErrorStatus.hxx StlAPI_Reader.cxx StlAPI_Reader.hxx StlAPI_Writer.cxx diff --git a/src/StlAPI/StlAPI.cxx b/src/StlAPI/StlAPI.cxx index 5fe95aff75..e926733a59 100644 --- a/src/StlAPI/StlAPI.cxx +++ b/src/StlAPI/StlAPI.cxx @@ -11,24 +11,32 @@ // Alternatively, this file may be used under the terms of Open CASCADE // commercial license or contractual agreement. - #include + #include #include #include -StlAPI_ErrorStatus StlAPI::Write(const TopoDS_Shape& aShape, - const Standard_CString aFile, - const Standard_Boolean aAsciiMode) +//============================================================================= +//function : Write +//purpose : +//============================================================================= +Standard_Boolean StlAPI::Write (const TopoDS_Shape& theShape, + const Standard_CString theFile, + const Standard_Boolean theAsciiMode) { - StlAPI_Writer writer; - writer.ASCIIMode() = aAsciiMode; - return writer.Write (aShape, aFile); + StlAPI_Writer aWriter; + aWriter.ASCIIMode() = theAsciiMode; + return aWriter.Write (theShape, theFile); } - -void StlAPI::Read(TopoDS_Shape& aShape,const Standard_CString aFile) +//============================================================================= +//function : Read +//purpose : +//============================================================================= +Standard_Boolean StlAPI::Read (TopoDS_Shape& theShape, + const Standard_CString theFile) { - StlAPI_Reader reader; - reader.Read (aShape, aFile); + StlAPI_Reader aReader; + return aReader.Read(theShape, theFile); } diff --git a/src/StlAPI/StlAPI.hxx b/src/StlAPI/StlAPI.hxx index 043b5b9a06..fa26856703 100644 --- a/src/StlAPI/StlAPI.hxx +++ b/src/StlAPI/StlAPI.hxx @@ -17,57 +17,37 @@ #ifndef _StlAPI_HeaderFile #define _StlAPI_HeaderFile +#include #include #include #include - -#include #include #include class TopoDS_Shape; class StlAPI_Writer; class StlAPI_Reader; - //! Offers the API for STL data manipulation. -class StlAPI +class StlAPI { public: DEFINE_STANDARD_ALLOC - //! Convert and write shape to STL format. - //! file is written in binary if aAsciiMode is False - //! otherwise it is written in Ascii (by default) - Standard_EXPORT static StlAPI_ErrorStatus Write (const TopoDS_Shape& aShape, const Standard_CString aFile, const Standard_Boolean aAsciiMode = Standard_True); - - //! Create a shape from a STL format. - Standard_EXPORT static void Read (TopoDS_Shape& aShape, const Standard_CString aFile); - - - - -protected: - - - - - -private: - - - - -friend class StlAPI_Writer; -friend class StlAPI_Reader; + //! File is written in binary if aAsciiMode is False otherwise it is written in Ascii (by default). + Standard_EXPORT static Standard_Boolean Write (const TopoDS_Shape& theShape, + const Standard_CString theFile, + const Standard_Boolean theAsciiMode = Standard_True); + + //! Legacy interface. + //! Read STL file and create a shape composed of triangular faces, one per facet. + //! This approach is very inefficient, especially for large files. + //! Consider reading STL file to Poly_Triangulation object instead (see class RWStl). + Standard_DEPRECATED("This method is very inefficient; see RWStl class for better alternative") + Standard_EXPORT static Standard_Boolean Read (TopoDS_Shape& theShape, + const Standard_CString aFile); }; - - - - - - #endif // _StlAPI_HeaderFile diff --git a/src/StlAPI/StlAPI_ErrorStatus.hxx b/src/StlAPI/StlAPI_ErrorStatus.hxx deleted file mode 100644 index 4d407ca4e5..0000000000 --- a/src/StlAPI/StlAPI_ErrorStatus.hxx +++ /dev/null @@ -1,30 +0,0 @@ -// Created on: 1997-05-13 -// Created by: Fabien REUTER -// Copyright (c) 1997-1999 Matra Datavision -// Copyright (c) 1999-2014 OPEN CASCADE SAS -// -// This file is part of Open CASCADE Technology software library. -// -// This library is free software; you can redistribute it and/or modify it under -// the terms of the GNU Lesser General Public License version 2.1 as published -// by the Free Software Foundation, with special exception defined in the file -// OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT -// distribution for complete text of the license and disclaimer of any warranty. -// -// Alternatively, this file may be used under the terms of Open CASCADE -// commercial license or contractual agreement. - -#ifndef _StlAPI_ErrorStatus_HeaderFile -#define _StlAPI_ErrorStatus_HeaderFile - -//! Set of statuses to indicate a type of the error -//! occurred during data retrieving and writing operations. -enum StlAPI_ErrorStatus -{ -StlAPI_StatusOK, -StlAPI_MeshIsEmpty, -StlAPI_CannotOpenFile, -StlAPI_WriteError -}; - -#endif // _StlAPI_ErrorStatus_HeaderFile diff --git a/src/StlAPI/StlAPI_Reader.cxx b/src/StlAPI/StlAPI_Reader.cxx index 034c05e382..00407cd101 100644 --- a/src/StlAPI/StlAPI_Reader.cxx +++ b/src/StlAPI/StlAPI_Reader.cxx @@ -11,6 +11,7 @@ // Alternatively, this file may be used under the terms of Open CASCADE // commercial license or contractual agreement. +#include #include #include @@ -20,9 +21,6 @@ #include #include #include -#include -#include -#include #include #include #include @@ -31,64 +29,68 @@ #include #include -StlAPI_Reader::StlAPI_Reader() {} - -void StlAPI_Reader::Read(TopoDS_Shape& aShape, const Standard_CString aFileName) +//============================================================================= +//function : Read +//purpose : +//============================================================================= +Standard_Boolean StlAPI_Reader::Read (TopoDS_Shape& theShape, + const Standard_CString theFileName) { - OSD_Path aFile(aFileName); - - Handle(StlMesh_Mesh) aSTLMesh = RWStl::ReadFile(aFile); - Standard_Integer NumberDomains = aSTLMesh->NbDomains(); - Standard_Integer iND; - gp_XYZ p1, p2, p3; - TopoDS_Vertex Vertex1, Vertex2, Vertex3; - TopoDS_Face AktFace; - TopoDS_Wire AktWire; + Handle(Poly_Triangulation) aMesh = RWStl::ReadFile (theFileName); + if (aMesh.IsNull()) + { + return Standard_False; + } + + TopoDS_Vertex aTriVertexes[3]; + TopoDS_Face aFace; + TopoDS_Wire aWire; BRepBuilderAPI_Sewing aSewingTool; - Standard_Real x1, y1, z1; - Standard_Real x2, y2, z2; - Standard_Real x3, y3, z3; - - aSewingTool.Init(1.0e-06,Standard_True); - + aSewingTool.Init (1.0e-06, Standard_True); + TopoDS_Compound aComp; BRep_Builder BuildTool; - BuildTool.MakeCompound( aComp ); + BuildTool.MakeCompound (aComp); - StlMesh_MeshExplorer aMExp (aSTLMesh); - - for (iND=1;iND<=NumberDomains;iND++) + const TColgp_Array1OfPnt& aNodes = aMesh->Nodes(); + const Poly_Array1OfTriangle& aTriangles = aMesh->Triangles(); + for (Standard_Integer aTriIdx = aTriangles.Lower(); + aTriIdx <= aTriangles.Upper(); + ++aTriIdx) { - for (aMExp.InitTriangle (iND); aMExp.MoreTriangle (); aMExp.NextTriangle ()) + const Poly_Triangle& aTriangle = aTriangles(aTriIdx); + + Standard_Integer anId[3]; + aTriangle.Get(anId[0], anId[1], anId[2]); + + const gp_Pnt& aPnt1 = aNodes (anId[0]); + const gp_Pnt& aPnt2 = aNodes (anId[1]); + const gp_Pnt& aPnt3 = aNodes (anId[2]); + if ((!(aPnt1.IsEqual (aPnt2, 0.0))) + && (!(aPnt1.IsEqual (aPnt3, 0.0)))) { - aMExp.TriangleVertices (x1,y1,z1,x2,y2,z2,x3,y3,z3); - p1.SetCoord(x1,y1,z1); - p2.SetCoord(x2,y2,z2); - p3.SetCoord(x3,y3,z3); - - if ((!(p1.IsEqual(p2,0.0))) && (!(p1.IsEqual(p3,0.0)))) + aTriVertexes[0] = BRepBuilderAPI_MakeVertex (aPnt1); + aTriVertexes[1] = BRepBuilderAPI_MakeVertex (aPnt2); + aTriVertexes[2] = BRepBuilderAPI_MakeVertex (aPnt3); + + aWire = BRepBuilderAPI_MakePolygon (aTriVertexes[0], aTriVertexes[1], aTriVertexes[2], Standard_True); + if (!aWire.IsNull()) { - Vertex1 = BRepBuilderAPI_MakeVertex(p1); - Vertex2 = BRepBuilderAPI_MakeVertex(p2); - Vertex3 = BRepBuilderAPI_MakeVertex(p3); - - AktWire = BRepBuilderAPI_MakePolygon( Vertex1, Vertex2, Vertex3, Standard_True); - - if( !AktWire.IsNull()) + aFace = BRepBuilderAPI_MakeFace (aWire); + if (!aFace.IsNull()) { - AktFace = BRepBuilderAPI_MakeFace( AktWire); - if(!AktFace.IsNull()) - BuildTool.Add( aComp, AktFace ); + BuildTool.Add (aComp, aFace); } } } } - aSTLMesh->Clear(); - aSewingTool.Load( aComp ); + aSewingTool.Load (aComp); aSewingTool.Perform(); - aShape = aSewingTool.SewedShape(); - if ( aShape.IsNull() ) - aShape = aComp; + theShape = aSewingTool.SewedShape(); + if (theShape.IsNull()) + { + theShape = aComp; + } + return Standard_True; } - diff --git a/src/StlAPI/StlAPI_Reader.hxx b/src/StlAPI/StlAPI_Reader.hxx index d35833af09..a7b6459e75 100644 --- a/src/StlAPI/StlAPI_Reader.hxx +++ b/src/StlAPI/StlAPI_Reader.hxx @@ -19,44 +19,20 @@ #include #include #include - #include -class TopoDS_Shape; +class TopoDS_Shape; //! Reading from stereolithography format. -class StlAPI_Reader +class StlAPI_Reader { public: - DEFINE_STANDARD_ALLOC - - - Standard_EXPORT StlAPI_Reader(); - - Standard_EXPORT void Read (TopoDS_Shape& aShape, const Standard_CString aFileName); - - - - -protected: - - - - - -private: - - - - + //! Reads STL file to the TopoDS_Shape (each triangle is converted to the face). + //! @return True if reading is successful + Standard_EXPORT Standard_Boolean Read (TopoDS_Shape& theShape, + const Standard_CString theFileName); }; - - - - - - #endif // _StlAPI_Reader_HeaderFile diff --git a/src/StlAPI/StlAPI_Writer.cxx b/src/StlAPI/StlAPI_Writer.cxx index 1b4c6fe5fa..5defbc452b 100644 --- a/src/StlAPI/StlAPI_Writer.cxx +++ b/src/StlAPI/StlAPI_Writer.cxx @@ -11,198 +11,102 @@ // Alternatively, this file may be used under the terms of Open CASCADE // commercial license or contractual agreement. +#include #include #include #include #include #include -#include -#include -#include #include #include #include #include #include +//============================================================================= +//function : StlAPI_Writer +//purpose : +//============================================================================= StlAPI_Writer::StlAPI_Writer() +: myASCIIMode (Standard_True) { - theStlMesh = new StlMesh_Mesh; - theASCIIMode = Standard_True; -} - -Standard_Boolean& StlAPI_Writer::ASCIIMode() -{ - return theASCIIMode; + // } -// Auxiliary tools -namespace +//============================================================================= +//function : Write +//purpose : +//============================================================================= +Standard_Boolean StlAPI_Writer::Write (const TopoDS_Shape& theShape, + const Standard_CString theFileName) { - // Tool to get triangles from triangulation taking into account face - // orientation and location - class TriangleAccessor - { - public: - TriangleAccessor (const TopoDS_Face& aFace) - { - TopLoc_Location aLoc; - myPoly = BRep_Tool::Triangulation (aFace, aLoc); - myTrsf = aLoc.Transformation(); - myNbTriangles = (myPoly.IsNull() ? 0 : myPoly->Triangles().Length()); - myInvert = (aFace.Orientation() == TopAbs_REVERSED); - if (myTrsf.IsNegative()) - myInvert = ! myInvert; - } - - int NbTriangles () const { return myNbTriangles; } + Standard_Integer aNbNodes = 0; + Standard_Integer aNbTriangles = 0; - // get i-th triangle and outward normal - void GetTriangle (int iTri, gp_Vec &theNormal, gp_Pnt &thePnt1, gp_Pnt &thePnt2, gp_Pnt &thePnt3) - { - // get positions of nodes - int iNode1, iNode2, iNode3; - myPoly->Triangles()(iTri).Get (iNode1, iNode2, iNode3); - thePnt1 = myPoly->Nodes()(iNode1); - thePnt2 = myPoly->Nodes()(myInvert ? iNode3 : iNode2); - thePnt3 = myPoly->Nodes()(myInvert ? iNode2 : iNode3); - - // apply transormation if not identity - if (myTrsf.Form() != gp_Identity) - { - thePnt1.Transform (myTrsf); - thePnt2.Transform (myTrsf); - thePnt3.Transform (myTrsf); - } - - // calculate normal - theNormal = (thePnt2.XYZ() - thePnt1.XYZ()) ^ (thePnt3.XYZ() - thePnt1.XYZ()); - Standard_Real aNorm = theNormal.Magnitude(); - if (aNorm > gp::Resolution()) - theNormal /= aNorm; - } - - private: - Handle(Poly_Triangulation) myPoly; - gp_Trsf myTrsf; - int myNbTriangles; - bool myInvert; - }; - - // convert to float and, on big-endian platform, to little-endian representation - inline float convertFloat (Standard_Real aValue) + // calculate total number of the nodes and triangles + for (TopExp_Explorer anExpSF (theShape, TopAbs_FACE); anExpSF.More(); anExpSF.Next()) { -#ifdef OCCT_BINARY_FILE_DO_INVERSE - return OSD_BinaryFile::InverseShortReal ((float)aValue); -#else - return (float)aValue; -#endif + TopLoc_Location aLoc; + Handle(Poly_Triangulation) aTriangulation = BRep_Tool::Triangulation (TopoDS::Face (anExpSF.Current()), aLoc); + aNbNodes += aTriangulation->NbNodes(); + aNbTriangles += aTriangulation->NbTriangles(); } -} -StlAPI_ErrorStatus StlAPI_Writer::Write(const TopoDS_Shape& theShape, const Standard_CString theFileName) -{ - // open file - FILE* aFile = OSD_OpenFile (theFileName, "wb"); - if (!aFile) - return StlAPI_CannotOpenFile; + // create temporary triangulation + Handle(Poly_Triangulation) aMesh = new Poly_Triangulation (aNbNodes, aNbTriangles, Standard_False); - // write - if (theASCIIMode) + // fill temporary triangulation + Standard_Integer aNodeOffset = 0; + Standard_Integer aTriangleOffet = 0; + for (TopExp_Explorer anExpSF (theShape, TopAbs_FACE); anExpSF.More(); anExpSF.Next()) { - // header - Fprintf (aFile, "solid shape, STL ascii file, created with Open CASCADE Technology\n"); + TopLoc_Location aLoc; + Handle(Poly_Triangulation) aTriangulation = BRep_Tool::Triangulation (TopoDS::Face (anExpSF.Current()), aLoc); - // facets - for (TopExp_Explorer exp (theShape, TopAbs_FACE); exp.More(); exp.Next()) - { - TriangleAccessor aTool (TopoDS::Face (exp.Current())); - for (int iTri = 1; iTri <= aTool.NbTriangles(); iTri++) - { - gp_Vec aNorm; - gp_Pnt aPnt1, aPnt2, aPnt3; - aTool.GetTriangle (iTri, aNorm, aPnt1, aPnt2, aPnt3); - - Fprintf (aFile, - " facet normal %12e %12e %12e\n" - " outer loop\n" - " vertex %12e %12e %12e\n" - " vertex %12e %12e %12e\n" - " vertex %12e %12e %12e\n" - " endloop\n" - " endfacet\n", - aNorm.X(), aNorm.Y(), aNorm.Z(), - aPnt1.X(), aPnt1.Y(), aPnt1.Z(), - aPnt2.X(), aPnt2.Y(), aPnt2.Z(), - aPnt3.X(), aPnt3.Y(), aPnt3.Z()); - } - } - - // footer - Fprintf (aFile, "endsolid shape\n"); - } - else - { - // header block (meaningless 80 bytes) - Fprintf (aFile, "%-80.80s", "STL binary file, created with Open CASCADE Technology"); + const TColgp_Array1OfPnt& aNodes = aTriangulation->Nodes(); + const Poly_Array1OfTriangle& aTriangles = aTriangulation->Triangles(); - // number of facets - int32_t aNbTri = 0; - for (TopExp_Explorer exp (theShape, TopAbs_FACE); exp.More(); exp.Next()) + // copy nodes + gp_Trsf aTrsf = aLoc.Transformation(); + for (Standard_Integer aNodeIter = aNodes.Lower(); aNodeIter <= aNodes.Upper(); ++aNodeIter) { - TopLoc_Location aLoc; - Handle(Poly_Triangulation) aPoly = - BRep_Tool::Triangulation (TopoDS::Face (exp.Current()), aLoc); - if (! aPoly.IsNull()) - aNbTri += aPoly->NbTriangles(); + gp_Pnt aPnt = aNodes (aNodeIter); + aPnt.Transform (aTrsf); + aMesh->ChangeNode (aNodeIter + aNodeOffset) = aPnt; } - // suppose that number of triangles must be little endian... -#ifdef OCCT_BINARY_FILE_DO_INVERSE - aNbTri = OSD_BinaryFile::InverseInteger (aNbTri); -#endif - fwrite (&aNbTri, sizeof(int32_t), 1, aFile); - // facets - struct Facet { - float nx, ny, nz; - float x1, y1, z1; - float x2, y2, z2; - float x3, y3, z3; - uint16_t dummy; - } f; - f.dummy = 0; - for (TopExp_Explorer exp (theShape, TopAbs_FACE); exp.More(); exp.Next()) + // copy triangles + const TopAbs_Orientation anOrientation = anExpSF.Current().Orientation(); + for (Standard_Integer aTriIter = aTriangles.Lower(); aTriIter <= aTriangles.Upper(); ++aTriIter) { - TriangleAccessor aTool (TopoDS::Face (exp.Current())); - for (int iTri = 1; iTri <= aTool.NbTriangles(); iTri++) - { - gp_Vec aNorm; - gp_Pnt aPnt1, aPnt2, aPnt3; - aTool.GetTriangle (iTri, aNorm, aPnt1, aPnt2, aPnt3); - - f.nx = convertFloat (aNorm.X()); - f.ny = convertFloat (aNorm.Y()); - f.nz = convertFloat (aNorm.Z()); + Poly_Triangle aTri = aTriangles (aTriIter); - f.x1 = convertFloat (aPnt1.X()); - f.y1 = convertFloat (aPnt1.Y()); - f.z1 = convertFloat (aPnt1.Z()); - - f.x2 = convertFloat (aPnt2.X()); - f.y2 = convertFloat (aPnt2.Y()); - f.z2 = convertFloat (aPnt2.Z()); + Standard_Integer anId[3]; + aTri.Get (anId[0], anId[1], anId[2]); + if (anOrientation == TopAbs_REVERSED) + { + // Swap 1, 2. + Standard_Integer aTmpIdx = anId[1]; + anId[1] = anId[2]; + anId[2] = aTmpIdx; + } - f.x3 = convertFloat (aPnt3.X()); - f.y3 = convertFloat (aPnt3.Y()); - f.z3 = convertFloat (aPnt3.Z()); + // Update nodes according to the offset. + anId[0] += aNodeOffset; + anId[1] += aNodeOffset; + anId[2] += aNodeOffset; - fwrite (&f, 50 /* 50 bytes per facet */, 1, aFile); - } + aTri.Set (anId[0], anId[1], anId[2]); + aMesh->ChangeTriangle (aTriIter + aTriangleOffet) = aTri; } + + aNodeOffset += aNodes.Size(); + aTriangleOffet += aTriangles.Size(); } - fclose (aFile); - return ferror(aFile) ? StlAPI_WriteError : StlAPI_StatusOK; + OSD_Path aPath (theFileName); + return myASCIIMode + ? RWStl::WriteAscii (aMesh, aPath) + : RWStl::WriteBinary (aMesh, aPath); } - diff --git a/src/StlAPI/StlAPI_Writer.hxx b/src/StlAPI/StlAPI_Writer.hxx index 4238ca017d..257212e4dc 100644 --- a/src/StlAPI/StlAPI_Writer.hxx +++ b/src/StlAPI/StlAPI_Writer.hxx @@ -16,66 +16,39 @@ #ifndef _StlAPI_Writer_HeaderFile #define _StlAPI_Writer_HeaderFile +#include #include #include #include - #include -#include #include -class StlMesh_Mesh; -class TopoDS_Shape; +class TopoDS_Shape; //! This class creates and writes -//! STL files from Open CASCADE shapes. An STL file can be -//! written to an existing STL file or to a new one.. -class StlAPI_Writer +//! STL files from Open CASCADE shapes. An STL file can be written to an existing STL file or to a new one. +class StlAPI_Writer { public: DEFINE_STANDARD_ALLOC - - //! Creates a writer object with - //! default parameters: ASCIIMode. + //! Creates a writer object with default parameters: ASCIIMode. Standard_EXPORT StlAPI_Writer(); - - //! Returns the address to the - //! flag defining the 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 generated - //! file is an ASCII file. If the mode returns False, the - //! generated file is a binary file. - Standard_EXPORT Standard_Boolean& ASCIIMode(); - - //! Converts a given shape to STL format and writes it to file with a given filename. - //! \return the error state. - Standard_EXPORT StlAPI_ErrorStatus Write (const TopoDS_Shape& aShape, const Standard_CString aFileName); - - - - -protected: - - + //! Returns the address to the flag defining the 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 generated file is an ASCII file. + //! If the mode returns False, the generated file is a binary file. + Standard_Boolean& ASCIIMode() { return myASCIIMode; } + //! Converts a given shape to STL format and writes it to file with a given filename. + //! \return the error state. + Standard_EXPORT Standard_Boolean Write (const TopoDS_Shape& theShape, + const Standard_CString theFileName); private: - - - - Standard_Boolean theASCIIMode; - Handle(StlMesh_Mesh) theStlMesh; - - + Standard_Boolean myASCIIMode; }; - - - - - - #endif // _StlAPI_Writer_HeaderFile diff --git a/src/StlMesh/FILES b/src/StlMesh/FILES deleted file mode 100644 index 8a770c8dae..0000000000 --- a/src/StlMesh/FILES +++ /dev/null @@ -1,16 +0,0 @@ -StlMesh.cxx -StlMesh.hxx -StlMesh_Mesh.cxx -StlMesh_Mesh.hxx -StlMesh_Mesh.lxx -StlMesh_MeshDomain.cxx -StlMesh_MeshDomain.hxx -StlMesh_MeshDomain.lxx -StlMesh_MeshExplorer.cxx -StlMesh_MeshExplorer.hxx -StlMesh_MeshExplorer.lxx -StlMesh_MeshTriangle.cxx -StlMesh_MeshTriangle.hxx -StlMesh_SequenceOfMesh.hxx -StlMesh_SequenceOfMeshDomain.hxx -StlMesh_SequenceOfMeshTriangle.hxx diff --git a/src/StlMesh/StlMesh.cxx b/src/StlMesh/StlMesh.cxx deleted file mode 100644 index 266d458a12..0000000000 --- a/src/StlMesh/StlMesh.cxx +++ /dev/null @@ -1,78 +0,0 @@ -// Created on: 1996-06-21 -// Created by: Bruno TACCI -// Copyright (c) 1996-1999 Matra Datavision -// Copyright (c) 1999-2014 OPEN CASCADE SAS -// -// This file is part of Open CASCADE Technology software library. -// -// This library is free software; you can redistribute it and/or modify it under -// the terms of the GNU Lesser General Public License version 2.1 as published -// by the Free Software Foundation, with special exception defined in the file -// OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT -// distribution for complete text of the license and disclaimer of any warranty. -// -// Alternatively, this file may be used under the terms of Open CASCADE -// commercial license or contractual agreement. - - -#include -#include -#include -#include -#include - -//======================================================================= -//function : Merge -//purpose : -//======================================================================= -Handle(StlMesh_Mesh) StlMesh::Merge(const Handle(StlMesh_Mesh)& mesh1, const Handle(StlMesh_Mesh)& mesh2) -{ - Handle(StlMesh_Mesh) mergeMesh = new StlMesh_Mesh; - StlMesh_SequenceOfMeshTriangle aSeqOfTriangle; - TColgp_SequenceOfXYZ aSeqOfVertex; - Standard_Real xn,yn,zn; - Standard_Integer v1,v2,v3; - - // Chargement de mesh1 dans mergeMesh - // Boucle sur les domaines puis sur les triangles - - Standard_Integer idom; - for (idom = 1; idom <= mesh1->NbDomains(); idom++) { - aSeqOfTriangle = mesh1->Triangles(idom); - aSeqOfVertex = mesh1->Vertices(idom); - mergeMesh->AddDomain(mesh1->Deflection(idom)); - - for (Standard_Integer itri = 1; itri <= mesh1->NbTriangles(idom); itri++) { - const Handle(StlMesh_MeshTriangle) aTrian = aSeqOfTriangle.Value(itri); - aTrian->GetVertexAndOrientation(v1,v2,v3,xn,yn,zn); - mergeMesh->AddTriangle(v1,v2,v3,xn,yn,zn); - } - - for (Standard_Integer iver = 1; iver <= mesh1->NbVertices(idom); iver++) { - mergeMesh->AddVertex(aSeqOfVertex.Value(iver).X(), - aSeqOfVertex.Value(iver).Y(), - aSeqOfVertex.Value(iver).Z()); - } - - } - // Idem avec mesh2 - - for (idom = 1; idom <= mesh2->NbDomains(); idom++) { - aSeqOfTriangle = mesh2->Triangles(idom); - aSeqOfVertex = mesh2->Vertices(idom); - mergeMesh->AddDomain(mesh2->Deflection(idom)); - - for (Standard_Integer itri = 1; itri <= mesh2->NbTriangles(idom); itri++) { - const Handle(StlMesh_MeshTriangle) aTrian = aSeqOfTriangle.Value(itri); - aTrian->GetVertexAndOrientation(v1,v2,v3,xn,yn,zn); - mergeMesh->AddTriangle(v1,v2,v3,xn,yn,zn); - } - - for (Standard_Integer iver = 1; iver <= mesh2->NbVertices(idom); iver++) { - mergeMesh->AddVertex(aSeqOfVertex.Value(iver).X(), - aSeqOfVertex.Value(iver).Y(), - aSeqOfVertex.Value(iver).Z()); - } - } - return mergeMesh; -} diff --git a/src/StlMesh/StlMesh.hxx b/src/StlMesh/StlMesh.hxx deleted file mode 100644 index 8f6765ed15..0000000000 --- a/src/StlMesh/StlMesh.hxx +++ /dev/null @@ -1,73 +0,0 @@ -// Created on: 1995-09-21 -// Created by: Philippe GIRODENGO -// Copyright (c) 1995-1999 Matra Datavision -// Copyright (c) 1999-2014 OPEN CASCADE SAS -// -// This file is part of Open CASCADE Technology software library. -// -// This library is free software; you can redistribute it and/or modify it under -// the terms of the GNU Lesser General Public License version 2.1 as published -// by the Free Software Foundation, with special exception defined in the file -// OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT -// distribution for complete text of the license and disclaimer of any warranty. -// -// Alternatively, this file may be used under the terms of Open CASCADE -// commercial license or contractual agreement. - -#ifndef _StlMesh_HeaderFile -#define _StlMesh_HeaderFile - -#include -#include -#include - -class StlMesh_Mesh; -class StlMesh_Mesh; -class StlMesh_MeshExplorer; -class StlMesh_MeshDomain; -class StlMesh_MeshTriangle; - - -//! Implements a basic mesh data-structure for the -//! needs of the application fast prototyping. -class StlMesh -{ -public: - - DEFINE_STANDARD_ALLOC - - - //! Sequence of meshes - //! Make a merge of two Mesh and returns a new Mesh. - //! Very useful if you want to merge partMesh and CheckSurfaceMesh - //! for example - Standard_EXPORT static Handle(StlMesh_Mesh) Merge (const Handle(StlMesh_Mesh)& mesh1, const Handle(StlMesh_Mesh)& mesh2); - - - - -protected: - - - - - -private: - - - - -friend class StlMesh_Mesh; -friend class StlMesh_MeshExplorer; -friend class StlMesh_MeshDomain; -friend class StlMesh_MeshTriangle; - -}; - - - - - - - -#endif // _StlMesh_HeaderFile diff --git a/src/StlMesh/StlMesh_Mesh.cxx b/src/StlMesh/StlMesh_Mesh.cxx deleted file mode 100644 index 2310e12c15..0000000000 --- a/src/StlMesh/StlMesh_Mesh.cxx +++ /dev/null @@ -1,181 +0,0 @@ -// Created on: 1995-09-25 -// Created by: Philippe GIRODENGO -// Copyright (c) 1995-1999 Matra Datavision -// Copyright (c) 1999-2014 OPEN CASCADE SAS -// -// This file is part of Open CASCADE Technology software library. -// -// This library is free software; you can redistribute it and/or modify it under -// the terms of the GNU Lesser General Public License version 2.1 as published -// by the Free Software Foundation, with special exception defined in the file -// OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT -// distribution for complete text of the license and disclaimer of any warranty. -// -// Alternatively, this file may be used under the terms of Open CASCADE -// commercial license or contractual agreement. - -//======================================================================= - -#include -#include -#include -#include -#include -#include -#include -#include - -IMPLEMENT_STANDARD_RTTIEXT(StlMesh_Mesh,Standard_Transient) - -//======================================================================= -//function : StlMesh_Mesh -//design : -//warning : -//======================================================================= -StlMesh_Mesh::StlMesh_Mesh() -: nbTriangles (0), nbVertices (0), xyzmax (-(Precision::Infinite()), -(Precision::Infinite()), -(Precision::Infinite())), xyzmin (Precision::Infinite(), Precision::Infinite(), Precision::Infinite()) -{ } - -//======================================================================= -//function : AddDomain -//design : -//warning : -//======================================================================= - -void StlMesh_Mesh::AddDomain() -{ - Handle(StlMesh_MeshDomain) MD = new StlMesh_MeshDomain; - domains.Append (MD); -} - -//======================================================================= -//function : AddDomain -//design : -//warning : -//======================================================================= - -void StlMesh_Mesh::AddDomain(const Standard_Real Deflection) -{ - Handle(StlMesh_MeshDomain) MD = new StlMesh_MeshDomain (Deflection); - domains.Append (MD); -} - -//======================================================================= -//function : AddTriangle -//design : -//warning : -//======================================================================= - -Standard_Integer StlMesh_Mesh::AddTriangle(const Standard_Integer V1, const Standard_Integer V2, - const Standard_Integer V3, const Standard_Real Xn, - const Standard_Real Yn, const Standard_Real Zn) -{ - nbTriangles++; - return (domains.Last())->AddTriangle (V1, V2, V3, Xn, Yn, Zn); -} - -//======================================================================= -//function : AddVertex -//design : -//warning : -//======================================================================= - -Standard_Integer StlMesh_Mesh::AddVertex(const Standard_Real X, const Standard_Real Y, const Standard_Real Z) -{ - nbVertices++; - if (X > xyzmax.X()) xyzmax.SetX (X); - if (Y > xyzmax.Y()) xyzmax.SetY (Y); - if (Z > xyzmax.Z()) xyzmax.SetZ (Z); - if (X < xyzmin.X()) xyzmin.SetX (X); - if (Y < xyzmin.Y()) xyzmin.SetY (Y); - if (Z < xyzmin.Z()) xyzmin.SetZ (Z); - - return (domains.Last())->AddVertex (X, Y, Z); -} - -//======================================================================= -//function : AddOnlyNewVertex -//design : -//warning : -//======================================================================= - -Standard_Integer StlMesh_Mesh::AddOnlyNewVertex(const Standard_Real X, const Standard_Real Y, const Standard_Real Z) -{ - Standard_Boolean IsNew = Standard_True; - Standard_Integer VIndex = (domains.Last())->AddOnlyNewVertex (X, Y, Z, IsNew); - if (IsNew) nbVertices++; - return VIndex; -} - -//======================================================================= -//function : Bounds -//design : -//warning : -//======================================================================= - -void StlMesh_Mesh::Bounds(gp_XYZ& XYZmax, gp_XYZ& XYZmin) const -{ - XYZmax = xyzmax; - XYZmin = xyzmin; -} - -//======================================================================= -//function : Clear -//design : -//warning : -//======================================================================= - -void StlMesh_Mesh::Clear() -{ - nbTriangles = 0; - nbVertices = 0; - xyzmax.SetCoord(-(Precision::Infinite()),-(Precision::Infinite()),-(Precision::Infinite())); - xyzmin.SetCoord(Precision::Infinite(),Precision::Infinite(),Precision::Infinite()); - domains.Clear (); -} - -//======================================================================= -//function : Deflection -//design : -//warning : -//======================================================================= - -Standard_Real StlMesh_Mesh::Deflection(const Standard_Integer DomainIndex) const -{return (domains.Value (DomainIndex))->Deflection ();} - -//======================================================================= -//function : NbTriangles -//design : -//warning : -//======================================================================= - -Standard_Integer StlMesh_Mesh::NbTriangles(const Standard_Integer DomainIndex) const -{ return (domains.Value(DomainIndex))->NbTriangles ();} - -//======================================================================= -//function : NbVertices -//design : -//warning : -//======================================================================= - -Standard_Integer StlMesh_Mesh::NbVertices(const Standard_Integer DomainIndex) const -{ return (domains.Value(DomainIndex))->NbVertices ();} - -//======================================================================= -//function : Triangles -//design : -//warning : -//======================================================================= - -const StlMesh_SequenceOfMeshTriangle& StlMesh_Mesh::Triangles(const Standard_Integer DomainIndex) const -{ return (domains.Value (DomainIndex))->Triangles ();} - -//======================================================================= -//function : Vertices -//design : -//warning : -//======================================================================= - -const TColgp_SequenceOfXYZ& StlMesh_Mesh::Vertices(const Standard_Integer DomainIndex) const -{ return (domains.Value (DomainIndex))->Vertices ();} - diff --git a/src/StlMesh/StlMesh_Mesh.hxx b/src/StlMesh/StlMesh_Mesh.hxx deleted file mode 100644 index 9706f0e26a..0000000000 --- a/src/StlMesh/StlMesh_Mesh.hxx +++ /dev/null @@ -1,160 +0,0 @@ -// Created on: 1995-09-21 -// Created by: Philippe GIRODENGO -// Copyright (c) 1995-1999 Matra Datavision -// Copyright (c) 1999-2014 OPEN CASCADE SAS -// -// This file is part of Open CASCADE Technology software library. -// -// This library is free software; you can redistribute it and/or modify it under -// the terms of the GNU Lesser General Public License version 2.1 as published -// by the Free Software Foundation, with special exception defined in the file -// OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT -// distribution for complete text of the license and disclaimer of any warranty. -// -// Alternatively, this file may be used under the terms of Open CASCADE -// commercial license or contractual agreement. - -#ifndef _StlMesh_Mesh_HeaderFile -#define _StlMesh_Mesh_HeaderFile - -#include -#include - -#include -#include -#include -#include -#include -#include -#include -#include -class Standard_NegativeValue; -class Standard_NullValue; -class Standard_NoSuchObject; -class gp_XYZ; - - -class StlMesh_Mesh; -DEFINE_STANDARD_HANDLE(StlMesh_Mesh, Standard_Transient) - -//! Mesh definition. The mesh contains one or several -//! domains. Each mesh domain contains a set of -//! triangles. Each domain can have its own deflection -//! value. -class StlMesh_Mesh : public Standard_Transient -{ - -public: - - - //! Creates an empty mesh. - Standard_EXPORT StlMesh_Mesh(); - - //! Adds a new mesh domain. The mesh deflection is - //! defaulted to Confusion from package Precision. - Standard_EXPORT virtual void AddDomain(); - - //! Adds a new mesh domain. - //! Raised if the deflection is lower than zero - //! Raised if the deflection is lower than Confusion - //! from package Precision - Standard_EXPORT virtual void AddDomain (const Standard_Real Deflection); - - //! Build a triangle with the triplet of vertices (V1, - //! V2, V3). This triplet defines the indexes of the - //! vertex in the current domain The coordinates Xn, - //! Yn, Zn defines the normal direction to the - //! triangle. Returns the range of the triangle in - //! the current domain. - Standard_EXPORT virtual Standard_Integer AddTriangle (const Standard_Integer V1, const Standard_Integer V2, const Standard_Integer V3, const Standard_Real Xn, const Standard_Real Yn, const Standard_Real Zn); - - //! Returns the range of the vertex in the current - //! domain. - Standard_EXPORT virtual Standard_Integer AddVertex (const Standard_Real X, const Standard_Real Y, const Standard_Real Z); - - //! Returns the range of the vertex in the current - //! domain. The current vertex is not inserted in the - //! mesh if it already exist. - Standard_EXPORT virtual Standard_Integer AddOnlyNewVertex (const Standard_Real X, const Standard_Real Y, const Standard_Real Z); - - //! Each vertex of the mesh verifies the following - //! relations : - //! XYZMin.X() <= X <= XYZMax.X() - //! XYZMin.Y() <= Y <= XYZMax.y() - //! XYZMin.Z() <= Z <= XYZMax.Z() - Standard_EXPORT virtual void Bounds (gp_XYZ& XYZmax, gp_XYZ& XYZmin) const; - - Standard_EXPORT virtual void Clear(); - - //! Returns the deflection of the mesh of the domain - //! of range . - //! Raised if is lower than 1 or greater - //! than the number of domains. - Standard_EXPORT virtual Standard_Real Deflection (const Standard_Integer DomainIndex) const; - - virtual Standard_Boolean IsEmpty() const; - - //! Number of domains in the mesh. - virtual Standard_Integer NbDomains() const; - - //! Cumulative Number of triangles in the mesh. - Standard_Integer NbTriangles() const; - - //! Number of triangles in the domain of range - //! . - //! Raised if is lower than 1 or greater - //! than the number of domains. - Standard_EXPORT virtual Standard_Integer NbTriangles (const Standard_Integer DomainIndex) const; - - //! Cumulative Number of vertices in the mesh. - virtual Standard_Integer NbVertices() const; - - //! Number of vertices in the domain of range - //! . - //! Raised if is lower than 1 or greater - //! than the number of domains. - Standard_EXPORT virtual Standard_Integer NbVertices (const Standard_Integer DomainIndex) const; - - //! Returns the set of triangle of the mesh domain of range - //! . - //! Raised if is lower than 1 or greater - //! than the number of domains. - Standard_EXPORT virtual const StlMesh_SequenceOfMeshTriangle& Triangles (const Standard_Integer DomainIndex = 1) const; - - //! Returns the coordinates of the vertices of the - //! mesh domain of range . {XV1, YV1, - //! ZV1, XV2, YV2, ZV2, XV3,.....} - //! Raised if is lower than 1 or greater - //! than the number of domains. - Standard_EXPORT virtual const TColgp_SequenceOfXYZ& Vertices (const Standard_Integer DomainIndex = 1) const; - - - - - DEFINE_STANDARD_RTTIEXT(StlMesh_Mesh,Standard_Transient) - -protected: - - - Standard_Integer nbTriangles; - Standard_Integer nbVertices; - StlMesh_SequenceOfMeshDomain domains; - gp_XYZ xyzmax; - gp_XYZ xyzmin; - - -private: - - - - -}; - - -#include - - - - - -#endif // _StlMesh_Mesh_HeaderFile diff --git a/src/StlMesh/StlMesh_Mesh.lxx b/src/StlMesh/StlMesh_Mesh.lxx deleted file mode 100644 index bbb12a2d98..0000000000 --- a/src/StlMesh/StlMesh_Mesh.lxx +++ /dev/null @@ -1,61 +0,0 @@ -// Created on: 1995-09-25 -// Created by: Philippe GIRODENGO -// Copyright (c) 1995-1999 Matra Datavision -// Copyright (c) 1999-2014 OPEN CASCADE SAS -// -// This file is part of Open CASCADE Technology software library. -// -// This library is free software; you can redistribute it and/or modify it under -// the terms of the GNU Lesser General Public License version 2.1 as published -// by the Free Software Foundation, with special exception defined in the file -// OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT -// distribution for complete text of the license and disclaimer of any warranty. -// -// Alternatively, this file may be used under the terms of Open CASCADE -// commercial license or contractual agreement. - -//======================================================================= -//======================================================================= -//function : IsEmpty -//design : -//warning : -//======================================================================= - -inline Standard_Boolean StlMesh_Mesh::IsEmpty() const -{return domains.IsEmpty ();} - -//======================================================================= -//function : NbDomains -//design : -//warning : -//======================================================================= - -inline Standard_Integer StlMesh_Mesh::NbDomains() const -{ return domains.Length ();} - -//======================================================================= -//function : NbTriangles -//design : -//warning : -//======================================================================= - -inline Standard_Integer StlMesh_Mesh::NbTriangles() const -{return nbTriangles;} - -//======================================================================= -//function : NbVertices -//design : -//warning : -//======================================================================= - -inline Standard_Integer StlMesh_Mesh::NbVertices() const -{return nbVertices;} - - - - - - - - - diff --git a/src/StlMesh/StlMesh_MeshDomain.cxx b/src/StlMesh/StlMesh_MeshDomain.cxx deleted file mode 100644 index 3804272e9e..0000000000 --- a/src/StlMesh/StlMesh_MeshDomain.cxx +++ /dev/null @@ -1,101 +0,0 @@ -// Created on: 1995-09-25 -// Created by: Philippe GIRODENGO -// Copyright (c) 1995-1999 Matra Datavision -// Copyright (c) 1999-2014 OPEN CASCADE SAS -// -// This file is part of Open CASCADE Technology software library. -// -// This library is free software; you can redistribute it and/or modify it under -// the terms of the GNU Lesser General Public License version 2.1 as published -// by the Free Software Foundation, with special exception defined in the file -// OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT -// distribution for complete text of the license and disclaimer of any warranty. -// -// Alternatively, this file may be used under the terms of Open CASCADE -// commercial license or contractual agreement. - -//======================================================================= - -#include -#include -#include -#include -#include -#include -#include - -IMPLEMENT_STANDARD_RTTIEXT(StlMesh_MeshDomain,Standard_Transient) - -//======================================================================= -//function : StlMesh_MeshDomain -//design : -//warning : -//======================================================================= -StlMesh_MeshDomain::StlMesh_MeshDomain() : deflection (Precision::Confusion ()), nbVertices (0), nbTriangles (0) -{ -} - - -//======================================================================= -//function : StlMesh_MeshDomain -//design : -//warning : -//======================================================================= - -StlMesh_MeshDomain::StlMesh_MeshDomain(const Standard_Real Deflection) - : deflection (Deflection), nbVertices (0), nbTriangles (0) { } - - -//======================================================================= -//function : AddTriangle -//design : -//warning : -//======================================================================= - - Standard_Integer StlMesh_MeshDomain::AddTriangle(const Standard_Integer V1, - const Standard_Integer V2, const Standard_Integer V3, - const Standard_Real Xn, const Standard_Real Yn, - const Standard_Real Zn) -{ - const Handle (StlMesh_MeshTriangle) tri = new StlMesh_MeshTriangle (V1, V2, V3, Xn, Yn, Zn); - trianglesVertex.Append (tri); - nbTriangles++; - return nbTriangles; -} - -//======================================================================= -//function : AddVertex -//design : -//warning : -//======================================================================= - -Standard_Integer StlMesh_MeshDomain::AddVertex(const Standard_Real X, const Standard_Real Y, const Standard_Real Z) -{ - gp_XYZ Vx (X, Y, Z); - vertexCoords.Append (Vx); - nbVertices++; - return nbVertices; -} - -//======================================================================= -//function : AddOnlyNewVertex -//design : Adds the vertex only if X and Y and Z doesn`t already exists. -//======================================================================= - -Standard_Integer StlMesh_MeshDomain::AddOnlyNewVertex(const Standard_Real X, - const Standard_Real Y, - const Standard_Real Z, - Standard_Boolean& IsNew) -{ - gp_XYZ Vx (X, Y, Z); - IsNew = Standard_True; - vertexCoords.Append (Vx); - nbVertices++; - return nbVertices; -} - - - - - - diff --git a/src/StlMesh/StlMesh_MeshDomain.hxx b/src/StlMesh/StlMesh_MeshDomain.hxx deleted file mode 100644 index cad6948116..0000000000 --- a/src/StlMesh/StlMesh_MeshDomain.hxx +++ /dev/null @@ -1,117 +0,0 @@ -// Created on: 1995-09-21 -// Created by: Philippe GIRODENGO -// Copyright (c) 1995-1999 Matra Datavision -// Copyright (c) 1999-2014 OPEN CASCADE SAS -// -// This file is part of Open CASCADE Technology software library. -// -// This library is free software; you can redistribute it and/or modify it under -// the terms of the GNU Lesser General Public License version 2.1 as published -// by the Free Software Foundation, with special exception defined in the file -// OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT -// distribution for complete text of the license and disclaimer of any warranty. -// -// Alternatively, this file may be used under the terms of Open CASCADE -// commercial license or contractual agreement. - -#ifndef _StlMesh_MeshDomain_HeaderFile -#define _StlMesh_MeshDomain_HeaderFile - -#include -#include - -#include -#include -#include -#include -#include -#include -class Standard_NegativeValue; -class Standard_NullValue; - - -class StlMesh_MeshDomain; -DEFINE_STANDARD_HANDLE(StlMesh_MeshDomain, Standard_Transient) - -//! A mesh domain is a set of triangles defined with -//! three geometric vertices and a given orientation. -//! The mesh domain has its own deflection. -//! Internal class used to classify the triangles of each domain. -class StlMesh_MeshDomain : public Standard_Transient -{ - -public: - - - //! The mesh deflection is defaulted to Confusion from - //! package Precision. - Standard_EXPORT StlMesh_MeshDomain(); - - //! Raised if the deflection is lower than zero - //! Raised if the deflection is lower than Confusion - //! from package Precision - Standard_EXPORT StlMesh_MeshDomain(const Standard_Real Deflection); - - //! Build a triangle with the triplet of vertices (V1, - //! V2, V3). This triplet defines the indexes of the - //! vertex in the current domain The coordinates Xn, - //! Yn, Zn defines the normal direction to the - //! triangle. Returns the range of the triangle in - //! the current domain. - Standard_EXPORT virtual Standard_Integer AddTriangle (const Standard_Integer V1, const Standard_Integer V2, const Standard_Integer V3, const Standard_Real Xn, const Standard_Real Yn, const Standard_Real Zn); - - //! Returns the range of the vertex in the current - //! domain. - Standard_EXPORT virtual Standard_Integer AddVertex (const Standard_Real X, const Standard_Real Y, const Standard_Real Z); - - //! Returns the range of the vertex in the current - //! domain. The current vertex is not inserted in the - //! mesh if it already exist. - Standard_EXPORT virtual Standard_Integer AddOnlyNewVertex (const Standard_Real X, const Standard_Real Y, const Standard_Real Z, Standard_Boolean& IsNew); - - virtual Standard_Real Deflection() const; - - //! Number of triangles in the mesh. - virtual Standard_Integer NbTriangles() const; - - //! Number of vertices in the mesh. - virtual Standard_Integer NbVertices() const; - - //! Returns the set of triangles of the current mesh domain - virtual const StlMesh_SequenceOfMeshTriangle& Triangles() const; - - //! Returns the coordinates of the vertices of the - //! mesh domain of range . {XV1, YV1, - //! ZV1, XV2, YV2, ZV2, XV3,.....} - virtual const TColgp_SequenceOfXYZ& Vertices() const; - - - - - DEFINE_STANDARD_RTTIEXT(StlMesh_MeshDomain,Standard_Transient) - -protected: - - - - -private: - - - Standard_Real deflection; - Standard_Integer nbVertices; - Standard_Integer nbTriangles; - TColgp_SequenceOfXYZ vertexCoords; - StlMesh_SequenceOfMeshTriangle trianglesVertex; - - -}; - - -#include - - - - - -#endif // _StlMesh_MeshDomain_HeaderFile diff --git a/src/StlMesh/StlMesh_MeshDomain.lxx b/src/StlMesh/StlMesh_MeshDomain.lxx deleted file mode 100644 index 906d17dc7f..0000000000 --- a/src/StlMesh/StlMesh_MeshDomain.lxx +++ /dev/null @@ -1,63 +0,0 @@ -// Created on: 1995-09-25 -// Created by: Philippe GIRODENGO -// Copyright (c) 1995-1999 Matra Datavision -// Copyright (c) 1999-2014 OPEN CASCADE SAS -// -// This file is part of Open CASCADE Technology software library. -// -// This library is free software; you can redistribute it and/or modify it under -// the terms of the GNU Lesser General Public License version 2.1 as published -// by the Free Software Foundation, with special exception defined in the file -// OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT -// distribution for complete text of the license and disclaimer of any warranty. -// -// Alternatively, this file may be used under the terms of Open CASCADE -// commercial license or contractual agreement. - -//======================================================================= - -//======================================================================= -//function : Deflection -//design : -//warning : -//======================================================================= - -inline Standard_Real StlMesh_MeshDomain::Deflection() const -{ return deflection; } - -//======================================================================= -//function : NbTriangles -//design : -//warning : -//======================================================================= - -inline Standard_Integer StlMesh_MeshDomain::NbTriangles() const -{ return nbTriangles; } - -//======================================================================= -//function : NbVertices -//design : -//warning : -//======================================================================= - -inline Standard_Integer StlMesh_MeshDomain::NbVertices() const -{ return nbVertices; } - -//======================================================================= -//function : Triangles -//design : -//warning : -//======================================================================= - -inline const StlMesh_SequenceOfMeshTriangle& StlMesh_MeshDomain::Triangles() const -{ return trianglesVertex; } - -//======================================================================= -//function : Vertices -//design : -//warning : -//======================================================================= - - inline const TColgp_SequenceOfXYZ& StlMesh_MeshDomain::Vertices() const -{ return vertexCoords; } - diff --git a/src/StlMesh/StlMesh_MeshExplorer.cxx b/src/StlMesh/StlMesh_MeshExplorer.cxx deleted file mode 100644 index 56e48e97cf..0000000000 --- a/src/StlMesh/StlMesh_MeshExplorer.cxx +++ /dev/null @@ -1,121 +0,0 @@ -// Created on: 1995-09-25 -// Created by: Philippe GIRODENGO -// Copyright (c) 1995-1999 Matra Datavision -// Copyright (c) 1999-2014 OPEN CASCADE SAS -// -// This file is part of Open CASCADE Technology software library. -// -// This library is free software; you can redistribute it and/or modify it under -// the terms of the GNU Lesser General Public License version 2.1 as published -// by the Free Software Foundation, with special exception defined in the file -// OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT -// distribution for complete text of the license and disclaimer of any warranty. -// -// Alternatively, this file may be used under the terms of Open CASCADE -// commercial license or contractual agreement. - -//======================================================================= - -#include -#include -#include -#include -#include -#include - -//======================================================================= -//function : StlMesh_MeshExplorer -//design : -//warning : -//======================================================================= -StlMesh_MeshExplorer::StlMesh_MeshExplorer(const Handle(StlMesh_Mesh)& M) - : domainIndex (0), nbTriangles (0) ,triangleIndex (0) { mesh = M;} - - -//======================================================================= -//function : Deflection -//design : -//warning : -//======================================================================= - -Standard_Real StlMesh_MeshExplorer::Deflection() const -{ return mesh->Deflection (domainIndex);} - - -//======================================================================= -//function : InitTriangle -//design : -//warning : -//======================================================================= - -void StlMesh_MeshExplorer::InitTriangle(const Standard_Integer DomainIndex) -{ - triangleIndex = 1; - domainIndex = DomainIndex; - nbTriangles = mesh->NbTriangles (domainIndex); - if (nbTriangles > 0) { - trianglesdef.Assign (mesh->Triangles (DomainIndex)); - trianglesVertex.Assign (mesh->Vertices (DomainIndex)); - const Handle (StlMesh_MeshTriangle) trian = trianglesdef.First(); - trian->GetVertexAndOrientation (v1,v2,v3,xn,yn,zn); - } -} - -//======================================================================= -//function : NextTriangle -//design : -//warning : -//======================================================================= - -void StlMesh_MeshExplorer::NextTriangle() -{ - triangleIndex++; - if (triangleIndex <= nbTriangles) { - const Handle (StlMesh_MeshTriangle) trian = trianglesdef.Value (triangleIndex); - trian->GetVertexAndOrientation (v1,v2,v3,xn,yn,zn); - } -} - -//======================================================================= -//function : TriangleVertices -//design : -//warning : -//======================================================================= - -void StlMesh_MeshExplorer::TriangleVertices(Standard_Real& X1, Standard_Real& Y1, - Standard_Real& Z1, Standard_Real& X2, - Standard_Real& Y2, Standard_Real& Z2, - Standard_Real& X3, Standard_Real& Y3, - Standard_Real& Z3) const -{ - Standard_NoSuchObject_Raise_if (triangleIndex > nbTriangles, " StlMesh_MeshExplorer::TriangleVertices"); - - X1 = (trianglesVertex.Value(v1)).X(); - Y1 = (trianglesVertex.Value(v1)).Y(); - Z1 = (trianglesVertex.Value(v1)).Z(); - X2 = (trianglesVertex.Value(v2)).X(); - Y2 = (trianglesVertex.Value(v2)).Y(); - Z2 = (trianglesVertex.Value(v2)).Z(); - X3 = (trianglesVertex.Value(v3)).X(); - Y3 = (trianglesVertex.Value(v3)).Y(); - Z3 = (trianglesVertex.Value(v3)).Z(); -} - -//======================================================================= -//function : TriangleDirection -//design : -//warning : -//======================================================================= - -void StlMesh_MeshExplorer::TriangleOrientation(Standard_Real& Xn, Standard_Real& Yn, Standard_Real& Zn) const -{ - Xn = xn; - Yn = yn; - Zn = zn; -} - - - - - - diff --git a/src/StlMesh/StlMesh_MeshExplorer.hxx b/src/StlMesh/StlMesh_MeshExplorer.hxx deleted file mode 100644 index 5dc3571bcb..0000000000 --- a/src/StlMesh/StlMesh_MeshExplorer.hxx +++ /dev/null @@ -1,105 +0,0 @@ -// Created on: 1995-09-21 -// Created by: Philippe GIRODENGO -// Copyright (c) 1995-1999 Matra Datavision -// Copyright (c) 1999-2014 OPEN CASCADE SAS -// -// This file is part of Open CASCADE Technology software library. -// -// This library is free software; you can redistribute it and/or modify it under -// the terms of the GNU Lesser General Public License version 2.1 as published -// by the Free Software Foundation, with special exception defined in the file -// OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT -// distribution for complete text of the license and disclaimer of any warranty. -// -// Alternatively, this file may be used under the terms of Open CASCADE -// commercial license or contractual agreement. - -#ifndef _StlMesh_MeshExplorer_HeaderFile -#define _StlMesh_MeshExplorer_HeaderFile - -#include -#include -#include - -#include -#include -#include -#include -#include -class StlMesh_Mesh; -class Standard_OutOfRange; -class Standard_NoMoreObject; -class Standard_NoSuchObject; - - -//! Provides facilities to explore the triangles of -//! each mesh domain. -class StlMesh_MeshExplorer -{ -public: - - DEFINE_STANDARD_ALLOC - - - Standard_EXPORT StlMesh_MeshExplorer(const Handle(StlMesh_Mesh)& M); - - //! Returns the mesh deflection of the current domain. - Standard_EXPORT Standard_Real Deflection() const; - - //! Initializes the exploration of the triangles of - //! the mesh domain of range . - //! Raised if is lower than 1 or greater - //! than the number of domains. - Standard_EXPORT void InitTriangle (const Standard_Integer DomainIndex = 1); - - Standard_Boolean MoreTriangle() const; - - //! Raised if there is no more triangle in the current - //! domain. - Standard_EXPORT void NextTriangle(); - - //! Raised if there is no more triangle in the current - //! domain. - Standard_EXPORT void TriangleVertices (Standard_Real& X1, Standard_Real& Y1, Standard_Real& Z1, Standard_Real& X2, Standard_Real& Y2, Standard_Real& Z2, Standard_Real& X3, Standard_Real& Y3, Standard_Real& Z3) const; - - //! Raised if there is no more triangle in the current - //! domain. - Standard_EXPORT void TriangleOrientation (Standard_Real& Xn, Standard_Real& Yn, Standard_Real& Zn) const; - - - - -protected: - - - - - -private: - - - - Handle(StlMesh_Mesh) mesh; - Standard_Real xn; - Standard_Real yn; - Standard_Real zn; - Standard_Integer v1; - Standard_Integer v2; - Standard_Integer v3; - Standard_Integer domainIndex; - Standard_Integer nbTriangles; - Standard_Integer triangleIndex; - TColgp_SequenceOfXYZ trianglesVertex; - StlMesh_SequenceOfMeshTriangle trianglesdef; - - -}; - - -#include - - - - - -#endif // _StlMesh_MeshExplorer_HeaderFile diff --git a/src/StlMesh/StlMesh_MeshExplorer.lxx b/src/StlMesh/StlMesh_MeshExplorer.lxx deleted file mode 100644 index 8099c20f9b..0000000000 --- a/src/StlMesh/StlMesh_MeshExplorer.lxx +++ /dev/null @@ -1,27 +0,0 @@ -// Created on: 1995-09-25 -// Created by: Philippe GIRODENGO -// Copyright (c) 1995-1999 Matra Datavision -// Copyright (c) 1999-2014 OPEN CASCADE SAS -// -// This file is part of Open CASCADE Technology software library. -// -// This library is free software; you can redistribute it and/or modify it under -// the terms of the GNU Lesser General Public License version 2.1 as published -// by the Free Software Foundation, with special exception defined in the file -// OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT -// distribution for complete text of the license and disclaimer of any warranty. -// -// Alternatively, this file may be used under the terms of Open CASCADE -// commercial license or contractual agreement. - -//======================================================================= - -//======================================================================= -//function : MoreTriangle -//design : -//warning : -//======================================================================= - -inline Standard_Boolean StlMesh_MeshExplorer::MoreTriangle() const -{ return triangleIndex <= nbTriangles; } - diff --git a/src/StlMesh/StlMesh_MeshTriangle.cxx b/src/StlMesh/StlMesh_MeshTriangle.cxx deleted file mode 100644 index aceee641bb..0000000000 --- a/src/StlMesh/StlMesh_MeshTriangle.cxx +++ /dev/null @@ -1,117 +0,0 @@ -// Created on: 1995-09-25 -// Created by: Philippe GIRODENGO -// Copyright (c) 1995-1999 Matra Datavision -// Copyright (c) 1999-2014 OPEN CASCADE SAS -// -// This file is part of Open CASCADE Technology software library. -// -// This library is free software; you can redistribute it and/or modify it under -// the terms of the GNU Lesser General Public License version 2.1 as published -// by the Free Software Foundation, with special exception defined in the file -// OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT -// distribution for complete text of the license and disclaimer of any warranty. -// -// Alternatively, this file may be used under the terms of Open CASCADE -// commercial license or contractual agreement. - -//======================================================================= - -#include -#include -#include -#include -#include - -IMPLEMENT_STANDARD_RTTIEXT(StlMesh_MeshTriangle,Standard_Transient) - -//======================================================================= -//function : StlMesh_MeshTriangle -//design : -//warning : -//======================================================================= -StlMesh_MeshTriangle::StlMesh_MeshTriangle() - : MyV1 (0), MyV2 (0), MyV3 (0), MyXn (0.0), MyYn (0.0), MyZn (0.0) { } - - -//======================================================================= -//function : StlMesh_MeshTriangle -//design : -//warning : -//======================================================================= - - StlMesh_MeshTriangle::StlMesh_MeshTriangle(const Standard_Integer V1, - const Standard_Integer V2, - const Standard_Integer V3, - const Standard_Real Xn, - const Standard_Real Yn, - const Standard_Real Zn) -: MyV1 (V1), MyV2 (V2), MyV3 (V3), MyXn (Xn), MyYn (Yn), MyZn (Zn) { } - - -//======================================================================= -//function : GetVertexAndOrientation -//design : -//warning : -//======================================================================= - -void StlMesh_MeshTriangle::GetVertexAndOrientation(Standard_Integer& V1, - Standard_Integer& V2, - Standard_Integer& V3, - Standard_Real& Xn, - Standard_Real& Yn, - Standard_Real& Zn) const -{ - V1 = MyV1; - V2 = MyV2; - V3 = MyV3; - Xn = MyXn; - Yn = MyYn; - Zn = MyZn; -} - -//======================================================================= -//function : SetVertexAndOrientation -//design : -//warning : -//======================================================================= - -void StlMesh_MeshTriangle::SetVertexAndOrientation(const Standard_Integer V1, const Standard_Integer V2, - const Standard_Integer V3, const Standard_Real Xn, - const Standard_Real Yn, const Standard_Real Zn) -{ - MyV1 = V1; - MyV2 = V2; - MyV3 = V3; - MyXn = Xn; - MyYn = Yn; - MyZn = Zn; -} - -//======================================================================= -//function : GetVertex -//design : -//warning : -//======================================================================= - -void StlMesh_MeshTriangle::GetVertex(Standard_Integer& V1, Standard_Integer& V2, Standard_Integer& V3) const -{ - V1 = MyV1; - V2 = MyV2; - V3 = MyV3; -} - -//======================================================================= -//function : SetVertex -//design : -//warning : -//======================================================================= - -void StlMesh_MeshTriangle::SetVertex(const Standard_Integer V1, const Standard_Integer V2, const Standard_Integer V3) -{ - MyV1 = V1; - MyV2 = V2; - MyV3 = V3; -} - - - diff --git a/src/StlMesh/StlMesh_MeshTriangle.hxx b/src/StlMesh/StlMesh_MeshTriangle.hxx deleted file mode 100644 index ba9724e1f8..0000000000 --- a/src/StlMesh/StlMesh_MeshTriangle.hxx +++ /dev/null @@ -1,91 +0,0 @@ -// Created on: 1995-09-21 -// Created by: Philippe GIRODENGO -// Copyright (c) 1995-1999 Matra Datavision -// Copyright (c) 1999-2014 OPEN CASCADE SAS -// -// This file is part of Open CASCADE Technology software library. -// -// This library is free software; you can redistribute it and/or modify it under -// the terms of the GNU Lesser General Public License version 2.1 as published -// by the Free Software Foundation, with special exception defined in the file -// OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT -// distribution for complete text of the license and disclaimer of any warranty. -// -// Alternatively, this file may be used under the terms of Open CASCADE -// commercial license or contractual agreement. - -#ifndef _StlMesh_MeshTriangle_HeaderFile -#define _StlMesh_MeshTriangle_HeaderFile - -#include -#include - -#include -#include -#include -class Standard_NegativeValue; - - -class StlMesh_MeshTriangle; -DEFINE_STANDARD_HANDLE(StlMesh_MeshTriangle, Standard_Transient) - -//! A mesh triangle is defined with -//! three geometric vertices and an orientation -class StlMesh_MeshTriangle : public Standard_Transient -{ - -public: - - - //! empty constructor - Standard_EXPORT StlMesh_MeshTriangle(); - - //! create a triangle defined with the indexes of its three vertices - //! and its orientation - //! Raised if V1, V2 or V3 is lower than zero - Standard_EXPORT StlMesh_MeshTriangle(const Standard_Integer V1, const Standard_Integer V2, const Standard_Integer V3, const Standard_Real Xn, const Standard_Real Yn, const Standard_Real Zn); - - //! get indexes of the three vertices (V1,V2,V3) and the orientation - Standard_EXPORT void GetVertexAndOrientation (Standard_Integer& V1, Standard_Integer& V2, Standard_Integer& V3, Standard_Real& Xn, Standard_Real& Yn, Standard_Real& Zn) const; - - //! set indexes of the three vertices (V1,V2,V3) and the orientation - //! Raised if V1, V2 or V3 is lower than zero - Standard_EXPORT void SetVertexAndOrientation (const Standard_Integer V1, const Standard_Integer V2, const Standard_Integer V3, const Standard_Real Xn, const Standard_Real Yn, const Standard_Real Zn); - - //! get indexes of the three vertices (V1,V2,V3) - Standard_EXPORT void GetVertex (Standard_Integer& V1, Standard_Integer& V2, Standard_Integer& V3) const; - - //! set indexes of the three vertices (V1,V2,V3) - //! Raised if V1, V2 or V3 is lower than zero - Standard_EXPORT void SetVertex (const Standard_Integer V1, const Standard_Integer V2, const Standard_Integer V3); - - - - - DEFINE_STANDARD_RTTIEXT(StlMesh_MeshTriangle,Standard_Transient) - -protected: - - - - -private: - - - Standard_Integer MyV1; - Standard_Integer MyV2; - Standard_Integer MyV3; - Standard_Real MyXn; - Standard_Real MyYn; - Standard_Real MyZn; - - -}; - - - - - - - -#endif // _StlMesh_MeshTriangle_HeaderFile diff --git a/src/StlMesh/StlMesh_SequenceOfMesh.hxx b/src/StlMesh/StlMesh_SequenceOfMesh.hxx deleted file mode 100644 index 17fd0ba3c0..0000000000 --- a/src/StlMesh/StlMesh_SequenceOfMesh.hxx +++ /dev/null @@ -1,26 +0,0 @@ -// Created on: 1995-09-21 -// Created by: Philippe GIRODENGO -// Copyright (c) 1995-1999 Matra Datavision -// Copyright (c) 1999-2014 OPEN CASCADE SAS -// -// This file is part of Open CASCADE Technology software library. -// -// This library is free software; you can redistribute it and/or modify it under -// the terms of the GNU Lesser General Public License version 2.1 as published -// by the Free Software Foundation, with special exception defined in the file -// OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT -// distribution for complete text of the license and disclaimer of any warranty. -// -// Alternatively, this file may be used under the terms of Open CASCADE -// commercial license or contractual agreement. - -#ifndef StlMesh_SequenceOfMesh_HeaderFile -#define StlMesh_SequenceOfMesh_HeaderFile - -#include -#include - -typedef NCollection_Sequence StlMesh_SequenceOfMesh; - - -#endif diff --git a/src/StlMesh/StlMesh_SequenceOfMeshDomain.hxx b/src/StlMesh/StlMesh_SequenceOfMeshDomain.hxx deleted file mode 100644 index 901e6187d7..0000000000 --- a/src/StlMesh/StlMesh_SequenceOfMeshDomain.hxx +++ /dev/null @@ -1,26 +0,0 @@ -// Created on: 1995-09-21 -// Created by: Philippe GIRODENGO -// Copyright (c) 1995-1999 Matra Datavision -// Copyright (c) 1999-2014 OPEN CASCADE SAS -// -// This file is part of Open CASCADE Technology software library. -// -// This library is free software; you can redistribute it and/or modify it under -// the terms of the GNU Lesser General Public License version 2.1 as published -// by the Free Software Foundation, with special exception defined in the file -// OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT -// distribution for complete text of the license and disclaimer of any warranty. -// -// Alternatively, this file may be used under the terms of Open CASCADE -// commercial license or contractual agreement. - -#ifndef StlMesh_SequenceOfMeshDomain_HeaderFile -#define StlMesh_SequenceOfMeshDomain_HeaderFile - -#include -#include - -typedef NCollection_Sequence StlMesh_SequenceOfMeshDomain; - - -#endif diff --git a/src/StlMesh/StlMesh_SequenceOfMeshTriangle.hxx b/src/StlMesh/StlMesh_SequenceOfMeshTriangle.hxx deleted file mode 100644 index dd9f58b155..0000000000 --- a/src/StlMesh/StlMesh_SequenceOfMeshTriangle.hxx +++ /dev/null @@ -1,26 +0,0 @@ -// Created on: 1995-09-21 -// Created by: Philippe GIRODENGO -// Copyright (c) 1995-1999 Matra Datavision -// Copyright (c) 1999-2014 OPEN CASCADE SAS -// -// This file is part of Open CASCADE Technology software library. -// -// This library is free software; you can redistribute it and/or modify it under -// the terms of the GNU Lesser General Public License version 2.1 as published -// by the Free Software Foundation, with special exception defined in the file -// OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT -// distribution for complete text of the license and disclaimer of any warranty. -// -// Alternatively, this file may be used under the terms of Open CASCADE -// commercial license or contractual agreement. - -#ifndef StlMesh_SequenceOfMeshTriangle_HeaderFile -#define StlMesh_SequenceOfMeshTriangle_HeaderFile - -#include -#include - -typedef NCollection_Sequence StlMesh_SequenceOfMeshTriangle; - - -#endif diff --git a/src/StlTransfer/FILES b/src/StlTransfer/FILES deleted file mode 100644 index 0e10e441f6..0000000000 --- a/src/StlTransfer/FILES +++ /dev/null @@ -1,2 +0,0 @@ -StlTransfer.cxx -StlTransfer.hxx diff --git a/src/StlTransfer/StlTransfer.cxx b/src/StlTransfer/StlTransfer.cxx deleted file mode 100644 index f12c71d272..0000000000 --- a/src/StlTransfer/StlTransfer.cxx +++ /dev/null @@ -1,187 +0,0 @@ -// Created on: 2000-06-23 -// Created by: Sergey MOZOKHIN -// Copyright (c) 2000-2014 OPEN CASCADE SAS -// -// This file is part of Open CASCADE Technology software library. -// -// This library is free software; you can redistribute it and/or modify it under -// the terms of the GNU Lesser General Public License version 2.1 as published -// by the Free Software Foundation, with special exception defined in the file -// OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT -// distribution for complete text of the license and disclaimer of any warranty. -// -// Alternatively, this file may be used under the terms of Open CASCADE -// commercial license or contractual agreement. - -//======================================================================= - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -//function computes normals for surface -static void Normal(const TopoDS_Face& aFace, - Poly_Connect& pc, - TColgp_Array1OfDir& Nor) -{ - const Handle(Poly_Triangulation)& T = pc.Triangulation(); - BRepAdaptor_Surface S; - Standard_Boolean hasUV = T->HasUVNodes(); - Standard_Integer i; - TopLoc_Location l; - Handle(Geom_Surface) GS = BRep_Tool::Surface(aFace, l); - - if (hasUV && !GS.IsNull()) { - Standard_Boolean OK = Standard_True; - gp_Vec D1U,D1V; - gp_Vec D2U,D2V,D2UV; - gp_Pnt P; - Standard_Real U, V; - CSLib_DerivativeStatus aStatus; - CSLib_NormalStatus NStat; - S.Initialize(aFace, Standard_False); - const TColgp_Array1OfPnt2d& UVNodes = T->UVNodes(); - if (S.GetType() != GeomAbs_Plane) { - for (i = UVNodes.Lower(); i <= UVNodes.Upper(); i++) { - U = UVNodes(i).X(); - V = UVNodes(i).Y(); - S.D1(U,V,P,D1U,D1V); - CSLib::Normal (D1U, D1V, Precision::Angular(), aStatus, Nor (i)); - if (aStatus != CSLib_Done) { - S.D2(U,V,P,D1U,D1V,D2U,D2V,D2UV); - CSLib::Normal(D1U,D1V,D2U,D2V,D2UV,Precision::Angular(),OK,NStat,Nor(i)); - } - if (aFace.Orientation() == TopAbs_REVERSED) (Nor(i)).Reverse(); - } - } - else { - gp_Dir NPlane; - U = UVNodes(UVNodes.Lower()).X(); - V = UVNodes(UVNodes.Lower()).Y(); - S.D1(U,V,P,D1U,D1V); - CSLib::Normal (D1U, D1V, Precision::Angular(), aStatus, NPlane); - if (aStatus != CSLib_Done) { - S.D2(U,V,P,D1U,D1V,D2U,D2V,D2UV); - CSLib::Normal(D1U,D1V,D2U,D2V,D2UV,Precision::Angular(),OK,NStat,NPlane); - } - if (aFace.Orientation() == TopAbs_REVERSED) NPlane.Reverse(); - Nor.Init(NPlane); - - } - } - else { - const TColgp_Array1OfPnt& Nodes = T->Nodes(); - Standard_Integer n[3]; - const Poly_Array1OfTriangle& triangles = T->Triangles(); - - for (i = Nodes.Lower(); i <= Nodes.Upper(); i++) { - gp_XYZ eqPlan(0, 0, 0); - for (pc.Initialize(i); pc.More(); pc.Next()) { - triangles(pc.Value()).Get(n[0], n[1], n[2]); - gp_XYZ v1(Nodes(n[1]).Coord()-Nodes(n[0]).Coord()); - gp_XYZ v2(Nodes(n[2]).Coord()-Nodes(n[1]).Coord()); - eqPlan += (v1^v2).Normalized(); - } - Nor(i) = gp_Dir(eqPlan); - if (aFace.Orientation() == TopAbs_REVERSED) (Nor(i)).Reverse(); - } - } - -} -void StlTransfer::RetrieveMesh (const TopoDS_Shape& Shape, - const Handle(StlMesh_Mesh)& Mesh) -{ - for (TopExp_Explorer itf(Shape,TopAbs_FACE); itf.More(); itf.Next()) { - TopoDS_Face face = TopoDS::Face(itf.Current()); - TopLoc_Location Loc, loc; - Handle(Poly_Triangulation) theTriangulation = BRep_Tool::Triangulation(face, Loc); - if (theTriangulation.IsNull()) continue; //Meshing was not done for this face! - Poly_Array1OfTriangle theTriangles(1,theTriangulation->NbTriangles()); - theTriangles.Assign(theTriangulation->Triangles()); - Mesh->AddDomain (theTriangulation->Deflection()); - - TColgp_Array1OfPnt thePoints(1, theTriangulation->NbNodes()); - thePoints.Assign(theTriangulation->Nodes()); - //compute normal of face - const TColgp_Array1OfPnt& Nodes = theTriangulation->Nodes(); - TColgp_Array1OfDir NORMAL(Nodes.Lower(), Nodes.Upper()); - Poly_Connect pc(theTriangulation); - Normal(face, pc, NORMAL); - Standard_Integer i; - for(i=1;i<=thePoints.Length();i++) { - Standard_Real X1, Y1, Z1; - gp_Pnt p = thePoints.Value(i); - p.Transform(Loc.Transformation()); - p.Coord (X1, Y1, Z1); - Mesh->AddVertex (X1, Y1, Z1); - } - try { - OCC_CATCH_SIGNALS - for (i=1;i<=theTriangles.Length();i++) { - Standard_Integer V1, V2, V3; - Poly_Triangle triangle = theTriangles.Value(i); - triangle.Get(V1, V2, V3); - gp_Pnt P1, P2, P3; - P1 = Mesh->Vertices(Mesh->NbDomains()).Value(V1); - P2 = Mesh->Vertices(Mesh->NbDomains()).Value(V2); - P3 = Mesh->Vertices(Mesh->NbDomains()).Value(V3); - gp_Vec average = NORMAL(V1);; - - //check angle between vectors - gp_Vec V1V2(P1, P2), V2V3(P2, P3); - Standard_Integer A,B,C; - gp_Vec vec = V1V2^V2V3; - Standard_Real modul1, modul2; - modul1 = average.XYZ().Modulus(); - modul2 = vec.XYZ().Modulus(); - if (modul2>Precision::Confusion ()) vec.Divide(modul2); - A=V1;B=V2;C=V3; - // vec.Transform(loc); - if (modul1>Precision::Confusion () && modul2>Precision::Confusion ()) { - Standard_Real an = vec.Angle(average); - if ( an > M_PI/2) { - A = V3;B=V2;C=V1; - } - else { - A=V1;B=V2;C=V3; - } - } - Mesh->AddTriangle (A, B, C, average.X(), average.Y(), average.Z()); - } - } - catch(Standard_Failure) - { -#ifdef OCCT_DEBUG - cout << "Fail in StlTransfer::BuildIncrementalMesh" << endl; -#endif - } - } -} - - - - - - diff --git a/src/StlTransfer/StlTransfer.hxx b/src/StlTransfer/StlTransfer.hxx deleted file mode 100644 index 6686bb8e2c..0000000000 --- a/src/StlTransfer/StlTransfer.hxx +++ /dev/null @@ -1,66 +0,0 @@ -// Created on: 1994-11-14 -// Created by: Jean Claude VAUTHIER -// Copyright (c) 1994-1999 Matra Datavision -// Copyright (c) 1999-2014 OPEN CASCADE SAS -// -// This file is part of Open CASCADE Technology software library. -// -// This library is free software; you can redistribute it and/or modify it under -// the terms of the GNU Lesser General Public License version 2.1 as published -// by the Free Software Foundation, with special exception defined in the file -// OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT -// distribution for complete text of the license and disclaimer of any warranty. -// -// Alternatively, this file may be used under the terms of Open CASCADE -// commercial license or contractual agreement. - -#ifndef _StlTransfer_HeaderFile -#define _StlTransfer_HeaderFile - -#include -#include -#include - -class TopoDS_Shape; -class StlMesh_Mesh; - - -//! The package Algorithm for Meshing implements -//! 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. -class StlTransfer -{ -public: - - DEFINE_STANDARD_ALLOC - - - //! Retrieve a Mesh data-structure from the Shape, convert and store it into the Mesh. - Standard_EXPORT static void RetrieveMesh (const TopoDS_Shape& Shape, const Handle(StlMesh_Mesh)& Mesh); - - - - -protected: - - - - - -private: - - - - - -}; - - - - - - - -#endif // _StlTransfer_HeaderFile diff --git a/src/TKSTL/PACKAGES b/src/TKSTL/PACKAGES index cb0df699de..ba06cc7ee4 100755 --- a/src/TKSTL/PACKAGES +++ b/src/TKSTL/PACKAGES @@ -1,4 +1,2 @@ -StlMesh StlAPI -StlTransfer RWStl diff --git a/src/XSDRAWSTLVRML/XSDRAWSTLVRML.cxx b/src/XSDRAWSTLVRML/XSDRAWSTLVRML.cxx index 9cfc7917a8..22197809fb 100644 --- a/src/XSDRAWSTLVRML/XSDRAWSTLVRML.cxx +++ b/src/XSDRAWSTLVRML/XSDRAWSTLVRML.cxx @@ -17,6 +17,7 @@ #include #include #include +#include #include #include #include @@ -45,13 +46,12 @@ #include #include #include -#include -#include #include #include #include #include #include +#include #include #include #include @@ -90,27 +90,50 @@ static Standard_Integer writestl } StlAPI_Writer aWriter; aWriter.ASCIIMode() = isASCIIMode; - 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; - } + Standard_Boolean isOK = aWriter.Write (aShape, argv[2]); + if (!isOK) + di << "** Error **: Mesh writing has been failed.\n"; } return 0; } -static Standard_Integer readstl -(Draw_Interpretor& di, Standard_Integer argc, const char** argv) +//============================================================================= +//function : readstl +//purpose : Reads stl file +//============================================================================= +static Standard_Integer readstl(Draw_Interpretor& theDI, + Standard_Integer theArgc, + const char** theArgv) { - if (argc<3) di << "wrong number of parameters" << "\n"; - else { - TopoDS_Shape aShape ; - StlAPI::Read(aShape,argv[2]); - DBRep::Set(argv[1],aShape); + if (theArgc < 3) + { + theDI << "wrong number of parameters" << "\n"; + return 1; } + else + { + if (theArgc == 4 && + strcmp("triangulation", theArgv[3]) == 0) + { + // Read STL file to the triangulation. + Handle(Poly_Triangulation) aTriangulation = RWStl::ReadFile (theArgv[2]); + + TopoDS_Face aFace; + BRep_Builder aB; + aB.MakeFace(aFace); + aB.UpdateFace(aFace, aTriangulation); + DBRep::Set(theArgv[1], aFace); + } + else + { + TopoDS_Shape aShape; + Standard_DISABLE_DEPRECATION_WARNINGS + StlAPI::Read(aShape, theArgv[2]); + Standard_ENABLE_DEPRECATION_WARNINGS + DBRep::Set(theArgv[1], aShape); + } + } + return 0; } @@ -260,7 +283,7 @@ static Standard_Integer createmesh // Progress indicator OSD_Path aFile( argv[2] ); Handle(Draw_ProgressIndicator) aProgress = new Draw_ProgressIndicator (di, 1); - Handle(StlMesh_Mesh) aSTLMesh = RWStl::ReadFile (aFile, aProgress); + Handle(Poly_Triangulation) aSTLMesh = RWStl::ReadFile (aFile, aProgress); di << "Reading OK...\n"; Handle( XSDRAWSTLVRML_DataSource ) aDS = new XSDRAWSTLVRML_DataSource( aSTLMesh ); @@ -275,7 +298,7 @@ static Standard_Integer createmesh // Hide all nodes by default Handle(TColStd_HPackedMapOfInteger) aNodes = new TColStd_HPackedMapOfInteger(); - Standard_Integer aLen = aSTLMesh->Vertices().Length(); + Standard_Integer aLen = aSTLMesh->Nodes().Length(); for ( Standard_Integer anIndex = 1; anIndex <= aLen; anIndex++ ) aNodes->ChangeMap().Add( anIndex ); aMesh->SetHiddenNodes( aNodes ); @@ -1223,7 +1246,7 @@ 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 ("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 ("readstl", "shape file [triangulation: no by default]",__FILE__,readstl,g); theCommands.Add ("loadvrml" , "shape file",__FILE__,loadvrml,g); theCommands.Add ("meshfromstl", "creates MeshVS_Mesh from STL file", __FILE__, createmesh, g ); diff --git a/src/XSDRAWSTLVRML/XSDRAWSTLVRML_DataSource.cxx b/src/XSDRAWSTLVRML/XSDRAWSTLVRML_DataSource.cxx index de5d7a1673..2e57d979e9 100644 --- a/src/XSDRAWSTLVRML/XSDRAWSTLVRML_DataSource.cxx +++ b/src/XSDRAWSTLVRML/XSDRAWSTLVRML_DataSource.cxx @@ -13,15 +13,13 @@ // Alternatively, this file may be used under the terms of Open CASCADE // commercial license or contractual agreement. +#include +#include #include -#include -#include -#include #include #include #include -#include IMPLEMENT_STANDARD_RTTIEXT(XSDRAWSTLVRML_DataSource,MeshVS_DataSource) @@ -29,13 +27,13 @@ IMPLEMENT_STANDARD_RTTIEXT(XSDRAWSTLVRML_DataSource,MeshVS_DataSource) // Function : Constructor // Purpose : //================================================================ -XSDRAWSTLVRML_DataSource::XSDRAWSTLVRML_DataSource( const Handle( StlMesh_Mesh )& aMesh ) +XSDRAWSTLVRML_DataSource::XSDRAWSTLVRML_DataSource (const Handle(Poly_Triangulation)& aMesh) { myMesh = aMesh; if( !myMesh.IsNull() ) { - const TColgp_SequenceOfXYZ& aCoords = myMesh->Vertices(); + const TColgp_Array1OfPnt& aCoords = myMesh->Nodes(); Standard_Integer len = aCoords.Length(), i, j; myNodeCoords = new TColStd_HArray2OfReal(1, len, 1, 3); cout << "Nodes : " << len << endl; @@ -45,14 +43,14 @@ XSDRAWSTLVRML_DataSource::XSDRAWSTLVRML_DataSource( const Handle( StlMesh_Mesh ) for( i = 1; i <= len; i++ ) { myNodes.Add( i ); - xyz = aCoords(i); + xyz = aCoords(i).XYZ(); myNodeCoords->SetValue(i, 1, xyz.X()); myNodeCoords->SetValue(i, 2, xyz.Y()); myNodeCoords->SetValue(i, 3, xyz.Z()); } - const StlMesh_SequenceOfMeshTriangle& aSeq = myMesh->Triangles(); + const Poly_Array1OfTriangle& aSeq = myMesh->Triangles(); len = aSeq.Length(); myElemNormals = new TColStd_HArray2OfReal(1, len, 1, 3); myElemNodes = new TColStd_HArray2OfInteger(1, len, 1, 3); @@ -62,19 +60,33 @@ XSDRAWSTLVRML_DataSource::XSDRAWSTLVRML_DataSource( const Handle( StlMesh_Mesh ) for( i = 1; i <= len; i++ ) { myElements.Add( i ); - Handle( StlMesh_MeshTriangle ) aTriangle = aSeq.Value( i ); - Standard_Integer V[3]; Standard_Real nx, ny, nz; - aTriangle->GetVertexAndOrientation( V[0], V[1], V[2], nx, ny, nz ); + const Poly_Triangle& aTri = aSeq(i); + + Standard_Integer V[3]; + aTri.Get (V[0], V[1], V[2]); + + const gp_Pnt aP1 = aCoords (V[0]); + const gp_Pnt aP2 = aCoords (V[1]); + const gp_Pnt aP3 = aCoords (V[2]); + + gp_Vec aV1(aP1, aP2); + gp_Vec aV2(aP2, aP3); + + gp_Vec aN = aV1.Crossed(aV2); + if (aN.SquareMagnitude() > Precision::SquareConfusion()) + aN.Normalize(); + else + aN.SetCoord(0.0, 0.0, 0.0); for( j = 0; j < 3; j++ ) { myElemNodes->SetValue(i, j+1, V[j]); } - myElemNormals->SetValue(i, 1, nx); - myElemNormals->SetValue(i, 2, ny); - myElemNormals->SetValue(i, 3, nz); + myElemNormals->SetValue (i, 1, aN.X()); + myElemNormals->SetValue (i, 2, aN.Y()); + myElemNormals->SetValue (i, 3, aN.Z()); } } cout << "Construction is finished" << endl; diff --git a/src/XSDRAWSTLVRML/XSDRAWSTLVRML_DataSource.hxx b/src/XSDRAWSTLVRML/XSDRAWSTLVRML_DataSource.hxx index 22a1838faa..2e478b2471 100644 --- a/src/XSDRAWSTLVRML/XSDRAWSTLVRML_DataSource.hxx +++ b/src/XSDRAWSTLVRML/XSDRAWSTLVRML_DataSource.hxx @@ -30,7 +30,7 @@ #include #include #include -class StlMesh_Mesh; +#include class XSDRAWSTLVRML_DataSource; @@ -44,7 +44,7 @@ public: //! Constructor - Standard_EXPORT XSDRAWSTLVRML_DataSource(const Handle(StlMesh_Mesh)& aMesh); + Standard_EXPORT XSDRAWSTLVRML_DataSource(const Handle(Poly_Triangulation)& aMesh); //! Returns geometry information about node ( if IsElement is False ) or element ( IsElement is True ) //! by co-ordinates. For element this method must return all its nodes co-ordinates in the strict order: X, Y, Z and @@ -85,7 +85,7 @@ protected: private: - Handle(StlMesh_Mesh) myMesh; + Handle(Poly_Triangulation) myMesh; TColStd_PackedMapOfInteger myNodes; TColStd_PackedMapOfInteger myElements; Handle(TColStd_HArray2OfInteger) myElemNodes; diff --git a/src/XSDRAWSTLVRML/XSDRAWSTLVRML_DataSource3D.cxx b/src/XSDRAWSTLVRML/XSDRAWSTLVRML_DataSource3D.cxx index 5dce587406..6845cad24e 100644 --- a/src/XSDRAWSTLVRML/XSDRAWSTLVRML_DataSource3D.cxx +++ b/src/XSDRAWSTLVRML/XSDRAWSTLVRML_DataSource3D.cxx @@ -15,8 +15,6 @@ #include -#include -#include #include #include #include diff --git a/tests/bugs/moddata_1/bug1048 b/tests/bugs/moddata_1/bug1048 deleted file mode 100755 index af9c06f6c1..0000000000 --- a/tests/bugs/moddata_1/bug1048 +++ /dev/null @@ -1,23 +0,0 @@ -puts "================" -puts "OCC1048" -puts "================" -puts "" - -pload QAcommands - -restore [locate_data_file OCC1048.brep] result - -set list [OCC1048 result] - -set NBTRIANGLES 0 -regexp {Info: +Number +of +triangles += +([-0-9.+eE]+)} $list full NBTRIANGLES - -if { ${NBTRIANGLES} > 0 } { - puts "OCC1048: OK" -} else { - puts "OCC1048: Error" -} - -checkview -display result -2d -path ${imagedir}/${test_image}.png - -