MeshedSurface.C
Go to the documentation of this file.
1 /*---------------------------------------------------------------------------*\
2  ========= |
3  \\ / F ield | OpenFOAM: The Open Source CFD Toolbox
4  \\ / O peration |
5  \\ / A nd | Copyright (C) 2011-2014 OpenFOAM Foundation
6  \\/ M anipulation |
7 -------------------------------------------------------------------------------
8 License
9  This file is part of OpenFOAM.
10 
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.
15 
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.
20 
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/>.
23 
24 \*---------------------------------------------------------------------------*/
25 
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"
37 
38 // * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
39 
40 template<class Face>
42 {
43  return false;
44 }
45 
46 
47 template<class Face>
49 {
50  return wordHashSet(*fileExtensionConstructorTablePtr_);
51 }
52 
53 
54 template<class Face>
56 {
57  return wordHashSet(*writefileExtensionMemberFunctionTablePtr_);
58 }
59 
60 
61 // * * * * * * * * * * * * * Static Member Functions * * * * * * * * * * * * //
62 
63 template<class Face>
65 (
66  const word& ext,
67  const bool verbose
68 )
69 {
70  return fileFormats::surfaceFormatsCore::checkSupport
71  (
72  readTypes() | FriendType::readTypes(),
73  ext,
74  verbose,
75  "reading"
76  );
77 }
78 
79 
80 template<class Face>
82 (
83  const word& ext,
84  const bool verbose
85 )
86 {
87  return fileFormats::surfaceFormatsCore::checkSupport
88  (
89  writeTypes() | ProxyType::writeTypes(),
90  ext,
91  verbose,
92  "writing"
93  );
94 }
95 
96 
97 template<class Face>
99 (
100  const fileName& name,
101  const bool verbose
102 )
103 {
104  word ext = name.ext();
105  if (ext == "gz")
106  {
107  ext = name.lessExt().ext();
108  }
109  return canReadType(ext, verbose);
110 }
111 
112 
113 template<class Face>
115 (
116  const fileName& name,
117  const MeshedSurface<Face>& surf
118 )
119 {
120  if (debug)
121  {
122  Info<< "MeshedSurface::write"
123  "(const fileName&, const MeshedSurface&) : "
124  "writing to " << name
125  << endl;
126  }
127 
128  const word ext = name.ext();
129 
130  typename writefileExtensionMemberFunctionTable::iterator mfIter =
131  writefileExtensionMemberFunctionTablePtr_->find(ext);
132 
133  if (mfIter == writefileExtensionMemberFunctionTablePtr_->end())
134  {
135  // no direct writer, delegate to proxy if possible
136  wordHashSet supported = ProxyType::writeTypes();
137 
138  if (supported.found(ext))
139  {
140  MeshedSurfaceProxy<Face>(surf).write(name);
141  }
142  else
143  {
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  }
158 }
159 
160 
161 // * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
162 
163 template<class Face>
165 :
166  ParentType(List<Face>(), pointField())
167 {}
168 
169 
170 template<class Face>
172 (
173  const Xfer<pointField>& pointLst,
174  const Xfer<List<Face> >& faceLst,
175  const Xfer<surfZoneList>& zoneLst
176 )
177 :
179  zones_()
180 {
181  reset(pointLst, faceLst, zoneLst);
182 }
183 
184 
185 template<class Face>
187 (
188  const Xfer<pointField>& pointLst,
189  const Xfer<List<Face> >& faceLst,
190  const labelUList& zoneSizes,
191  const UList<word>& zoneNames
192 )
193 :
195 {
196  reset(pointLst, faceLst, Xfer<surfZoneList>());
197 
198  if (zoneSizes.size())
199  {
200  if (zoneNames.size())
201  {
202  addZones(zoneSizes, zoneNames);
203  }
204  else
205  {
206  addZones(zoneSizes);
207  }
208  }
209 }
210 
211 
212 template<class Face>
214 (
215  const MeshedSurface<Face>& surf
216 )
217 :
218  ParentType(surf.faces(), surf.points()),
219  zones_(surf.surfZones())
220 {}
221 
222 
223 template<class Face>
225 (
226  const UnsortedMeshedSurface<Face>& surf
227 )
228 :
229  ParentType(List<Face>(), surf.points())
230 {
232  this->storedZones() = surf.sortedZones(faceMap);
233 
234  const List<Face>& origFaces = surf.faces();
235  List<Face> newFaces(origFaces.size());
236 
237  forAll(newFaces, faceI)
238  {
239  newFaces[faceMap[faceI]] = origFaces[faceI];
240  }
241 
242  this->storedFaces().transfer(newFaces);
243 }
244 
245 
246 template<class Face>
248 :
249  ParentType(List<Face>(), pointField())
250 {
251  // same face type as surfMesh
253  (
254  xferCopy(mesh.points()),
255  xferCopy(mesh.faces()),
256  xferCopy(mesh.surfZones())
257  );
258 
259  this->transcribe(surf);
260 }
261 
262 
263 template<class Face>
265 (
266  const polyBoundaryMesh& bMesh,
267  const bool useGlobalPoints
268 )
269 :
271 {
272  const polyMesh& mesh = bMesh.mesh();
273  const polyPatchList& bPatches = bMesh;
274 
275  // Get a single patch for all boundaries
276  primitivePatch allBoundary
277  (
279  (
280  mesh.faces(),
281  mesh.nFaces() - mesh.nInternalFaces(),
282  mesh.nInternalFaces()
283  ),
284  mesh.points()
285  );
286 
287  // use global/local points:
288  const pointField& bPoints =
289  (
290  useGlobalPoints ? mesh.points() : allBoundary.localPoints()
291  );
292 
293  // global/local face addressing:
294  const List<Face>& bFaces =
295  (
296  useGlobalPoints ? allBoundary : allBoundary.localFaces()
297  );
298 
299 
300  // create zone list
301  surfZoneList newZones(bPatches.size());
302 
303  label startFaceI = 0;
304  label nZone = 0;
305  forAll(bPatches, patchI)
306  {
307  const polyPatch& p = bPatches[patchI];
308 
309  if (p.size())
310  {
311  newZones[nZone] = surfZone
312  (
313  p.name(),
314  p.size(),
315  startFaceI,
316  nZone
317  );
318 
319  nZone++;
320  startFaceI += p.size();
321  }
322  }
323 
324  newZones.setSize(nZone);
325 
326  // same face type as the polyBoundaryMesh
328  (
329  xferCopy(bPoints),
330  xferCopy(bFaces),
331  xferMove(newZones)
332  );
333 
334  this->transcribe(surf);
335 }
336 
337 
338 template<class Face>
340 (
341  const fileName& name,
342  const word& ext
343 )
344 :
346 {
347  read(name, ext);
348 }
349 
350 
351 template<class Face>
353 :
354  ParentType(List<Face>(), pointField())
355 {
356  read(name);
357 }
358 
359 
360 template<class Face>
362 (
363  const Time& t,
364  const word& surfName
365 )
366 :
368 {
369  surfMesh mesh
370  (
371  IOobject
372  (
373  "dummyName",
374  t.timeName(),
375  t,
378  false
379  ),
380  surfName
381  );
382 
383  // same face type as surfMesh
385  (
386  xferMove(mesh.storedPoints()),
387  xferMove(mesh.storedFaces()),
388  xferMove(mesh.storedZones())
389  );
390 
391  this->transcribe(surf);
392 }
393 
394 
395 template<class Face>
397 (
398  const Xfer<UnsortedMeshedSurface<Face> >& surf
399 )
400 :
402 {
403  transfer(surf());
404 }
405 
406 
407 template<class Face>
409 (
410  const Xfer<MeshedSurface<Face> >& surf
411 )
412 :
414 {
415  transfer(surf());
416 }
417 
418 
419 
420 // * * * * * * * * * * * * * * * * Destructor * * * * * * * * * * * * * * * //
421 
422 template<class Face>
424 {}
425 
426 
427 // * * * * * * * * * * * * Protected Member Functions * * * * * * * * * * * //
428 
429 template<class Face>
431 (
432  const labelUList& faceMap
433 )
434 {
435  // recalculate the zone start/size
436  if (notNull(faceMap) && faceMap.size())
437  {
438  surfZoneList& zones = storedZones();
439 
440  if (zones.size() == 1)
441  {
442  // optimized for single zone case
443  zones[0].size() = faceMap.size();
444  }
445  else if (zones.size())
446  {
447  label newFaceI = 0;
448  label origEndI = 0;
449  forAll(zones, zoneI)
450  {
451  surfZone& zone = zones[zoneI];
452 
453  // adjust zone start
454  zone.start() = newFaceI;
455  origEndI += zone.size();
456 
457  for (label faceI = newFaceI; faceI < faceMap.size(); ++faceI)
458  {
459  if (faceMap[faceI] < origEndI)
460  {
461  ++newFaceI;
462  }
463  else
464  {
465  break;
466  }
467  }
468 
469  // adjust zone size
470  zone.size() = newFaceI - zone.start();
471  }
472  }
473  }
474 }
475 
476 
477 // * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
478 
479 template<class Face>
481 {
483 
484  storedPoints().clear();
485  storedFaces().clear();
486  storedZones().clear();
487 }
488 
489 
490 template<class Face>
492 {
493  // Adapt for new point position
494  ParentType::movePoints(newPoints);
495 
496  // Copy new points
497  storedPoints() = newPoints;
498 }
499 
500 
501 template<class Face>
502 void Foam::MeshedSurface<Face>::scalePoints(const scalar scaleFactor)
503 {
504  // avoid bad scaling
505  if (scaleFactor > 0 && scaleFactor != 1.0)
506  {
507  pointField newPoints(scaleFactor*this->points());
508 
509  // Adapt for new point position
510  ParentType::movePoints(newPoints);
511 
512  storedPoints() = newPoints;
513  }
514 }
515 
516 
517 template<class Face>
519 (
520  const Xfer<pointField>& pointLst,
521  const Xfer<List<Face> >& faceLst,
522  const Xfer<surfZoneList>& zoneLst
523 )
524 {
526 
527  // Take over new primitive data.
528  // Optimized to avoid overwriting data at all
529  if (notNull(pointLst))
530  {
531  storedPoints().transfer(pointLst());
532  }
533 
534  if (notNull(faceLst))
535  {
536  storedFaces().transfer(faceLst());
537  }
538 
539  if (notNull(zoneLst))
540  {
541  storedZones().transfer(zoneLst());
542  }
543 }
544 
545 
546 template<class Face>
548 (
549  const Xfer<List<point> >& pointLst,
550  const Xfer<List<Face> >& faceLst,
551  const Xfer<surfZoneList>& zoneLst
552 )
553 {
555 
556  // Take over new primitive data.
557  // Optimized to avoid overwriting data at all
558  if (notNull(pointLst))
559  {
560  storedPoints().transfer(pointLst());
561  }
562 
563  if (notNull(faceLst))
564  {
565  storedFaces().transfer(faceLst());
566  }
567 
568  if (notNull(zoneLst))
569  {
570  storedZones().transfer(zoneLst());
571  }
572 }
573 
574 
575 // Remove badly degenerate faces, double faces.
576 template<class Face>
577 void Foam::MeshedSurface<Face>::cleanup(const bool verbose)
578 {
579  // merge points (already done for STL, TRI)
580  stitchFaces(SMALL, verbose);
581 
582  checkFaces(verbose);
583  this->checkTopology(verbose);
584 }
585 
586 
587 template<class Face>
589 (
590  const scalar tol,
591  const bool verbose
592 )
593 {
594  pointField& pointLst = this->storedPoints();
595 
596  // Merge points
597  labelList pointMap(pointLst.size());
598  pointField newPoints(pointLst.size());
599 
600  bool hasMerged = mergePoints(pointLst, tol, verbose, pointMap, newPoints);
601 
602  if (!hasMerged)
603  {
604  return false;
605  }
606 
607  if (verbose)
608  {
609  Info<< "MeshedSurface::stitchFaces : Renumbering all faces"
610  << endl;
611  }
612 
613  // Set the coordinates to the merged ones
614  pointLst.transfer(newPoints);
615 
616  List<Face>& faceLst = this->storedFaces();
617 
618  List<label> faceMap(faceLst.size());
619 
620  // Reset the point labels to the unique points array
621  label newFaceI = 0;
622  forAll(faceLst, faceI)
623  {
624  Face& f = faceLst[faceI];
625  forAll(f, fp)
626  {
627  f[fp] = pointMap[f[fp]];
628  }
629 
630  // for extra safety: collapse face as well
631  if (f.collapse() >= 3)
632  {
633  if (newFaceI != faceI)
634  {
635  faceLst[newFaceI] = f;
636  }
637  faceMap[newFaceI] = faceI;
638  newFaceI++;
639  }
640  else if (verbose)
641  {
642  Pout<< "MeshedSurface::stitchFaces : "
643  << "Removing collapsed face " << faceI << endl
644  << " vertices :" << f << endl;
645  }
646  }
647  pointMap.clear();
648 
649  if (newFaceI != faceLst.size())
650  {
651  if (verbose)
652  {
653  Pout<< "MeshedSurface::stitchFaces : "
654  << "Removed " << faceLst.size() - newFaceI
655  << " faces" << endl;
656  }
657  faceLst.setSize(newFaceI);
658  faceMap.setSize(newFaceI);
659  remapFaces(faceMap);
660  }
661  faceMap.clear();
662 
663  // Merging points might have changed geometric factors
665  return true;
666 }
667 
668 
669 // Remove badly degenerate faces and double faces.
670 template<class Face>
672 (
673  const bool verbose
674 )
675 {
676  bool changed = false;
677  List<Face>& faceLst = this->storedFaces();
678 
679  List<label> faceMap(faceLst.size());
680 
681  label newFaceI = 0;
682  // Detect badly labelled faces and mark degenerate faces
683  const label maxPointI = this->points().size() - 1;
684  forAll(faceLst, faceI)
685  {
686  Face& f = faceLst[faceI];
687 
688  // avoid degenerate faces
689  if (f.collapse() >= 3)
690  {
691  forAll(f, fp)
692  {
693  if (f[fp] < 0 || f[fp] > maxPointI)
694  {
695  FatalErrorIn("MeshedSurface::checkFaces(bool)")
696  << "face " << f
697  << " uses point indices outside point range 0.."
698  << maxPointI
699  << exit(FatalError);
700  }
701  }
702 
703  faceMap[faceI] = faceI;
704  newFaceI++;
705  }
706  else
707  {
708  // mark as bad face
709  faceMap[faceI] = -1;
710 
711  changed = true;
712  if (verbose)
713  {
714  WarningIn
715  (
716  "MeshedSurface::checkFaces(bool verbose)"
717  ) << "face[" << faceI << "] = " << f
718  << " does not have three unique vertices" << endl;
719  }
720  }
721  }
722 
723  // Detect doubled faces
724  // do not touch the faces
725  const labelListList& fFaces = this->faceFaces();
726  newFaceI = 0;
727  forAll(faceLst, faceI)
728  {
729  // skip already collapsed faces:
730  if (faceMap[faceI] < 0)
731  {
732  continue;
733  }
734 
735  const Face& f = faceLst[faceI];
736 
737  // duplicate face check
738  bool okay = true;
739  const labelList& neighbours = fFaces[faceI];
740 
741  // Check if faceNeighbours use same points as this face.
742  // Note: discards normal information - sides of baffle are merged.
743  forAll(neighbours, neighI)
744  {
745  const label neiFaceI = neighbours[neighI];
746 
747  if (neiFaceI <= faceI || faceMap[neiFaceI] < 0)
748  {
749  // lower numbered faces already checked
750  // skip neighbours that are themselves collapsed
751  continue;
752  }
753 
754  const Face& nei = faceLst[neiFaceI];
755 
756  if (f == nei)
757  {
758  okay = false;
759 
760  if (verbose)
761  {
762  WarningIn
763  (
764  "MeshedSurface::checkFaces(bool verbose)"
765  ) << "faces share the same vertices:" << nl
766  << " face[" << faceI << "] : " << f << nl
767  << " face[" << neiFaceI << "] : " << nei << endl;
768  // printFace(Warning, " ", f, points());
769  // printFace(Warning, " ", nei, points());
770  }
771 
772  break;
773  }
774  }
775 
776  if (okay)
777  {
778  faceMap[faceI] = faceI;
779  newFaceI++;
780  }
781  else
782  {
783  faceMap[faceI] = -1;
784  }
785  }
786 
787  // Phase 1: pack
788  // Done to keep numbering constant in phase 1
789 
790  if (changed || newFaceI < faceLst.size())
791  {
792  changed = true;
793 
794  if (verbose)
795  {
796  WarningIn
797  (
798  "MeshedSurface::checkFaces(bool verbose)"
799  ) << "Removed " << faceLst.size() - newFaceI
800  << " illegal faces." << endl;
801  }
802 
803  // compress the face list
804  newFaceI = 0;
805  forAll(faceLst, faceI)
806  {
807  if (faceMap[faceI] >= 0)
808  {
809  if (newFaceI != faceI)
810  {
811  faceLst[newFaceI] = faceLst[faceI];
812  }
813  faceMap[newFaceI] = faceI;
814  newFaceI++;
815  }
816  }
817 
818  faceLst.setSize(newFaceI);
819  remapFaces(faceMap);
820  }
821  faceMap.clear();
822 
823  // Topology can change because of renumbering
825  return changed;
826 }
827 
828 
829 template<class Face>
831 {
832  return triangulate
833  (
834  const_cast<List<label>&>(List<label>::null())
835  );
836 }
837 
838 
839 template<class Face>
841 (
842  List<label>& faceMapOut
843 )
844 {
845  label nTri = 0;
846  label maxTri = 0; // the maximum number of triangles for any single face
847  List<Face>& faceLst = this->storedFaces();
848 
849  // determine how many triangles will be needed
850  forAll(faceLst, faceI)
851  {
852  const label n = faceLst[faceI].nTriangles();
853  if (maxTri < n)
854  {
855  maxTri = n;
856  }
857  nTri += n;
858  }
859 
860  // nothing to do
861  if (nTri <= faceLst.size())
862  {
863  if (notNull(faceMapOut))
864  {
865  faceMapOut.clear();
866  }
867  return 0;
868  }
869 
870  List<Face> newFaces(nTri);
872 
873  // reuse storage from optional faceMap
874  if (notNull(faceMapOut))
875  {
876  faceMap.transfer(faceMapOut);
877  }
878  faceMap.setSize(nTri);
879 
880  // remember the number of *additional* faces
881  nTri -= faceLst.size();
882 
883  if (this->points().empty())
884  {
885  // triangulate without points
886  // simple face triangulation around f[0]
887  label newFaceI = 0;
888  forAll(faceLst, faceI)
889  {
890  const Face& f = faceLst[faceI];
891 
892  for (label fp = 1; fp < f.size() - 1; ++fp)
893  {
894  label fp1 = f.fcIndex(fp);
895 
896  newFaces[newFaceI] = triFace(f[0], f[fp], f[fp1]);
897  faceMap[newFaceI] = faceI;
898  newFaceI++;
899  }
900  }
901  }
902  else
903  {
904  // triangulate with points
905  List<face> tmpTri(maxTri);
906 
907  label newFaceI = 0;
908  forAll(faceLst, faceI)
909  {
910  // 'face' not '<Face>'
911  const face& f = faceLst[faceI];
912 
913  label nTmp = 0;
914  f.triangles(this->points(), nTmp, tmpTri);
915  for (label triI = 0; triI < nTmp; triI++)
916  {
917  newFaces[newFaceI] = Face
918  (
919  static_cast<labelUList&>(tmpTri[triI])
920  );
921  faceMap[newFaceI] = faceI;
922  newFaceI++;
923  }
924  }
925  }
926 
927  faceLst.transfer(newFaces);
928  remapFaces(faceMap);
929 
930  // optionally return the faceMap
931  if (notNull(faceMapOut))
932  {
933  faceMapOut.transfer(faceMap);
934  }
935  faceMap.clear();
936 
937  // Topology can change because of renumbering
939  return nTri;
940 }
941 
942 
943 
944 
945 template<class Face>
947 (
948  const labelHashSet& include,
949  labelList& pointMap,
950  labelList& faceMap
951 ) const
952 {
953  const pointField& locPoints = this->localPoints();
954  const List<Face>& locFaces = this->localFaces();
955 
956 
957  // Fill pointMap, faceMap
958  PatchTools::subsetMap(*this, include, pointMap, faceMap);
959 
960  // Create compact coordinate list and forward mapping array
961  pointField newPoints(pointMap.size());
962  labelList oldToNew(locPoints.size());
963  forAll(pointMap, pointI)
964  {
965  newPoints[pointI] = locPoints[pointMap[pointI]];
966  oldToNew[pointMap[pointI]] = pointI;
967  }
968 
969  // create/copy a new zones list, each zone with zero size
970  surfZoneList newZones(this->surfZones());
971  forAll(newZones, zoneI)
972  {
973  newZones[zoneI].size() = 0;
974  }
975 
976  // Renumber face node labels
977  List<Face> newFaces(faceMap.size());
978  forAll(faceMap, faceI)
979  {
980  const label origFaceI = faceMap[faceI];
981  newFaces[faceI] = Face(locFaces[origFaceI]);
982 
983  // Renumber labels for face
984  Face& f = newFaces[faceI];
985  forAll(f, fp)
986  {
987  f[fp] = oldToNew[f[fp]];
988  }
989  }
990  oldToNew.clear();
991 
992  // recalculate the zones start/size
993  label newFaceI = 0;
994  label origEndI = 0;
995 
996  // adjust zone sizes
997  forAll(newZones, zoneI)
998  {
999  surfZone& zone = newZones[zoneI];
1000 
1001  // adjust zone start
1002  zone.start() = newFaceI;
1003  origEndI += zone.size();
1004 
1005  for (label faceI = newFaceI; faceI < faceMap.size(); ++faceI)
1006  {
1007  if (faceMap[faceI] < origEndI)
1008  {
1009  ++newFaceI;
1010  }
1011  else
1012  {
1013  break;
1014  }
1015  }
1016 
1017  // adjust zone size
1018  zone.size() = newFaceI - zone.start();
1019  }
1020 
1021 
1022  // construct a sub-surface
1023  return MeshedSurface
1024  (
1025  xferMove(newPoints),
1026  xferMove(newFaces),
1027  xferMove(newZones)
1028  );
1029 }
1030 
1031 
1032 template<class Face>
1035  const labelHashSet& include
1036 ) const
1037 {
1038  labelList pointMap, faceMap;
1039  return subsetMesh(include, pointMap, faceMap);
1040 }
1041 
1042 
1043 
1044 template<class Face>
1047  MeshedSurface<Face>& surf
1048 )
1049 {
1050  reset
1051  (
1052  xferMove(surf.storedPoints()),
1053  xferMove(surf.storedFaces()),
1054  xferMove(surf.storedZones())
1055  );
1056 }
1057 
1058 
1059 template<class Face>
1063 )
1064 {
1065  clear();
1066 
1068  surfZoneList zoneLst = surf.sortedZones(faceMap);
1069 
1070  if (zoneLst.size() <= 1)
1071  {
1072  reset
1073  (
1074  xferMove(surf.storedPoints()),
1075  xferMove(surf.storedFaces()),
1077  );
1078  }
1079  else
1080  {
1081  List<Face>& oldFaces = surf.storedFaces();
1082  List<Face> newFaces(faceMap.size());
1083 
1084  forAll(faceMap, faceI)
1085  {
1086  newFaces[faceMap[faceI]].transfer(oldFaces[faceI]);
1087  }
1088 
1089  reset
1090  (
1091  xferMove(surf.storedPoints()),
1092  xferMove(newFaces),
1093  xferMove(zoneLst)
1094  );
1095  }
1096 
1097  faceMap.clear();
1098  surf.clear();
1099 }
1100 
1101 
1102 template<class Face>
1104 {
1105  return xferMove(*this);
1106 }
1107 
1108 
1109 // Read from file, determine format from extension
1110 template<class Face>
1112 {
1113  word ext = name.ext();
1114  if (ext == "gz")
1115  {
1116  fileName unzipName = name.lessExt();
1117  return read(unzipName, unzipName.ext());
1118  }
1119  else
1120  {
1121  return read(name, ext);
1122  }
1123 }
1124 
1125 
1126 // Read from file in given format
1127 template<class Face>
1130  const fileName& name,
1131  const word& ext
1132 )
1133 {
1134  clear();
1135 
1136  // read via selector mechanism
1137  transfer(New(name, ext)());
1138  return true;
1139 }
1140 
1141 
1142 template<class Face>
1145  const Time& t,
1146  const word& surfName
1147 ) const
1148 {
1149  MeshedSurfaceProxy<Face>(*this).write(t, surfName);
1150 }
1151 
1152 
1153 // * * * * * * * * * * * * * * * Member Operators * * * * * * * * * * * * * //
1154 
1155 template<class Face>
1157 {
1158  clear();
1159 
1160  this->storedPoints() = surf.points();
1161  this->storedFaces() = surf.faces();
1162  this->storedZones() = surf.surfZones();
1163 }
1164 
1165 
1166 template<class Face>
1168 {
1170  (
1171  this->points(),
1172  this->faces(),
1173  this->surfZones()
1174  );
1175 }
1176 
1177 
1178 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
1179 
1180 #include "MeshedSurfaceZones.C"
1181 #include "MeshedSurfaceIO.C"
1182 #include "MeshedSurfaceNew.C"
1183 
1184 // ************************************************************************* //
void transcribe(MeshedSurface< face > &)
Transfer points/zones and transcribe face -> triFace.
A surface mesh consisting of general polygon faces.
Definition: surfMesh.H:55
label start() const
Return start label of this zone in the face list.
Definition: surfZone.H:132
word ext() const
Return file name extension (part after last .)
Definition: fileName.C:323
HashSet wordHashSet
A HashSet with word keys.
Definition: HashSet.H:207
virtual void cleanup(const bool verbose)
Remove invalid faces.
const labelListList & faceFaces() const
Return face-face addressing.
pointField & storedPoints()
Non-const access to global points.
Definition: surfMesh.H:111
label size() const
Return the number of elements in the PtrList.
Definition: PtrListI.H:32
label nFaces() const
label size() const
Return size of this zone in the face list.
Definition: surfZone.H:144
const List< surfZone > & surfZones() const
Const access to the surface zones.
Pair< int > faceMap(const label facePi, const face &faceP, const label faceNi, const face &faceN)
Xfer< T > xferCopy(const T &)
const word & name() const
Return name.
A templated 1D list of pointers to objects of type <T>, where the size of the array is known and used...
Definition: List.H:61
void transfer(List< T > &)
Transfer the contents of the argument List into this list.
Definition: List.C:390
word name(const complex &)
Return a string representation of a complex.
Definition: complex.C:47
labelList f(nPoints)
virtual void remapFaces(const labelUList &faceMap)
Set new zones from faceMap.
Xfer< MeshedSurface< Face > > xfer()
Transfer contents to the Xfer container.
static bool canReadType(const word &ext, const bool verbose=false)
Can we read this file format?
Definition: MeshedSurface.C:65
Merge points. See below.
bool empty() const
Return true if the UList is empty (ie, size() is zero).
Definition: UListI.H:313
static wordHashSet readTypes()
Definition: MeshedSurface.C:48
static void write(const fileName &, const MeshedSurfaceProxy< Face > &)
Write to file.
surfZoneList & storedZones()
Non-const access to the zones.
Definition: surfMesh.H:123
A proxy for writing MeshedSurface, UnsortedMeshedSurface and surfMesh to various file formats...
Definition: MeshedSurface.H:73
A simple container for copying or transferring objects of type <T>.
Definition: Xfer.H:85
A class for handling words, derived from string.
Definition: word.H:59
intWM_LABEL_SIZE_t label
A label is an int32_t or int64_t as specified by the pre-processor macro WM_LABEL_SIZE.
Definition: label.H:59
static word timeName(const scalar, const int precision=precision_)
Return time name of given scalar time.
Definition: Time.C:741
void size(const label)
Override size to be inconsistent with allocated storage.
Definition: ListI.H:76
errorManipArg< error, int > exit(error &err, const int errNo=1)
Definition: errorManip.H:124
label fcIndex(const label i) const
Return the forward circular index, i.e. the next index.
Definition: UListI.H:58
Various functions to operate on Lists.
face triFace(3)
bool notNull(const T &t)
Return true if t is not a reference to the nullObject of type T.
Definition: nullObjectI.H:46
messageStream Info
dynamicFvMesh & mesh
MeshedSurface()
Construct null.
Xfer< T > xferMove(T &)
bool checkTopology(const bool report=false, labelHashSet *setPtr=NULL) const
Check surface formed by patch for manifoldness (see above).
vectorField pointField
pointField is a vectorField.
Definition: pointFieldFwd.H:42
static wordHashSet writeTypes()
Definition: MeshedSurface.C:55
pointField & storedPoints()
Non-const access to global points.
runTime write()
static void write(const fileName &, const MeshedSurface< Face > &)
Write to file.
A patch is a list of labels that address the faces in the global face list.
Definition: polyPatch.H:66
virtual void clear()
Clear all storage.
virtual void clear()
Clear all storage.
static autoPtr< MeshedSurface > New(const fileName &, const word &ext)
Select constructed from filename (explicit extension)
label n
A 1D array of objects of type <T>, where the size of the vector is known and used for subscript bound...
Definition: HashTable.H:59
A face is a list of labels corresponding to mesh vertices.
Definition: face.H:75
Class to control time during OpenFOAM simulations that is also the top-level objectRegistry.
Definition: Time.H:68
const Field< point > & localPoints() const
Return pointField of points in patch.
void clear()
Clear the list, i.e. set size to zero.
Definition: List.C:379
virtual const surfZoneList & surfZones() const
Return surface zones.
Definition: surfMesh.H:223
static const char nl
Definition: Ostream.H:260
void setSize(const label)
Reset size of List.
Definition: List.C:318
Ostream & endl(Ostream &os)
Add newline and flush stream.
Definition: Ostream.H:251
const List< Face > & faces() const
Return const access to the faces.
IOobject defines the attributes of an object for which implicit objectRegistry management is supporte...
Definition: IOobject.H:91
#define WarningIn(functionName)
Report a warning using Foam::Warning.
Base class for zones.
Definition: zone.H:57
virtual const pointField & points() const
Return raw points.
Definition: polyMesh.C:1035
Foam::polyBoundaryMesh.
volScalarField & p
Definition: createFields.H:51
PrimitivePatch< face, List, const pointField > bMesh
Holder of faceList and points. (v.s. e.g. primitivePatch which references points) ...
Definition: bMesh.H:45
virtual void reset(const Xfer< pointField > &points, const Xfer< List< Face > > &faces, const Xfer< surfZoneList > &zones)
Reset primitive data (points, faces and zones)
#define forAll(list, i)
Definition: UList.H:421
surfZoneList & storedZones()
Non-const access to the zones.
virtual ~MeshedSurface()
Destructor.
label size() const
Return the number of elements in the UList.
Definition: UListI.H:299
Macros for easy insertion into run-time selection tables.
A surface zone on a MeshedSurface.
Definition: surfZone.H:62
#define FatalErrorIn(functionName)
Report an error message using Foam::FatalError.
Definition: error.H:314
label nInternalFaces() const
label mergePoints(const UList< Type > &points, const scalar mergeTol, const bool verbose, labelList &pointMap, const Type &origin=Type::zero)
Sorts and merges points. All points closer than/equal mergeTol get merged.
virtual void addZones(const UList< surfZone > &, const bool cullEmpty=false)
Add surface zones.
void operator=(const MeshedSurface< Face > &)
A surface geometry mesh, in which the surface zone information is conveyed by the &#39;zoneId&#39; associated...
Definition: MeshedSurface.H:74
Mesh consisting of general polyhedral cells.
Definition: polyMesh.H:74
virtual const pointField & points() const
Return points.
Definition: surfMesh.C:339
error FatalError
static bool isTri()
Face storage only handles triangulated faces.
Definition: MeshedSurface.C:41
const polyMesh & mesh() const
Return the mesh reference.
A class for handling file names.
Definition: fileName.H:69
A 1D vector of objects of type <T>, where the size of the vector is known and can be used for subscri...
Definition: HashTable.H:60
A HashTable with keys but without contents.
Definition: HashSet.H:59
A surface geometry mesh with zone information, not to be confused with the similarly named surfaceMes...
Definition: MeshedSurface.H:72
fileName lessExt() const
Return file name without extension (part before last .)
Definition: fileName.C:307
static void subsetMap(const PrimitivePatch< Face, FaceList, PointField, PointType > &, const BoolListType &includeFaces, labelList &pointMap, labelList &faceMap)
Determine the mapping for a sub-patch.
const List< Face > & localFaces() const
Return patch faces addressing into local point list.
virtual void movePoints(const pointField &)
Move points.
A List obtained as a section of another List.
Definition: SubList.H:53
List< Face > & storedFaces()
Non-const access to the faces.
void transfer(MeshedSurface< Face > &)
Transfer the contents of the argument and annul the argument.
static bool canWriteType(const word &ext, const bool verbose=false)
Can we write this file format?
Definition: MeshedSurface.C:82
virtual const faceList & faces() const
Return raw faces.
Definition: polyMesh.C:1060
virtual label triangulate()
Triangulate in-place, returning the number of triangles added.
MeshedSurface subsetMesh(const labelHashSet &include, labelList &pointMap, labelList &faceMap) const
Return new surface.
virtual void scalePoints(const scalar)
Scale points. A non-positive factor is ignored.
virtual void movePoints(const Field< point > &)
Correct patch after moving points.
virtual const faceList & faces() const
Return faces.
Definition: surfMesh.C:345
label triangles(const pointField &points, label &triI, faceList &triFaces) const
Split into triangles using existing points.
Definition: face.C:835
bool found(const Key &) const
Return true if hashedEntry is found in table.
Definition: HashTable.C:109
surfZoneList sortedZones(labelList &faceMap) const
Sort faces according to zoneIds.
const Field< point > & points() const
Return reference to global points.
virtual bool checkFaces(const bool verbose=false)
virtual bool stitchFaces(const scalar tol=SMALL, const bool verbose=false)
prefixOSstream Pout(cout,"Pout")
Definition: IOstreams.H:53
bool read(const fileName &, const word &ext)
Read from file. Chooses reader based on explicit extension.
static bool canRead(const fileName &, const bool verbose=false)
Can we read this file format?
Definition: MeshedSurface.C:99
faceList & storedFaces()
Non-const access to the faces.
Definition: surfMesh.H:117