00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026 #include "AC3DsurfaceFormat.H"
00027 #include <OpenFOAM/clock.H>
00028 #include <OpenFOAM/IStringStream.H>
00029 #include <OpenFOAM/tensor.H>
00030 #include <OpenFOAM/primitivePatch.H>
00031
00032
00033
00034 template<class Face>
00035 Foam::fileFormats::AC3DsurfaceFormat<Face>::AC3DsurfaceFormat
00036 (
00037 const fileName& filename
00038 )
00039 {
00040 read(filename);
00041 }
00042
00043
00044
00045
00046 template<class Face>
00047 bool Foam::fileFormats::AC3DsurfaceFormat<Face>::read
00048 (
00049 const fileName& filename
00050 )
00051 {
00052 const bool mustTriangulate = this->isTri();
00053 this->clear();
00054
00055 IFstream is(filename);
00056 if (!is.good())
00057 {
00058 FatalErrorIn
00059 (
00060 "fileFormats::AC3DsurfaceFormat::read(const fileName&)"
00061 )
00062 << "Cannot read file " << filename
00063 << exit(FatalError);
00064 }
00065
00066 string line, cmd, args;
00067
00068 is.getLine(line);
00069
00070 string version = line.substr(4);
00071
00072 if (version != "b")
00073 {
00074 WarningIn
00075 (
00076 "fileFormats::AC3DsurfaceFormat::read(const fileName&)"
00077 )
00078 << "When reading AC3D file " << filename
00079 << " read header " << line << " with version "
00080 << version << endl
00081 << "Only tested reading with version 'b'."
00082 << " This might give problems" << endl;
00083 }
00084
00085
00086 if (!cueTo(is, "OBJECT", args) || (args != "world"))
00087 {
00088 FatalErrorIn
00089 (
00090 "fileFormats::AC3DsurfaceFormat::read(const fileName&)"
00091 )
00092 << "Cannot find \"OBJECT world\" in file " << filename
00093 << exit(FatalError);
00094 }
00095
00096
00097 args = cueToOrDie(is, "kids");
00098 label nZones = parse<int>(args);
00099
00100
00101 label vertexOffset = 0;
00102
00103 DynamicList<point> dynPoints;
00104 DynamicList<Face> dynFaces;
00105 List<word> names(nZones);
00106 List<label> sizes(nZones, 0);
00107
00108 for (label zoneI = 0; zoneI < nZones; ++zoneI)
00109 {
00110 names[zoneI] = word("zone") + Foam::name(zoneI);
00111
00112 args = cueToOrDie(is, "OBJECT", "while reading " + names[zoneI]);
00113
00114
00115 label nZonePoints = 0;
00116 vector location(pTraits<vector>::zero);
00117
00118
00119
00120 while (is.good())
00121 {
00122
00123
00124 if (!readCmd(is, cmd, args))
00125 {
00126 FatalErrorIn
00127 (
00128 "fileFormats::AC3DsurfaceFormat::read(const fileName&)"
00129 )
00130 << "Did not read up to \"kids 0\" while reading zone "
00131 << zoneI << " from file " << filename
00132 << exit(FatalError);
00133 }
00134
00135 if (cmd == "name")
00136 {
00137
00138 string str = parse<string>(args);
00139 string::stripInvalid<word>(str);
00140
00141 names[zoneI] = str;
00142 }
00143 else if (cmd == "rot")
00144 {
00145
00146
00147
00148
00149
00150
00151
00152
00153
00154 WarningIn
00155 (
00156 "fileFormats::AC3DsurfaceFormat::read"
00157 "(const fileName&)"
00158 )
00159 << "rot (rotation tensor) command not implemented"
00160 << "Line:" << cmd << ' ' << args << endl
00161 << "while reading zone " << zoneI << endl;
00162 }
00163 else if (cmd == "loc")
00164 {
00165
00166 IStringStream lineStream(args);
00167
00168 lineStream
00169 >> location.x()
00170 >> location.y()
00171 >> location.z();
00172 }
00173 else if (cmd == "numvert")
00174 {
00175
00176 nZonePoints = parse<int>(args);
00177
00178 for (label vertI = 0; vertI < nZonePoints; ++vertI)
00179 {
00180 is.getLine(line);
00181 IStringStream lineStream(line);
00182
00183 point pt;
00184 lineStream
00185 >> pt.x() >> pt.y() >> pt.z();
00186
00187
00188 dynPoints.append(location + pt);
00189 }
00190 }
00191 else if (cmd == "numsurf")
00192 {
00193 label nFaces = parse<int>(args);
00194
00195 for (label faceI = 0; faceI < nFaces; ++faceI)
00196 {
00197 static string errorMsg =
00198 string(" while reading face ")
00199 + Foam::name(faceI) + " on zone "
00200 + Foam::name(zoneI)
00201 + " from file " + filename;
00202
00203 cueToOrDie(is, "SURF", errorMsg);
00204 cueToOrDie(is, "mat", errorMsg);
00205 args = cueToOrDie(is, "refs", errorMsg);
00206
00207 label nVert = parse<int>(args);
00208
00209 List<label> verts(nVert);
00210 forAll(verts, vertI)
00211 {
00212 is.getLine(line);
00213 verts[vertI] = parse<int>(line) + vertexOffset;
00214 }
00215
00216 UList<label>& f = static_cast<UList<label>&>(verts);
00217
00218 if (mustTriangulate && f.size() > 3)
00219 {
00220
00221
00222 for (label fp1 = 1; fp1 < f.size() - 1; ++fp1)
00223 {
00224 label fp2 = f.fcIndex(fp1);
00225
00226 dynFaces.append(triFace(f[0], f[fp1], f[fp2]));
00227 sizes[zoneI]++;
00228 }
00229 }
00230 else
00231 {
00232 dynFaces.append(Face(f));
00233 sizes[zoneI]++;
00234 }
00235 }
00236
00237
00238
00239 vertexOffset += nZonePoints;
00240 }
00241 else if (cmd == "kids")
00242 {
00243
00244 label nKids = parse<int>(args);
00245
00246 if (nKids != 0)
00247 {
00248 FatalErrorIn
00249 (
00250 "fileFormats::AC3DsurfaceFormat::read(const fileName&)"
00251 )
00252 << "Can only read objects without kids."
00253 << " Encountered " << nKids << " kids when"
00254 << " reading zone " << zoneI
00255 << exit(FatalError);
00256 }
00257
00258
00259 break;
00260 }
00261 }
00262 }
00263
00264
00265 this->storedPoints().transfer(dynPoints);
00266 this->storedFaces().transfer(dynFaces);
00267
00268
00269 this->addZones(sizes, names, true);
00270 this->stitchFaces(SMALL);
00271 return true;
00272 }
00273
00274
00275 template<class Face>
00276 void Foam::fileFormats::AC3DsurfaceFormat<Face>::write
00277 (
00278 const fileName& filename,
00279 const MeshedSurfaceProxy<Face>& surf
00280 )
00281 {
00282 const pointField& pointLst = surf.points();
00283 const List<Face>& faceLst = surf.faces();
00284
00285 const List<surfZone>& zones =
00286 (
00287 surf.surfZones().size()
00288 ? surf.surfZones()
00289 : AC3DsurfaceFormat::oneZone(faceLst)
00290 );
00291
00292 const bool useFaceMap = (surf.useFaceMap() && zones.size() > 1);
00293
00294 if (useFaceMap)
00295 {
00296 FatalErrorIn
00297 (
00298 "fileFormats::AC3DsurfaceFormat::write"
00299 "(const fileName&, const MeshedSurfaceProxy<Face>&)"
00300 )
00301 << "output with faceMap is not supported " << filename
00302 << exit(FatalError);
00303 }
00304
00305
00306 OFstream os(filename);
00307 if (!os.good())
00308 {
00309 FatalErrorIn
00310 (
00311 "fileFormats::AC3DsurfaceFormat::write"
00312 "(const fileName&, const MeshedSurfaceProxy<Face>&)"
00313 )
00314 << "Cannot open file for writing " << filename
00315 << exit(FatalError);
00316 }
00317
00318 writeHeader(os, zones);
00319
00320 forAll(zones, zoneI)
00321 {
00322 const surfZone& zone = zones[zoneI];
00323
00324 os << "OBJECT poly" << nl
00325 << "name \"" << zone.name() << "\"\n";
00326
00327
00328
00329 PrimitivePatch<Face, UList, const pointField&> patch
00330 (
00331 SubList<Face>
00332 (
00333 faceLst,
00334 zone.size(),
00335 zone.start()
00336 ),
00337 pointLst
00338 );
00339
00340 os << "numvert " << patch.nPoints() << endl;
00341
00342 forAll(patch.localPoints(), ptI)
00343 {
00344 const point& pt = patch.localPoints()[ptI];
00345
00346 os << pt.x() << ' ' << pt.y() << ' ' << pt.z() << nl;
00347 }
00348
00349 os << "numsurf " << patch.localFaces().size() << endl;
00350
00351 forAll(patch.localFaces(), localFaceI)
00352 {
00353 const Face& f = patch.localFaces()[localFaceI];
00354
00355 os << "SURF 0x20" << nl
00356 << "mat " << zoneI << nl
00357 << "refs " << f.size() << nl;
00358
00359 forAll(f, fp)
00360 {
00361 os << f[fp] << " 0 0" << nl;
00362 }
00363 }
00364
00365 os << "kids 0" << endl;
00366 }
00367 }
00368
00369
00370 template<class Face>
00371 void Foam::fileFormats::AC3DsurfaceFormat<Face>::write
00372 (
00373 const fileName& filename,
00374 const UnsortedMeshedSurface<Face>& surf
00375 )
00376 {
00377 labelList faceMap;
00378 List<surfZone> zoneLst = surf.sortedZones(faceMap);
00379
00380 if (zoneLst.size() <= 1)
00381 {
00382 write
00383 (
00384 filename,
00385 MeshedSurfaceProxy<Face>
00386 (
00387 surf.points(),
00388 surf.faces(),
00389 zoneLst
00390 )
00391 );
00392 }
00393 else
00394 {
00395 OFstream os(filename);
00396 if (!os.good())
00397 {
00398 FatalErrorIn
00399 (
00400 "fileFormats::AC3DsurfaceFormat::write"
00401 "(const fileName&, const MeshedSurfaceProxy<Face>&)"
00402 )
00403 << "Cannot open file for writing " << filename
00404 << exit(FatalError);
00405 }
00406
00407 writeHeader(os, zoneLst);
00408
00409 label faceIndex = 0;
00410 forAll(zoneLst, zoneI)
00411 {
00412 const surfZone& zone = zoneLst[zoneI];
00413
00414 os << "OBJECT poly" << nl
00415 << "name \"" << zone.name() << "\"\n";
00416
00417
00418 labelHashSet include(surf.size());
00419
00420 forAll(zone, localFaceI)
00421 {
00422 const label faceI = faceMap[faceIndex++];
00423 include.insert(faceI);
00424 }
00425
00426 UnsortedMeshedSurface<Face> subm = surf.subsetMesh(include);
00427
00428
00429 os << "numvert " << subm.nPoints() << endl;
00430
00431 forAll(subm.localPoints(), ptI)
00432 {
00433 const point& pt = subm.localPoints()[ptI];
00434
00435 os << pt.x() << ' ' << pt.y() << ' ' << pt.z() << endl;
00436 }
00437
00438 os << "numsurf " << subm.localFaces().size() << endl;
00439
00440 forAll(subm.localFaces(), localFaceI)
00441 {
00442 const Face& f = subm.localFaces()[localFaceI];
00443
00444 os << "SURF 0x20" << nl
00445 << "mat " << zoneI << nl
00446 << "refs " << f.size() << nl;
00447
00448 forAll(f, fp)
00449 {
00450 os << f[fp] << " 0 0" << nl;
00451 }
00452 }
00453
00454 os << "kids 0" << endl;
00455 }
00456 }
00457 }
00458
00459
00460