initial commit for version 1.6.x patch release
[OpenFOAM-1.6.x.git] / src / surfMesh / MeshedSurface / MeshedSurface.C
blob8bcab42089f7936519567d3e0c9ce922decee5cc
1 /*---------------------------------------------------------------------------*\
2   =========                 |
3   \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox
4    \\    /   O peration     |
5     \\  /    A nd           | Copyright (C) 1991-2009 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 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
19     for more details.
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 "MeshedSurface.H"
28 #include "UnsortedMeshedSurface.H"
29 #include "MeshedSurfaceProxy.H"
30 #include "mergePoints.H"
31 #include "Time.H"
32 #include "ListOps.H"
33 #include "polyBoundaryMesh.H"
34 #include "polyMesh.H"
35 #include "surfMesh.H"
36 #include "primitivePatch.H"
37 #include "addToRunTimeSelectionTable.H"
39 // * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
41 template<class Face>
42 inline bool Foam::MeshedSurface<Face>::isTri()
44     return false;
48 template<class Face>
49 Foam::wordHashSet Foam::MeshedSurface<Face>::readTypes()
51     return wordHashSet(*fileExtensionConstructorTablePtr_);
55 template<class Face>
56 Foam::wordHashSet Foam::MeshedSurface<Face>::writeTypes()
58     return wordHashSet(*writefileExtensionMemberFunctionTablePtr_);
62 // * * * * * * * * * * * * * Static Member Functions * * * * * * * * * * * * //
64 template<class Face>
65 bool Foam::MeshedSurface<Face>::canReadType
67     const word& ext,
68     const bool verbose
71     return checkSupport
72     (
73         readTypes() | FriendType::readTypes(),
74         ext,
75         verbose,
76         "reading"
77    );
81 template<class Face>
82 bool Foam::MeshedSurface<Face>::canWriteType
84     const word& ext,
85     const bool verbose
88     return checkSupport
89     (
90         writeTypes() | ProxyType::writeTypes(),
91         ext,
92         verbose,
93         "writing"
94     );
98 template<class Face>
99 bool Foam::MeshedSurface<Face>::canRead
101     const fileName& name,
102     const bool verbose
105     word ext = name.ext();
106     if (ext == "gz")
107     {
108         ext = name.lessExt().ext();
109     }
110     return canReadType(ext, verbose);
114 template<class Face>
115 void Foam::MeshedSurface<Face>::write
117     const fileName& name,
118     const MeshedSurface<Face>& surf
121     if (debug)
122     {
123         Info<< "MeshedSurface::write"
124             "(const fileName&, const MeshedSurface&) : "
125             "writing to " << name
126             << endl;
127     }
129     const word ext = name.ext();
131     typename writefileExtensionMemberFunctionTable::iterator mfIter =
132         writefileExtensionMemberFunctionTablePtr_->find(ext);
134     if (mfIter == writefileExtensionMemberFunctionTablePtr_->end())
135     {
136         // no direct writer, delegate to proxy if possible
137         wordHashSet supported = ProxyType::writeTypes();
139         if (supported.found(ext))
140         {
141             MeshedSurfaceProxy<Face>(surf).write(name);
142         }
143         else
144         {
145             FatalErrorIn
146             (
147                 "MeshedSurface::write"
148                 "(const fileName&, const MeshedSurface&)"
149             )   << "Unknown file extension " << ext << nl << nl
150                 << "Valid types are :" << endl
151                 << (supported | writeTypes())
152                 << exit(FatalError);
153         }
154     }
155     else
156     {
157         mfIter()(name, surf);
158     }
162 // * * * * * * * * * * * * * * * * Constructors  * * * * * * * * * * * * * * //
164 template<class Face>
165 Foam::MeshedSurface<Face>::MeshedSurface()
167     ParentType(List<Face>(), pointField())
171 template<class Face>
172 Foam::MeshedSurface<Face>::MeshedSurface
174     const Xfer< pointField >& pointLst,
175     const Xfer< List<Face> >& faceLst,
176     const Xfer< surfZoneList >& zoneLst
179     ParentType(List<Face>(), pointField()),
180     zones_()
182     reset(pointLst, faceLst, zoneLst);
186 template<class Face>
187 Foam::MeshedSurface<Face>::MeshedSurface
189     const Xfer< pointField >& pointLst,
190     const Xfer< List<Face> >& faceLst,
191     const UList<label>& zoneSizes,
192     const UList<word>& zoneNames
195     ParentType(List<Face>(), pointField())
197     reset(pointLst, faceLst, Xfer<surfZoneList>());
199     if (zoneSizes.size())
200     {
201         if (zoneNames.size())
202         {
203             addZones(zoneSizes, zoneNames);
204         }
205         else
206         {
207             addZones(zoneSizes);
208         }
209     }
213 template<class Face>
214 Foam::MeshedSurface<Face>::MeshedSurface
216     const MeshedSurface<Face>& surf
219     ParentType(surf.faces(), surf.points()),
220     zones_(surf.surfZones())
224 template<class Face>
225 Foam::MeshedSurface<Face>::MeshedSurface
227     const UnsortedMeshedSurface<Face>& surf
230     ParentType(List<Face>(), surf.points())
232     labelList faceMap;
233     this->storedZones().transfer(surf.sortedZones(faceMap));
235     const List<Face>& origFaces = surf.faces();
236     List<Face> newFaces(origFaces.size());
238     // this is somewhat like ListOps reorder and/or IndirectList
239     forAll(newFaces, faceI)
240     {
241         newFaces[faceI] = origFaces[faceMap[faceI]];
242     }
244     this->storedFaces().transfer(newFaces);
248 template<class Face>
249 Foam::MeshedSurface<Face>::MeshedSurface(const surfMesh& mesh)
251     ParentType(List<Face>(), pointField())
253     // same face type as surfMesh
254     MeshedSurface<face> surf
255     (
256         xferCopy(mesh.points()),
257         xferCopy(mesh.faces()),
258         xferCopy(mesh.surfZones())
259     );
261     this->transcribe(surf);
265 template<class Face>
266 Foam::MeshedSurface<Face>::MeshedSurface
268     const polyBoundaryMesh& bMesh,
269     const bool useGlobalPoints
272     ParentType(List<Face>(), pointField())
274     const polyMesh& mesh = bMesh.mesh();
275     const polyPatchList& bPatches = bMesh;
277     // Get a single patch for all boundaries
278     primitivePatch allBoundary
279     (
280         SubList<face>
281         (
282             mesh.faces(),
283             mesh.nFaces() - mesh.nInternalFaces(),
284             mesh.nInternalFaces()
285         ),
286         mesh.points()
287     );
289     // use global/local points:
290     const pointField& bPoints =
291     (
292         useGlobalPoints ? mesh.points() : allBoundary.localPoints()
293     );
295     // global/local face addressing:
296     const List<Face>& bFaces =
297     (
298         useGlobalPoints ? allBoundary : allBoundary.localFaces()
299     );
302     // create zone list
303     surfZoneList newZones(bPatches.size());
305     label startFaceI = 0;
306     label nZone = 0;
307     forAll(bPatches, patchI)
308     {
309         const polyPatch& p = bPatches[patchI];
311         if (p.size())
312         {
313             newZones[nZone] = surfZone
314             (
315                 p.name(),
316                 p.size(),
317                 startFaceI,
318                 nZone
319             );
321             nZone++;
322             startFaceI += p.size();
323         }
324     }
326     newZones.setSize(nZone);
328     // same face type as the polyBoundaryMesh
329     MeshedSurface<face> surf
330     (
331         xferCopy(bPoints),
332         xferCopy(bFaces),
333         xferMove(newZones)
334     );
336     this->transcribe(surf);
340 template<class Face>
341 Foam::MeshedSurface<Face>::MeshedSurface
343     const fileName& name,
344     const word& ext
347     ParentType(List<Face>(), pointField())
349     read(name, ext);
353 template<class Face>
354 Foam::MeshedSurface<Face>::MeshedSurface(const fileName& name)
356     ParentType(List<Face>(), pointField())
358     read(name);
362 template<class Face>
363 Foam::MeshedSurface<Face>::MeshedSurface
365     const Time& t,
366     const word& surfName
369     ParentType(List<Face>(), pointField())
371     surfMesh mesh
372     (
373         IOobject
374         (
375             "dummyName",
376             t.timeName(),
377             t,
378             IOobject::MUST_READ,
379             IOobject::NO_WRITE,
380             false
381         ),
382         surfName
383     );
385     // same face type as surfMesh
386     MeshedSurface<face> surf
387     (
388         xferMove(mesh.storedPoints()),
389         xferMove(mesh.storedFaces()),
390         xferMove(mesh.storedZones())
391     );
393     this->transcribe(surf);
397 template<class Face>
398 Foam::MeshedSurface<Face>::MeshedSurface
400     const Xfer< UnsortedMeshedSurface<Face> >& surf
403     ParentType(List<Face>(), pointField())
405     transfer(surf());
409 template<class Face>
410 Foam::MeshedSurface<Face>::MeshedSurface
412     const Xfer< MeshedSurface<Face> >& surf
415     ParentType(List<Face>(), pointField())
417     transfer(surf());
422 // * * * * * * * * * * * * * * * * Destructor  * * * * * * * * * * * * * * * //
424 template<class Face>
425 Foam::MeshedSurface<Face>::~MeshedSurface()
429 // * * * * * * * * * * * * * Private Member Functions  * * * * * * * * * * * //
432 // * * * * * * * * * * * * Protected Member Functions  * * * * * * * * * * * //
434 template<class Face>
435 void Foam::MeshedSurface<Face>::remapFaces
437     const UList<label>& faceMap
440     // recalculate the zone start/size
441     if (&faceMap && faceMap.size())
442     {
443         surfZoneList& zones = storedZones();
445         if (zones.size() == 1)
446         {
447             // optimized for single zone case
448             zones[0].size() = faceMap.size();
449         }
450         else if (zones.size())
451         {
452             label newFaceI = 0;
453             label origEndI = 0;
454             forAll(zones, zoneI)
455             {
456                 surfZone& zone = zones[zoneI];
458                 // adjust zone start
459                 zone.start() = newFaceI;
460                 origEndI += zone.size();
462                 for (label faceI = newFaceI; faceI < faceMap.size(); ++faceI)
463                 {
464                     if (faceMap[faceI] < origEndI)
465                     {
466                         ++newFaceI;
467                     }
468                     else
469                     {
470                         break;
471                     }
472                 }
474                 // adjust zone size
475                 zone.size() = newFaceI - zone.start();
476             }
477         }
478     }
482 // * * * * * * * * * * * * * * * Member Functions  * * * * * * * * * * * * * //
484 template<class Face>
485 void Foam::MeshedSurface<Face>::clear()
487     ParentType::clearOut();
489     storedPoints().clear();
490     storedFaces().clear();
491     storedZones().clear();
495 template<class Face>
496 void Foam::MeshedSurface<Face>::movePoints(const pointField& newPoints)
498     // Remove all geometry dependent data
499     ParentType::clearTopology();
501     // Adapt for new point position
502     ParentType::movePoints(newPoints);
504     // Copy new points
505     storedPoints() = newPoints;
509 template<class Face>
510 void Foam::MeshedSurface<Face>::scalePoints(const scalar& scaleFactor)
512     // avoid bad scaling
513     if (scaleFactor > 0 && scaleFactor != 1.0)
514     {
515         // Remove all geometry dependent data
516         ParentType::clearTopology();
518         // Adapt for new point position
519         ParentType::movePoints(pointField());
521         storedPoints() *= scaleFactor;
522     }
526 template<class Face>
527 void Foam::MeshedSurface<Face>::reset
529     const Xfer< pointField >& pointLst,
530     const Xfer< List<Face> >& faceLst,
531     const Xfer< surfZoneList >& zoneLst
534     ParentType::clearOut();
536     // Take over new primitive data.
537     // Optimized to avoid overwriting data at all
538     if (&pointLst)
539     {
540         storedPoints().transfer(pointLst());
541     }
543     if (&faceLst)
544     {
545         storedFaces().transfer(faceLst());
546     }
548     if (&zoneLst)
549     {
550         storedZones().transfer(zoneLst());
551     }
555 template<class Face>
556 void Foam::MeshedSurface<Face>::reset
558     const Xfer< List<point> >& pointLst,
559     const Xfer< List<Face> >& faceLst,
560     const Xfer< surfZoneList >& zoneLst
563     ParentType::clearOut();
565     // Take over new primitive data.
566     // Optimized to avoid overwriting data at all
567     if (&pointLst)
568     {
569         storedPoints().transfer(pointLst());
570     }
572     if (&faceLst)
573     {
574         storedFaces().transfer(faceLst());
575     }
577     if (&zoneLst)
578     {
579         storedZones().transfer(zoneLst());
580     }
584 // Remove badly degenerate faces, double faces.
585 template<class Face>
586 void Foam::MeshedSurface<Face>::cleanup(const bool verbose)
588     // merge points (already done for STL, TRI)
589     stitchFaces(SMALL, verbose);
591     checkFaces(verbose);
592     this->checkTopology(verbose);
596 template<class Face>
597 bool Foam::MeshedSurface<Face>::stitchFaces
599     const scalar tol,
600     const bool verbose
603     pointField& pointLst = this->storedPoints();
605     // Merge points
606     labelList  pointMap(pointLst.size());
607     pointField newPoints(pointLst.size());
609     bool hasMerged = mergePoints(pointLst, tol, verbose, pointMap, newPoints);
611     if (!hasMerged)
612     {
613         return false;
614     }
616     if (verbose)
617     {
618         Info<< "MeshedSurface::stitchFaces : Renumbering all faces"
619             << endl;
620     }
622     // Set the coordinates to the merged ones
623     pointLst.transfer(newPoints);
625     List<Face>& faceLst = this->storedFaces();
627     List<label> faceMap(faceLst.size());
629     // Reset the point labels to the unique points array
630     label newFaceI = 0;
631     forAll(faceLst, faceI)
632     {
633         Face& f = faceLst[faceI];
634         forAll(f, fp)
635         {
636             f[fp] = pointMap[f[fp]];
637         }
639         // for extra safety: collapse face as well
640         if (f.collapse() >= 3)
641         {
642             if (newFaceI != faceI)
643             {
644                 faceLst[newFaceI] = f;
645             }
646             faceMap[newFaceI] = faceI;
647             newFaceI++;
648         }
649         else if (verbose)
650         {
651             Pout<< "MeshedSurface::stitchFaces : "
652                 << "Removing collapsed face " << faceI << endl
653                 << "    vertices   :" << f << endl;
654         }
655     }
656     pointMap.clear();
658     if (newFaceI != faceLst.size())
659     {
660         if (verbose)
661         {
662             Pout<< "MeshedSurface::stitchFaces : "
663                 << "Removed " << faceLst.size() - newFaceI
664                 << " faces" << endl;
665         }
666         faceLst.setSize(newFaceI);
667         remapFaces(faceMap);
668     }
669     faceMap.clear();
671     // Merging points might have changed geometric factors
672     ParentType::clearOut();
673     return true;
677 // Remove badly degenerate faces and double faces.
678 template<class Face>
679 bool Foam::MeshedSurface<Face>::checkFaces
681     const bool verbose
684     bool changed = false;
685     List<Face>& faceLst = this->storedFaces();
687     List<label> faceMap(faceLst.size());
689     label newFaceI = 0;
690     // Detect badly labelled faces and mark degenerate faces
691     const label maxPointI = this->points().size() - 1;
692     forAll(faceLst, faceI)
693     {
694         Face& f = faceLst[faceI];
696         // avoid degenerate faces
697         if (f.collapse() >= 3)
698         {
699             forAll(f, fp)
700             {
701                 if (f[fp] < 0 || f[fp] > maxPointI)
702                 {
703                     FatalErrorIn("MeshedSurface::checkFaces(bool)")
704                         << "face " << f
705                         << " uses point indices outside point range 0.."
706                     << maxPointI
707                         << exit(FatalError);
708                 }
709             }
711             faceMap[faceI] = faceI;
712             newFaceI++;
713         }
714         else
715         {
716             // mark as bad face
717             faceMap[faceI] = -1;
719             changed = true;
720             if (verbose)
721             {
722                 WarningIn
723                 (
724                     "MeshedSurface::checkFaces(bool verbose)"
725                 )   << "face[" << faceI << "] = " << f
726                     << " does not have three unique vertices" << endl;
727             }
728         }
729     }
731     // Detect doubled faces
732     // do not touch the faces
733     const labelListList& fFaces = this->faceFaces();
734     newFaceI = 0;
735     forAll(faceLst, faceI)
736     {
737         // skip already collapsed faces:
738         if (faceMap[faceI] < 0)
739         {
740             continue;
741         }
743         const Face& f = faceLst[faceI];
745         // duplicate face check
746         bool okay = true;
747         const labelList& neighbours = fFaces[faceI];
749         // Check if faceNeighbours use same points as this face.
750         // Note: discards normal information - sides of baffle are merged.
751         forAll(neighbours, neighI)
752         {
753             const label neiFaceI = neighbours[neighI];
755             if (neiFaceI <= faceI || faceMap[neiFaceI] < 0)
756             {
757                 // lower numbered faces already checked
758                 // skip neighbours that are themselves collapsed
759                 continue;
760             }
762             const Face& nei = faceLst[neiFaceI];
764             if (f == nei)
765             {
766                 okay = false;
768                 if (verbose)
769                 {
770                     WarningIn
771                     (
772                         "MeshedSurface::checkFaces(bool verbose)"
773                     )   << "faces share the same vertices:" << nl
774                         << "    face[" << faceI << "] : " << f << nl
775                         << "    face[" << neiFaceI << "] : " << nei << endl;
776                     // printFace(Warning, "    ", f, points());
777                     // printFace(Warning, "    ", nei, points());
778                 }
780                 break;
781             }
782         }
784         if (okay)
785         {
786             faceMap[faceI] = faceI;
787             newFaceI++;
788         }
789         else
790         {
791             faceMap[faceI] = -1;
792         }
793     }
795     // Phase 1: pack
796     // Done to keep numbering constant in phase 1
798     if (changed || newFaceI < faceLst.size())
799     {
800         changed = true;
802         if (verbose)
803         {
804             WarningIn
805             (
806                 "MeshedSurface::checkFaces(bool verbose)"
807             )   << "Removed " << faceLst.size() - newFaceI
808                 << " illegal faces." << endl;
809         }
811         // compress the face list
812         newFaceI = 0;
813         forAll(faceLst, faceI)
814         {
815             if (faceMap[faceI] >= 0)
816             {
817                 if (newFaceI != faceI)
818                 {
819                     faceLst[newFaceI] = faceLst[faceI];
820                 }
821                 faceMap[newFaceI] = faceI;
822                 newFaceI++;
823             }
824         }
826         faceLst.setSize(newFaceI);
827         remapFaces(faceMap);
828     }
829     faceMap.clear();
831     // Topology can change because of renumbering
832     ParentType::clearOut();
833     return changed;
837 template<class Face>
838 Foam::label Foam::MeshedSurface<Face>::triangulate()
840     return triangulate
841     (
842         const_cast<List<label>&>(List<label>::null())
843     );
847 template<class Face>
848 Foam::label Foam::MeshedSurface<Face>::triangulate
850     List<label>& faceMapOut
853     label nTri = 0;
854     label maxTri = 0;  // the maximum number of triangles for any single face
855     List<Face>& faceLst = this->storedFaces();
857     // determine how many triangles will be needed
858     forAll(faceLst, faceI)
859     {
860         const label n = faceLst[faceI].nTriangles();
861         if (maxTri < n)
862         {
863             maxTri = n;
864         }
865         nTri += n;
866     }
868     // nothing to do
869     if (nTri <= faceLst.size())
870     {
871         if (&faceMapOut)
872         {
873             faceMapOut.clear();
874         }
875         return 0;
876     }
878     List<Face>  newFaces(nTri);
879     List<label> faceMap;
881     // reuse storage from optional faceMap
882     if (&faceMapOut)
883     {
884         faceMap.transfer(faceMapOut);
885     }
886     faceMap.setSize(nTri);
888     // remember the number of *additional* faces
889     nTri -= faceLst.size();
891     if (this->points().empty())
892     {
893         // triangulate without points
894         // simple face triangulation around f[0]
895         label newFaceI = 0;
896         forAll(faceLst, faceI)
897         {
898             const Face& f = faceLst[faceI];
900             for (label fp = 1; fp < f.size() - 1; ++fp)
901             {
902                 label fp1 = f.fcIndex(fp);
904                 newFaces[newFaceI] = triFace(f[0], f[fp], f[fp1]);
905                 faceMap[newFaceI] = faceI;
906                 newFaceI++;
907             }
908         }
909     }
910     else
911     {
912         // triangulate with points
913         List<face> tmpTri(maxTri);
915         label newFaceI = 0;
916         forAll(faceLst, faceI)
917         {
918             // 'face' not '<Face>'
919             const face& f = faceLst[faceI];
921             label nTmp;
922             f.triangles(this->points(), nTmp, tmpTri);
923             for (label triI = 0; triI < nTmp; triI++)
924             {
925                 newFaces[newFaceI] = Face
926                 (
927                     static_cast<UList<label>&>(tmpTri[triI])
928                 );
929                 faceMap[newFaceI] = faceI;
930                 newFaceI++;
931             }
932         }
933     }
935     faceLst.transfer(newFaces);
936     remapFaces(faceMap);
938     // optionally return the faceMap
939     if (&faceMapOut)
940     {
941         faceMapOut.transfer(faceMap);
942     }
943     faceMap.clear();
945     // Topology can change because of renumbering
946     ParentType::clearOut();
947     return nTri;
953 template<class Face>
954 Foam::MeshedSurface<Face> Foam::MeshedSurface<Face>::subsetMesh
956     const labelHashSet& include,
957     labelList& pointMap,
958     labelList& faceMap
959 ) const
961     const pointField& locPoints = this->localPoints();
962     const List<Face>& locFaces  = this->localFaces();
965     // Fill pointMap, faceMap
966     PatchTools::subsetMap(*this, include, pointMap, faceMap);
968     // Create compact coordinate list and forward mapping array
969     pointField newPoints(pointMap.size());
970     labelList oldToNew(locPoints.size());
971     forAll(pointMap, pointI)
972     {
973         newPoints[pointI] = locPoints[pointMap[pointI]];
974         oldToNew[pointMap[pointI]] = pointI;
975     }
977     // create/copy a new zones list, each zone with zero size
978     surfZoneList newZones(this->surfZones());
979     forAll(newZones, zoneI)
980     {
981         newZones[zoneI].size() = 0;
982     }
984     // Renumber face node labels
985     List<Face> newFaces(faceMap.size());
986     forAll(faceMap, faceI)
987     {
988         const label origFaceI = faceMap[faceI];
989         newFaces[faceI] = Face(locFaces[origFaceI]);
991         // Renumber labels for face
992         Face& f = newFaces[faceI];
993         forAll(f, fp)
994         {
995             f[fp] = oldToNew[f[fp]];
996         }
997     }
998     oldToNew.clear();
1000     // recalculate the zones start/size
1001     label newFaceI = 0;
1002     label origEndI = 0;
1004     // adjust zone sizes
1005     forAll(newZones, zoneI)
1006     {
1007         surfZone& zone = newZones[zoneI];
1009         // adjust zone start
1010         zone.start() = newFaceI;
1011         origEndI += zone.size();
1013         for (label faceI = newFaceI; faceI < faceMap.size(); ++faceI)
1014         {
1015             if (faceMap[faceI] < origEndI)
1016             {
1017                 ++newFaceI;
1018             }
1019             else
1020             {
1021                 break;
1022             }
1023         }
1025         // adjust zone size
1026         zone.size() = newFaceI - zone.start();
1027     }
1030     // construct a sub-surface
1031     return MeshedSurface
1032     (
1033         xferMove(newPoints),
1034         xferMove(newFaces),
1035         xferMove(newZones)
1036     );
1040 template<class Face>
1041 Foam::MeshedSurface<Face>
1042 Foam::MeshedSurface<Face>::subsetMesh
1044     const labelHashSet& include
1045 ) const
1047     labelList pointMap, faceMap;
1048     return subsetMesh(include, pointMap, faceMap);
1053 template<class Face>
1054 void Foam::MeshedSurface<Face>::transfer
1056     MeshedSurface<Face>& surf
1059     reset
1060     (
1061         xferMove(surf.storedPoints()),
1062         xferMove(surf.storedFaces()),
1063         xferMove(surf.storedZones())
1064     );
1068 template<class Face>
1069 void Foam::MeshedSurface<Face>::transfer
1071     UnsortedMeshedSurface<Face>& surf
1074     clear();
1076     labelList faceMap;
1077     surfZoneList zoneLst = surf.sortedZones(faceMap);
1079     if (zoneLst.size() <= 1)
1080     {
1081         reset
1082         (
1083             xferMove(surf.storedPoints()),
1084             xferMove(surf.storedFaces()),
1085             Xfer<surfZoneList>()
1086         );
1087     }
1088     else
1089     {
1090         List<Face>& oldFaces = surf.storedFaces();
1091         List<Face> newFaces(faceMap.size());
1093         forAll(faceMap, faceI)
1094         {
1095             newFaces[faceI].transfer(oldFaces[faceMap[faceI]]);
1096         }
1098         reset
1099         (
1100             xferMove(surf.storedPoints()),
1101             xferMove(newFaces),
1102             xferMove(zoneLst)
1103         );
1104     }
1106     faceMap.clear();
1107     surf.clear();
1111 template<class Face>
1112 Foam::Xfer< Foam::MeshedSurface<Face> >
1113 Foam::MeshedSurface<Face>::xfer()
1115     return xferMove(*this);
1119 // Read from file, determine format from extension
1120 template<class Face>
1121 bool Foam::MeshedSurface<Face>::read(const fileName& name)
1123     word ext = name.ext();
1124     if (ext == "gz")
1125     {
1126         fileName unzipName = name.lessExt();
1127         return read(unzipName, unzipName.ext());
1128     }
1129     else
1130     {
1131         return read(name, ext);
1132     }
1136 // Read from file in given format
1137 template<class Face>
1138 bool Foam::MeshedSurface<Face>::read
1140     const fileName& name,
1141     const word& ext
1144     clear();
1146     // read via selector mechanism
1147     transfer(New(name, ext)());
1148     return true;
1152 template<class Face>
1153 void Foam::MeshedSurface<Face>::write
1155     const Time& t,
1156     const word& surfName
1157 ) const
1159     MeshedSurfaceProxy<Face>(*this).write(t, surfName);
1162 // * * * * * * * * * * * * * * * Member Operators  * * * * * * * * * * * * * //
1164 template<class Face>
1165 void Foam::MeshedSurface<Face>::operator=(const MeshedSurface& surf)
1167     clear();
1169     this->storedPoints() = surf.points();
1170     this->storedFaces()  = surf.faces();
1171     this->storedZones()  = surf.surfZones();
1175 template<class Face>
1176 Foam::MeshedSurface<Face>::operator
1177 Foam::MeshedSurfaceProxy<Face>() const
1179     return MeshedSurfaceProxy<Face>
1180     (
1181         this->points(),
1182         this->faces(),
1183         this->surfZones()
1184     );
1187 // * * * * * * * * * * * * * * * Friend Functions  * * * * * * * * * * * * * //
1189 // * * * * * * * * * * * * * * * IOstream Operators  * * * * * * * * * * * * //
1191 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
1193 #include "MeshedSurfaceZones.C"
1194 #include "MeshedSurfaceIO.C"
1195 #include "MeshedSurfaceNew.C"
1197 // ************************************************************************* //