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.
n StepToTopoDS
n StepVisual
n StlAPI
-n StlMesh
-n StlTransfer
n TopoDSToStep
n Transfer
n TransferBRep
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.
~~~~~
// 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();
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";
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());
}
//=======================================================================
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;
}
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);
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();
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";
return 0;
}
-#include <StlMesh_Mesh.hxx>
-#include <StlTransfer.hxx>
-//=======================================================================
-//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 = "<<NBTRIANGLES<<"\n";
-
- return 0;
-}
-
void QABugs::Commands_2(Draw_Interpretor& theCommands) {
const char *group = "QABugs";
theCommands.Add("OCC527", "OCC527 shape", __FILE__, OCC527, group);
- theCommands.Add("OCC1048", "OCC1048 shape", __FILE__, OCC1048, group);
return;
}
RWStl.cxx
RWStl.hxx
+RWStl_Reader.cxx
+RWStl_Reader.hxx
-// 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.
//
// Alternatively, this file may be used under the terms of Open CASCADE
// commercial license or contractual agreement.
+#include <RWStl.hxx>
-#include <BRepBuilderAPI_CellFilter.hxx>
-#include <BRepBuilderAPI_VertexInspector.hxx>
-#include <gp.hxx>
-#include <gp_Vec.hxx>
-#include <gp_XYZ.hxx>
-#include <Message.hxx>
-#include <Message_Messenger.hxx>
-#include <Message_ProgressIndicator.hxx>
#include <Message_ProgressSentry.hxx>
-#include <OSD.hxx>
+#include <NCollection_Vector.hxx>
#include <OSD_File.hxx>
-#include <OSD_Host.hxx>
#include <OSD_OpenFile.hxx>
-#include <OSD_Path.hxx>
-#include <OSD_Protection.hxx>
-#include <Precision.hxx>
-#include <RWStl.hxx>
-#include <Standard_NoMoreObject.hxx>
-#include <Standard_TypeMismatch.hxx>
-#include <StlMesh_Mesh.hxx>
-#include <StlMesh_MeshExplorer.hxx>
-#include <TCollection_AsciiString.hxx>
-
-#include <stdio.h>
-// 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 <RWStl_Reader.hxx>
+
+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<gp_XYZ> myNodes;
+ NCollection_Vector<Poly_Triangle> 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"
" 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<Standard_Character> 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;
}
-// 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.
//
#ifndef _RWStl_HeaderFile
#define _RWStl_HeaderFile
-#include <Standard.hxx>
-#include <Standard_DefineAlloc.hxx>
-#include <Standard_Handle.hxx>
#include <Message_ProgressIndicator.hxx>
+#include <OSD_Path.hxx>
+#include <Poly_Triangulation.hxx>
+#include <Standard_Macro.hxx>
-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
--- /dev/null
+// 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 <RWStl_Reader.hxx>
+
+#include <gp_XY.hxx>
+#include <Message.hxx>
+#include <Message_Messenger.hxx>
+#include <Message_ProgressSentry.hxx>
+#include <NCollection_DataMap.hxx>
+#include <NCollection_IncAllocator.hxx>
+#include <FSD_BinaryFile.hxx>
+#include <OSD_OpenFile.hxx>
+#include <OSD_Timer.hxx>
+#include <Precision.hxx>
+#include <Standard_CLocaleSentry.hxx>
+
+#include <algorithm>
+#include <limits>
+
+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<gp_XYZ, Standard_Integer, MergeNodeTool> 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<const float*>(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<int64_t>::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;
+}
--- /dev/null
+// 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 <Message_ProgressIndicator.hxx>
+#include <gp_XYZ.hxx>
+
+//! 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
StlAPI.cxx
StlAPI.hxx
-StlAPI_ErrorStatus.hxx
StlAPI_Reader.cxx
StlAPI_Reader.hxx
StlAPI_Writer.cxx
// Alternatively, this file may be used under the terms of Open CASCADE
// commercial license or contractual agreement.
-
#include <StlAPI.hxx>
+
#include <StlAPI_Reader.hxx>
#include <StlAPI_Writer.hxx>
#include <TopoDS_Shape.hxx>
-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);
}
#ifndef _StlAPI_HeaderFile
#define _StlAPI_HeaderFile
+#include <Poly_Triangulation.hxx>
#include <Standard.hxx>
#include <Standard_DefineAlloc.hxx>
#include <Standard_Handle.hxx>
-
-#include <StlAPI_ErrorStatus.hxx>
#include <Standard_CString.hxx>
#include <Standard_Boolean.hxx>
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
+++ /dev/null
-// 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
// Alternatively, this file may be used under the terms of Open CASCADE
// commercial license or contractual agreement.
+#include <StlAPI_Reader.hxx>
#include <BRep_Builder.hxx>
#include <BRepBuilderAPI_MakeFace.hxx>
#include <gp_Pnt.hxx>
#include <OSD_Path.hxx>
#include <RWStl.hxx>
-#include <StlAPI_Reader.hxx>
-#include <StlMesh_Mesh.hxx>
-#include <StlMesh_MeshExplorer.hxx>
#include <TopoDS_Compound.hxx>
#include <TopoDS_Edge.hxx>
#include <TopoDS_Face.hxx>
#include <TopoDS_Vertex.hxx>
#include <TopoDS_Wire.hxx>
-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;
}
-
#include <Standard.hxx>
#include <Standard_DefineAlloc.hxx>
#include <Standard_Handle.hxx>
-
#include <Standard_CString.hxx>
-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
// Alternatively, this file may be used under the terms of Open CASCADE
// commercial license or contractual agreement.
+#include <StlAPI_Writer.hxx>
#include <Bnd_Box.hxx>
#include <BRepBndLib.hxx>
#include <OSD_Path.hxx>
#include <OSD_OpenFile.hxx>
#include <RWStl.hxx>
-#include <StlAPI_Writer.hxx>
-#include <StlMesh_Mesh.hxx>
-#include <StlTransfer.hxx>
#include <BRep_Tool.hxx>
#include <TopoDS.hxx>
#include <TopoDS_Face.hxx>
#include <TopExp_Explorer.hxx>
#include <Poly_Triangulation.hxx>
+//=============================================================================
+//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);
}
-
#ifndef _StlAPI_Writer_HeaderFile
#define _StlAPI_Writer_HeaderFile
+#include <Poly_Triangulation.hxx>
#include <Standard.hxx>
#include <Standard_DefineAlloc.hxx>
#include <Standard_Handle.hxx>
-
#include <Standard_Boolean.hxx>
-#include <StlAPI_ErrorStatus.hxx>
#include <Standard_CString.hxx>
-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
+++ /dev/null
-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
+++ /dev/null
-// 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 <StlMesh.hxx>
-#include <StlMesh_Mesh.hxx>
-#include <StlMesh_MeshTriangle.hxx>
-#include <StlMesh_SequenceOfMeshTriangle.hxx>
-#include <TColgp_SequenceOfXYZ.hxx>
-
-//=======================================================================
-//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;
-}
+++ /dev/null
-// 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 <Standard.hxx>
-#include <Standard_DefineAlloc.hxx>
-#include <Standard_Handle.hxx>
-
-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
+++ /dev/null
-// 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 <gp_XYZ.hxx>
-#include <Precision.hxx>
-#include <Standard_NegativeValue.hxx>
-#include <Standard_NoSuchObject.hxx>
-#include <Standard_NullValue.hxx>
-#include <Standard_Type.hxx>
-#include <StlMesh_Mesh.hxx>
-#include <StlMesh_MeshDomain.hxx>
-
-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 ();}
-
+++ /dev/null
-// 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 <Standard.hxx>
-#include <Standard_Type.hxx>
-
-#include <Standard_Integer.hxx>
-#include <StlMesh_SequenceOfMeshDomain.hxx>
-#include <gp_XYZ.hxx>
-#include <Standard_Transient.hxx>
-#include <Standard_Real.hxx>
-#include <Standard_Boolean.hxx>
-#include <StlMesh_SequenceOfMeshTriangle.hxx>
-#include <TColgp_SequenceOfXYZ.hxx>
-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 <DomainIndex>.
- //! Raised if <DomainIndex> 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
- //! <DomainIndex>.
- //! Raised if <DomainIndex> 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
- //! <DomainIndex>.
- //! Raised if <DomainIndex> 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
- //! <DomainIndex>.
- //! Raised if <DomainIndex> 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 <DomainIndex>. {XV1, YV1,
- //! ZV1, XV2, YV2, ZV2, XV3,.....}
- //! Raised if <DomainIndex> 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 <StlMesh_Mesh.lxx>
-
-
-
-
-
-#endif // _StlMesh_Mesh_HeaderFile
+++ /dev/null
-// 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;}
-
-
-
-
-
-
-
-
-
+++ /dev/null
-// 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 <gp_XYZ.hxx>
-#include <Precision.hxx>
-#include <Standard_NegativeValue.hxx>
-#include <Standard_NullValue.hxx>
-#include <Standard_Type.hxx>
-#include <StlMesh_MeshDomain.hxx>
-#include <StlMesh_MeshTriangle.hxx>
-
-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;
-}
-
-
-
-
-
-
+++ /dev/null
-// 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 <Standard.hxx>
-#include <Standard_Type.hxx>
-
-#include <Standard_Real.hxx>
-#include <Standard_Integer.hxx>
-#include <TColgp_SequenceOfXYZ.hxx>
-#include <StlMesh_SequenceOfMeshTriangle.hxx>
-#include <Standard_Transient.hxx>
-#include <Standard_Boolean.hxx>
-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 <DomainIndex>. {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 <StlMesh_MeshDomain.lxx>
-
-
-
-
-
-#endif // _StlMesh_MeshDomain_HeaderFile
+++ /dev/null
-// 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; }
-
+++ /dev/null
-// 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 <Standard_NoMoreObject.hxx>
-#include <Standard_NoSuchObject.hxx>
-#include <Standard_OutOfRange.hxx>
-#include <StlMesh_Mesh.hxx>
-#include <StlMesh_MeshExplorer.hxx>
-#include <StlMesh_MeshTriangle.hxx>
-
-//=======================================================================
-//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;
-}
-
-
-
-
-
-
+++ /dev/null
-// 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 <Standard.hxx>
-#include <Standard_DefineAlloc.hxx>
-#include <Standard_Handle.hxx>
-
-#include <Standard_Real.hxx>
-#include <Standard_Integer.hxx>
-#include <TColgp_SequenceOfXYZ.hxx>
-#include <StlMesh_SequenceOfMeshTriangle.hxx>
-#include <Standard_Boolean.hxx>
-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 <DomainIndex>.
- //! Raised if <DomainIndex> 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 <StlMesh_MeshExplorer.lxx>
-
-
-
-
-
-#endif // _StlMesh_MeshExplorer_HeaderFile
+++ /dev/null
-// 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; }
-
+++ /dev/null
-// 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 <gp_XYZ.hxx>
-#include <Precision.hxx>
-#include <Standard_NegativeValue.hxx>
-#include <Standard_Type.hxx>
-#include <StlMesh_MeshTriangle.hxx>
-
-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;
-}
-
-
-
+++ /dev/null
-// 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 <Standard.hxx>
-#include <Standard_Type.hxx>
-
-#include <Standard_Integer.hxx>
-#include <Standard_Real.hxx>
-#include <Standard_Transient.hxx>
-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
+++ /dev/null
-// 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 <StlMesh_Mesh.hxx>
-#include <NCollection_Sequence.hxx>
-
-typedef NCollection_Sequence<Handle(StlMesh_Mesh)> StlMesh_SequenceOfMesh;
-
-
-#endif
+++ /dev/null
-// 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 <StlMesh_MeshDomain.hxx>
-#include <NCollection_Sequence.hxx>
-
-typedef NCollection_Sequence<Handle(StlMesh_MeshDomain)> StlMesh_SequenceOfMeshDomain;
-
-
-#endif
+++ /dev/null
-// 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 <StlMesh_MeshTriangle.hxx>
-#include <NCollection_Sequence.hxx>
-
-typedef NCollection_Sequence<Handle(StlMesh_MeshTriangle)> StlMesh_SequenceOfMeshTriangle;
-
-
-#endif
+++ /dev/null
-StlTransfer.cxx
-StlTransfer.hxx
+++ /dev/null
-// 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 <BRep_Tool.hxx>
-#include <BRepAdaptor_Surface.hxx>
-#include <BRepMesh_IncrementalMesh.hxx>
-#include <CSLib.hxx>
-#include <Geom_Surface.hxx>
-#include <gp_Dir.hxx>
-#include <gp_Pnt.hxx>
-#include <gp_Vec.hxx>
-#include <gp_XYZ.hxx>
-#include <Poly_Connect.hxx>
-#include <Poly_Triangulation.hxx>
-#include <Precision.hxx>
-#include <Standard_ErrorHandler.hxx>
-#include <Standard_Failure.hxx>
-#include <StlMesh_Mesh.hxx>
-#include <StlTransfer.hxx>
-#include <TColgp_Array1OfDir.hxx>
-#include <TColgp_Array1OfPnt2d.hxx>
-#include <TColgp_SequenceOfXYZ.hxx>
-#include <TopAbs.hxx>
-#include <TopExp_Explorer.hxx>
-#include <TopLoc_Location.hxx>
-#include <TopoDS.hxx>
-#include <TopoDS_Face.hxx>
-#include <TopoDS_Shape.hxx>
-
-//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
- }
- }
-}
-
-
-
-
-
-
+++ /dev/null
-// 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 <Standard.hxx>
-#include <Standard_DefineAlloc.hxx>
-#include <Standard_Handle.hxx>
-
-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
-StlMesh
StlAPI
-StlTransfer
RWStl
#include <AIS_InteractiveContext.hxx>
#include <Aspect_TypeOfMarker.hxx>
#include <Bnd_Box.hxx>
+#include <BRep_Builder.hxx>
#include <DBRep.hxx>
#include <Draw.hxx>
#include <Draw_Interpretor.hxx>
#include <StdSelect_ViewerSelector3d.hxx>
#include <StlAPI.hxx>
#include <StlAPI_Writer.hxx>
-#include <StlMesh_Mesh.hxx>
-#include <StlMesh_SequenceOfMeshTriangle.hxx>
#include <TColgp_SequenceOfXYZ.hxx>
#include <TCollection_AsciiString.hxx>
#include <TColStd_Array1OfReal.hxx>
#include <TColStd_HPackedMapOfInteger.hxx>
#include <TColStd_MapIteratorOfPackedMapOfInteger.hxx>
+#include <TopoDS_Face.hxx>
#include <TopoDS_Shape.hxx>
#include <V3d_View.hxx>
#include <ViewerTest.hxx>
}
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;
}
// 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 );
// 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 );
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 );
// Alternatively, this file may be used under the terms of Open CASCADE
// commercial license or contractual agreement.
+#include <XSDRAWSTLVRML_DataSource.hxx>
+#include <Precision.hxx>
#include <Standard_Type.hxx>
-#include <StlMesh_Mesh.hxx>
-#include <StlMesh_MeshTriangle.hxx>
-#include <StlMesh_SequenceOfMeshTriangle.hxx>
#include <TColgp_SequenceOfXYZ.hxx>
#include <TColStd_DataMapOfIntegerInteger.hxx>
#include <TColStd_DataMapOfIntegerReal.hxx>
-#include <XSDRAWSTLVRML_DataSource.hxx>
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;
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);
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;
#include <Standard_Address.hxx>
#include <TColStd_Array1OfInteger.hxx>
#include <Standard_Real.hxx>
-class StlMesh_Mesh;
+#include <Poly_Triangulation.hxx>
class XSDRAWSTLVRML_DataSource;
//! 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
private:
- Handle(StlMesh_Mesh) myMesh;
+ Handle(Poly_Triangulation) myMesh;
TColStd_PackedMapOfInteger myNodes;
TColStd_PackedMapOfInteger myElements;
Handle(TColStd_HArray2OfInteger) myElemNodes;
#include <Standard_Type.hxx>
-#include <StlMesh_MeshTriangle.hxx>
-#include <StlMesh_SequenceOfMeshTriangle.hxx>
#include <TColgp_SequenceOfXYZ.hxx>
#include <TColStd_DataMapOfIntegerInteger.hxx>
#include <TColStd_DataMapOfIntegerReal.hxx>
+++ /dev/null
-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
-
-