surfaceFeatures.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) 2018-2026 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 Description
25  Identifies features in a surface geometry and writes them to file,
26  based on control parameters specified by the user.
27 
28 \*---------------------------------------------------------------------------*/
29 
30 #include "argList.H"
31 #include "Time.H"
33 #include "featureEdgeMesh.H"
35 #include "surfaceFeatures.H"
36 #include "vtkWritePolyData.H"
37 #include "systemDict.H"
38 
39 using namespace Foam;
40 
41 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
42 
43 namespace Foam
44 {
45  autoPtr<surfaceFeatures> extractFromFile
46  (
47  const fileName& featureEdgeFile,
48  const triSurface& surf,
49  const Switch& geometricTestOnly
50  )
51  {
52  edgeMesh eMesh(featureEdgeFile);
53 
54  // Sometimes duplicate edges are present. Remove them.
55  eMesh.mergeEdges();
56 
57  Info<< nl << "Reading existing feature edges from file "
58  << featureEdgeFile << nl
59  << "Selecting edges purely based on geometric tests: "
60  << geometricTestOnly.asText() << endl;
61 
63  (
64  new surfaceFeatures
65  (
66  surf,
67  eMesh.points(),
68  eMesh.edges(),
69  1e-6,
70  geometricTestOnly
71  )
72  );
73  }
74 
75 
76  autoPtr<surfaceFeatures> extractFromSurface
77  (
78  const triSurface& surf,
79  const Switch& geometricTestOnly,
80  const scalar includedAngle
81  )
82  {
83  Info<< nl
84  << "Constructing feature set from included angle "
85  << includedAngle << nl
86  << "Selecting edges purely based on geometric tests: "
87  << geometricTestOnly.asText() << endl;
88 
90  (
91  new surfaceFeatures
92  (
93  surf,
94  includedAngle,
95  0,
96  0,
97  geometricTestOnly
98  )
99  );
100  }
101 
102 
103  autoPtr<surfaceFeatures> surfaceFeatureSet
104  (
105  const fileName& surfaceFileName,
106  const triSurface& surf,
107  const dictionary& dict,
108  const scalar includedAngle
109  )
110  {
111  const Switch geometricTestOnly = dict.lookupOrDefault<Switch>
112  (
113  "geometricTestOnly",
114  "no"
115  );
116 
117  if (dict.found("files"))
118  {
119  HashTable<fileName, fileName> fileNames(dict.lookup("files"));
120 
121  if (fileNames.found(surfaceFileName))
122  {
123  return extractFromFile
124  (
125  fileNames[surfaceFileName],
126  surf,
127  geometricTestOnly
128  );
129  }
130  else
131  {
132  return extractFromSurface
133  (
134  surf,
135  geometricTestOnly,
136  includedAngle
137  );
138  }
139  }
140  else
141  {
142  return extractFromSurface
143  (
144  surf,
145  geometricTestOnly,
146  includedAngle
147  );
148  }
149  }
150 
151 
152  void extractFeatures
153  (
154  const fileName& surfaceFileName,
155  const Time& runTime,
156  const dictionary& dict
157  )
158  {
159  const fileName sFeatFileName = surfaceFileName.lessExt().name();
160 
161  Info<< "Surface : " << surfaceFileName << nl << endl;
162 
163  const Switch writeVTK =
164  dict.lookupOrDefault<Switch>("writeVTK", "off");
165  const Switch writeObj =
166  dict.lookupOrDefault<Switch>("writeObj", "off");
167  const Switch verboseObj =
168  dict.lookupOrDefault<Switch>("verboseObj", "off");
169 
170  const Switch curvature =
171  dict.lookupOrDefault<Switch>("curvature", "off");
172  const Switch featureProximity =
173  dict.lookupOrDefault<Switch>("featureProximity", "off");
174 
175 
176  Info<< nl << "Feature line extraction is only valid on closed manifold "
177  << "surfaces." << endl;
178 
179  // Read
180  // ~~~~
181 
182  triSurface surf
183  (
184  runTime.path()
185  /runTime.constant()
187  /surfaceFileName
188  );
189 
190  Info<< "Statistics:" << endl;
191  surf.writeStats(Info);
192  Info<< endl;
193 
194  const faceList faces(surf.faces());
195 
196  // Either construct features from surface & featureAngle or read set.
197  // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
198 
199  const scalar includedAngle =
200  dict.lookup<scalar>("includedAngle", units::degrees);
201 
203  (
204  surfaceFeatureSet
205  (
206  surfaceFileName,
207  surf,
208  dict,
209  includedAngle
210  )
211  );
212 
213  // Trim set
214  // ~~~~~~~~
215 
216  if (dict.isDict("trimFeatures"))
217  {
218  dictionary trimDict = dict.subDict("trimFeatures");
219 
220  scalar minLen =
221  trimDict.lookupOrAddDefault<scalar>("minLen", -great);
222 
223  label minElem = trimDict.lookupOrAddDefault<label>("minElem", 0);
224 
225  // Trim away small groups of features
226  if (minElem > 0 || minLen > 0)
227  {
228  Info<< "Removing features of length < "
229  << minLen << endl;
230  Info<< "Removing features with number of edges < "
231  << minElem << endl;
232 
233  set().trimFeatures(minLen, minElem, includedAngle);
234  }
235  }
236 
237 
238  // Subset
239  // ~~~~~~
240 
241  // Convert to marked edges, points
242  List<surfaceFeatures::edgeStatus> edgeStat(set().toStatus());
243 
244  if (dict.isDict("subsetFeatures"))
245  {
246  const dictionary& subsetDict = dict.subDict
247  (
248  "subsetFeatures"
249  );
250 
251  if (subsetDict.found("insideBox"))
252  {
253  treeBoundBox bb(subsetDict.lookup("insideBox")());
254 
255  Info<< indent << "Selecting edges inside bb " << bb;
256  if (writeObj)
257  {
258  Info << " see insideBox.obj";
259  bb.writeOBJ("insideBox.obj");
260  }
261  Info<< endl;
262 
263  selectBox(surf, bb, true, edgeStat);
264  }
265  else if (subsetDict.found("outsideBox"))
266  {
267  treeBoundBox bb(subsetDict.lookup("outsideBox")());
268 
269  Info<< "Removing all edges inside bb " << bb;
270  if (writeObj)
271  {
272  Info<< " see outsideBox.obj" << endl;
273  bb.writeOBJ("outsideBox.obj");
274  }
275  Info<< endl;
276 
277  selectBox(surf, bb, false, edgeStat);
278  }
279 
280  const Switch nonManifoldEdges =
281  subsetDict.lookupOrDefault<Switch>("nonManifoldEdges", "yes");
282 
283  if (!nonManifoldEdges)
284  {
285  Info<< "Removing all non-manifold edges"
286  << " (edges with > 2 connected faces) unless they"
287  << " cross multiple regions" << endl;
288 
289  selectManifoldEdges(surf, 1e-5, includedAngle, edgeStat);
290  }
291 
292  const Switch openEdges =
293  subsetDict.lookupOrDefault<Switch>("openEdges", "yes");
294 
295  if (!openEdges)
296  {
297  Info<< "Removing all open edges"
298  << " (edges with 1 connected face)" << endl;
299 
300  forAll(edgeStat, edgei)
301  {
302  if (surf.edgeFaces()[edgei].size() == 1)
303  {
304  edgeStat[edgei] = surfaceFeatures::NONE;
305  }
306  }
307  }
308 
309  if (subsetDict.found("plane"))
310  {
311  const plane cutPlane(subsetDict.subDict("plane"));
312 
313  selectCutEdges(surf, cutPlane, edgeStat);
314 
315  Info<< "Only edges that intersect the plane with normal "
316  << cutPlane.normal()
317  << " and base point " << cutPlane.refPoint()
318  << " will be included as feature edges."<< endl;
319  }
320  }
321 
322 
323  surfaceFeatures newSet(surf);
324  newSet.setFromStatus(edgeStat, includedAngle);
325 
326  Info<< nl
327  << "Initial feature set:" << nl
328  << " feature points : " << newSet.featurePoints().size() << nl
329  << " feature edges : " << newSet.featureEdges().size() << nl
330  << " of which" << nl
331  << " region edges : " << newSet.nRegionEdges() << nl
332  << " external edges : " << newSet.nExternalEdges() << nl
333  << " internal edges : " << newSet.nInternalEdges() << nl
334  << endl;
335 
336  boolList surfBaffleRegions(surf.patches().size(), false);
337 
338  wordList surfBaffleNames;
339  dict.readIfPresent("baffles", surfBaffleNames);
340 
341  forAll(surf.patches(), pI)
342  {
343  const word& name = surf.patches()[pI].name();
344 
345  if (findIndex(surfBaffleNames, name) != -1)
346  {
347  Info<< "Adding baffle region " << name << endl;
348  surfBaffleRegions[pI] = true;
349  }
350  }
351 
352  // Extracting and writing a extendedFeatureEdgeMesh
354  (
355  newSet,
356  runTime,
357  sFeatFileName + ".extendedFeatureEdgeMesh",
358  surfBaffleRegions
359  );
360 
361 
362  if (dict.isDict("addFeatures"))
363  {
364  const word addFeName = dict.subDict("addFeatures")["name"];
365  Info<< "Adding (without merging) features from " << addFeName
366  << nl << endl;
367 
368  extendedFeatureEdgeMesh addFeMesh
369  (
370  IOobject
371  (
372  addFeName,
373  runTime.time().constant(),
374  "extendedFeatureEdgeMesh",
375  runTime.time(),
378  )
379  );
380  Info<< "Read " << addFeMesh.name() << nl;
381  addFeMesh.writeStats(Info);
382 
383  feMesh.add(addFeMesh);
384  }
385 
386 
387  Info<< nl
388  << "Final feature set:" << nl;
389  feMesh.writeStats(Info);
390 
391  Info<< nl << "Writing extendedFeatureEdgeMesh to "
392  << feMesh.relativeObjectPath() << endl;
393 
394  mkDir(feMesh.path());
395 
396  if (writeObj)
397  {
398  feMesh.writeObj
399  (
400  feMesh.path()/surfaceFileName.lessExt().name(),
401  verboseObj
402  );
403  }
404 
405  feMesh.write();
406 
407  // Write a featureEdgeMesh for backwards compatibility
408  featureEdgeMesh bfeMesh
409  (
410  IOobject
411  (
412  surfaceFileName.lessExt().name() + ".eMesh",
413  runTime.constant(),
415  runTime,
418  false
419  ),
420  feMesh.points(),
421  feMesh.edges()
422  );
423 
424  Info<< nl << "Writing featureEdgeMesh to "
425  << bfeMesh.relativeObjectPath() << endl;
426 
427  bfeMesh.regIOobject::write();
428 
429  // Data to write out in VTK format
430  wordList writeVTKFieldNames;
431  boolList writeVTKFieldIsPointValues;
432  #define DeclareWriteVTKFieldTypeValues(Type, nullArg) \
433  PtrList<const Field<Type>> writeVTKField##Type##Values;
434  FOR_ALL_FIELD_TYPES(DeclareWriteVTKFieldTypeValues);
435  #undef DeclareWriteVTKFieldTypeValues
436 
437  // Find distance between close features
438  if (dict.isDict("closeness"))
439  {
440  Info<< nl << "Extracting internal and external closeness of "
441  << "surface." << endl;
442 
443  const dictionary& closenessDict = dict.subDict("closeness");
444 
445  const Switch faceCloseness =
446  closenessDict.lookupOrDefault<Switch>("faceCloseness", "off");
447  const Switch pointCloseness =
448  closenessDict.lookupOrDefault<Switch>("pointCloseness", "off");
449 
450  const scalar internalAngleTolerance
451  (
452  closenessDict.lookupOrDefault<scalar>
453  (
454  "internalAngleTolerance",
456  80
457  )
458  );
459 
460  const scalar externalAngleTolerance
461  (
462  closenessDict.lookupOrDefault<scalar>
463  (
464  "externalAngleTolerance",
466  80
467  )
468  );
469 
470  // Searchable triSurface
471  const searchableSurfaces::triSurface searchSurf
472  (
473  IOobject
474  (
475  sFeatFileName + ".closeness",
476  runTime.constant(),
478  runTime
479  ),
480  surf
481  );
482 
483  if (faceCloseness)
484  {
485  Pair<tmp<scalarIOField>> closenessFields
486  (
487  searchSurf.extractCloseness
488  (
489  internalAngleTolerance,
490  externalAngleTolerance
491  )
492  );
493 
494  Info<< " writing "
495  << closenessFields.first()->name() << endl;
496  closenessFields.first()->write();
497 
498  Info<< " writing "
499  << closenessFields.second()->name() << endl;
500  closenessFields.second()->write();
501 
502  if (writeVTK)
503  {
504  writeVTKFieldNames.append("internalCloseness");
505  writeVTKFieldIsPointValues.append(false);
506  writeVTKFieldscalarValues.append
507  (
508  new scalarField(closenessFields.first())
509  );
510 
511  writeVTKFieldNames.append("externalCloseness");
512  writeVTKFieldIsPointValues.append(false);
513  writeVTKFieldscalarValues.append
514  (
515  new scalarField(closenessFields.second())
516  );
517  }
518  }
519 
520  if (pointCloseness)
521  {
522  Pair<tmp<scalarIOField >> closenessFields
523  (
524  searchSurf.extractPointCloseness
525  (
526  internalAngleTolerance,
527  externalAngleTolerance
528  )
529  );
530 
531  Info<< " writing "
532  << closenessFields.first()->name() << endl;
533  closenessFields.first()->write();
534 
535  Info<< " writing "
536  << closenessFields.second()->name() << endl;
537  closenessFields.second()->write();
538 
539  if (writeVTK)
540  {
541  const faceList faces(searchSurf.faces());
542  const Map<label>& meshPointMap = searchSurf.meshPointMap();
543 
544  const scalarIOField&
545  internalClosenessPointField = closenessFields.first();
546 
547  const scalarIOField&
548  externalClosenessPointField = closenessFields.second();
549 
550  scalarField internalCloseness(searchSurf.nPoints(), great);
551  scalarField externalCloseness(searchSurf.nPoints(), great);
552 
553  forAll(meshPointMap, pi)
554  {
555  internalCloseness[pi] =
556  internalClosenessPointField[meshPointMap[pi]];
557 
558  externalCloseness[pi] =
559  externalClosenessPointField[meshPointMap[pi]];
560  }
561 
562  writeVTKFieldNames.append("internalPointCloseness");
563  writeVTKFieldIsPointValues.append(true);
564  writeVTKFieldscalarValues.append
565  (
566  new scalarField(internalCloseness)
567  );
568 
569  writeVTKFieldNames.append("externalPointCloseness");
570  writeVTKFieldIsPointValues.append(true);
571  writeVTKFieldscalarValues.append
572  (
573  new scalarField(externalCloseness)
574  );
575  }
576  }
577  }
578 
579 
580  if (curvature)
581  {
582  Info<< nl << "Extracting curvature of surface at the points."
583  << endl;
584 
586  (
587  IOobject
588  (
589  sFeatFileName + ".curvature",
590  runTime.constant(),
592  runTime
593  ),
594  surf.curvature()
595  );
596 
597  k.write();
598 
599  if (writeVTK)
600  {
601  writeVTKFieldNames.append("curvature");
602  writeVTKFieldIsPointValues.append(true);
603  writeVTKFieldscalarValues.append(new scalarField(k));
604  }
605  }
606 
607 
608  if (featureProximity)
609  {
610  Info<< nl << "Extracting proximity of close feature points and "
611  << "edges to the surface" << endl;
612 
613  const scalar searchDistance =
614  dict.lookup<scalar>("maxFeatureProximity");
615 
616  scalarField featureProximity(surf.size(), searchDistance);
617 
618  forAll(surf, fi)
619  {
620  const triPointRef& tri = surf[fi].tri(surf.points());
621 
622  const Tuple2<point, scalar> crSqr = tri.circumCircleSqr();
623 
624  if (crSqr.second() < 0) continue;
625 
626  const point& c = crSqr.first();
627  const scalar rSqr = min(16*crSqr.second(), sqr(searchDistance));
628 
629  pointIndexHitList hitList;
630 
631  feMesh.allNearestFeatureEdges(c, rSqr, hitList);
632  featureProximity[fi] = min
633  (
634  feMesh.minDisconnectedDist(hitList),
635  featureProximity[fi]
636  );
637 
638  feMesh.allNearestFeaturePoints(c, rSqr, hitList);
639  featureProximity[fi] = min
640  (
641  minDist(hitList),
642  featureProximity[fi]
643  );
644  }
645 
646  scalarIOField featureProximityField
647  (
648  IOobject
649  (
650  sFeatFileName + ".featureProximity",
651  runTime.constant(),
653  runTime,
656  ),
657  featureProximity
658  );
659 
660  featureProximityField.write();
661 
662  if (writeVTK)
663  {
664  writeVTKFieldNames.append("featureProximity");
665  writeVTKFieldIsPointValues.append(false);
666  writeVTKFieldscalarValues.append
667  (
668  new scalarField(featureProximity)
669  );
670  }
671  }
672 
673  if (writeVTK)
674  {
675  #define WriteVTKResizeFieldTypeValues(Type, nullArg) \
676  writeVTKField##Type##Values.resize(writeVTKFieldNames.size());
677  FOR_ALL_FIELD_TYPES(WriteVTKResizeFieldTypeValues)
678  #undef WriteVTKResizeFieldTypeValues
679 
681  (
682  runTime.path()
683  /runTime.constant()
685  /sFeatFileName + "Features.vtk",
686  sFeatFileName,
687  runTime.writeFormat() == IOstream::BINARY,
688  surf.points(),
689  labelList(),
690  labelListList(),
691  faces,
692  writeVTKFieldNames,
693  writeVTKFieldIsPointValues,
694  UPtrList<const Field<label>>(writeVTKFieldNames.size())
695  #define WriteVTKFieldTypeValuesParameter(Type, nullArg) \
696  , UPtrList<const Field<Type>>(writeVTKField##Type##Values)
697  FOR_ALL_FIELD_TYPES(WriteVTKFieldTypeValuesParameter)
698  #undef WriteVTKFieldTypeValuesParameter
699  );
700  }
701 
702  Info<< endl;
703  }
704 
705 
706  void extractFeatures
707  (
708  const fileNameList& surfaceFileNames,
709  const Time& runTime,
710  const dictionary& dict
711  )
712  {
713  forAll(surfaceFileNames, i)
714  {
715  extractFeatures(surfaceFileNames[i], runTime, dict);
716  }
717  }
718 }
719 
720 
721 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
722 
723 int main(int argc, char *argv[])
724 {
726  (
727  "extract and write surface features to file"
728  );
730 
731  #include "addDictOption.H"
732 
733  #include "setRootCase.H"
734  #include "createTime.H"
735 
736  const dictionary dict(systemDict("surfaceFeaturesDict", args, runTime));
737 
738  if (dict.found("surfaces"))
739  {
740  extractFeatures
741  (
742  fileNameList(dict.lookup("surfaces")),
743  runTime,
744  dict
745  );
746  }
747  else
748  {
750  {
751  if (!iter().isDict())
752  {
753  continue;
754  }
755 
756  extractFeatures
757  (
758  fileNameList(iter().dict().lookup("surfaces")),
759  runTime,
760  iter().dict()
761  );
762  }
763  }
764 
765  Info<< "ExecutionTime = " << runTime.elapsedCpuTime() << " s"
766  << " ClockTime = " << runTime.elapsedClockTime() << " s"
767  << nl << endl;
768 
769  Info<< "End\n" << endl;
770 
771  return 0;
772 }
773 
774 
775 
776 // ************************************************************************* //
label k
#define forAll(list, i)
Loop across all elements in list.
Definition: UList.H:449
#define forAllConstIter(Container, container, iter)
Iterate across all elements in the container object of type.
Definition: UList.H:492
An STL-conforming hash table.
Definition: HashTable.H:127
A primitive field of type <Type> with automated input and output.
Definition: IOField.H:53
IOobject defines the attributes of an object for which implicit objectRegistry management is supporte...
Definition: IOobject.H:99
void append(const T &)
Append an element at the end of the list.
Definition: ListI.H:178
void size(const label)
Override size to be inconsistent with allocated storage.
Definition: ListI.H:164
virtual Ostream & write(const token &)
Write token.
Definition: Ostream.C:51
An ordered pair of two objects of type <Type> with first() and second() elements.
Definition: Pair.H:67
const Field< PointType > & points() const
Return reference to global points.
const labelListList & edgeFaces() const
Return edge-face addressing.
A simple wrapper around bool so that it can be read as a word: true/false, on/off,...
Definition: Switch.H:61
const char * asText() const
Return a text representation of the Switch.
Definition: Switch.C:118
static const word & constant()
Return constant name.
Definition: TimePaths.H:122
Class to control time during OpenFOAM simulations that is also the top-level objectRegistry.
Definition: Time.H:76
fileName path() const
Explicitly inherit path from TimePaths to disambiguate from.
Definition: TimePaths.H:138
IOstream::streamFormat writeFormat() const
Default write format.
Definition: Time.H:292
A 2-tuple for storing two objects of different types.
Definition: Tuple2.H:66
const Type2 & second() const
Return second.
Definition: Tuple2.H:131
const Type1 & first() const
Return first.
Definition: Tuple2.H:119
T & first()
Return the first element of the list.
Definition: UListI.H:114
A templated 1D list of pointers to objects of type <T>, where the size of the array is known and used...
Definition: UPtrList.H:66
static void addNote(const string &)
Add extra notes for the usage information.
Definition: argList.C:152
static void noParallel()
Remove the parallel options.
Definition: argList.C:168
An auto-pointer similar to the STL auto_ptr but with automatic casting to a reference to the type and...
Definition: autoPtr.H:51
time_t elapsedClockTime() const
Returns wall-clock time from clock instantiation.
Definition: clock.C:122
double elapsedCpuTime() const
Return CPU time (in seconds) from the start.
Definition: cpuTime.C:53
A list of keywords followed by any number of values (e.g. words and numbers) or sub-dictionaries.
Definition: dictionary.H:162
T lookupOrDefault(const word &, const T &) const
Find and return a T, if not found return the given default.
ITstream & lookup(const word &, bool recursive=false, bool patternMatch=true) const
Find and return an entry data stream.
Definition: dictionary.C:669
T lookupOrAddDefault(const word &, const T &)
Find and return a T, if not found return the given.
bool isDict(const word &) const
Check if entry is a sub-dictionary.
Definition: dictionary.C:732
const dictionary & subDict(const word &) const
Find and return a sub-dictionary.
Definition: dictionary.C:778
bool readIfPresent(const word &, T &, bool recursive=false, bool patternMatch=true) const
Find an entry if present, and assign to T.
bool found(const word &, bool recursive=false, bool patternMatch=true) const
Search dictionary for given keyword.
Definition: dictionary.C:468
Points connected by edges.
Definition: edgeMesh.H:72
A class for handling file names.
Definition: fileName.H:82
word name() const
Return file name (part beyond last /)
Definition: fileName.C:195
fileName lessExt() const
Return file name without extension (part before last .)
Definition: fileName.C:303
const Time & time() const
Return time.
Geometric class that creates a 2D plane and can return the intersection point between a line and the ...
Definition: plane.H:62
static const word & geometryDir()
Return the geometry directory name.
A surface geometry formed of discrete facets, e.g. triangles and/or quadrilaterals,...
Holds feature edges/points of surface.
Standard boundBox + extra functionality for use in octree.
Definition: treeBoundBox.H:90
label size() const
Return size.
Triangulated surface description with patch information.
Definition: triSurface.H:68
tmp< scalarField > curvature() const
Return the curvature of surface at the points.
Definition: triSurface.C:1155
const geometricSurfacePatchList & patches() const
Definition: triSurface.H:320
void writeStats(Ostream &) const
Write some statistics.
Definition: triSurface.C:1364
faceList faces() const
Return the list of triangles as a faceList.
Definition: triSurface.C:1142
A triangle primitive used to calculate face areas and swept volumes.
Definition: triangle.H:80
Tuple2< Point, scalar > circumCircleSqr() const
Return the circum-centre and radius-squared.
Definition: triangleI.H:120
A class for handling words, derived from string.
Definition: word.H:63
int main(int argc, char *argv[])
Definition: financialFoam.C:44
const dimensionedScalar c
Speed of light in a vacuum.
const unitSet & lookup(const word &unitName)
Lookup and return the named unit from the table.
Definition: units.C:346
const unitSet degrees
void write(const fileName &file, const word &title, const bool binary, const PointField &points, const VertexList &vertices, const LineList &lines, const FaceList &faces, const wordList &fieldNames, const boolList &fieldIsPointValues, const UPtrList< const Field< label >> &fieldLabelValues #define FieldTypeValuesConstArg(Type, nullArg))
Write VTK polygonal data to a file. Takes a PtrList of fields of labels and.
Namespace for OpenFOAM.
const doubleScalar e
Definition: doubleScalar.H:106
List< fileName > fileNameList
A List of fileNames.
Definition: fileNameList.H:50
scalar minDist(const List< pointIndexHit > &hitList)
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
bool mkDir(const fileName &, mode_t=0777)
Make a directory and return an error if it could not be created.
Definition: POSIX.C:290
Ostream & endl(Ostream &os)
Add newline and flush stream.
Definition: Ostream.H:288
void selectBox(const triSurface &surf, const boundBox &bb, const bool removeInside, List< surfaceFeatures::edgeStatus > &edgeStat)
Select edges inside or outside bounding box.
FOR_ALL_FIELD_TYPES(makeDimensionedPointFieldFunctions)
messageStream Info
Field< scalar > scalarField
Specialisation of Field<T> for scalar.
tmp< DimensionedField< typename outerProduct< Type, Type >::type, GeoMesh, Field >> sqr(const DimensionedField< Type, GeoMesh, PrimitiveField > &df)
List< labelList > labelListList
A List of labelList.
Definition: labelList.H:57
void selectManifoldEdges(const triSurface &surf, const scalar tol, const scalar includedAngle, List< surfaceFeatures::edgeStatus > &edgeStat)
Select manifold edges.
dimensioned< Type > min(const DimensionedField< Type, GeoMesh, PrimitiveField > &df)
word name(const LagrangianState state)
Return a string representation of a Lagrangian state enumeration.
void writeVTK(OFstream &os, const Type &value)
label findIndex(const ListType &, typename ListType::const_reference, const label start=0)
Find first occurrence of given element and return index,.
void selectCutEdges(const triSurface &surf, const plane &cutPlane, List< surfaceFeatures::edgeStatus > &edgeStat)
Select edges that are intersected by the given plane.
IOdictionary systemDict(const word &dictName, const argList &args, const objectRegistry &ob, const word &regionName=polyMesh::defaultRegion, const fileName &path=fileName::null)
Definition: systemDict.C:93
Ostream & indent(Ostream &os)
Indent stream.
Definition: Ostream.H:243
static const char nl
Definition: Ostream.H:297
dictionary dict
Foam::argList args(argc, argv)