-// File: RWStl.cxx
-// Created: Thu Oct 13 13:41:29 1994
-// Author: Marc LEGAY
-// <mle@bourdon>
-
-// Copyright: Matra Datavision
-
-#include <RWStl.ixx>
-#include <OSD_Protection.hxx>
+// Created on: 1994-10-13
+// Created by: Marc LEGAY
+// 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.
+
+
+#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 <OSD_File.hxx>
-#include <TCollection_AsciiString.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 <Precision.hxx>
+#include <StlMesh_Mesh.hxx>
#include <StlMesh_MeshExplorer.hxx>
-#include <OSD.hxx>
-#include <OSD_Host.hxx>
-#include <gp_XYZ.hxx>
-#include <gp.hxx>
-#include <stdio.h>
-#include <gp_Vec.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)
+{
+ 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)
+ {
+ index = indices.First(); // it should be only one
+ inspector.ClearResList();
+ }
+ else
+ {
+ index = mesh->AddVertex(p.X(), p.Y(), p.Z());
+ filter.Add(index, p);
+ inspector.Add(p);
+ }
+ return index;
+}
// constants
-static const int HEADER_SIZE = 84;
-static const int SIZEOF_STL_FACET = 50;
-static const int STL_MIN_FILE_SIZE = 284;
-static const int ASCII_LINES_PER_FACET = 7;
+static const size_t HEADER_SIZE = 84;
+static const size_t SIZEOF_STL_FACET = 50;
+static const size_t ASCII_LINES_PER_FACET = 7;
+
+static const int IND_THRESHOLD = 1000; // increment the indicator every 1k triangles
-//=============== =======================================================
+//=======================================================================
//function : WriteInteger
//purpose : writing a Little Endian 32 bits integer
//=======================================================================
bidargum.i = value;
Standard_Integer entier;
-
+
entier = bidargum.c[0] & 0xFF;
entier |= (bidargum.c[1] & 0xFF) << 0x08;
entier |= (bidargum.c[2] & 0xFF) << 0x10;
bidargum.f = (Standard_ShortReal)value;
Standard_Integer entier;
-
+
entier = bidargum.c[0] & 0xFF;
entier |= (bidargum.c[1] & 0xFF) << 0x08;
entier |= (bidargum.c[2] & 0xFF) << 0x10;
inline static Standard_Real ReadFloat2Double(OSD_File &aFile)
{
union {
- Standard_Boolean i; // don't be afraid, this is just an unsigned int
- Standard_ShortReal f;
+ uint32_t i;
+ float f;
}bidargum;
char c[4];
//purpose : write a binary STL file in Little Endian format
//=======================================================================
-Standard_Boolean RWStl::WriteBinary(const Handle(StlMesh_Mesh)& aMesh, const OSD_Path& aPath)
+Standard_Boolean RWStl::WriteBinary (const Handle(StlMesh_Mesh)& theMesh,
+ const OSD_Path& thePath,
+ const Handle(Message_ProgressIndicator)& theProgInd)
{
-
- OSD_File theFile = OSD_File (aPath);
- theFile.Build(OSD_WriteOnly,OSD_Protection());
+ 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;
-
- //pgo Standard_Real x,y,z;
-
+
+ // writing 80 bytes of the trash?
char sval[80];
- Standard_Integer NBTRIANGLES=0;
- unsigned int NBT;
- NBTRIANGLES = aMesh->NbTriangles();
- NBT = NBTRIANGLES ;
- theFile.Write ((Standard_Address)sval,80);
- WriteInteger(theFile,NBT);
-// theFile.Write ((Standard_Address)&NBT,4);
+ aFile.Write ((Standard_Address)sval,80);
+ WriteInteger (aFile, theMesh->NbTriangles());
+
int dum=0;
- StlMesh_MeshExplorer aMexp (aMesh);
-
-
- for (Standard_Integer nbd=1;nbd<=aMesh->NbDomains();nbd++) {
- 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 (theFile,Vnorm.X());
- WriteDouble2Float (theFile,Vnorm.Y());
- WriteDouble2Float (theFile,Vnorm.Z());
-
- WriteDouble2Float (theFile,x1);
- WriteDouble2Float (theFile,y1);
- WriteDouble2Float (theFile,z1);
-
- WriteDouble2Float (theFile,x2);
- WriteDouble2Float (theFile,y2);
- WriteDouble2Float (theFile,z2);
-
- WriteDouble2Float (theFile,x3);
- WriteDouble2Float (theFile,y3);
- WriteDouble2Float (theFile,z3);
-
- theFile.Write (&dum,2);
-
+ 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())
+ {
+ // 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);
+
+ WriteDouble2Float (aFile, x2);
+ WriteDouble2Float (aFile, y2);
+ WriteDouble2Float (aFile, z2);
+
+ WriteDouble2Float (aFile, x3);
+ WriteDouble2Float (aFile, y3);
+ WriteDouble2Float (aFile, z3);
+
+ aFile.Write (&dum, 2);
+
+ // update progress only per 1k triangles
+ if (++aTriangleInd % IND_THRESHOLD == 0)
+ {
+ if (!aTPS.More())
+ break;
+ aTPS.Next();
+ }
+ }
}
-
- theFile.Close ();
- return Standard_True;
+ aFile.Close();
+ Standard_Boolean isInterrupted = !aDPS.More();
+ return !isInterrupted;
}
//=======================================================================
//function : WriteAscii
//purpose : write an ASCII STL file
//=======================================================================
-Standard_Boolean RWStl::WriteAscii(const Handle(StlMesh_Mesh)& aMesh, const OSD_Path& aPath)
+Standard_Boolean RWStl::WriteAscii (const Handle(StlMesh_Mesh)& theMesh,
+ const OSD_Path& thePath,
+ const Handle(Message_ProgressIndicator)& theProgInd)
{
- OSD_File theFile = OSD_File (aPath);
+ OSD_File theFile (thePath);
theFile.Build(OSD_WriteOnly,OSD_Protection());
- TCollection_AsciiString buf = TCollection_AsciiString ("solid\n");
+ 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;
-
- //pgo Standard_Real x,y,z;
-
- char sval[16];
-
- StlMesh_MeshExplorer aMexp (aMesh);
-
- for (Standard_Integer nbd=1;nbd<=aMesh->NbDomains();nbd++) {
- for (aMexp.InitTriangle (nbd); aMexp.MoreTriangle (); aMexp.NextTriangle ()) {
+ 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())
+ {
+ // 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);
-
+
// Standard_Real x, y, z;
// aMexp.TriangleOrientation (x,y,z);
-
+
gp_XYZ Vect12 ((x2-x1), (y2-y1), (z2-z1));
gp_XYZ Vect23 ((x3-x2), (y3-y2), (z3-z2));
- gp_XYZ Vnorm = Vect12 ^ Vect23;
+ gp_XYZ Vnorm = Vect12 ^ Vect23;
Standard_Real Vmodul = Vnorm.Modulus ();
- if (Vmodul > gp::Resolution()){
- Vnorm.Divide (Vmodul);
+ if (Vmodul > gp::Resolution())
+ {
+ Vnorm.Divide (Vmodul);
}
- else {
- // si Vnorm est quasi-nul, on le charge a 0 explicitement
- Vnorm.SetCoord (0., 0., 0.);
+ else
+ {
+ // si Vnorm est quasi-nul, on le charge a 0 explicitement
+ Vnorm.SetCoord (0., 0., 0.);
}
- buf += " facet normal ";
- sprintf (sval,"% 12e",Vnorm.X());
- buf += sval;
- buf += " ";
- sprintf (sval,"% 12e",Vnorm.Y());
- buf += sval;
- buf += " ";
- sprintf (sval,"% 12e",Vnorm.Z());
- buf += sval;
- buf += '\n';
- theFile.Write (buf,buf.Length());buf.Clear();
- buf += " outer loop\n";
- theFile.Write (buf,buf.Length());buf.Clear();
-
- buf += " vertex ";
- sprintf (sval,"% 12e",x1);
- buf += sval;
- buf += " ";
- sprintf (sval,"% 12e",y1);
+ Sprintf (sval,
+ " 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",
+ Vnorm.X(), Vnorm.Y(), Vnorm.Z(),
+ x1, y1, z1,
+ x2, y2, z2,
+ x3, y3, z3);
buf += sval;
- buf += " ";
- sprintf (sval,"% 12e",z1);
- buf += sval;
- buf += '\n';
- theFile.Write (buf,buf.Length());buf.Clear();
-
- buf += " vertex ";
- sprintf (sval,"% 12e",x2);
- buf += sval;
- buf += " ";
- sprintf (sval,"% 12e",y2);
- buf += sval;
- buf += " ";
- sprintf (sval,"% 12e",z2);
- buf += sval;
- buf += '\n';
- theFile.Write (buf,buf.Length());buf.Clear();
-
- buf += " vertex ";
- sprintf (sval,"% 12e",x3);
- buf += sval;
- buf += " ";
- sprintf (sval,"% 12e",y3);
- buf += sval;
- buf += " ";
- sprintf (sval,"% 12e",z3);
- buf += sval;
- buf += '\n';
- theFile.Write (buf,buf.Length());buf.Clear();
- buf += " endloop\n";
- theFile.Write (buf,buf.Length());buf.Clear();
- buf += " endfacet\n";
- theFile.Write (buf,buf.Length());buf.Clear();
+ theFile.Write (buf, buf.Length()); buf.Clear();
+
+ // update progress only per 1k triangles
+ if (++aTriangleInd % IND_THRESHOLD == 0)
+ {
+ if (!aTPS.More())
+ break;
+ aTPS.Next();
+ }
}
}
-
+
buf += "endsolid\n";
- theFile.Write (buf,buf.Length());buf.Clear();
-
- theFile.Close ();
- return Standard_True;
+ theFile.Write (buf, buf.Length()); buf.Clear();
+ theFile.Close();
+ Standard_Boolean isInterrupted = !aDPS.More();
+ return !isInterrupted;
}
//=======================================================================
//function : ReadFile
-//Design :
-//Warning :
+//Design :
+//Warning :
//=======================================================================
-Handle_StlMesh_Mesh RWStl::ReadFile(const OSD_Path& aPath)
+Handle(StlMesh_Mesh) RWStl::ReadFile (const OSD_Path& thePath,
+ const Handle(Message_ProgressIndicator)& theProgInd)
{
- OSD_File file = OSD_File (aPath);
+ 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);
IsAscii = Standard_False;
}
}
-
- printf("%s\n",(IsAscii?"ascii":"binary"));
-
+#ifdef OCCT_DEBUG
+ cout << (IsAscii ? "ascii\n" : "binary\n");
+#endif
file.Close();
-
- if (IsAscii) {
- return RWStl::ReadAscii (aPath);
- } else {
- return RWStl::ReadBinary (aPath);
- }
+
+ return IsAscii ? RWStl::ReadAscii (thePath, theProgInd)
+ : RWStl::ReadBinary (thePath, theProgInd);
}
//=======================================================================
//function : ReadBinary
-//Design :
-//Warning :
+//Design :
+//Warning :
//=======================================================================
-Handle_StlMesh_Mesh RWStl::ReadBinary(const OSD_Path& aPath)
+Handle(StlMesh_Mesh) RWStl::ReadBinary (const OSD_Path& thePath,
+ const Handle(Message_ProgressIndicator)& /*theProgInd*/)
{
- Standard_Integer NBFACET;
Standard_Integer ifacet;
Standard_Real fx,fy,fz,fx1,fy1,fz1,fx2,fy2,fz2,fx3,fy3,fz3;
Standard_Integer i1,i2,i3,lread;
Standard_Address adr;
adr = (Standard_Address)buftest;
- // Open the file
- OSD_File theFile = OSD_File(aPath);
+ // 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_Integer filesize = theFile.Size();
+ Standard_Size filesize = theFile.Size();
- if ( (filesize - HEADER_SIZE) % SIZEOF_STL_FACET !=0
- || (filesize < STL_MIN_FILE_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)
+ {
Standard_NoMoreObject::Raise("RWStl::ReadBinary (wrong file size)");
}
- // 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
- NBFACET = ((filesize - HEADER_SIZE) / SIZEOF_STL_FACET);
+ 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)
+ {
+ Message::DefaultMessenger()->Send (TCollection_AsciiString ("RWStl - Binary STL file defines more triangles (") + aNbTrisInHeader
+ + ") that can be read (" + NBFACET + ") - probably corrupted file",
+ Message_Warning);
+ }
+ 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)
+ {
+ Message::DefaultMessenger()->Send (TCollection_AsciiString ("RWStl - Binary STL file has unidentified tail"),
+ Message_Warning);
+ }
// skip the header
theFile.Seek(HEADER_SIZE,OSD_FromBeginning);
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);
fy3 = ReadFloat2Double(theFile);
fz3 = ReadFloat2Double(theFile);
- i1 = ReadMesh->AddOnlyNewVertex (fx1,fy1,fz1);
- i2 = ReadMesh->AddOnlyNewVertex (fx2,fy2,fz2);
- i3 = ReadMesh->AddOnlyNewVertex (fx3,fy3,fz3);
+ // 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.Close ();
return ReadMesh;
-
}
+
//=======================================================================
//function : ReadAscii
-//Design :
-//Warning :
+//Design :
+//Warning :
//=======================================================================
-Handle_StlMesh_Mesh RWStl::ReadAscii(const OSD_Path& aPath)
+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_ShortReal x[4],y[4],z[4];
Standard_Integer i1,i2,i3;
Handle(StlMesh_Mesh) ReadMesh;
- aPath.SystemName( filename);
+ thePath.SystemName (filename);
- // Open the file
- FILE* file = fopen(filename.ToCString(),"r");
+ // Open the file
+ FILE* file = OSD_OpenFile(filename.ToCString(),"r");
fseek(file,0L,SEEK_END);
long filesize = ftell(file);
- fclose(file);
- file = fopen(filename.ToCString(),"r");
-
-
+ rewind(file);
// count the number of lines
for (ipos = 0; ipos < filesize; ++ipos) {
nbTris = (nbLines / ASCII_LINES_PER_FACET);
// go back to the beginning of the file
-// fclose(file);
-// file = fopen(filename.ToCString(),"r");
rewind(file);
// skip header
while (getc(file) != '\n');
-
- cout<< "start mesh\n";
- ReadMesh = new StlMesh_Mesh();
+#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
- for (iTri = 0; iTri < nbTris; ++iTri) {
+ Message_ProgressSentry aPS (theProgInd, "Triangles", 0, (nbTris - 1) * 1.0 / IND_THRESHOLD, 1);
+ for (iTri = 0; iTri < nbTris && aPS.More();)
+ {
+ char x[256]="", y[256]="", z[256]="";
+
// reading the facet normal
- fscanf(file,"%*s %*s %f %f %f\n",&x[0],&y[0],&z[0]);
+ 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"
- fscanf(file,"%*s %*s");
+ if (fscanf(file,"%*s %*s") < 0)
+ break;
// reading vertex
- fscanf(file,"%*s %f %f %f\n",&x[1],&y[1],&z[1]);
- fscanf(file,"%*s %f %f %f\n",&x[2],&y[2],&z[2]);
- fscanf(file,"%*s %f %f %f\n",&x[3],&y[3],&z[3]);
-
- // here the facet must be built and put in the mesh datastructure
-
- i1 = ReadMesh->AddOnlyNewVertex ((Standard_Real)x[1],(Standard_Real)y[1],(Standard_Real)z[1]);
- i2 = ReadMesh->AddOnlyNewVertex ((Standard_Real)x[2],(Standard_Real)y[2],(Standard_Real)z[2]);
- i3 = ReadMesh->AddOnlyNewVertex ((Standard_Real)x[3],(Standard_Real)y[3],(Standard_Real)z[3]);
- ReadMesh->AddTriangle (i1,i2,i3,(Standard_Real)x[0],(Standard_Real)y[0],(Standard_Real)z[0]);
+ 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"
- fscanf(file,"%*s");
+ if (fscanf(file,"%*s") < 0)
+ break;
// skip the keywords "endfacet"
- fscanf(file,"%*s");
+ if (fscanf(file,"%*s") < 0)
+ break;
+ // update progress only per 1k triangles
+ if (++iTri % IND_THRESHOLD == 0)
+ aPS.Next();
}
-
- cout<< "end mesh\n"<<endl;
+#ifdef OCCT_DEBUG
+ cout << "end mesh\n";
+#endif
fclose(file);
return ReadMesh;
-
}