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 "STLsurfaceFormat.H"
00027 #include <OpenFOAM/ListOps.H>
00028 #include <OpenFOAM/triPointRef.H>
00029
00030
00031
00032 template<class Face>
00033 inline void Foam::fileFormats::STLsurfaceFormat<Face>::writeShell
00034 (
00035 Ostream& os,
00036 const pointField& pointLst,
00037 const Face& f
00038 )
00039 {
00040
00041 vector norm = triPointRef
00042 (
00043 pointLst[f[0]],
00044 pointLst[f[1]],
00045 pointLst[f[2]]
00046 ).normal();
00047 norm /= mag(norm) + VSMALL;
00048
00049
00050
00051 const point& p0 = pointLst[f[0]];
00052 for (label fp1 = 1; fp1 < f.size() - 1; ++fp1)
00053 {
00054 label fp2 = f.fcIndex(fp1);
00055
00056 const point& p1 = pointLst[f[fp1]];
00057 const point& p2 = pointLst[f[fp2]];
00058
00059
00060 os << " facet normal "
00061 << norm.x() << ' ' << norm.y() << ' ' << norm.z() << nl
00062 << " outer loop\n"
00063 << " vertex " << p0.x() << ' ' << p0.y() << ' ' << p0.z() << nl
00064 << " vertex " << p1.x() << ' ' << p1.y() << ' ' << p1.z() << nl
00065 << " vertex " << p2.x() << ' ' << p2.y() << ' ' << p2.z() << nl
00066 << " endloop\n"
00067 << " endfacet" << endl;
00068 }
00069 }
00070
00071
00072 template<class Face>
00073 inline void Foam::fileFormats::STLsurfaceFormat<Face>::writeShell
00074 (
00075 ostream& os,
00076 const pointField& pointLst,
00077 const Face& f,
00078 const label zoneI
00079 )
00080 {
00081
00082 vector norm = triPointRef
00083 (
00084 pointLst[f[0]],
00085 pointLst[f[1]],
00086 pointLst[f[2]]
00087 ).normal();
00088 norm /= mag(norm) + VSMALL;
00089
00090
00091
00092 const point& p0 = pointLst[f[0]];
00093 for (label fp1 = 1; fp1 < f.size() - 1; ++fp1)
00094 {
00095 label fp2 = f.fcIndex(fp1);
00096
00097 STLtriangle stlTri
00098 (
00099 norm,
00100 p0,
00101 pointLst[f[fp1]],
00102 pointLst[f[fp2]],
00103 zoneI
00104 );
00105
00106 stlTri.write(os);
00107 }
00108 }
00109
00110
00111
00112
00113 template<class Face>
00114 Foam::fileFormats::STLsurfaceFormat<Face>::STLsurfaceFormat
00115 (
00116 const fileName& filename
00117 )
00118 {
00119 read(filename);
00120 }
00121
00122
00123
00124
00125 template<class Face>
00126 bool Foam::fileFormats::STLsurfaceFormat<Face>::read
00127 (
00128 const fileName& filename
00129 )
00130 {
00131 this->clear();
00132
00133
00134 STLsurfaceFormatCore reader(filename);
00135
00136
00137 this->storedPoints().transfer(reader.points());
00138
00139
00140 List<word> names(reader.names().xfer());
00141 List<label> sizes(reader.sizes().xfer());
00142 List<label> zoneIds(reader.zoneIds().xfer());
00143
00144
00145 List<Face> faceLst(zoneIds.size());
00146
00147 if (reader.sorted())
00148 {
00149
00150 forAll(faceLst, faceI)
00151 {
00152 const label startPt = 3*faceI;
00153 faceLst[faceI] = triFace(startPt, startPt+1, startPt+2);
00154 }
00155 }
00156 else
00157 {
00158
00159
00160 List<label> faceMap;
00161 sortedOrder(zoneIds, faceMap);
00162
00163
00164 forAll(faceMap, faceI)
00165 {
00166 const label startPt = 3*faceMap[faceI];
00167 faceLst[faceI] = triFace(startPt, startPt+1, startPt+2);
00168 }
00169 }
00170 zoneIds.clear();
00171
00172
00173 this->storedFaces().transfer(faceLst);
00174
00175 if (names.size())
00176 {
00177 this->addZones(sizes, names);
00178 }
00179 else
00180 {
00181 this->addZones(sizes);
00182 }
00183
00184 this->stitchFaces(SMALL);
00185 return true;
00186 }
00187
00188
00189
00190 template<class Face>
00191 void Foam::fileFormats::STLsurfaceFormat<Face>::writeAscii
00192 (
00193 const fileName& filename,
00194 const MeshedSurfaceProxy<Face>& surf
00195 )
00196 {
00197 OFstream os(filename);
00198 if (!os.good())
00199 {
00200 FatalErrorIn
00201 (
00202 "fileFormats::STLsurfaceFormat::writeAscii"
00203 "(const fileName&, const MeshedSurfaceProxy<Face>&)"
00204 )
00205 << "Cannot open file for writing " << filename
00206 << exit(FatalError);
00207 }
00208
00209 const pointField& pointLst = surf.points();
00210 const List<Face>& faceLst = surf.faces();
00211 const List<label>& faceMap = surf.faceMap();
00212
00213 const List<surfZone>& zones =
00214 (
00215 surf.surfZones().size() > 1
00216 ? surf.surfZones()
00217 : STLsurfaceFormat::oneZone(faceLst)
00218 );
00219
00220 const bool useFaceMap = (surf.useFaceMap() && zones.size() > 1);
00221
00222 label faceIndex = 0;
00223 forAll(zones, zoneI)
00224 {
00225
00226 const surfZone& zone = zones[zoneI];
00227
00228 os << "solid " << zone.name() << nl;
00229
00230 if (useFaceMap)
00231 {
00232 forAll(zone, localFaceI)
00233 {
00234 const label faceI = faceMap[faceIndex++];
00235 writeShell(os, pointLst, faceLst[faceI]);
00236 }
00237 }
00238 else
00239 {
00240 forAll(zone, localFaceI)
00241 {
00242 writeShell(os, pointLst, faceLst[faceIndex++]);
00243 }
00244 }
00245 os << "endsolid " << zone.name() << endl;
00246 }
00247 }
00248
00249
00250 template<class Face>
00251 void Foam::fileFormats::STLsurfaceFormat<Face>::writeBinary
00252 (
00253 const fileName& filename,
00254 const MeshedSurfaceProxy<Face>& surf
00255 )
00256 {
00257 std::ofstream os(filename.c_str(), std::ios::binary);
00258 if (!os.good())
00259 {
00260 FatalErrorIn
00261 (
00262 "fileFormats::STLsurfaceFormat::writeBinary"
00263 "(const fileName&, const MeshedSurfaceProxy<Face>&)"
00264 )
00265 << "Cannot open file for writing " << filename
00266 << exit(FatalError);
00267 }
00268
00269
00270 const pointField& pointLst = surf.points();
00271 const List<Face>& faceLst = surf.faces();
00272 const List<label>& faceMap = surf.faceMap();
00273
00274 const List<surfZone>& zones =
00275 (
00276 surf.surfZones().size() > 1
00277 ? surf.surfZones()
00278 : STLsurfaceFormat::oneZone(faceLst)
00279 );
00280
00281 const bool useFaceMap = (surf.useFaceMap() && zones.size() > 1);
00282
00283
00284 unsigned int nTris = 0;
00285 if (MeshedSurface<Face>::isTri())
00286 {
00287 nTris = faceLst.size();
00288 }
00289 else
00290 {
00291
00292 forAll(faceLst, faceI)
00293 {
00294 nTris += faceLst[faceI].size() - 2;
00295 }
00296 }
00297
00298
00299 STLsurfaceFormatCore::writeHeaderBINARY(os, nTris);
00300
00301 label faceIndex = 0;
00302 forAll(zones, zoneI)
00303 {
00304 const surfZone& zone = zones[zoneI];
00305
00306 if (useFaceMap)
00307 {
00308 forAll(zone, localFaceI)
00309 {
00310 writeShell
00311 (
00312 os,
00313 pointLst,
00314 faceLst[faceMap[faceIndex++]],
00315 zoneI
00316 );
00317 }
00318 }
00319 else
00320 {
00321 forAll(zone, localFaceI)
00322 {
00323 writeShell
00324 (
00325 os,
00326 pointLst,
00327 faceLst[faceIndex++],
00328 zoneI
00329 );
00330 }
00331 }
00332 }
00333 }
00334
00335
00336 template<class Face>
00337 void Foam::fileFormats::STLsurfaceFormat<Face>::writeAscii
00338 (
00339 const fileName& filename,
00340 const UnsortedMeshedSurface<Face>& surf
00341 )
00342 {
00343 OFstream os(filename);
00344 if (!os.good())
00345 {
00346 FatalErrorIn
00347 (
00348 "fileFormats::STLsurfaceFormat::writeAscii"
00349 "(const fileName&, const UnsortedMeshedSurface<Face>&)"
00350 )
00351 << "Cannot open file for writing " << filename
00352 << exit(FatalError);
00353 }
00354
00355
00356 if (surf.zoneToc().size() == 1)
00357 {
00358 const pointField& pointLst = surf.points();
00359 const List<Face>& faceLst = surf.faces();
00360
00361 os << "solid " << surf.zoneToc()[0].name() << endl;
00362 forAll(faceLst, faceI)
00363 {
00364 writeShell(os, pointLst, faceLst[faceI]);
00365 }
00366 os << "endsolid " << surf.zoneToc()[0].name() << endl;
00367 }
00368 else
00369 {
00370 labelList faceMap;
00371 List<surfZone> zoneLst = surf.sortedZones(faceMap);
00372
00373 writeAscii
00374 (
00375 filename,
00376 MeshedSurfaceProxy<Face>
00377 (
00378 surf.points(),
00379 surf.faces(),
00380 zoneLst,
00381 faceMap
00382 )
00383 );
00384 }
00385 }
00386
00387
00388 template<class Face>
00389 void Foam::fileFormats::STLsurfaceFormat<Face>::writeBinary
00390 (
00391 const fileName& filename,
00392 const UnsortedMeshedSurface<Face>& surf
00393 )
00394 {
00395 std::ofstream os(filename.c_str(), std::ios::binary);
00396 if (!os.good())
00397 {
00398 FatalErrorIn
00399 (
00400 "fileFormats::STLsurfaceFormat::writeBinary"
00401 "(const fileName&, const UnsortedMeshedSurface<Face>&)"
00402 )
00403 << "Cannot open file for writing " << filename
00404 << exit(FatalError);
00405 }
00406
00407 const pointField& pointLst = surf.points();
00408 const List<Face>& faceLst = surf.faces();
00409 const List<label>& zoneIds = surf.zoneIds();
00410
00411 unsigned int nTris = 0;
00412 if (MeshedSurface<Face>::isTri())
00413 {
00414 nTris = faceLst.size();
00415 }
00416 else
00417 {
00418
00419 forAll(faceLst, faceI)
00420 {
00421 nTris += faceLst[faceI].size() - 2;
00422 }
00423 }
00424
00425
00426 STLsurfaceFormatCore::writeHeaderBINARY(os, nTris);
00427
00428
00429 forAll(faceLst, faceI)
00430 {
00431 writeShell
00432 (
00433 os,
00434 pointLst,
00435 faceLst[faceI],
00436 zoneIds[faceI]
00437 );
00438 }
00439 }
00440
00441
00442 template<class Face>
00443 void Foam::fileFormats::STLsurfaceFormat<Face>::write
00444 (
00445 const fileName& filename,
00446 const MeshedSurfaceProxy<Face>& surf
00447 )
00448 {
00449 const word ext = filename.ext();
00450
00451
00452 if (ext == "stlb")
00453 {
00454 writeBinary(filename, surf);
00455 }
00456 else
00457 {
00458 writeAscii(filename, surf);
00459 }
00460 }
00461
00462
00463 template<class Face>
00464 void Foam::fileFormats::STLsurfaceFormat<Face>::write
00465 (
00466 const fileName& filename,
00467 const UnsortedMeshedSurface<Face>& surf
00468 )
00469 {
00470 word ext = filename.ext();
00471
00472
00473 if (ext == "stlb")
00474 {
00475 writeBinary(filename, surf);
00476 }
00477 else
00478 {
00479 writeAscii(filename, surf);
00480 }
00481 }
00482
00483
00484