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