1 /*---------------------------------------------------------------------------*\
3 \\ / F ield | foam-extend: Open Source CFD
4 \\ / O peration | Version: 3.2
5 \\ / A nd | Web: http://www.foam-extend.org
6 \\/ M anipulation | For copyright notice see file Copyright
7 -------------------------------------------------------------------------------
9 This file is part of foam-extend.
11 foam-extend is free software: you can redistribute it and/or modify it
12 under the terms of the GNU General Public License as published by the
13 Free Software Foundation, either version 3 of the License, or (at your
14 option) any later version.
16 foam-extend is distributed in the hope that it will be useful, but
17 WITHOUT ANY WARRANTY; without even the implied warranty of
18 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
19 General Public License for more details.
21 You should have received a copy of the GNU General Public License
22 along with foam-extend. If not, see <http://www.gnu.org/licenses/>.
24 \*---------------------------------------------------------------------------*/
26 #include "STLsurfaceFormat.H"
28 #include "triPointRef.H"
30 // * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * //
33 inline void Foam::fileFormats::STLsurfaceFormat<Face>::writeShell
36 const pointField& pointLst,
40 // calculate the normal ourselves, for flexibility and speed
41 vector norm = triPointRef
47 norm /= mag(norm) + VSMALL;
49 // simple triangulation about f[0].
50 // better triangulation should have been done before
51 const point& p0 = pointLst[f[0]];
52 for (label fp1 = 1; fp1 < f.size() - 1; ++fp1)
54 label fp2 = f.fcIndex(fp1);
56 const point& p1 = pointLst[f[fp1]];
57 const point& p2 = pointLst[f[fp2]];
60 os << " facet normal "
61 << norm.x() << ' ' << norm.y() << ' ' << norm.z() << nl
63 << " vertex " << p0.x() << ' ' << p0.y() << ' ' << p0.z() << nl
64 << " vertex " << p1.x() << ' ' << p1.y() << ' ' << p1.z() << nl
65 << " vertex " << p2.x() << ' ' << p2.y() << ' ' << p2.z() << nl
67 << " endfacet" << endl;
73 inline void Foam::fileFormats::STLsurfaceFormat<Face>::writeShell
76 const pointField& pointLst,
81 // calculate the normal ourselves, for flexibility and speed
82 vector norm = triPointRef
88 norm /= mag(norm) + VSMALL;
90 // simple triangulation about f[0].
91 // better triangulation should have been done before
92 const point& p0 = pointLst[f[0]];
93 for (label fp1 = 1; fp1 < f.size() - 1; ++fp1)
95 label fp2 = f.fcIndex(fp1);
111 // * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
114 Foam::fileFormats::STLsurfaceFormat<Face>::STLsurfaceFormat
116 const fileName& filename
123 // * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
126 bool Foam::fileFormats::STLsurfaceFormat<Face>::read
128 const fileName& filename
133 // read in the values
134 STLsurfaceFormatCore reader(filename);
137 this->storedPoints().transfer(reader.points());
139 // retrieve the original zone information
140 List<word> names(reader.names().xfer());
141 List<label> sizes(reader.sizes().xfer());
142 List<label> zoneIds(reader.zoneIds().xfer());
144 // generate the (sorted) faces
145 List<Face> faceLst(zoneIds.size());
149 // already sorted - generate directly
150 forAll(faceLst, faceI)
152 const label startPt = 3*faceI;
153 faceLst[faceI] = triFace(startPt, startPt+1, startPt+2);
158 // unsorted - determine the sorted order:
159 // avoid SortableList since we discard the main list anyhow
161 sortedOrder(zoneIds, faceMap);
163 // generate sorted faces
164 forAll(faceMap, faceI)
166 const label startPt = 3*faceMap[faceI];
167 faceLst[faceI] = triFace(startPt, startPt+1, startPt+2);
173 this->storedFaces().transfer(faceLst);
177 this->addZones(sizes, names);
181 this->addZones(sizes);
184 this->stitchFaces(SMALL);
191 void Foam::fileFormats::STLsurfaceFormat<Face>::writeAscii
193 const fileName& filename,
194 const MeshedSurfaceProxy<Face>& surf
197 OFstream os(filename);
202 "fileFormats::STLsurfaceFormat::writeAscii"
203 "(const fileName&, const MeshedSurfaceProxy<Face>&)"
205 << "Cannot open file for writing " << filename
209 const pointField& pointLst = surf.points();
210 const List<Face>& faceLst = surf.faces();
211 const List<label>& faceMap = surf.faceMap();
213 const List<surfZone>& zones =
215 surf.surfZones().size() > 1
217 : STLsurfaceFormat::oneZone(faceLst)
220 const bool useFaceMap = (surf.useFaceMap() && zones.size() > 1);
225 // Print all faces belonging to this zone
226 const surfZone& zone = zones[zoneI];
228 os << "solid " << zone.name() << nl;
232 forAll(zone, localFaceI)
234 const label faceI = faceMap[faceIndex++];
235 writeShell(os, pointLst, faceLst[faceI]);
240 forAll(zone, localFaceI)
242 writeShell(os, pointLst, faceLst[faceIndex++]);
245 os << "endsolid " << zone.name() << endl;
251 void Foam::fileFormats::STLsurfaceFormat<Face>::writeBinary
253 const fileName& filename,
254 const MeshedSurfaceProxy<Face>& surf
257 std::ofstream os(filename.c_str(), std::ios::binary);
262 "fileFormats::STLsurfaceFormat::writeBinary"
263 "(const fileName&, const MeshedSurfaceProxy<Face>&)"
265 << "Cannot open file for writing " << filename
270 const pointField& pointLst = surf.points();
271 const List<Face>& faceLst = surf.faces();
272 const List<label>& faceMap = surf.faceMap();
274 const List<surfZone>& zones =
276 surf.surfZones().size() > 1
278 : STLsurfaceFormat::oneZone(faceLst)
281 const bool useFaceMap = (surf.useFaceMap() && zones.size() > 1);
284 unsigned int nTris = 0;
285 if (MeshedSurface<Face>::isTri())
287 nTris = faceLst.size();
291 // count triangles for on-the-fly triangulation
292 forAll(faceLst, faceI)
294 nTris += faceLst[faceI].size() - 2;
298 // Write the STL header
299 STLsurfaceFormatCore::writeHeaderBINARY(os, nTris);
304 const surfZone& zone = zones[zoneI];
308 forAll(zone, localFaceI)
314 faceLst[faceMap[faceIndex++]],
321 forAll(zone, localFaceI)
327 faceLst[faceIndex++],
337 void Foam::fileFormats::STLsurfaceFormat<Face>::writeAscii
339 const fileName& filename,
340 const UnsortedMeshedSurface<Face>& surf
343 OFstream os(filename);
348 "fileFormats::STLsurfaceFormat::writeAscii"
349 "(const fileName&, const UnsortedMeshedSurface<Face>&)"
351 << "Cannot open file for writing " << filename
355 // a single zone - we can skip sorting
356 if (surf.zoneToc().size() == 1)
358 const pointField& pointLst = surf.points();
359 const List<Face>& faceLst = surf.faces();
361 os << "solid " << surf.zoneToc()[0].name() << endl;
362 forAll(faceLst, faceI)
364 writeShell(os, pointLst, faceLst[faceI]);
366 os << "endsolid " << surf.zoneToc()[0].name() << endl;
371 List<surfZone> zoneLst = surf.sortedZones(faceMap);
376 MeshedSurfaceProxy<Face>
389 void Foam::fileFormats::STLsurfaceFormat<Face>::writeBinary
391 const fileName& filename,
392 const UnsortedMeshedSurface<Face>& surf
395 std::ofstream os(filename.c_str(), std::ios::binary);
400 "fileFormats::STLsurfaceFormat::writeBinary"
401 "(const fileName&, const UnsortedMeshedSurface<Face>&)"
403 << "Cannot open file for writing " << filename
407 const pointField& pointLst = surf.points();
408 const List<Face>& faceLst = surf.faces();
409 const List<label>& zoneIds = surf.zoneIds();
411 unsigned int nTris = 0;
412 if (MeshedSurface<Face>::isTri())
414 nTris = faceLst.size();
418 // count triangles for on-the-fly triangulation
419 forAll(faceLst, faceI)
421 nTris += faceLst[faceI].size() - 2;
425 // Write the STL header
426 STLsurfaceFormatCore::writeHeaderBINARY(os, nTris);
428 // always write unsorted
429 forAll(faceLst, faceI)
443 void Foam::fileFormats::STLsurfaceFormat<Face>::write
445 const fileName& filename,
446 const MeshedSurfaceProxy<Face>& surf
449 const word ext = filename.ext();
451 // handle 'stlb' as binary directly
454 writeBinary(filename, surf);
458 writeAscii(filename, surf);
464 void Foam::fileFormats::STLsurfaceFormat<Face>::write
466 const fileName& filename,
467 const UnsortedMeshedSurface<Face>& surf
470 word ext = filename.ext();
472 // handle 'stlb' as binary directly
475 writeBinary(filename, surf);
479 writeAscii(filename, surf);
484 // ************************************************************************* //