1 /*---------------------------------------------------------------------------*\
3 \\ / F ield | OpenFOAM: The Open Source CFD Toolbox
5 \\ / A nd | Copyright (C) 2011 OpenFOAM Foundation
7 -------------------------------------------------------------------------------
9 This file is part of OpenFOAM.
11 OpenFOAM is free software: you can redistribute it and/or modify it
12 under the terms of the GNU General Public License as published by
13 the Free Software Foundation, either version 3 of the License, or
14 (at your option) any later version.
16 OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
17 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
18 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
21 You should have received a copy of the GNU General Public License
22 along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>.
24 \*---------------------------------------------------------------------------*/
26 #include "AC3DsurfaceFormat.H"
28 #include "IStringStream.H"
30 #include "primitivePatch.H"
32 // * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
35 Foam::fileFormats::AC3DsurfaceFormat<Face>::AC3DsurfaceFormat
37 const fileName& filename
44 // * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
47 bool Foam::fileFormats::AC3DsurfaceFormat<Face>::read
49 const fileName& filename
52 const bool mustTriangulate = this->isTri();
55 IFstream is(filename);
60 "fileFormats::AC3DsurfaceFormat::read(const fileName&)"
62 << "Cannot read file " << filename
66 string line, cmd, args;
70 string version = line.substr(4);
76 "fileFormats::AC3DsurfaceFormat::read(const fileName&)"
78 << "When reading AC3D file " << filename
79 << " read header " << line << " with version "
81 << "Only tested reading with version 'b'."
82 << " This might give problems" << endl;
86 if (!cueTo(is, "OBJECT", args) || (args != "world"))
90 "fileFormats::AC3DsurfaceFormat::read(const fileName&)"
92 << "Cannot find \"OBJECT world\" in file " << filename
96 // # of kids is the # of zones
97 args = cueToOrDie(is, "kids");
98 label nZones = parse<int>(args);
100 // Start of vertices for object/zones
101 label vertexOffset = 0;
103 DynamicList<point> dynPoints;
104 DynamicList<Face> dynFaces;
105 List<word> names(nZones);
106 List<label> sizes(nZones, 0);
108 for (label zoneI = 0; zoneI < nZones; ++zoneI)
110 names[zoneI] = word("zone") + Foam::name(zoneI);
112 args = cueToOrDie(is, "OBJECT", "while reading " + names[zoneI]);
114 // number of vertices for this zone
115 label nZonePoints = 0;
116 vector location(pTraits<vector>::zero);
117 // tensor rotation(I);
119 // Read all info for current zone
122 // Read line and get first word. If end of file break since
123 // zone should always end with 'kids' command ?not sure.
124 if (!readCmd(is, cmd, args))
128 "fileFormats::AC3DsurfaceFormat::read(const fileName&)"
130 << "Did not read up to \"kids 0\" while reading zone "
131 << zoneI << " from file " << filename
138 string str = parse<string>(args);
139 string::stripInvalid<word>(str);
143 else if (cmd == "rot")
145 // rot %f %f %f %f %f %f %f %f %f
147 // IStringStream lineStream(args);
150 // >> rotation.xx() >> rotation.xy() >> rotation.xz()
151 // >> rotation.yx() >> rotation.yy() >> rotation.yz()
152 // >> rotation.zx() >> rotation.zy() >> rotation.zz();
156 "fileFormats::AC3DsurfaceFormat::read"
159 << "rot (rotation tensor) command not implemented"
160 << "Line:" << cmd << ' ' << args << endl
161 << "while reading zone " << zoneI << endl;
163 else if (cmd == "loc")
166 IStringStream lineStream(args);
173 else if (cmd == "numvert")
176 nZonePoints = parse<int>(args);
178 for (label vertI = 0; vertI < nZonePoints; ++vertI)
181 IStringStream lineStream(line);
185 >> pt.x() >> pt.y() >> pt.z();
187 // Offset with current translation vector
188 dynPoints.append(location + pt);
191 else if (cmd == "numsurf")
193 label nFaces = parse<int>(args);
195 for (label faceI = 0; faceI < nFaces; ++faceI)
197 static string errorMsg =
198 string(" while reading face ")
199 + Foam::name(faceI) + " on zone "
201 + " from file " + filename;
203 cueToOrDie(is, "SURF", errorMsg);
204 cueToOrDie(is, "mat", errorMsg);
205 args = cueToOrDie(is, "refs", errorMsg);
207 label nVert = parse<int>(args);
209 List<label> verts(nVert);
213 verts[vertI] = parse<int>(line) + vertexOffset;
216 labelUList& f = static_cast<labelUList&>(verts);
218 if (mustTriangulate && f.size() > 3)
220 // simple face triangulation about f[0]
221 // points may be incomplete
222 for (label fp1 = 1; fp1 < f.size() - 1; ++fp1)
224 label fp2 = f.fcIndex(fp1);
226 dynFaces.append(triFace(f[0], f[fp1], f[fp2]));
232 dynFaces.append(Face(f));
237 // Done the current zone.
238 // Increment the offset vertices are stored at
239 vertexOffset += nZonePoints;
241 else if (cmd == "kids")
243 // 'kids' denotes the end of the current zone.
244 label nKids = parse<int>(args);
250 "fileFormats::AC3DsurfaceFormat::read(const fileName&)"
252 << "Can only read objects without kids."
253 << " Encountered " << nKids << " kids when"
254 << " reading zone " << zoneI
258 // Done reading current zone
264 // transfer to normal lists
265 this->storedPoints().transfer(dynPoints);
266 this->storedFaces().transfer(dynFaces);
268 // add zones, culling empty ones
269 this->addZones(sizes, names, true);
270 this->stitchFaces(SMALL);
276 void Foam::fileFormats::AC3DsurfaceFormat<Face>::write
278 const fileName& filename,
279 const MeshedSurfaceProxy<Face>& surf
282 const pointField& pointLst = surf.points();
283 const List<Face>& faceLst = surf.faces();
285 const List<surfZone>& zones =
287 surf.surfZones().size()
289 : surfaceFormatsCore::oneZone(faceLst)
292 const bool useFaceMap = (surf.useFaceMap() && zones.size() > 1);
298 "fileFormats::AC3DsurfaceFormat::write"
299 "(const fileName&, const MeshedSurfaceProxy<Face>&)"
301 << "output with faceMap is not supported " << filename
306 OFstream os(filename);
311 "fileFormats::AC3DsurfaceFormat::write"
312 "(const fileName&, const MeshedSurfaceProxy<Face>&)"
314 << "Cannot open file for writing " << filename
318 writeHeader(os, zones);
322 const surfZone& zone = zones[zoneI];
324 os << "OBJECT poly" << nl
325 << "name \"" << zone.name() << "\"\n";
327 // Temporary PrimitivePatch to calculate compact points & faces
328 // use 'UList' to avoid allocations!
329 PrimitivePatch<Face, UList, const pointField&> patch
340 os << "numvert " << patch.nPoints() << endl;
342 forAll(patch.localPoints(), ptI)
344 const point& pt = patch.localPoints()[ptI];
346 os << pt.x() << ' ' << pt.y() << ' ' << pt.z() << nl;
349 os << "numsurf " << patch.localFaces().size() << endl;
351 forAll(patch.localFaces(), localFaceI)
353 const Face& f = patch.localFaces()[localFaceI];
355 os << "SURF 0x20" << nl // polygon
356 << "mat " << zoneI << nl
357 << "refs " << f.size() << nl;
361 os << f[fp] << " 0 0" << nl;
365 os << "kids 0" << endl;
371 void Foam::fileFormats::AC3DsurfaceFormat<Face>::write
373 const fileName& filename,
374 const UnsortedMeshedSurface<Face>& surf
378 List<surfZone> zoneLst = surf.sortedZones(faceMap);
380 if (zoneLst.size() <= 1)
385 MeshedSurfaceProxy<Face>
395 OFstream os(filename);
400 "fileFormats::AC3DsurfaceFormat::write"
401 "(const fileName&, const MeshedSurfaceProxy<Face>&)"
403 << "Cannot open file for writing " << filename
407 writeHeader(os, zoneLst);
410 forAll(zoneLst, zoneI)
412 const surfZone& zone = zoneLst[zoneI];
414 os << "OBJECT poly" << nl
415 << "name \"" << zone.name() << "\"\n";
417 // Create zone with only zone faces included for ease of addressing
418 labelHashSet include(surf.size());
420 forAll(zone, localFaceI)
422 const label faceI = faceMap[faceIndex++];
423 include.insert(faceI);
426 UnsortedMeshedSurface<Face> subm = surf.subsetMesh(include);
428 // Now we have isolated surface for this patch alone. Write it.
429 os << "numvert " << subm.nPoints() << endl;
431 forAll(subm.localPoints(), ptI)
433 const point& pt = subm.localPoints()[ptI];
435 os << pt.x() << ' ' << pt.y() << ' ' << pt.z() << endl;
438 os << "numsurf " << subm.localFaces().size() << endl;
440 forAll(subm.localFaces(), localFaceI)
442 const Face& f = subm.localFaces()[localFaceI];
444 os << "SURF 0x20" << nl // polygon
445 << "mat " << zoneI << nl
446 << "refs " << f.size() << nl;
450 os << f[fp] << " 0 0" << nl;
454 os << "kids 0" << endl;
460 // ************************************************************************* //