1 /*---------------------------------------------------------------------------*\
3 \\ / F ield | OpenFOAM: The Open Source CFD Toolbox
5 \\ / A nd | Copyright (C) 1991-2009 OpenCFD Ltd.
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 the
13 Free Software Foundation; either version 2 of the License, or (at your
14 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, write to the Free Software Foundation,
23 Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
25 \*---------------------------------------------------------------------------*/
27 #include "AC3DsurfaceFormat.H"
29 #include "IStringStream.H"
31 #include "primitivePatch.H"
33 // * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
36 Foam::fileFormats::AC3DsurfaceFormat<Face>::AC3DsurfaceFormat
38 const fileName& filename
45 // * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
48 bool Foam::fileFormats::AC3DsurfaceFormat<Face>::read
50 const fileName& filename
53 const bool mustTriangulate = this->isTri();
56 IFstream is(filename);
61 "fileFormats::AC3DsurfaceFormat::read(const fileName&)"
63 << "Cannot read file " << filename
67 string line, cmd, args;
71 string version = line.substr(4);
77 "fileFormats::AC3DsurfaceFormat::read(const fileName&)"
79 << "When reading AC3D file " << filename
80 << " read header " << line << " with version "
82 << "Only tested reading with version 'b'."
83 << " This might give problems" << endl;
87 if (!cueTo(is, "OBJECT", args) || (args != "world"))
91 "fileFormats::AC3DsurfaceFormat::read(const fileName&)"
93 << "Cannot find \"OBJECT world\" in file " << filename
97 // # of kids is the # of zones
98 args = cueToOrDie(is, "kids");
99 label nZones = parse<int>(args);
101 // Start of vertices for object/zones
102 label vertexOffset = 0;
104 DynamicList<point> dynPoints;
105 DynamicList<Face> dynFaces;
106 List<word> names(nZones);
107 List<label> sizes(nZones, 0);
109 for (label zoneI = 0; zoneI < nZones; ++zoneI)
111 names[zoneI] = word("zone") + Foam::name(zoneI);
113 args = cueToOrDie(is, "OBJECT", "while reading " + names[zoneI]);
115 // number of vertices for this zone
116 label nZonePoints = 0;
117 vector location(pTraits<vector>::zero);
118 // tensor rotation(I);
120 // Read all info for current zone
123 // Read line and get first word. If end of file break since
124 // zone should always end with 'kids' command ?not sure.
125 if (!readCmd(is, cmd, args))
129 "fileFormats::AC3DsurfaceFormat::read(const fileName&)"
131 << "Did not read up to \"kids 0\" while reading zone "
132 << zoneI << " from file " << filename
139 string str = parse<string>(args);
140 string::stripInvalid<word>(str);
144 else if (cmd == "rot")
146 // rot %f %f %f %f %f %f %f %f %f
148 // IStringStream lineStream(args);
151 // >> rotation.xx() >> rotation.xy() >> rotation.xz()
152 // >> rotation.yx() >> rotation.yy() >> rotation.yz()
153 // >> rotation.zx() >> rotation.zy() >> rotation.zz();
157 "fileFormats::AC3DsurfaceFormat::read"
160 << "rot (rotation tensor) command not implemented"
161 << "Line:" << cmd << ' ' << args << endl
162 << "while reading zone " << zoneI << endl;
164 else if (cmd == "loc")
167 IStringStream lineStream(args);
174 else if (cmd == "numvert")
177 nZonePoints = parse<int>(args);
179 for (label vertI = 0; vertI < nZonePoints; ++vertI)
182 IStringStream lineStream(line);
186 >> pt.x() >> pt.y() >> pt.z();
188 // Offset with current translation vector
189 dynPoints.append(location + pt);
192 else if (cmd == "numsurf")
194 label nFaces = parse<int>(args);
196 for (label faceI = 0; faceI < nFaces; ++faceI)
198 static string errorMsg =
199 string(" while reading face ")
200 + Foam::name(faceI) + " on zone "
202 + " from file " + filename;
204 cueToOrDie(is, "SURF", errorMsg);
205 cueToOrDie(is, "mat", errorMsg);
206 args = cueToOrDie(is, "refs", errorMsg);
208 label nVert = parse<int>(args);
210 List<label> verts(nVert);
214 verts[vertI] = parse<int>(line) + vertexOffset;
217 UList<label>& f = static_cast<UList<label>&>(verts);
219 if (mustTriangulate && f.size() > 3)
221 // simple face triangulation about f[0]
222 // points may be incomplete
223 for (label fp1 = 1; fp1 < f.size() - 1; ++fp1)
225 label fp2 = f.fcIndex(fp1);
227 dynFaces.append(triFace(f[0], f[fp1], f[fp2]));
233 dynFaces.append(Face(f));
238 // Done the current zone.
239 // Increment the offset vertices are stored at
240 vertexOffset += nZonePoints;
242 else if (cmd == "kids")
244 // 'kids' denotes the end of the current zone.
245 label nKids = parse<int>(args);
251 "fileFormats::AC3DsurfaceFormat::read(const fileName&)"
253 << "Can only read objects without kids."
254 << " Encountered " << nKids << " kids when"
255 << " reading zone " << zoneI
259 // Done reading current zone
265 // transfer to normal lists
266 this->storedPoints().transfer(dynPoints);
267 this->storedFaces().transfer(dynFaces);
269 // add zones, culling empty ones
270 this->addZones(sizes, names, true);
271 this->stitchFaces(SMALL);
277 void Foam::fileFormats::AC3DsurfaceFormat<Face>::write
279 const fileName& filename,
280 const MeshedSurfaceProxy<Face>& surf
283 const pointField& pointLst = surf.points();
284 const List<Face>& faceLst = surf.faces();
286 const List<surfZone>& zones =
288 surf.surfZones().size()
293 const bool useFaceMap = (surf.useFaceMap() && zones.size() > 1);
299 "fileFormats::AC3DsurfaceFormat::write"
300 "(const fileName&, const MeshedSurfaceProxy<Face>&)"
302 << "output with faceMap is not supported " << filename
307 OFstream os(filename);
312 "fileFormats::AC3DsurfaceFormat::write"
313 "(const fileName&, const MeshedSurfaceProxy<Face>&)"
315 << "Cannot open file for writing " << filename
319 writeHeader(os, zones);
323 const surfZone& zone = zones[zoneI];
325 os << "OBJECT poly" << nl
326 << "name \"" << zone.name() << "\"\n";
328 // Temporary PrimitivePatch to calculate compact points & faces
329 // use 'UList' to avoid allocations!
330 PrimitivePatch<Face, UList, const pointField&> patch
341 os << "numvert " << patch.nPoints() << endl;
343 forAll(patch.localPoints(), ptI)
345 const point& pt = patch.localPoints()[ptI];
347 os << pt.x() << ' ' << pt.y() << ' ' << pt.z() << nl;
350 os << "numsurf " << patch.localFaces().size() << endl;
352 forAll(patch.localFaces(), localFaceI)
354 const Face& f = patch.localFaces()[localFaceI];
356 os << "SURF 0x20" << nl // polygon
357 << "mat " << zoneI << nl
358 << "refs " << f.size() << nl;
362 os << f[fp] << " 0 0" << nl;
366 os << "kids 0" << endl;
372 void Foam::fileFormats::AC3DsurfaceFormat<Face>::write
374 const fileName& filename,
375 const UnsortedMeshedSurface<Face>& surf
379 List<surfZone> zoneLst = surf.sortedZones(faceMap);
381 if (zoneLst.size() <= 1)
386 MeshedSurfaceProxy<Face>
396 OFstream os(filename);
401 "fileFormats::AC3DsurfaceFormat::write"
402 "(const fileName&, const MeshedSurfaceProxy<Face>&)"
404 << "Cannot open file for writing " << filename
408 writeHeader(os, zoneLst);
411 forAll(zoneLst, zoneI)
413 const surfZone& zone = zoneLst[zoneI];
415 os << "OBJECT poly" << nl
416 << "name \"" << zone.name() << "\"\n";
418 // Create zone with only zone faces included for ease of addressing
419 labelHashSet include(surf.size());
421 forAll(zone, localFaceI)
423 const label faceI = faceMap[faceIndex++];
424 include.insert(faceI);
427 UnsortedMeshedSurface<Face> subm = surf.subsetMesh(include);
429 // Now we have isolated surface for this patch alone. Write it.
430 os << "numvert " << subm.nPoints() << endl;
432 forAll(subm.localPoints(), ptI)
434 const point& pt = subm.localPoints()[ptI];
436 os << pt.x() << ' ' << pt.y() << ' ' << pt.z() << endl;
439 os << "numsurf " << subm.localFaces().size() << endl;
441 forAll(subm.localFaces(), localFaceI)
443 const Face& f = subm.localFaces()[localFaceI];
445 os << "SURF 0x20" << nl // polygon
446 << "mat " << zoneI << nl
447 << "refs " << f.size() << nl;
451 os << f[fp] << " 0 0" << nl;
455 os << "kids 0" << endl;
461 // ************************************************************************* //