ENH: cylinderAnnulusToCell: new cellSource for cellSets
[OpenFOAM-1.7.x.git] / src / surfMesh / MeshedSurface / MeshedSurface.C
blob9621934563fd31155eccfb664b23d5e96261a8da
1 /*---------------------------------------------------------------------------*\
2   =========                 |
3   \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox
4    \\    /   O peration     |
5     \\  /    A nd           | Copyright (C) 1991-2010 OpenCFD Ltd.
6      \\/     M anipulation  |
7 -------------------------------------------------------------------------------
8 License
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
19     for more details.
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 "MeshedSurface.H"
27 #include "UnsortedMeshedSurface.H"
28 #include "MeshedSurfaceProxy.H"
29 #include "mergePoints.H"
30 #include "Time.H"
31 #include "ListOps.H"
32 #include "polyBoundaryMesh.H"
33 #include "polyMesh.H"
34 #include "surfMesh.H"
35 #include "primitivePatch.H"
36 #include "addToRunTimeSelectionTable.H"
38 // * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
40 template<class Face>
41 inline bool Foam::MeshedSurface<Face>::isTri()
43     return false;
47 template<class Face>
48 Foam::wordHashSet Foam::MeshedSurface<Face>::readTypes()
50     return wordHashSet(*fileExtensionConstructorTablePtr_);
54 template<class Face>
55 Foam::wordHashSet Foam::MeshedSurface<Face>::writeTypes()
57     return wordHashSet(*writefileExtensionMemberFunctionTablePtr_);
61 // * * * * * * * * * * * * * Static Member Functions * * * * * * * * * * * * //
63 template<class Face>
64 bool Foam::MeshedSurface<Face>::canReadType
66     const word& ext,
67     const bool verbose
70     return checkSupport
71     (
72         readTypes() | FriendType::readTypes(),
73         ext,
74         verbose,
75         "reading"
76    );
80 template<class Face>
81 bool Foam::MeshedSurface<Face>::canWriteType
83     const word& ext,
84     const bool verbose
87     return checkSupport
88     (
89         writeTypes() | ProxyType::writeTypes(),
90         ext,
91         verbose,
92         "writing"
93     );
97 template<class Face>
98 bool Foam::MeshedSurface<Face>::canRead
100     const fileName& name,
101     const bool verbose
104     word ext = name.ext();
105     if (ext == "gz")
106     {
107         ext = name.lessExt().ext();
108     }
109     return canReadType(ext, verbose);
113 template<class Face>
114 void Foam::MeshedSurface<Face>::write
116     const fileName& name,
117     const MeshedSurface<Face>& surf
120     if (debug)
121     {
122         Info<< "MeshedSurface::write"
123             "(const fileName&, const MeshedSurface&) : "
124             "writing to " << name
125             << endl;
126     }
128     const word ext = name.ext();
130     typename writefileExtensionMemberFunctionTable::iterator mfIter =
131         writefileExtensionMemberFunctionTablePtr_->find(ext);
133     if (mfIter == writefileExtensionMemberFunctionTablePtr_->end())
134     {
135         // no direct writer, delegate to proxy if possible
136         wordHashSet supported = ProxyType::writeTypes();
138         if (supported.found(ext))
139         {
140             MeshedSurfaceProxy<Face>(surf).write(name);
141         }
142         else
143         {
144             FatalErrorIn
145             (
146                 "MeshedSurface::write"
147                 "(const fileName&, const MeshedSurface&)"
148             )   << "Unknown file extension " << ext << nl << nl
149                 << "Valid types are :" << endl
150                 << (supported | writeTypes())
151                 << exit(FatalError);
152         }
153     }
154     else
155     {
156         mfIter()(name, surf);
157     }
161 // * * * * * * * * * * * * * * * * Constructors  * * * * * * * * * * * * * * //
163 template<class Face>
164 Foam::MeshedSurface<Face>::MeshedSurface()
166     ParentType(List<Face>(), pointField())
170 template<class Face>
171 Foam::MeshedSurface<Face>::MeshedSurface
173     const Xfer< pointField >& pointLst,
174     const Xfer< List<Face> >& faceLst,
175     const Xfer< surfZoneList >& zoneLst
178     ParentType(List<Face>(), pointField()),
179     zones_()
181     reset(pointLst, faceLst, zoneLst);
185 template<class Face>
186 Foam::MeshedSurface<Face>::MeshedSurface
188     const Xfer< pointField >& pointLst,
189     const Xfer< List<Face> >& faceLst,
190     const UList<label>& zoneSizes,
191     const UList<word>& zoneNames
194     ParentType(List<Face>(), pointField())
196     reset(pointLst, faceLst, Xfer<surfZoneList>());
198     if (zoneSizes.size())
199     {
200         if (zoneNames.size())
201         {
202             addZones(zoneSizes, zoneNames);
203         }
204         else
205         {
206             addZones(zoneSizes);
207         }
208     }
212 template<class Face>
213 Foam::MeshedSurface<Face>::MeshedSurface
215     const MeshedSurface<Face>& surf
218     ParentType(surf.faces(), surf.points()),
219     zones_(surf.surfZones())
223 template<class Face>
224 Foam::MeshedSurface<Face>::MeshedSurface
226     const UnsortedMeshedSurface<Face>& surf
229     ParentType(List<Face>(), surf.points())
231     labelList faceMap;
232     this->storedZones().transfer(surf.sortedZones(faceMap));
234     const List<Face>& origFaces = surf.faces();
235     List<Face> newFaces(origFaces.size());
237     // this is somewhat like ListOps reorder and/or IndirectList
238     forAll(newFaces, faceI)
239     {
240         newFaces[faceI] = origFaces[faceMap[faceI]];
241     }
243     this->storedFaces().transfer(newFaces);
247 template<class Face>
248 Foam::MeshedSurface<Face>::MeshedSurface(const surfMesh& mesh)
250     ParentType(List<Face>(), pointField())
252     // same face type as surfMesh
253     MeshedSurface<face> surf
254     (
255         xferCopy(mesh.points()),
256         xferCopy(mesh.faces()),
257         xferCopy(mesh.surfZones())
258     );
260     this->transcribe(surf);
264 template<class Face>
265 Foam::MeshedSurface<Face>::MeshedSurface
267     const polyBoundaryMesh& bMesh,
268     const bool useGlobalPoints
271     ParentType(List<Face>(), pointField())
273     const polyMesh& mesh = bMesh.mesh();
274     const polyPatchList& bPatches = bMesh;
276     // Get a single patch for all boundaries
277     primitivePatch allBoundary
278     (
279         SubList<face>
280         (
281             mesh.faces(),
282             mesh.nFaces() - mesh.nInternalFaces(),
283             mesh.nInternalFaces()
284         ),
285         mesh.points()
286     );
288     // use global/local points:
289     const pointField& bPoints =
290     (
291         useGlobalPoints ? mesh.points() : allBoundary.localPoints()
292     );
294     // global/local face addressing:
295     const List<Face>& bFaces =
296     (
297         useGlobalPoints ? allBoundary : allBoundary.localFaces()
298     );
301     // create zone list
302     surfZoneList newZones(bPatches.size());
304     label startFaceI = 0;
305     label nZone = 0;
306     forAll(bPatches, patchI)
307     {
308         const polyPatch& p = bPatches[patchI];
310         if (p.size())
311         {
312             newZones[nZone] = surfZone
313             (
314                 p.name(),
315                 p.size(),
316                 startFaceI,
317                 nZone
318             );
320             nZone++;
321             startFaceI += p.size();
322         }
323     }
325     newZones.setSize(nZone);
327     // same face type as the polyBoundaryMesh
328     MeshedSurface<face> surf
329     (
330         xferCopy(bPoints),
331         xferCopy(bFaces),
332         xferMove(newZones)
333     );
335     this->transcribe(surf);
339 template<class Face>
340 Foam::MeshedSurface<Face>::MeshedSurface
342     const fileName& name,
343     const word& ext
346     ParentType(List<Face>(), pointField())
348     read(name, ext);
352 template<class Face>
353 Foam::MeshedSurface<Face>::MeshedSurface(const fileName& name)
355     ParentType(List<Face>(), pointField())
357     read(name);
361 template<class Face>
362 Foam::MeshedSurface<Face>::MeshedSurface
364     const Time& t,
365     const word& surfName
368     ParentType(List<Face>(), pointField())
370     surfMesh mesh
371     (
372         IOobject
373         (
374             "dummyName",
375             t.timeName(),
376             t,
377             IOobject::MUST_READ,
378             IOobject::NO_WRITE,
379             false
380         ),
381         surfName
382     );
384     // same face type as surfMesh
385     MeshedSurface<face> surf
386     (
387         xferMove(mesh.storedPoints()),
388         xferMove(mesh.storedFaces()),
389         xferMove(mesh.storedZones())
390     );
392     this->transcribe(surf);
396 template<class Face>
397 Foam::MeshedSurface<Face>::MeshedSurface
399     const Xfer< UnsortedMeshedSurface<Face> >& surf
402     ParentType(List<Face>(), pointField())
404     transfer(surf());
408 template<class Face>
409 Foam::MeshedSurface<Face>::MeshedSurface
411     const Xfer< MeshedSurface<Face> >& surf
414     ParentType(List<Face>(), pointField())
416     transfer(surf());
421 // * * * * * * * * * * * * * * * * Destructor  * * * * * * * * * * * * * * * //
423 template<class Face>
424 Foam::MeshedSurface<Face>::~MeshedSurface()
428 // * * * * * * * * * * * * * Private Member Functions  * * * * * * * * * * * //
431 // * * * * * * * * * * * * Protected Member Functions  * * * * * * * * * * * //
433 template<class Face>
434 void Foam::MeshedSurface<Face>::remapFaces
436     const UList<label>& faceMap
439     // recalculate the zone start/size
440     if (&faceMap && faceMap.size())
441     {
442         surfZoneList& zones = storedZones();
444         if (zones.size() == 1)
445         {
446             // optimized for single zone case
447             zones[0].size() = faceMap.size();
448         }
449         else if (zones.size())
450         {
451             label newFaceI = 0;
452             label origEndI = 0;
453             forAll(zones, zoneI)
454             {
455                 surfZone& zone = zones[zoneI];
457                 // adjust zone start
458                 zone.start() = newFaceI;
459                 origEndI += zone.size();
461                 for (label faceI = newFaceI; faceI < faceMap.size(); ++faceI)
462                 {
463                     if (faceMap[faceI] < origEndI)
464                     {
465                         ++newFaceI;
466                     }
467                     else
468                     {
469                         break;
470                     }
471                 }
473                 // adjust zone size
474                 zone.size() = newFaceI - zone.start();
475             }
476         }
477     }
481 // * * * * * * * * * * * * * * * Member Functions  * * * * * * * * * * * * * //
483 template<class Face>
484 void Foam::MeshedSurface<Face>::clear()
486     ParentType::clearOut();
488     storedPoints().clear();
489     storedFaces().clear();
490     storedZones().clear();
494 template<class Face>
495 void Foam::MeshedSurface<Face>::movePoints(const pointField& newPoints)
497     // Remove all geometry dependent data
498     ParentType::clearTopology();
500     // Adapt for new point position
501     ParentType::movePoints(newPoints);
503     // Copy new points
504     storedPoints() = newPoints;
508 template<class Face>
509 void Foam::MeshedSurface<Face>::scalePoints(const scalar& scaleFactor)
511     // avoid bad scaling
512     if (scaleFactor > 0 && scaleFactor != 1.0)
513     {
514         // Remove all geometry dependent data
515         ParentType::clearTopology();
517         // Adapt for new point position
518         ParentType::movePoints(pointField());
520         storedPoints() *= scaleFactor;
521     }
525 template<class Face>
526 void Foam::MeshedSurface<Face>::reset
528     const Xfer< pointField >& pointLst,
529     const Xfer< List<Face> >& faceLst,
530     const Xfer< surfZoneList >& zoneLst
533     ParentType::clearOut();
535     // Take over new primitive data.
536     // Optimized to avoid overwriting data at all
537     if (&pointLst)
538     {
539         storedPoints().transfer(pointLst());
540     }
542     if (&faceLst)
543     {
544         storedFaces().transfer(faceLst());
545     }
547     if (&zoneLst)
548     {
549         storedZones().transfer(zoneLst());
550     }
554 template<class Face>
555 void Foam::MeshedSurface<Face>::reset
557     const Xfer< List<point> >& pointLst,
558     const Xfer< List<Face> >& faceLst,
559     const Xfer< surfZoneList >& zoneLst
562     ParentType::clearOut();
564     // Take over new primitive data.
565     // Optimized to avoid overwriting data at all
566     if (&pointLst)
567     {
568         storedPoints().transfer(pointLst());
569     }
571     if (&faceLst)
572     {
573         storedFaces().transfer(faceLst());
574     }
576     if (&zoneLst)
577     {
578         storedZones().transfer(zoneLst());
579     }
583 // Remove badly degenerate faces, double faces.
584 template<class Face>
585 void Foam::MeshedSurface<Face>::cleanup(const bool verbose)
587     // merge points (already done for STL, TRI)
588     stitchFaces(SMALL, verbose);
590     checkFaces(verbose);
591     this->checkTopology(verbose);
595 template<class Face>
596 bool Foam::MeshedSurface<Face>::stitchFaces
598     const scalar tol,
599     const bool verbose
602     pointField& pointLst = this->storedPoints();
604     // Merge points
605     labelList  pointMap(pointLst.size());
606     pointField newPoints(pointLst.size());
608     bool hasMerged = mergePoints(pointLst, tol, verbose, pointMap, newPoints);
610     if (!hasMerged)
611     {
612         return false;
613     }
615     if (verbose)
616     {
617         Info<< "MeshedSurface::stitchFaces : Renumbering all faces"
618             << endl;
619     }
621     // Set the coordinates to the merged ones
622     pointLst.transfer(newPoints);
624     List<Face>& faceLst = this->storedFaces();
626     List<label> faceMap(faceLst.size());
628     // Reset the point labels to the unique points array
629     label newFaceI = 0;
630     forAll(faceLst, faceI)
631     {
632         Face& f = faceLst[faceI];
633         forAll(f, fp)
634         {
635             f[fp] = pointMap[f[fp]];
636         }
638         // for extra safety: collapse face as well
639         if (f.collapse() >= 3)
640         {
641             if (newFaceI != faceI)
642             {
643                 faceLst[newFaceI] = f;
644             }
645             faceMap[newFaceI] = faceI;
646             newFaceI++;
647         }
648         else if (verbose)
649         {
650             Pout<< "MeshedSurface::stitchFaces : "
651                 << "Removing collapsed face " << faceI << endl
652                 << "    vertices   :" << f << endl;
653         }
654     }
655     pointMap.clear();
657     if (newFaceI != faceLst.size())
658     {
659         if (verbose)
660         {
661             Pout<< "MeshedSurface::stitchFaces : "
662                 << "Removed " << faceLst.size() - newFaceI
663                 << " faces" << endl;
664         }
665         faceLst.setSize(newFaceI);
666         remapFaces(faceMap);
667     }
668     faceMap.clear();
670     // Merging points might have changed geometric factors
671     ParentType::clearOut();
672     return true;
676 // Remove badly degenerate faces and double faces.
677 template<class Face>
678 bool Foam::MeshedSurface<Face>::checkFaces
680     const bool verbose
683     bool changed = false;
684     List<Face>& faceLst = this->storedFaces();
686     List<label> faceMap(faceLst.size());
688     label newFaceI = 0;
689     // Detect badly labelled faces and mark degenerate faces
690     const label maxPointI = this->points().size() - 1;
691     forAll(faceLst, faceI)
692     {
693         Face& f = faceLst[faceI];
695         // avoid degenerate faces
696         if (f.collapse() >= 3)
697         {
698             forAll(f, fp)
699             {
700                 if (f[fp] < 0 || f[fp] > maxPointI)
701                 {
702                     FatalErrorIn("MeshedSurface::checkFaces(bool)")
703                         << "face " << f
704                         << " uses point indices outside point range 0.."
705                     << maxPointI
706                         << exit(FatalError);
707                 }
708             }
710             faceMap[faceI] = faceI;
711             newFaceI++;
712         }
713         else
714         {
715             // mark as bad face
716             faceMap[faceI] = -1;
718             changed = true;
719             if (verbose)
720             {
721                 WarningIn
722                 (
723                     "MeshedSurface::checkFaces(bool verbose)"
724                 )   << "face[" << faceI << "] = " << f
725                     << " does not have three unique vertices" << endl;
726             }
727         }
728     }
730     // Detect doubled faces
731     // do not touch the faces
732     const labelListList& fFaces = this->faceFaces();
733     newFaceI = 0;
734     forAll(faceLst, faceI)
735     {
736         // skip already collapsed faces:
737         if (faceMap[faceI] < 0)
738         {
739             continue;
740         }
742         const Face& f = faceLst[faceI];
744         // duplicate face check
745         bool okay = true;
746         const labelList& neighbours = fFaces[faceI];
748         // Check if faceNeighbours use same points as this face.
749         // Note: discards normal information - sides of baffle are merged.
750         forAll(neighbours, neighI)
751         {
752             const label neiFaceI = neighbours[neighI];
754             if (neiFaceI <= faceI || faceMap[neiFaceI] < 0)
755             {
756                 // lower numbered faces already checked
757                 // skip neighbours that are themselves collapsed
758                 continue;
759             }
761             const Face& nei = faceLst[neiFaceI];
763             if (f == nei)
764             {
765                 okay = false;
767                 if (verbose)
768                 {
769                     WarningIn
770                     (
771                         "MeshedSurface::checkFaces(bool verbose)"
772                     )   << "faces share the same vertices:" << nl
773                         << "    face[" << faceI << "] : " << f << nl
774                         << "    face[" << neiFaceI << "] : " << nei << endl;
775                     // printFace(Warning, "    ", f, points());
776                     // printFace(Warning, "    ", nei, points());
777                 }
779                 break;
780             }
781         }
783         if (okay)
784         {
785             faceMap[faceI] = faceI;
786             newFaceI++;
787         }
788         else
789         {
790             faceMap[faceI] = -1;
791         }
792     }
794     // Phase 1: pack
795     // Done to keep numbering constant in phase 1
797     if (changed || newFaceI < faceLst.size())
798     {
799         changed = true;
801         if (verbose)
802         {
803             WarningIn
804             (
805                 "MeshedSurface::checkFaces(bool verbose)"
806             )   << "Removed " << faceLst.size() - newFaceI
807                 << " illegal faces." << endl;
808         }
810         // compress the face list
811         newFaceI = 0;
812         forAll(faceLst, faceI)
813         {
814             if (faceMap[faceI] >= 0)
815             {
816                 if (newFaceI != faceI)
817                 {
818                     faceLst[newFaceI] = faceLst[faceI];
819                 }
820                 faceMap[newFaceI] = faceI;
821                 newFaceI++;
822             }
823         }
825         faceLst.setSize(newFaceI);
826         remapFaces(faceMap);
827     }
828     faceMap.clear();
830     // Topology can change because of renumbering
831     ParentType::clearOut();
832     return changed;
836 template<class Face>
837 Foam::label Foam::MeshedSurface<Face>::triangulate()
839     return triangulate
840     (
841         const_cast<List<label>&>(List<label>::null())
842     );
846 template<class Face>
847 Foam::label Foam::MeshedSurface<Face>::triangulate
849     List<label>& faceMapOut
852     label nTri = 0;
853     label maxTri = 0;  // the maximum number of triangles for any single face
854     List<Face>& faceLst = this->storedFaces();
856     // determine how many triangles will be needed
857     forAll(faceLst, faceI)
858     {
859         const label n = faceLst[faceI].nTriangles();
860         if (maxTri < n)
861         {
862             maxTri = n;
863         }
864         nTri += n;
865     }
867     // nothing to do
868     if (nTri <= faceLst.size())
869     {
870         if (&faceMapOut)
871         {
872             faceMapOut.clear();
873         }
874         return 0;
875     }
877     List<Face>  newFaces(nTri);
878     List<label> faceMap;
880     // reuse storage from optional faceMap
881     if (&faceMapOut)
882     {
883         faceMap.transfer(faceMapOut);
884     }
885     faceMap.setSize(nTri);
887     // remember the number of *additional* faces
888     nTri -= faceLst.size();
890     if (this->points().empty())
891     {
892         // triangulate without points
893         // simple face triangulation around f[0]
894         label newFaceI = 0;
895         forAll(faceLst, faceI)
896         {
897             const Face& f = faceLst[faceI];
899             for (label fp = 1; fp < f.size() - 1; ++fp)
900             {
901                 label fp1 = f.fcIndex(fp);
903                 newFaces[newFaceI] = triFace(f[0], f[fp], f[fp1]);
904                 faceMap[newFaceI] = faceI;
905                 newFaceI++;
906             }
907         }
908     }
909     else
910     {
911         // triangulate with points
912         List<face> tmpTri(maxTri);
914         label newFaceI = 0;
915         forAll(faceLst, faceI)
916         {
917             // 'face' not '<Face>'
918             const face& f = faceLst[faceI];
920             label nTmp = 0;
921             f.triangles(this->points(), nTmp, tmpTri);
922             for (label triI = 0; triI < nTmp; triI++)
923             {
924                 newFaces[newFaceI] = Face
925                 (
926                     static_cast<UList<label>&>(tmpTri[triI])
927                 );
928                 faceMap[newFaceI] = faceI;
929                 newFaceI++;
930             }
931         }
932     }
934     faceLst.transfer(newFaces);
935     remapFaces(faceMap);
937     // optionally return the faceMap
938     if (&faceMapOut)
939     {
940         faceMapOut.transfer(faceMap);
941     }
942     faceMap.clear();
944     // Topology can change because of renumbering
945     ParentType::clearOut();
946     return nTri;
952 template<class Face>
953 Foam::MeshedSurface<Face> Foam::MeshedSurface<Face>::subsetMesh
955     const labelHashSet& include,
956     labelList& pointMap,
957     labelList& faceMap
958 ) const
960     const pointField& locPoints = this->localPoints();
961     const List<Face>& locFaces  = this->localFaces();
964     // Fill pointMap, faceMap
965     PatchTools::subsetMap(*this, include, pointMap, faceMap);
967     // Create compact coordinate list and forward mapping array
968     pointField newPoints(pointMap.size());
969     labelList oldToNew(locPoints.size());
970     forAll(pointMap, pointI)
971     {
972         newPoints[pointI] = locPoints[pointMap[pointI]];
973         oldToNew[pointMap[pointI]] = pointI;
974     }
976     // create/copy a new zones list, each zone with zero size
977     surfZoneList newZones(this->surfZones());
978     forAll(newZones, zoneI)
979     {
980         newZones[zoneI].size() = 0;
981     }
983     // Renumber face node labels
984     List<Face> newFaces(faceMap.size());
985     forAll(faceMap, faceI)
986     {
987         const label origFaceI = faceMap[faceI];
988         newFaces[faceI] = Face(locFaces[origFaceI]);
990         // Renumber labels for face
991         Face& f = newFaces[faceI];
992         forAll(f, fp)
993         {
994             f[fp] = oldToNew[f[fp]];
995         }
996     }
997     oldToNew.clear();
999     // recalculate the zones start/size
1000     label newFaceI = 0;
1001     label origEndI = 0;
1003     // adjust zone sizes
1004     forAll(newZones, zoneI)
1005     {
1006         surfZone& zone = newZones[zoneI];
1008         // adjust zone start
1009         zone.start() = newFaceI;
1010         origEndI += zone.size();
1012         for (label faceI = newFaceI; faceI < faceMap.size(); ++faceI)
1013         {
1014             if (faceMap[faceI] < origEndI)
1015             {
1016                 ++newFaceI;
1017             }
1018             else
1019             {
1020                 break;
1021             }
1022         }
1024         // adjust zone size
1025         zone.size() = newFaceI - zone.start();
1026     }
1029     // construct a sub-surface
1030     return MeshedSurface
1031     (
1032         xferMove(newPoints),
1033         xferMove(newFaces),
1034         xferMove(newZones)
1035     );
1039 template<class Face>
1040 Foam::MeshedSurface<Face>
1041 Foam::MeshedSurface<Face>::subsetMesh
1043     const labelHashSet& include
1044 ) const
1046     labelList pointMap, faceMap;
1047     return subsetMesh(include, pointMap, faceMap);
1052 template<class Face>
1053 void Foam::MeshedSurface<Face>::transfer
1055     MeshedSurface<Face>& surf
1058     reset
1059     (
1060         xferMove(surf.storedPoints()),
1061         xferMove(surf.storedFaces()),
1062         xferMove(surf.storedZones())
1063     );
1067 template<class Face>
1068 void Foam::MeshedSurface<Face>::transfer
1070     UnsortedMeshedSurface<Face>& surf
1073     clear();
1075     labelList faceMap;
1076     surfZoneList zoneLst = surf.sortedZones(faceMap);
1078     if (zoneLst.size() <= 1)
1079     {
1080         reset
1081         (
1082             xferMove(surf.storedPoints()),
1083             xferMove(surf.storedFaces()),
1084             Xfer<surfZoneList>()
1085         );
1086     }
1087     else
1088     {
1089         List<Face>& oldFaces = surf.storedFaces();
1090         List<Face> newFaces(faceMap.size());
1092         forAll(faceMap, faceI)
1093         {
1094             newFaces[faceI].transfer(oldFaces[faceMap[faceI]]);
1095         }
1097         reset
1098         (
1099             xferMove(surf.storedPoints()),
1100             xferMove(newFaces),
1101             xferMove(zoneLst)
1102         );
1103     }
1105     faceMap.clear();
1106     surf.clear();
1110 template<class Face>
1111 Foam::Xfer< Foam::MeshedSurface<Face> >
1112 Foam::MeshedSurface<Face>::xfer()
1114     return xferMove(*this);
1118 // Read from file, determine format from extension
1119 template<class Face>
1120 bool Foam::MeshedSurface<Face>::read(const fileName& name)
1122     word ext = name.ext();
1123     if (ext == "gz")
1124     {
1125         fileName unzipName = name.lessExt();
1126         return read(unzipName, unzipName.ext());
1127     }
1128     else
1129     {
1130         return read(name, ext);
1131     }
1135 // Read from file in given format
1136 template<class Face>
1137 bool Foam::MeshedSurface<Face>::read
1139     const fileName& name,
1140     const word& ext
1143     clear();
1145     // read via selector mechanism
1146     transfer(New(name, ext)());
1147     return true;
1151 template<class Face>
1152 void Foam::MeshedSurface<Face>::write
1154     const Time& t,
1155     const word& surfName
1156 ) const
1158     MeshedSurfaceProxy<Face>(*this).write(t, surfName);
1161 // * * * * * * * * * * * * * * * Member Operators  * * * * * * * * * * * * * //
1163 template<class Face>
1164 void Foam::MeshedSurface<Face>::operator=(const MeshedSurface& surf)
1166     clear();
1168     this->storedPoints() = surf.points();
1169     this->storedFaces()  = surf.faces();
1170     this->storedZones()  = surf.surfZones();
1174 template<class Face>
1175 Foam::MeshedSurface<Face>::operator
1176 Foam::MeshedSurfaceProxy<Face>() const
1178     return MeshedSurfaceProxy<Face>
1179     (
1180         this->points(),
1181         this->faces(),
1182         this->surfZones()
1183     );
1186 // * * * * * * * * * * * * * * * Friend Functions  * * * * * * * * * * * * * //
1188 // * * * * * * * * * * * * * * * IOstream Operators  * * * * * * * * * * * * //
1190 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
1192 #include "MeshedSurfaceZones.C"
1193 #include "MeshedSurfaceIO.C"
1194 #include "MeshedSurfaceNew.C"
1196 // ************************************************************************* //