Commit | Line | Data |
---|---|---|
b311480e | 1 | // Created on: 1994-10-13 |
2 | // Created by: Marc LEGAY | |
3 | // Copyright (c) 1994-1999 Matra Datavision | |
973c2be1 | 4 | // Copyright (c) 1999-2014 OPEN CASCADE SAS |
b311480e | 5 | // |
973c2be1 | 6 | // This file is part of Open CASCADE Technology software library. |
b311480e | 7 | // |
d5f74e42 | 8 | // This library is free software; you can redistribute it and/or modify it under |
9 | // the terms of the GNU Lesser General Public License version 2.1 as published | |
973c2be1 | 10 | // by the Free Software Foundation, with special exception defined in the file |
11 | // OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT | |
12 | // distribution for complete text of the license and disclaimer of any warranty. | |
b311480e | 13 | // |
973c2be1 | 14 | // Alternatively, this file may be used under the terms of Open CASCADE |
15 | // commercial license or contractual agreement. | |
7fd59977 | 16 | |
ed482379 | 17 | #include <RWStl.ixx> |
7fd59977 | 18 | #include <OSD_Protection.hxx> |
19 | #include <OSD_File.hxx> | |
9c6afe19 | 20 | #include <Message_ProgressSentry.hxx> |
7fd59977 | 21 | #include <TCollection_AsciiString.hxx> |
22 | #include <Standard_NoMoreObject.hxx> | |
23 | #include <Standard_TypeMismatch.hxx> | |
24 | #include <Precision.hxx> | |
25 | #include <StlMesh_MeshExplorer.hxx> | |
26 | #include <OSD.hxx> | |
27 | #include <OSD_Host.hxx> | |
28 | #include <gp_XYZ.hxx> | |
29 | #include <gp.hxx> | |
30 | #include <stdio.h> | |
31 | #include <gp_Vec.hxx> | |
32 | ||
7fd59977 | 33 | // constants |
8cb69787 | 34 | static const size_t HEADER_SIZE = 84; |
35 | static const size_t SIZEOF_STL_FACET = 50; | |
36 | static const size_t STL_MIN_FILE_SIZE = 284; | |
37 | static const size_t ASCII_LINES_PER_FACET = 7; | |
38 | ||
39 | static const int IND_THRESHOLD = 1000; // increment the indicator every 1k triangles | |
7fd59977 | 40 | |
ed482379 | 41 | //======================================================================= |
7fd59977 | 42 | //function : WriteInteger |
43 | //purpose : writing a Little Endian 32 bits integer | |
44 | //======================================================================= | |
45 | ||
46 | inline static void WriteInteger(OSD_File& ofile,const Standard_Integer value) | |
47 | { | |
48 | union { | |
49 | Standard_Integer i;// don't be afraid, this is just an unsigned int | |
50 | char c[4]; | |
51 | } bidargum; | |
52 | ||
53 | bidargum.i = value; | |
54 | ||
55 | Standard_Integer entier; | |
ed482379 | 56 | |
7fd59977 | 57 | entier = bidargum.c[0] & 0xFF; |
58 | entier |= (bidargum.c[1] & 0xFF) << 0x08; | |
59 | entier |= (bidargum.c[2] & 0xFF) << 0x10; | |
60 | entier |= (bidargum.c[3] & 0xFF) << 0x18; | |
61 | ||
62 | ofile.Write((char *)&entier,sizeof(bidargum.c)); | |
63 | } | |
64 | ||
65 | //======================================================================= | |
66 | //function : WriteDouble2Float | |
67 | //purpose : writing a Little Endian 32 bits float | |
68 | //======================================================================= | |
69 | ||
70 | inline static void WriteDouble2Float(OSD_File& ofile,Standard_Real value) | |
71 | { | |
72 | union { | |
73 | Standard_ShortReal f; | |
74 | char c[4]; | |
75 | } bidargum; | |
76 | ||
77 | bidargum.f = (Standard_ShortReal)value; | |
78 | ||
79 | Standard_Integer entier; | |
ed482379 | 80 | |
7fd59977 | 81 | entier = bidargum.c[0] & 0xFF; |
82 | entier |= (bidargum.c[1] & 0xFF) << 0x08; | |
83 | entier |= (bidargum.c[2] & 0xFF) << 0x10; | |
84 | entier |= (bidargum.c[3] & 0xFF) << 0x18; | |
85 | ||
86 | ofile.Write((char *)&entier,sizeof(bidargum.c)); | |
87 | } | |
88 | ||
89 | ||
90 | //======================================================================= | |
91 | //function : readFloat2Double | |
92 | //purpose : reading a Little Endian 32 bits float | |
93 | //======================================================================= | |
94 | ||
95 | inline static Standard_Real ReadFloat2Double(OSD_File &aFile) | |
96 | { | |
97 | union { | |
98 | Standard_Boolean i; // don't be afraid, this is just an unsigned int | |
99 | Standard_ShortReal f; | |
100 | }bidargum; | |
101 | ||
102 | char c[4]; | |
103 | Standard_Address adr; | |
104 | adr = (Standard_Address)c; | |
105 | Standard_Integer lread; | |
106 | aFile.Read(adr,4,lread); | |
107 | bidargum.i = c[0] & 0xFF; | |
108 | bidargum.i |= (c[1] & 0xFF) << 0x08; | |
109 | bidargum.i |= (c[2] & 0xFF) << 0x10; | |
110 | bidargum.i |= (c[3] & 0xFF) << 0x18; | |
111 | ||
112 | return (Standard_Real)(bidargum.f); | |
113 | } | |
114 | ||
115 | ||
116 | ||
117 | //======================================================================= | |
118 | //function : WriteBinary | |
119 | //purpose : write a binary STL file in Little Endian format | |
120 | //======================================================================= | |
121 | ||
9c6afe19 RK |
122 | Standard_Boolean RWStl::WriteBinary (const Handle(StlMesh_Mesh)& theMesh, |
123 | const OSD_Path& thePath, | |
124 | const Handle(Message_ProgressIndicator)& theProgInd) | |
7fd59977 | 125 | { |
9c6afe19 RK |
126 | OSD_File aFile (thePath); |
127 | aFile.Build (OSD_WriteOnly, OSD_Protection()); | |
7fd59977 | 128 | |
129 | Standard_Real x1, y1, z1; | |
130 | Standard_Real x2, y2, z2; | |
131 | Standard_Real x3, y3, z3; | |
ed482379 | 132 | |
9c6afe19 | 133 | // writing 80 bytes of the trash? |
7fd59977 | 134 | char sval[80]; |
9c6afe19 RK |
135 | aFile.Write ((Standard_Address)sval,80); |
136 | WriteInteger (aFile, theMesh->NbTriangles()); | |
137 | ||
7fd59977 | 138 | int dum=0; |
9c6afe19 RK |
139 | StlMesh_MeshExplorer aMexp (theMesh); |
140 | ||
141 | // create progress sentry for domains | |
142 | Standard_Integer aNbDomains = theMesh->NbDomains(); | |
143 | Message_ProgressSentry aDPS (theProgInd, "Mesh domains", 0, aNbDomains, 1); | |
144 | for (Standard_Integer nbd = 1; nbd <= aNbDomains && aDPS.More(); nbd++, aDPS.Next()) | |
145 | { | |
146 | // create progress sentry for triangles in domain | |
147 | Message_ProgressSentry aTPS (theProgInd, "Triangles", 0, | |
148 | theMesh->NbTriangles (nbd), IND_THRESHOLD); | |
149 | Standard_Integer aTriangleInd = 0; | |
150 | for (aMexp.InitTriangle (nbd); aMexp.MoreTriangle(); aMexp.NextTriangle()) | |
151 | { | |
152 | aMexp.TriangleVertices (x1,y1,z1,x2,y2,z2,x3,y3,z3); | |
153 | //pgo aMexp.TriangleOrientation (x,y,z); | |
154 | gp_XYZ Vect12 ((x2-x1), (y2-y1), (z2-z1)); | |
155 | gp_XYZ Vect13 ((x3-x1), (y3-y1), (z3-z1)); | |
156 | gp_XYZ Vnorm = Vect12 ^ Vect13; | |
157 | Standard_Real Vmodul = Vnorm.Modulus (); | |
158 | if (Vmodul > gp::Resolution()) | |
159 | { | |
160 | Vnorm.Divide(Vmodul); | |
161 | } | |
162 | else | |
163 | { | |
164 | // si Vnorm est quasi-nul, on le charge a 0 explicitement | |
165 | Vnorm.SetCoord (0., 0., 0.); | |
166 | } | |
167 | ||
168 | WriteDouble2Float (aFile, Vnorm.X()); | |
169 | WriteDouble2Float (aFile, Vnorm.Y()); | |
170 | WriteDouble2Float (aFile, Vnorm.Z()); | |
171 | ||
172 | WriteDouble2Float (aFile, x1); | |
173 | WriteDouble2Float (aFile, y1); | |
174 | WriteDouble2Float (aFile, z1); | |
175 | ||
176 | WriteDouble2Float (aFile, x2); | |
177 | WriteDouble2Float (aFile, y2); | |
178 | WriteDouble2Float (aFile, z2); | |
179 | ||
180 | WriteDouble2Float (aFile, x3); | |
181 | WriteDouble2Float (aFile, y3); | |
182 | WriteDouble2Float (aFile, z3); | |
ed482379 | 183 | |
9c6afe19 RK |
184 | aFile.Write (&dum, 2); |
185 | ||
186 | // update progress only per 1k triangles | |
187 | if (++aTriangleInd % IND_THRESHOLD == 0) | |
188 | { | |
189 | if (!aTPS.More()) | |
190 | break; | |
191 | aTPS.Next(); | |
7fd59977 | 192 | } |
9c6afe19 | 193 | } |
7fd59977 | 194 | } |
9c6afe19 RK |
195 | aFile.Close(); |
196 | Standard_Boolean isInterrupted = !aDPS.More(); | |
197 | return !isInterrupted; | |
7fd59977 | 198 | } |
199 | //======================================================================= | |
200 | //function : WriteAscii | |
201 | //purpose : write an ASCII STL file | |
202 | //======================================================================= | |
203 | ||
9c6afe19 RK |
204 | Standard_Boolean RWStl::WriteAscii (const Handle(StlMesh_Mesh)& theMesh, |
205 | const OSD_Path& thePath, | |
206 | const Handle(Message_ProgressIndicator)& theProgInd) | |
7fd59977 | 207 | { |
9c6afe19 | 208 | OSD_File theFile (thePath); |
7fd59977 | 209 | theFile.Build(OSD_WriteOnly,OSD_Protection()); |
9c6afe19 | 210 | TCollection_AsciiString buf ("solid\n"); |
7fd59977 | 211 | theFile.Write (buf,buf.Length());buf.Clear(); |
ed482379 | 212 | |
7fd59977 | 213 | Standard_Real x1, y1, z1; |
214 | Standard_Real x2, y2, z2; | |
215 | Standard_Real x3, y3, z3; | |
9c6afe19 RK |
216 | char sval[512]; |
217 | ||
218 | // create progress sentry for domains | |
219 | Standard_Integer aNbDomains = theMesh->NbDomains(); | |
220 | Message_ProgressSentry aDPS (theProgInd, "Mesh domains", 0, aNbDomains, 1); | |
221 | StlMesh_MeshExplorer aMexp (theMesh); | |
222 | for (Standard_Integer nbd = 1; nbd <= aNbDomains && aDPS.More(); nbd++, aDPS.Next()) | |
223 | { | |
224 | // create progress sentry for triangles in domain | |
225 | Message_ProgressSentry aTPS (theProgInd, "Triangles", 0, | |
226 | theMesh->NbTriangles (nbd), IND_THRESHOLD); | |
227 | Standard_Integer aTriangleInd = 0; | |
228 | for (aMexp.InitTriangle (nbd); aMexp.MoreTriangle(); aMexp.NextTriangle()) | |
229 | { | |
7fd59977 | 230 | aMexp.TriangleVertices (x1,y1,z1,x2,y2,z2,x3,y3,z3); |
ed482379 | 231 | |
7fd59977 | 232 | // Standard_Real x, y, z; |
233 | // aMexp.TriangleOrientation (x,y,z); | |
ed482379 | 234 | |
7fd59977 | 235 | gp_XYZ Vect12 ((x2-x1), (y2-y1), (z2-z1)); |
236 | gp_XYZ Vect23 ((x3-x2), (y3-y2), (z3-z2)); | |
9c6afe19 | 237 | gp_XYZ Vnorm = Vect12 ^ Vect23; |
7fd59977 | 238 | Standard_Real Vmodul = Vnorm.Modulus (); |
9c6afe19 RK |
239 | if (Vmodul > gp::Resolution()) |
240 | { | |
241 | Vnorm.Divide (Vmodul); | |
242 | } | |
243 | else | |
244 | { | |
245 | // si Vnorm est quasi-nul, on le charge a 0 explicitement | |
246 | Vnorm.SetCoord (0., 0., 0.); | |
7fd59977 | 247 | } |
91322f44 | 248 | Sprintf (sval, |
9c6afe19 RK |
249 | " facet normal % 12e % 12e % 12e\n" |
250 | " outer loop\n" | |
251 | " vertex % 12e % 12e % 12e\n" | |
252 | " vertex % 12e % 12e % 12e\n" | |
253 | " vertex % 12e % 12e % 12e\n" | |
254 | " endloop\n" | |
255 | " endfacet\n", | |
256 | Vnorm.X(), Vnorm.Y(), Vnorm.Z(), | |
257 | x1, y1, z1, | |
258 | x2, y2, z2, | |
259 | x3, y3, z3); | |
68bc5ed7 | 260 | buf += sval; |
9c6afe19 RK |
261 | theFile.Write (buf, buf.Length()); buf.Clear(); |
262 | ||
263 | // update progress only per 1k triangles | |
264 | if (++aTriangleInd % IND_THRESHOLD == 0) | |
265 | { | |
266 | if (!aTPS.More()) | |
267 | break; | |
268 | aTPS.Next(); | |
7fd59977 | 269 | } |
7fd59977 | 270 | } |
271 | } | |
ed482379 | 272 | |
7fd59977 | 273 | buf += "endsolid\n"; |
9c6afe19 RK |
274 | theFile.Write (buf, buf.Length()); buf.Clear(); |
275 | theFile.Close(); | |
276 | Standard_Boolean isInterrupted = !aDPS.More(); | |
277 | return !isInterrupted; | |
7fd59977 | 278 | } |
279 | //======================================================================= | |
280 | //function : ReadFile | |
ed482379 K |
281 | //Design : |
282 | //Warning : | |
7fd59977 | 283 | //======================================================================= |
284 | ||
857ffd5e | 285 | Handle(StlMesh_Mesh) RWStl::ReadFile (const OSD_Path& thePath, |
9c6afe19 | 286 | const Handle(Message_ProgressIndicator)& theProgInd) |
7fd59977 | 287 | { |
9c6afe19 | 288 | OSD_File file (thePath); |
7fd59977 | 289 | file.Open(OSD_ReadOnly,OSD_Protection(OSD_RWD,OSD_RWD,OSD_RWD,OSD_RWD)); |
290 | Standard_Boolean IsAscii; | |
291 | unsigned char str[128]; | |
292 | Standard_Integer lread,i; | |
293 | Standard_Address ach; | |
294 | ach = (Standard_Address)str; | |
ed482379 | 295 | |
7fd59977 | 296 | // we skip the header which is in Ascii for both modes |
297 | file.Read(ach,HEADER_SIZE,lread); | |
298 | ||
299 | // we read 128 characters to detect if we have a non-ascii char | |
300 | file.Read(ach,sizeof(str),lread); | |
301 | ||
302 | IsAscii = Standard_True; | |
303 | for (i = 0; i< lread && IsAscii; ++i) { | |
304 | if (str[i] > '~') { | |
305 | IsAscii = Standard_False; | |
306 | } | |
307 | } | |
ed482379 K |
308 | #ifdef DEB |
309 | cout << (IsAscii ? "ascii\n" : "binary\n"); | |
310 | #endif | |
7fd59977 | 311 | file.Close(); |
ed482379 | 312 | |
9c6afe19 RK |
313 | return IsAscii ? RWStl::ReadAscii (thePath, theProgInd) |
314 | : RWStl::ReadBinary (thePath, theProgInd); | |
7fd59977 | 315 | } |
316 | ||
317 | //======================================================================= | |
318 | //function : ReadBinary | |
ed482379 K |
319 | //Design : |
320 | //Warning : | |
7fd59977 | 321 | //======================================================================= |
322 | ||
857ffd5e | 323 | Handle(StlMesh_Mesh) RWStl::ReadBinary (const OSD_Path& thePath, |
9c6afe19 | 324 | const Handle(Message_ProgressIndicator)& /*theProgInd*/) |
7fd59977 | 325 | { |
326 | Standard_Integer NBFACET; | |
327 | Standard_Integer ifacet; | |
328 | Standard_Real fx,fy,fz,fx1,fy1,fz1,fx2,fy2,fz2,fx3,fy3,fz3; | |
329 | Standard_Integer i1,i2,i3,lread; | |
330 | char buftest[5]; | |
331 | Standard_Address adr; | |
332 | adr = (Standard_Address)buftest; | |
333 | ||
ed482379 | 334 | // Open the file |
9c6afe19 | 335 | OSD_File theFile (thePath); |
7fd59977 | 336 | theFile.Open(OSD_ReadOnly,OSD_Protection(OSD_RWD,OSD_RWD,OSD_RWD,OSD_RWD)); |
337 | ||
338 | // the size of the file (minus the header size) | |
339 | // must be a multiple of SIZEOF_STL_FACET | |
340 | ||
341 | // compute file size | |
6ff736d8 | 342 | Standard_Size filesize = theFile.Size(); |
7fd59977 | 343 | |
ed482379 | 344 | if ( (filesize - HEADER_SIZE) % SIZEOF_STL_FACET !=0 |
7fd59977 | 345 | || (filesize < STL_MIN_FILE_SIZE)) { |
346 | Standard_NoMoreObject::Raise("RWStl::ReadBinary (wrong file size)"); | |
347 | } | |
348 | ||
349 | // don't trust the number of triangles which is coded in the file | |
350 | // sometimes it is wrong, and with this technique we don't need to swap endians for integer | |
6ff736d8 | 351 | NBFACET = (Standard_Integer)((filesize - HEADER_SIZE) / SIZEOF_STL_FACET); |
7fd59977 | 352 | |
353 | // skip the header | |
354 | theFile.Seek(HEADER_SIZE,OSD_FromBeginning); | |
355 | ||
356 | // create the StlMesh_Mesh object | |
357 | Handle(StlMesh_Mesh) ReadMesh = new StlMesh_Mesh (); | |
358 | ReadMesh->AddDomain (); | |
359 | ||
360 | for (ifacet=1; ifacet<=NBFACET; ++ifacet) { | |
361 | // read normal coordinates | |
362 | fx = ReadFloat2Double(theFile); | |
363 | fy = ReadFloat2Double(theFile); | |
364 | fz = ReadFloat2Double(theFile); | |
365 | ||
366 | // read vertex 1 | |
367 | fx1 = ReadFloat2Double(theFile); | |
368 | fy1 = ReadFloat2Double(theFile); | |
369 | fz1 = ReadFloat2Double(theFile); | |
370 | ||
371 | // read vertex 2 | |
372 | fx2 = ReadFloat2Double(theFile); | |
373 | fy2 = ReadFloat2Double(theFile); | |
374 | fz2 = ReadFloat2Double(theFile); | |
375 | ||
376 | // read vertex 3 | |
377 | fx3 = ReadFloat2Double(theFile); | |
378 | fy3 = ReadFloat2Double(theFile); | |
379 | fz3 = ReadFloat2Double(theFile); | |
380 | ||
381 | i1 = ReadMesh->AddOnlyNewVertex (fx1,fy1,fz1); | |
382 | i2 = ReadMesh->AddOnlyNewVertex (fx2,fy2,fz2); | |
383 | i3 = ReadMesh->AddOnlyNewVertex (fx3,fy3,fz3); | |
384 | ReadMesh->AddTriangle (i1,i2,i3,fx,fy,fz); | |
385 | ||
386 | // skip extra bytes | |
387 | theFile.Read(adr,2,lread); | |
388 | } | |
389 | ||
390 | theFile.Close (); | |
391 | return ReadMesh; | |
ed482379 | 392 | |
7fd59977 | 393 | } |
394 | //======================================================================= | |
395 | //function : ReadAscii | |
ed482379 K |
396 | //Design : |
397 | //Warning : | |
7fd59977 | 398 | //======================================================================= |
399 | ||
857ffd5e | 400 | Handle(StlMesh_Mesh) RWStl::ReadAscii (const OSD_Path& thePath, |
9c6afe19 | 401 | const Handle(Message_ProgressIndicator)& theProgInd) |
7fd59977 | 402 | { |
403 | TCollection_AsciiString filename; | |
404 | long ipos; | |
405 | Standard_Integer nbLines = 0; | |
406 | Standard_Integer nbTris = 0; | |
407 | Standard_Integer iTri; | |
7fd59977 | 408 | Standard_Integer i1,i2,i3; |
409 | Handle(StlMesh_Mesh) ReadMesh; | |
410 | ||
9c6afe19 | 411 | thePath.SystemName (filename); |
7fd59977 | 412 | |
ed482379 | 413 | // Open the file |
7fd59977 | 414 | FILE* file = fopen(filename.ToCString(),"r"); |
415 | ||
416 | fseek(file,0L,SEEK_END); | |
417 | ||
418 | long filesize = ftell(file); | |
419 | ||
420 | fclose(file); | |
421 | file = fopen(filename.ToCString(),"r"); | |
422 | ||
7fd59977 | 423 | // count the number of lines |
424 | for (ipos = 0; ipos < filesize; ++ipos) { | |
425 | if (getc(file) == '\n') | |
426 | nbLines++; | |
427 | } | |
428 | ||
429 | // compute number of triangles | |
430 | nbTris = (nbLines / ASCII_LINES_PER_FACET); | |
431 | ||
432 | // go back to the beginning of the file | |
433 | // fclose(file); | |
434 | // file = fopen(filename.ToCString(),"r"); | |
435 | rewind(file); | |
436 | ||
437 | // skip header | |
438 | while (getc(file) != '\n'); | |
ed482379 K |
439 | #ifdef DEB |
440 | cout << "start mesh\n"; | |
441 | #endif | |
442 | ReadMesh = new StlMesh_Mesh(); | |
7fd59977 | 443 | ReadMesh->AddDomain(); |
444 | ||
445 | // main reading | |
9c6afe19 RK |
446 | Message_ProgressSentry aPS (theProgInd, "Triangles", 0, (nbTris - 1) * 1.0 / IND_THRESHOLD, 1); |
447 | for (iTri = 0; iTri < nbTris && aPS.More();) | |
448 | { | |
91322f44 | 449 | char x[256]="", y[256]="", z[256]=""; |
450 | ||
7fd59977 | 451 | // reading the facet normal |
91322f44 | 452 | if (3 != fscanf(file,"%*s %*s %80s %80s %80s\n", x, y, z)) |
453 | break; // error should be properly reported | |
454 | gp_XYZ aN (Atof(x), Atof(y), Atof(z)); | |
7fd59977 | 455 | |
456 | // skip the keywords "outer loop" | |
457 | fscanf(file,"%*s %*s"); | |
458 | ||
459 | // reading vertex | |
91322f44 | 460 | if (3 != fscanf(file,"%*s %80s %80s %80s\n", x, y, z)) |
461 | break; // error should be properly reported | |
462 | gp_XYZ aV1 (Atof(x), Atof(y), Atof(z)); | |
463 | if (3 != fscanf(file,"%*s %80s %80s %80s\n", x, y, z)) | |
464 | break; // error should be properly reported | |
465 | gp_XYZ aV2 (Atof(x), Atof(y), Atof(z)); | |
466 | if (3 != fscanf(file,"%*s %80s %80s %80s\n", x, y, z)) | |
467 | break; // error should be properly reported | |
468 | gp_XYZ aV3 (Atof(x), Atof(y), Atof(z)); | |
7fd59977 | 469 | |
ed482379 | 470 | // here the facet must be built and put in the mesh datastructure |
7fd59977 | 471 | |
91322f44 | 472 | i1 = ReadMesh->AddOnlyNewVertex (aV1.X(), aV1.Y(), aV1.Z()); |
473 | i2 = ReadMesh->AddOnlyNewVertex (aV2.X(), aV2.Y(), aV2.Z()); | |
474 | i3 = ReadMesh->AddOnlyNewVertex (aV3.X(), aV3.Y(), aV3.Z()); | |
475 | ReadMesh->AddTriangle (i1, i2, i3, aN.X(), aN.Y(), aN.Z()); | |
7fd59977 | 476 | |
477 | // skip the keywords "endloop" | |
478 | fscanf(file,"%*s"); | |
479 | ||
480 | // skip the keywords "endfacet" | |
481 | fscanf(file,"%*s"); | |
482 | ||
9c6afe19 RK |
483 | // update progress only per 1k triangles |
484 | if (++iTri % IND_THRESHOLD == 0) | |
485 | aPS.Next(); | |
7fd59977 | 486 | } |
ed482379 K |
487 | #ifdef DEB |
488 | cout << "end mesh\n"; | |
489 | #endif | |
7fd59977 | 490 | fclose(file); |
491 | return ReadMesh; | |
7fd59977 | 492 | } |