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 "triSurface.H"
00027 #include <OpenFOAM/demandDrivenData.H>
00028 #include <OpenFOAM/IFstream.H>
00029 #include <OpenFOAM/OFstream.H>
00030 #include <OpenFOAM/Time.H>
00031 #include <OpenFOAM/boundBox.H>
00032 #include <OpenFOAM/SortableList.H>
00033 #include <OpenFOAM/PackedBoolList.H>
00034
00035
00036
00037
00038 namespace Foam
00039 {
00040 defineTypeNameAndDebug(Foam::triSurface, 0);
00041 }
00042
00043
00044 Foam::fileName Foam::triSurface::triSurfInstance(const Time& d)
00045 {
00046 fileName foamName(d.caseName() + ".ftr");
00047
00048
00049
00050
00051 instantList ts = d.times();
00052 label i;
00053
00054 for (i=ts.size()-1; i>=0; i--)
00055 {
00056 if (ts[i].value() <= d.timeOutputValue())
00057 {
00058 break;
00059 }
00060 }
00061
00062
00063
00064
00065 if (i>=0)
00066 {
00067 for (label j=i; j>=0; j--)
00068 {
00069 if (isFile(d.path()/ts[j].name()/typeName/foamName))
00070 {
00071 if (debug)
00072 {
00073 Pout<< " triSurface::triSurfInstance(const Time& d)"
00074 << "reading " << foamName
00075 << " from " << ts[j].name()/typeName
00076 << endl;
00077 }
00078
00079 return ts[j].name();
00080 }
00081 }
00082 }
00083
00084 if (debug)
00085 {
00086 Pout<< " triSurface::triSurfInstance(const Time& d)"
00087 << "reading " << foamName
00088 << " from constant/" << endl;
00089 }
00090 return "constant";
00091 }
00092
00093
00094 Foam::List<Foam::labelledTri> Foam::triSurface::convertToTri
00095 (
00096 const faceList& faces,
00097 const label defaultRegion
00098 )
00099 {
00100 List<labelledTri> triFaces(faces.size());
00101
00102 forAll(triFaces, faceI)
00103 {
00104 const face& f = faces[faceI];
00105
00106 if (f.size() != 3)
00107 {
00108 FatalErrorIn
00109 (
00110 "triSurface::convertToTri"
00111 "(const faceList&, const label)"
00112 ) << "Face at position " << faceI
00113 << " does not have three vertices:" << f
00114 << abort(FatalError);
00115 }
00116
00117 labelledTri& tri = triFaces[faceI];
00118
00119 tri[0] = f[0];
00120 tri[1] = f[1];
00121 tri[2] = f[2];
00122 tri.region() = defaultRegion;
00123 }
00124
00125 return triFaces;
00126 }
00127
00128
00129 Foam::List<Foam::labelledTri> Foam::triSurface::convertToTri
00130 (
00131 const triFaceList& faces,
00132 const label defaultRegion
00133 )
00134 {
00135 List<labelledTri> triFaces(faces.size());
00136
00137 forAll(triFaces, faceI)
00138 {
00139 const triFace& f = faces[faceI];
00140
00141 labelledTri& tri = triFaces[faceI];
00142
00143 tri[0] = f[0];
00144 tri[1] = f[1];
00145 tri[2] = f[2];
00146 tri.region() = defaultRegion;
00147 }
00148
00149 return triFaces;
00150 }
00151
00152
00153
00154
00155 void Foam::triSurface::printTriangle
00156 (
00157 Ostream& os,
00158 const string& pre,
00159 const labelledTri& f,
00160 const pointField& points
00161 )
00162 {
00163 os
00164 << pre.c_str() << "vertex numbers:"
00165 << f[0] << ' ' << f[1] << ' ' << f[2] << endl
00166 << pre.c_str() << "vertex coords :"
00167 << points[f[0]] << ' ' << points[f[1]] << ' ' << points[f[2]]
00168 << pre.c_str() << "region :" << f.region() << endl
00169 << endl;
00170 }
00171
00172
00173 Foam::string Foam::triSurface::getLineNoComment(IFstream& is)
00174 {
00175 string line;
00176 do
00177 {
00178 is.getLine(line);
00179 }
00180 while ((line.empty() || line[0] == '#') && is.good());
00181
00182 return line;
00183 }
00184
00185
00186
00187 void Foam::triSurface::checkTriangles(const bool verbose)
00188 {
00189
00190 const label maxPointI = points().size() - 1;
00191
00192 forAll(*this, faceI)
00193 {
00194 const labelledTri& f = (*this)[faceI];
00195
00196 if
00197 (
00198 (f[0] < 0) || (f[0] > maxPointI)
00199 || (f[1] < 0) || (f[1] > maxPointI)
00200 || (f[2] < 0) || (f[2] > maxPointI)
00201 )
00202 {
00203 FatalErrorIn("triSurface::checkTriangles(bool)")
00204 << "triangle " << f
00205 << " uses point indices outside point range 0.."
00206 << maxPointI
00207 << exit(FatalError);
00208 }
00209 }
00210
00211
00212
00213
00214
00215
00216
00217 boolList valid(size(), true);
00218 bool hasInvalid = false;
00219
00220 const labelListList& fFaces = faceFaces();
00221
00222 forAll(*this, faceI)
00223 {
00224 const labelledTri& f = (*this)[faceI];
00225
00226 if ((f[0] == f[1]) || (f[0] == f[2]) || (f[1] == f[2]))
00227 {
00228
00229 valid[faceI] = false;
00230 hasInvalid = true;
00231
00232 if (verbose)
00233 {
00234 WarningIn
00235 (
00236 "triSurface::checkTriangles(bool verbose)"
00237 ) << "triangle " << faceI
00238 << " does not have three unique vertices:\n";
00239 printTriangle(Warning, " ", f, points());
00240 }
00241 }
00242 else
00243 {
00244
00245 const labelList& neighbours = fFaces[faceI];
00246
00247
00248
00249 forAll(neighbours, neighbourI)
00250 {
00251 if (neighbours[neighbourI] <= faceI)
00252 {
00253
00254 continue;
00255 }
00256
00257 const labelledTri& n = (*this)[neighbours[neighbourI]];
00258
00259 if
00260 (
00261 ((f[0] == n[0]) || (f[0] == n[1]) || (f[0] == n[2]))
00262 && ((f[1] == n[0]) || (f[1] == n[1]) || (f[1] == n[2]))
00263 && ((f[2] == n[0]) || (f[2] == n[1]) || (f[2] == n[2]))
00264 )
00265 {
00266 valid[faceI] = false;
00267 hasInvalid = true;
00268
00269 if (verbose)
00270 {
00271 WarningIn
00272 (
00273 "triSurface::checkTriangles(bool verbose)"
00274 ) << "triangles share the same vertices:\n"
00275 << " face 1 :" << faceI << endl;
00276 printTriangle(Warning, " ", f, points());
00277
00278 Warning
00279 << endl
00280 << " face 2 :"
00281 << neighbours[neighbourI] << endl;
00282 printTriangle(Warning, " ", n, points());
00283 }
00284
00285 break;
00286 }
00287 }
00288 }
00289 }
00290
00291 if (hasInvalid)
00292 {
00293
00294 label newFaceI = 0;
00295 forAll(*this, faceI)
00296 {
00297 if (valid[faceI])
00298 {
00299 const labelledTri& f = (*this)[faceI];
00300 (*this)[newFaceI++] = f;
00301 }
00302 }
00303
00304 if (verbose)
00305 {
00306 WarningIn
00307 (
00308 "triSurface::checkTriangles(bool verbose)"
00309 ) << "Removing " << size() - newFaceI
00310 << " illegal faces." << endl;
00311 }
00312 (*this).setSize(newFaceI);
00313
00314
00315 clearOut();
00316 }
00317 }
00318
00319
00320
00321 void Foam::triSurface::checkEdges(const bool verbose)
00322 {
00323 const labelListList& eFaces = edgeFaces();
00324
00325 forAll(eFaces, edgeI)
00326 {
00327 const labelList& myFaces = eFaces[edgeI];
00328
00329 if (myFaces.empty())
00330 {
00331 FatalErrorIn("triSurface::checkEdges(bool verbose)")
00332 << "Edge " << edgeI << " with vertices " << edges()[edgeI]
00333 << " has no edgeFaces"
00334 << exit(FatalError);
00335 }
00336 else if (myFaces.size() > 2)
00337 {
00338 WarningIn
00339 (
00340 "triSurface::checkEdges(bool verbose)"
00341 ) << "Edge " << edgeI << " with vertices " << edges()[edgeI]
00342 << " has more than 2 faces connected to it : " << myFaces
00343 << endl;
00344 }
00345 }
00346 }
00347
00348
00349
00350 bool Foam::triSurface::read(Istream& is)
00351 {
00352 is >> patches_ >> storedPoints() >> storedFaces();
00353
00354 return true;
00355 }
00356
00357
00358
00359 bool Foam::triSurface::read
00360 (
00361 const fileName& name,
00362 const word& ext,
00363 const bool check
00364 )
00365 {
00366 if (check && !exists(name))
00367 {
00368 FatalErrorIn
00369 (
00370 "triSurface::read(const fileName&, const word&, const bool)"
00371 ) << "Cannnot read " << name << exit(FatalError);
00372 }
00373
00374 if (ext == "gz")
00375 {
00376 fileName unzipName = name.lessExt();
00377
00378
00379 return read(unzipName, unzipName.ext(), false);
00380 }
00381 else if (ext == "ftr")
00382 {
00383 return read(IFstream(name)());
00384 }
00385 else if (ext == "stl")
00386 {
00387 return readSTL(name);
00388 }
00389 else if (ext == "stlb")
00390 {
00391 return readSTL(name);
00392 }
00393 else if (ext == "gts")
00394 {
00395 return readGTS(name);
00396 }
00397 else if (ext == "obj")
00398 {
00399 return readOBJ(name);
00400 }
00401 else if (ext == "off")
00402 {
00403 return readOFF(name);
00404 }
00405 else if (ext == "tri")
00406 {
00407 return readTRI(name);
00408 }
00409 else if (ext == "ac")
00410 {
00411 return readAC(name);
00412 }
00413 else if (ext == "nas")
00414 {
00415 return readNAS(name);
00416 }
00417 else
00418 {
00419 FatalErrorIn
00420 (
00421 "triSurface::read(const fileName&, const word&)"
00422 ) << "unknown file extension " << ext
00423 << ". Supported extensions are '.ftr', '.stl', '.stlb', '.gts'"
00424 << ", '.obj', '.ac', '.off', '.nas' and '.tri'"
00425 << exit(FatalError);
00426
00427 return false;
00428 }
00429 }
00430
00431
00432
00433 void Foam::triSurface::write
00434 (
00435 const fileName& name,
00436 const word& ext,
00437 const bool sort
00438 ) const
00439 {
00440 if (ext == "ftr")
00441 {
00442 return write(OFstream(name)());
00443 }
00444 else if (ext == "stl")
00445 {
00446 return writeSTLASCII(OFstream(name)());
00447 }
00448 else if (ext == "stlb")
00449 {
00450 ofstream outFile(name.c_str(), std::ios::binary);
00451
00452 writeSTLBINARY(outFile);
00453 }
00454 else if (ext == "gts")
00455 {
00456 return writeGTS(sort, OFstream(name)());
00457 }
00458 else if (ext == "obj")
00459 {
00460 writeOBJ(sort, OFstream(name)());
00461 }
00462 else if (ext == "off")
00463 {
00464 writeOFF(sort, OFstream(name)());
00465 }
00466 else if (ext == "vtk")
00467 {
00468 writeVTK(sort, OFstream(name)());
00469 }
00470 else if (ext == "tri")
00471 {
00472 writeTRI(sort, OFstream(name)());
00473 }
00474 else if (ext == "dx")
00475 {
00476 writeDX(sort, OFstream(name)());
00477 }
00478 else if (ext == "ac")
00479 {
00480 writeAC(OFstream(name)());
00481 }
00482 else if (ext == "smesh")
00483 {
00484 writeSMESH(sort, OFstream(name)());
00485 }
00486 else
00487 {
00488 FatalErrorIn
00489 (
00490 "triSurface::write(const fileName&, const word&, const bool)"
00491 ) << "unknown file extension " << ext
00492 << ". Supported extensions are '.ftr', '.stl', '.stlb', "
00493 << "'.gts', '.obj', '.vtk'"
00494 << ", '.off', '.dx', '.smesh', '.ac' and '.tri'"
00495 << exit(FatalError);
00496 }
00497 }
00498
00499
00500
00501
00502 Foam::surfacePatchList Foam::triSurface::calcPatches(labelList& faceMap) const
00503 {
00504
00505 SortableList<label> sortedRegion(size());
00506
00507 forAll(sortedRegion, faceI)
00508 {
00509 sortedRegion[faceI] = operator[](faceI).region();
00510 }
00511 sortedRegion.sort();
00512
00513 faceMap = sortedRegion.indices();
00514
00515
00516 label maxRegion = patches_.size()-1;
00517
00518 if (faceMap.size())
00519 {
00520 maxRegion = max
00521 (
00522 maxRegion,
00523 operator[](faceMap[faceMap.size() - 1]).region()
00524 );
00525 }
00526
00527
00528 surfacePatchList newPatches(maxRegion + 1);
00529
00530
00531 forAll(*this, faceI)
00532 {
00533 label region = operator[](faceI).region();
00534
00535 newPatches[region].size()++;
00536 }
00537
00538
00539
00540
00541 label startFaceI = 0;
00542 forAll(newPatches, newPatchI)
00543 {
00544 surfacePatch& newPatch = newPatches[newPatchI];
00545
00546 newPatch.index() = newPatchI;
00547
00548 label oldPatchI = newPatchI;
00549
00550
00551 newPatch.start() = startFaceI;
00552
00553
00554
00555 if ((oldPatchI < patches_.size()) && (patches_[oldPatchI].name() != ""))
00556 {
00557 newPatch.name() = patches_[oldPatchI].name();
00558 }
00559 else
00560 {
00561 newPatch.name() = word("patch") + name(newPatchI);
00562 }
00563
00564 if
00565 (
00566 (oldPatchI < patches_.size())
00567 && (patches_[oldPatchI].geometricType() != "")
00568 )
00569 {
00570 newPatch.geometricType() = patches_[oldPatchI].geometricType();
00571 }
00572 else
00573 {
00574 newPatch.geometricType() = "empty";
00575 }
00576
00577 startFaceI += newPatch.size();
00578 }
00579
00580 return newPatches;
00581 }
00582
00583
00584 void Foam::triSurface::setDefaultPatches()
00585 {
00586 labelList faceMap;
00587
00588
00589 surfacePatchList newPatches(calcPatches(faceMap));
00590
00591
00592 patches_.setSize(newPatches.size());
00593
00594 forAll(newPatches, patchI)
00595 {
00596 patches_[patchI].index() = patchI;
00597 patches_[patchI].name() = newPatches[patchI].name();
00598 patches_[patchI].geometricType() = newPatches[patchI].geometricType();
00599 }
00600 }
00601
00602
00603
00604
00605 Foam::triSurface::triSurface()
00606 :
00607 ParentType(List<Face>(), pointField()),
00608 patches_(0),
00609 sortedEdgeFacesPtr_(NULL),
00610 edgeOwnerPtr_(NULL)
00611 {}
00612
00613
00614
00615 Foam::triSurface::triSurface
00616 (
00617 const List<labelledTri>& triangles,
00618 const geometricSurfacePatchList& patches,
00619 const pointField& points
00620 )
00621 :
00622 ParentType(triangles, points),
00623 patches_(patches),
00624 sortedEdgeFacesPtr_(NULL),
00625 edgeOwnerPtr_(NULL)
00626 {}
00627
00628
00629 Foam::triSurface::triSurface
00630 (
00631 List<labelledTri>& triangles,
00632 const geometricSurfacePatchList& patches,
00633 pointField& points,
00634 const bool reUse
00635 )
00636 :
00637 ParentType(triangles, points, reUse),
00638 patches_(patches),
00639 sortedEdgeFacesPtr_(NULL),
00640 edgeOwnerPtr_(NULL)
00641 {}
00642
00643
00644 Foam::triSurface::triSurface
00645 (
00646 const List<labelledTri>& triangles,
00647 const pointField& points
00648 )
00649 :
00650 ParentType(triangles, points),
00651 patches_(),
00652 sortedEdgeFacesPtr_(NULL),
00653 edgeOwnerPtr_(NULL)
00654 {
00655 setDefaultPatches();
00656 }
00657
00658
00659 Foam::triSurface::triSurface
00660 (
00661 const triFaceList& triangles,
00662 const pointField& points
00663 )
00664 :
00665 ParentType(convertToTri(triangles, 0), points),
00666 patches_(),
00667 sortedEdgeFacesPtr_(NULL),
00668 edgeOwnerPtr_(NULL)
00669 {
00670 setDefaultPatches();
00671 }
00672
00673
00674 Foam::triSurface::triSurface(const fileName& name)
00675 :
00676 ParentType(List<Face>(), pointField()),
00677 patches_(),
00678 sortedEdgeFacesPtr_(NULL),
00679 edgeOwnerPtr_(NULL)
00680 {
00681 word ext = name.ext();
00682
00683 read(name, ext);
00684
00685 setDefaultPatches();
00686 }
00687
00688
00689 Foam::triSurface::triSurface(Istream& is)
00690 :
00691 ParentType(List<Face>(), pointField()),
00692 patches_(),
00693 sortedEdgeFacesPtr_(NULL),
00694 edgeOwnerPtr_(NULL)
00695 {
00696 read(is);
00697
00698 setDefaultPatches();
00699 }
00700
00701
00702 Foam::triSurface::triSurface(const Time& d)
00703 :
00704 ParentType(List<Face>(), pointField()),
00705 patches_(),
00706 sortedEdgeFacesPtr_(NULL),
00707 edgeOwnerPtr_(NULL)
00708 {
00709 fileName foamFile(d.caseName() + ".ftr");
00710
00711 fileName foamPath(d.path()/triSurfInstance(d)/typeName/foamFile);
00712
00713 IFstream foamStream(foamPath);
00714
00715 read(foamStream);
00716
00717 setDefaultPatches();
00718 }
00719
00720
00721 Foam::triSurface::triSurface(const triSurface& ts)
00722 :
00723 ParentType(ts, ts.points()),
00724 patches_(ts.patches()),
00725 sortedEdgeFacesPtr_(NULL),
00726 edgeOwnerPtr_(NULL)
00727 {}
00728
00729
00730
00731
00732 Foam::triSurface::~triSurface()
00733 {
00734 clearOut();
00735 }
00736
00737
00738
00739
00740 void Foam::triSurface::clearTopology()
00741 {
00742 ParentType::clearTopology();
00743 deleteDemandDrivenData(sortedEdgeFacesPtr_);
00744 deleteDemandDrivenData(edgeOwnerPtr_);
00745 }
00746
00747
00748 void Foam::triSurface::clearPatchMeshAddr()
00749 {
00750 ParentType::clearPatchMeshAddr();
00751 }
00752
00753
00754 void Foam::triSurface::clearOut()
00755 {
00756 ParentType::clearOut();
00757
00758 clearTopology();
00759 clearPatchMeshAddr();
00760 }
00761
00762
00763 const Foam::labelListList& Foam::triSurface::sortedEdgeFaces() const
00764 {
00765 if (!sortedEdgeFacesPtr_)
00766 {
00767 calcSortedEdgeFaces();
00768 }
00769
00770 return *sortedEdgeFacesPtr_;
00771 }
00772
00773
00774 const Foam::labelList& Foam::triSurface::edgeOwner() const
00775 {
00776 if (!edgeOwnerPtr_)
00777 {
00778 calcEdgeOwner();
00779 }
00780
00781 return *edgeOwnerPtr_;
00782 }
00783
00784
00785
00786 void Foam::triSurface::movePoints(const pointField& newPoints)
00787 {
00788
00789 deleteDemandDrivenData(sortedEdgeFacesPtr_);
00790
00791
00792 ParentType::movePoints(newPoints);
00793
00794
00795 storedPoints() = newPoints;
00796 }
00797
00798
00799
00800 void Foam::triSurface::scalePoints(const scalar& scaleFactor)
00801 {
00802
00803 if (scaleFactor > 0 && scaleFactor != 1.0)
00804 {
00805
00806 clearTopology();
00807
00808
00809 ParentType::movePoints(pointField());
00810
00811 storedPoints() *= scaleFactor;
00812 }
00813 }
00814
00815
00816
00817 void Foam::triSurface::cleanup(const bool verbose)
00818 {
00819
00820 stitchTriangles(points(), SMALL, verbose);
00821
00822
00823 clearOut();
00824
00825 checkTriangles(verbose);
00826
00827 checkEdges(verbose);
00828 }
00829
00830
00831
00832
00833 void Foam::triSurface::markZone
00834 (
00835 const boolList& borderEdge,
00836 const label faceI,
00837 const label currentZone,
00838 labelList& faceZone
00839 ) const
00840 {
00841
00842 labelList changedFaces(1, faceI);
00843
00844 while(true)
00845 {
00846
00847 DynamicList<label> newChangedFaces(2*changedFaces.size());
00848
00849 forAll(changedFaces, i)
00850 {
00851 label faceI = changedFaces[i];
00852
00853 const labelList& fEdges = faceEdges()[faceI];
00854
00855 forAll(fEdges, i)
00856 {
00857 label edgeI = fEdges[i];
00858
00859 if (!borderEdge[edgeI])
00860 {
00861 const labelList& eFaces = edgeFaces()[edgeI];
00862
00863 forAll(eFaces, j)
00864 {
00865 label nbrFaceI = eFaces[j];
00866
00867 if (faceZone[nbrFaceI] == -1)
00868 {
00869 faceZone[nbrFaceI] = currentZone;
00870 newChangedFaces.append(nbrFaceI);
00871 }
00872 else if (faceZone[nbrFaceI] != currentZone)
00873 {
00874 FatalErrorIn
00875 (
00876 "triSurface::markZone(const boolList&,"
00877 "const label, const label, labelList&) const"
00878 )
00879 << "Zones " << faceZone[nbrFaceI]
00880 << " at face " << nbrFaceI
00881 << " connects to zone " << currentZone
00882 << " at face " << faceI
00883 << abort(FatalError);
00884 }
00885 }
00886 }
00887 }
00888 }
00889
00890 if (newChangedFaces.empty())
00891 {
00892 break;
00893 }
00894
00895 changedFaces.transfer(newChangedFaces);
00896 }
00897 }
00898
00899
00900
00901
00902 Foam::label Foam::triSurface::markZones
00903 (
00904 const boolList& borderEdge,
00905 labelList& faceZone
00906 ) const
00907 {
00908 faceZone.setSize(size());
00909 faceZone = -1;
00910
00911 if (borderEdge.size() != nEdges())
00912 {
00913 FatalErrorIn
00914 (
00915 "triSurface::markZones"
00916 "(const boolList&, labelList&)"
00917 )
00918 << "borderEdge boolList not same size as number of edges" << endl
00919 << "borderEdge:" << borderEdge.size() << endl
00920 << "nEdges :" << nEdges()
00921 << exit(FatalError);
00922 }
00923
00924 label zoneI = 0;
00925
00926 for (label startFaceI = 0;; zoneI++)
00927 {
00928
00929 for (; startFaceI < size(); startFaceI++)
00930 {
00931 if (faceZone[startFaceI] == -1)
00932 {
00933 break;
00934 }
00935 }
00936
00937 if (startFaceI >= size())
00938 {
00939 break;
00940 }
00941
00942 faceZone[startFaceI] = zoneI;
00943
00944 markZone(borderEdge, startFaceI, zoneI, faceZone);
00945 }
00946
00947 return zoneI;
00948 }
00949
00950
00951 void Foam::triSurface::subsetMeshMap
00952 (
00953 const boolList& include,
00954 labelList& pointMap,
00955 labelList& faceMap
00956 ) const
00957 {
00958 const List<labelledTri>& locFaces = localFaces();
00959
00960 label faceI = 0;
00961 label pointI = 0;
00962
00963 faceMap.setSize(locFaces.size());
00964
00965 pointMap.setSize(nPoints());
00966
00967 boolList pointHad(nPoints(), false);
00968
00969 forAll(include, oldFacei)
00970 {
00971 if (include[oldFacei])
00972 {
00973
00974 faceMap[faceI++] = oldFacei;
00975
00976
00977 const labelledTri& tri = locFaces[oldFacei];
00978
00979 label a = tri[0];
00980 if (!pointHad[a])
00981 {
00982 pointHad[a] = true;
00983 pointMap[pointI++] = a;
00984 }
00985
00986 label b = tri[1];
00987 if (!pointHad[b])
00988 {
00989 pointHad[b] = true;
00990 pointMap[pointI++] = b;
00991 }
00992
00993 label c = tri[2];
00994 if (!pointHad[c])
00995 {
00996 pointHad[c] = true;
00997 pointMap[pointI++] = c;
00998 }
00999 }
01000 }
01001
01002
01003 faceMap.setSize(faceI);
01004
01005 pointMap.setSize(pointI);
01006 }
01007
01008
01009 Foam::triSurface Foam::triSurface::subsetMesh
01010 (
01011 const boolList& include,
01012 labelList& pointMap,
01013 labelList& faceMap
01014 ) const
01015 {
01016 const pointField& locPoints = localPoints();
01017 const List<labelledTri>& locFaces = localFaces();
01018
01019
01020 subsetMeshMap(include, pointMap, faceMap);
01021
01022
01023
01024 pointField newPoints(pointMap.size());
01025 labelList oldToNew(locPoints.size());
01026 forAll(pointMap, pointi)
01027 {
01028 newPoints[pointi] = locPoints[pointMap[pointi]];
01029 oldToNew[pointMap[pointi]] = pointi;
01030 }
01031
01032
01033 List<labelledTri> newTriangles(faceMap.size());
01034
01035 forAll(faceMap, facei)
01036 {
01037
01038 const labelledTri& tri = locFaces[faceMap[facei]];
01039
01040 newTriangles[facei][0] = oldToNew[tri[0]];
01041 newTriangles[facei][1] = oldToNew[tri[1]];
01042 newTriangles[facei][2] = oldToNew[tri[2]];
01043 newTriangles[facei].region() = tri.region();
01044 }
01045
01046
01047 return triSurface(newTriangles, patches(), newPoints, true);
01048 }
01049
01050
01051 void Foam::triSurface::write
01052 (
01053 const fileName& name,
01054 const bool sortByRegion
01055 ) const
01056 {
01057 write(name, name.ext(), sortByRegion);
01058 }
01059
01060
01061 void Foam::triSurface::write(Ostream& os) const
01062 {
01063 os << patches() << endl;
01064
01065
01066 os << points() << nl
01067 << static_cast<const List<labelledTri>&>(*this) << endl;
01068
01069
01070 os.check("triSurface::write(Ostream&)");
01071 }
01072
01073
01074 void Foam::triSurface::write(const Time& d) const
01075 {
01076 fileName foamFile(d.caseName() + ".ftr");
01077
01078 fileName foamPath(d.path()/triSurfInstance(d)/typeName/foamFile);
01079
01080 OFstream foamStream(foamPath);
01081
01082 write(foamStream);
01083 }
01084
01085
01086 void Foam::triSurface::writeStats(Ostream& os) const
01087 {
01088
01089
01090 PackedBoolList pointIsUsed(points().size());
01091
01092 label nPoints = 0;
01093 boundBox bb = boundBox::invertedBox;
01094
01095 forAll(*this, triI)
01096 {
01097 const labelledTri& f = operator[](triI);
01098
01099 forAll(f, fp)
01100 {
01101 label pointI = f[fp];
01102 if (pointIsUsed.set(pointI, 1))
01103 {
01104 bb.min() = ::Foam::min(bb.min(), points()[pointI]);
01105 bb.max() = ::Foam::max(bb.max(), points()[pointI]);
01106 nPoints++;
01107 }
01108 }
01109 }
01110
01111 os << "Triangles : " << size() << endl
01112 << "Vertices : " << nPoints << endl
01113 << "Bounding Box : " << bb << endl;
01114 }
01115
01116
01117
01118
01119 void Foam::triSurface::operator=(const triSurface& ts)
01120 {
01121 List<labelledTri>::operator=(ts);
01122 clearOut();
01123 storedPoints() = ts.points();
01124 patches_ = ts.patches();
01125 }
01126
01127
01128
01129
01130 Foam::Ostream& Foam::operator<<(Ostream& os, const triSurface& sm)
01131 {
01132 sm.write(os);
01133 return os;
01134 }
01135
01136
01137