surfaceFeatureExtract.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 | www.openfoam.com
6  \\/ M anipulation |
7 -------------------------------------------------------------------------------
8  Copyright (C) 2011-2016 OpenFOAM Foundation
9  Copyright (C) 2015-2020 OpenCFD Ltd.
10 -------------------------------------------------------------------------------
11 License
12  This file is part of OpenFOAM.
13 
14  OpenFOAM is free software: you can redistribute it and/or modify it
15  under the terms of the GNU General Public License as published by
16  the Free Software Foundation, either version 3 of the License, or
17  (at your option) any later version.
18 
19  OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
20  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
21  FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
22  for more details.
23 
24  You should have received a copy of the GNU General Public License
25  along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>.
26 
27 Application
28  surfaceFeatureExtract
29 
30 Group
31  grpSurfaceUtilities
32 
33 Description
34  Extracts and writes surface features to file. All but the basic feature
35  extraction is a work-in-progress.
36 
37  The extraction process is driven by the \a system/surfaceFeatureExtractDict
38  dictionary, but the \a -dict option can be used to define an alternative
39  location.
40 
41  The \a system/surfaceFeatureExtractDict dictionary contains entries
42  for each extraction process.
43  The name of the individual dictionary is used to load the input surface
44  (found under \a constant/triSurface) and also as the basename for the
45  output.
46 
47  If the \c surfaces entry is present in a sub-dictionary, it has absolute
48  precedence over a surface name deduced from the dictionary name.
49  If the dictionary name itself does not have an extension, the \c surfaces
50  entry becomes mandatory since in this case the dictionary name cannot
51  represent an input surface file (ie, there is no file extension).
52  The \c surfaces entry is a wordRe list, which allows loading and
53  combining of multiple surfaces. Any exactly specified surface names must
54  exist, but surfaces selected via regular expressions need not exist.
55  The selection mechanism preserves order and is without duplicates.
56  For example,
57  \verbatim
58  dictName
59  {
60  surfaces (surface1.stl "other.*" othersurf.obj);
61  ...
62  }
63  \endverbatim
64 
65  When loading surfaces, the points/faces/regions of each surface are
66  normally offset to create an aggregated surface. No merging of points
67  or faces is done. The optional entry \c loadingOption can be used to
68  adjust the treatment of the regions when loading single or multiple files,
69  with selections according to the Foam::triSurfaceLoader::loadingOption
70  enumeration.
71  \verbatim
72  dictName
73  {
74  // Optional treatment of surface regions when loading
75  // (single, file, offset, merge)
76  loadingOption file;
77  ...
78  }
79  \endverbatim
80  The \c loadingOption is primarily used in combination with the
81  \c intersectionMethod (specifically its \c region option).
82  The default \c loadingOption is normally \c offset,
83  but this changes to \c file if the \c intersectionMethod
84  \c region is being used.
85 
86  Once surfaces have been loaded, the first stage is to extract
87  features according to the specified \c extractionMethod with values
88  as per the following table:
89  \table
90  extractionMethod | Description
91  none | No feature extraction
92  extractFromFile | Load features from the file named in featureEdgeFile
93  extractFromSurface | Extract features from surface geometry
94  \endtable
95 
96  There are a few entries that influence the extraction behaviour:
97  \verbatim
98  // File to use for extractFromFile input
99  featureEdgeFile "FileName"
100 
101  // Mark edges whose adjacent surface normals are at an angle less
102  // than includedAngle as features
103  // - 0 : selects no edges
104  // - 180: selects all edges
105  includedAngle 120;
106 
107  // Do not mark region edges
108  geometricTestOnly yes;
109  \endverbatim
110 
111  This initial set of edges can be trimmed:
112  \verbatim
113  trimFeatures
114  {
115  // Remove features with fewer than the specified number of edges
116  minElem 0;
117 
118  // Remove features shorter than the specified cumulative length
119  minLen 0.0;
120  }
121  \endverbatim
122 
123  and subsetted
124  \verbatim
125  subsetFeatures
126  {
127  // Use a plane to select feature edges (normal)(basePoint)
128  // Only keep edges that intersect the plane
129  plane (1 0 0)(0 0 0);
130 
131  // Select feature edges using a box // (minPt)(maxPt)
132  // Only keep edges inside the box:
133  insideBox (0 0 0)(1 1 1);
134 
135  // Only keep edges outside the box:
136  outsideBox (0 0 0)(1 1 1);
137 
138  // Keep nonManifold edges (edges with >2 connected faces where
139  // the faces form more than two different normal planes)
140  nonManifoldEdges yes;
141 
142  // Keep open edges (edges with 1 connected face)
143  openEdges yes;
144  }
145  \endverbatim
146 
147  Subsequently, additional features can be added from another file:
148  \verbatim
149  addFeatures
150  {
151  // Add (without merging) another extendedFeatureEdgeMesh
152  name axZ.extendedFeatureEdgeMesh;
153  }
154  \endverbatim
155 
156  The intersectionMethod provides a final means of adding additional
157  features. These are loosely termed "self-intersection", since it
158  detects the face/face intersections of the loaded surface or surfaces.
159 
160  \table
161  intersectionMethod | Description
162  none | Do nothing
163  self | All face/face intersections
164  region | Limit face/face intersections to those between different regions.
165  \endtable
166  The optional \c tolerance tuning parameter is available for handling
167  the face/face intersections, but should normally not be touched.
168 
169  As well as the normal extendedFeatureEdgeMesh written,
170  other items can be selected with boolean switches:
171 
172  \table
173  Output option | Description
174  closeness | Output the closeness of surface elements to other surface elements.
175  curvature | Output surface curvature
176  featureProximity | Output the proximity of feature points and edges to another
177  writeObj | Write features to OBJ format for postprocessing
178  writeVTK | Write closeness/curvature/proximity fields as VTK for postprocessing
179  \endtable
180 
181 Note
182  Although surfaceFeatureExtract can do many things, there are still a fair
183  number of corner cases where it may not produce the desired result.
184 \*---------------------------------------------------------------------------*/
185 
186 #include "argList.H"
187 #include "Time.H"
188 #include "triSurface.H"
189 #include "triSurfaceTools.H"
190 #include "edgeMeshTools.H"
192 #include "surfaceIntersection.H"
193 #include "featureEdgeMesh.H"
194 #include "extendedFeatureEdgeMesh.H"
195 #include "treeBoundBox.H"
196 #include "meshTools.H"
197 #include "OBJstream.H"
198 #include "triSurfaceMesh.H"
199 #include "foamVtkSurfaceWriter.H"
200 #include "unitConversion.H"
201 #include "plane.H"
202 #include "point.H"
203 #include "triSurfaceLoader.H"
204 
205 using namespace Foam;
206 
207 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
208 
209 int main(int argc, char *argv[])
210 {
212  (
213  "Extract and write surface feature lines to file.\n"
214  "Feature line extraction only valid on closed manifold surfaces."
215  );
216 
218  argList::noFunctionObjects(); // Never use function objects
219 
221  (
222  "dict",
223  "file",
224  "Read surfaceFeatureExtractDict from specified location"
225  );
226 
227  #include "setRootCase.H"
228  #include "createTime.H"
229 
230  Info<< nl
231  << "Note: "
232  << "Feature line extraction only valid on closed manifold surfaces"
233  << nl << nl;
234 
235  const word dictName("surfaceFeatureExtractDict");
237 
238  Info<< "Reading " << dictIO.name() << nl << endl;
239  const IOdictionary dict(dictIO);
240 
241  // Loader for available triSurface surface files
242  triSurfaceLoader loader(runTime);
243 
244  // Where to write VTK output files
245  const fileName vtkOutputDir = runTime.constantPath()/"triSurface";
246 
247  for (const entry& dEntry : dict)
248  {
249  if (!dEntry.isDict() || dEntry.keyword().isPattern()) // safety
250  {
251  continue;
252  }
253 
254  const word& dictName = dEntry.keyword();
255  const dictionary& surfaceDict = dEntry.dict();
256 
257  if (!surfaceDict.found("extractionMethod"))
258  {
259  // Insist on an extractionMethod
260  continue;
261  }
262 
263  // The output name based in dictionary name (without extensions)
264  const word outputName = dictName.lessExt();
265 
268  (
269  surfaceDict
270  );
271 
272  // We don't needs the intersectionMethod yet, but can use it
273  // for setting a reasonable loading option
274  const surfaceIntersection::intersectionType selfIntersect =
276  (
277  "intersectionMethod",
278  surfaceDict,
280  );
281 
282  const Switch writeObj("writeObj", surfaceDict, Switch::OFF);
283 
284  const Switch writeVTK("writeVTK", surfaceDict, Switch::OFF);
285 
286  // The "surfaces" entry is normally optional, but make it mandatory
287  // if the dictionary name doesn't have an extension
288  // (ie, probably not a surface filename at all).
289  // If it is missing, this will fail nicely with an appropriate error
290  // message.
291  if (surfaceDict.found("surfaces") || !dictName.hasExt())
292  {
293  loader.select(surfaceDict.get<wordRes>("surfaces"));
294  }
295  else
296  {
297  loader.select(dictName);
298  }
299 
300  // DebugVar(loader.available());
301  // DebugVar(outputName);
302 
303  if (loader.selected().empty())
304  {
306  << "No surfaces specified/found for entry: "
307  << dictName << exit(FatalError);
308  }
309 
310  Info<< "Surfaces : ";
311  if (loader.selected().size() == 1)
312  {
313  Info<< loader.selected().first() << nl;
314  }
315  else
316  {
317  Info<< flatOutput(loader.selected()) << nl;
318  }
319  Info<< "Output : " << outputName << nl;
320 
321  // Loading option - default depends on context
322  triSurfaceLoader::loadingOption loadingOption =
324  (
325  "loadingOption",
326  surfaceDict,
327  (
328  selfIntersect == surfaceIntersection::SELF_REGION
331  )
332  );
333 
334  Info<<"Load options : "
335  << triSurfaceLoader::loadingOptionNames[loadingOption] << nl
336  << "Write options:"
337  << " writeObj=" << writeObj
338  << " writeVTK=" << writeVTK << nl;
339 
340  scalar scaleFactor = -1;
341  // Allow rescaling of the surface points (eg, mm -> m)
342  if (surfaceDict.readIfPresent("scale", scaleFactor) && scaleFactor > 0)
343  {
344  Info<<"Scaling : " << scaleFactor << nl;
345  }
346 
347  // Load a single file, or load and combine multiple selected files
348  autoPtr<triSurface> surfPtr = loader.load(loadingOption, scaleFactor);
349  if (!surfPtr.valid() || surfPtr().empty())
350  {
352  << "Problem loading surface(s) for entry: "
353  << dictName << exit(FatalError);
354  }
355 
356  triSurface surf = surfPtr();
357 
358  Info<< nl
359  << "Statistics:" << nl;
360  surf.writeStats(Info);
361 
362  // Need a copy as plain faces if outputting VTK format
363  faceList faces;
364  if (writeVTK)
365  {
366  faces.setSize(surf.size());
367  forAll(surf, fi)
368  {
369  faces[fi] = surf[fi];
370  }
371  }
372 
373  //
374  // Extract features using the preferred extraction method
375  //
376  autoPtr<surfaceFeatures> features = extractor().features(surf);
377 
378  // Trim set
379  // ~~~~~~~~
380 
381  // Option: "trimFeatures" (dictionary)
382  if (surfaceDict.isDict("trimFeatures"))
383  {
384  const dictionary& trimDict = surfaceDict.subDict("trimFeatures");
385 
386  const scalar minLen =
387  trimDict.getOrDefault<scalar>("minLen", 0);
388  const label minElem =
389  trimDict.getOrDefault<label>("minElem", 0);
390 
391  // Trim away small groups of features
392  if (minLen > 0 || minElem > 0)
393  {
394  if (minLen > 0)
395  {
396  Info<< "Removing features of length < "
397  << minLen << endl;
398  }
399  if (minElem > 0)
400  {
401  Info<< "Removing features with number of edges < "
402  << minElem << endl;
403  }
404 
405  features().trimFeatures
406  (
407  minLen, minElem, extractor().includedAngle()
408  );
409  }
410  }
411 
412  // Subset
413  // ~~~~~~
414 
415  // Convert to marked edges, points
416  List<surfaceFeatures::edgeStatus> edgeStat(features().toStatus());
417 
418  // Option: "subsetFeatures" (dictionary)
419  if (surfaceDict.isDict("subsetFeatures"))
420  {
421  const dictionary& subsetDict = surfaceDict.subDict
422  (
423  "subsetFeatures"
424  );
425 
426  // Suboption: "insideBox"
427  if (subsetDict.found("insideBox"))
428  {
429  treeBoundBox bb(subsetDict.lookup("insideBox")());
430 
431  Info<< "Subset edges inside box " << bb << endl;
432  features().subsetBox(edgeStat, bb);
433 
434  {
435  OBJstream os("subsetBox.obj");
436 
437  Info<< "Dumping bounding box " << bb
438  << " as lines to obj file "
439  << os.name() << endl;
440 
441  os.write(bb);
442  }
443  }
444  // Suboption: "outsideBox"
445  else if (subsetDict.found("outsideBox"))
446  {
447  treeBoundBox bb(subsetDict.lookup("outsideBox")());
448 
449  Info<< "Exclude edges outside box " << bb << endl;
450  features().excludeBox(edgeStat, bb);
451 
452  {
453  OBJstream os("deleteBox.obj");
454 
455  Info<< "Dumping bounding box " << bb
456  << " as lines to obj file "
457  << os.name() << endl;
458 
459  os.write(bb);
460  }
461  }
462 
463  // Suboption: "nonManifoldEdges" (false: remove non-manifold edges)
464  if (!subsetDict.getOrDefault("nonManifoldEdges", true))
465  {
466  Info<< "Removing all non-manifold edges"
467  << " (edges with > 2 connected faces) unless they"
468  << " cross multiple regions" << endl;
469 
470  features().checkFlatRegionEdge
471  (
472  edgeStat,
473  1e-5, // tol
474  extractor().includedAngle()
475  );
476  }
477 
478  // Suboption: "openEdges" (false: remove open edges)
479  if (!subsetDict.getOrDefault("openEdges", true))
480  {
481  Info<< "Removing all open edges"
482  << " (edges with 1 connected face)" << endl;
483 
484  features().excludeOpen(edgeStat);
485  }
486 
487  // Suboption: "plane"
488  if (subsetDict.found("plane"))
489  {
490  plane cutPlane(subsetDict.lookup("plane")());
491 
492  Info<< "Only include feature edges that intersect the plane"
493  << " with normal " << cutPlane.normal()
494  << " and origin " << cutPlane.origin() << endl;
495 
496  features().subsetPlane(edgeStat, cutPlane);
497  }
498  }
499 
500  surfaceFeatures newSet(surf);
501  newSet.setFromStatus(edgeStat, extractor().includedAngle());
502 
503  Info<< nl << "Initial ";
504  newSet.writeStats(Info);
505 
506  boolList surfBaffleRegions(surf.patches().size(), false);
507  if (surfaceDict.found("baffles"))
508  {
509  wordRes baffleSelect(surfaceDict.get<wordRes>("baffles"));
510 
511  wordList patchNames(surf.patches().size());
512  forAll(surf.patches(), patchi)
513  {
514  patchNames[patchi] = surf.patches()[patchi].name();
515  }
516 
517  labelList indices(baffleSelect.matching(patchNames));
518 
519  for (const label patchId : indices)
520  {
521  surfBaffleRegions[patchId] = true;
522  }
523 
524  if (indices.size())
525  {
526  Info<< "Adding " << indices.size() << " baffle regions: (";
527 
528  forAll(surfBaffleRegions, patchi)
529  {
530  if (surfBaffleRegions[patchi])
531  {
532  Info<< ' ' << patchNames[patchi];
533  }
534  }
535  Info<< " )" << nl << nl;
536  }
537  }
538 
539  // Extracting and writing a extendedFeatureEdgeMesh
541  (
542  newSet,
543  runTime,
544  outputName + ".extendedFeatureEdgeMesh",
545  surfBaffleRegions
546  );
547 
548 
549  if (surfaceDict.isDict("addFeatures"))
550  {
551  const word addFeName
552  (
553  surfaceDict.subDict("addFeatures").get<word>("name")
554  );
555 
556  Info<< "Adding (without merging) features from " << addFeName
557  << nl << endl;
558 
559  extendedFeatureEdgeMesh addFeMesh
560  (
561  IOobject
562  (
563  addFeName,
564  runTime.time().constant(),
565  "extendedFeatureEdgeMesh",
566  runTime.time(),
569  )
570  );
571  Info<< "Read " << addFeMesh.name() << nl;
572  edgeMeshTools::writeStats(Info, addFeMesh);
573 
574  feMesh.add(addFeMesh);
575  }
576 
577  if (selfIntersect != surfaceIntersection::NONE)
578  {
579  triSurfaceSearch query(surf);
580  surfaceIntersection intersect(query, surfaceDict);
581 
582  // Remove rounding noise. For consistency could use 1e-6,
583  // as per extractFromFile implementation
584 
585  intersect.mergePoints(10*SMALL);
586 
587  labelPair sizeInfo
588  (
589  intersect.cutPoints().size(),
590  intersect.cutEdges().size()
591  );
592 
593  if (intersect.cutEdges().size())
594  {
595  extendedEdgeMesh addMesh
596  (
597  intersect.cutPoints(),
598  intersect.cutEdges()
599  );
600 
601  feMesh.add(addMesh);
602 
603  sizeInfo[0] = addMesh.points().size();
604  sizeInfo[1] = addMesh.edges().size();
605  }
606  Info<< nl
607  << "intersection: "
609  << nl
610  << " points : " << sizeInfo[0] << nl
611  << " edges : " << sizeInfo[1] << nl;
612  }
613 
614  Info<< nl << "Final ";
616 
617  Info<< nl << "Writing extendedFeatureEdgeMesh to "
618  << feMesh.objectPath() << endl;
619 
620  mkDir(feMesh.path());
621 
622  if (writeObj)
623  {
624  feMesh.writeObj(feMesh.path()/outputName);
625  }
626 
627  feMesh.write();
628 
629  // Write a featureEdgeMesh (.eMesh) for backwards compatibility
630  // Used by snappyHexMesh (JUN-2017)
631  if (true)
632  {
633  featureEdgeMesh bfeMesh
634  (
635  IOobject
636  (
637  outputName + ".eMesh", // name
638  runTime.constant(), // instance
639  "triSurface",
640  runTime, // registry
643  false
644  ),
645  feMesh.points(),
646  feMesh.edges()
647  );
648 
649  Info<< nl << "Writing featureEdgeMesh to "
650  << bfeMesh.objectPath() << endl;
651 
652  bfeMesh.regIOobject::write();
653  }
654 
655 
656  // Output information
657 
658  const bool optCloseness =
659  surfaceDict.getOrDefault("closeness", false);
660 
661  const bool optProximity =
662  surfaceDict.getOrDefault("featureProximity", false);
663 
664  const bool optCurvature =
665  surfaceDict.getOrDefault("curvature", false);
666 
667 
668  // For VTK legacy format, we would need an a priori count of
669  // CellData and PointData fields.
670  // For convenience, we therefore only use the XML formats
671 
672  autoPtr<vtk::surfaceWriter> vtkWriter;
673 
674  if (optCloseness || optProximity || optCurvature)
675  {
676  if (writeVTK)
677  {
678  vtkWriter.reset
679  (
681  (
682  surf.points(),
683  faces,
684  (vtkOutputDir / outputName),
685  false // serial only
686  )
687  );
688 
689  vtkWriter->writeGeometry();
690 
691  Info<< "Writing VTK to "
692  << runTime.relativePath(vtkWriter->output()) << nl;
693  }
694  }
695  else
696  {
697  continue; // Nothing to output
698  }
699 
700 
701  // Option: "closeness"
702  if (optCloseness)
703  {
704  Pair<tmp<scalarField>> tcloseness =
706  (
707  runTime,
708  outputName,
709  surf,
710  45, // internalAngleTolerance
711  10 // externalAngleTolerance
712  );
713 
714  if (vtkWriter.valid())
715  {
716  vtkWriter->beginCellData();
717  vtkWriter->write("internalCloseness", tcloseness[0]());
718  vtkWriter->write("externalCloseness", tcloseness[1]());
719  }
720  }
721 
722  // Option: "featureProximity"
723  if (optCloseness)
724  {
725  const scalar maxProximity =
726  surfaceDict.getOrDefault<scalar>("maxFeatureProximity", 1);
727 
728  tmp<scalarField> tproximity =
730  (
731  runTime,
732  outputName,
733  feMesh,
734  surf,
735  maxProximity
736  );
737 
738  if (vtkWriter.valid())
739  {
740  vtkWriter->beginCellData();
741  vtkWriter->write("featureProximity", tproximity());
742  }
743  }
744 
745  // Option: "curvature"
746  if (optCurvature)
747  {
748  tmp<scalarField> tcurvature =
750  (
751  runTime,
752  outputName,
753  surf
754  );
755 
756  if (vtkWriter.valid())
757  {
758  vtkWriter->beginPointData();
759  vtkWriter->write("curvature", tcurvature());
760  }
761  }
762 
763  Info<< endl;
764  }
765 
767 
768  Info<< "End\n" << endl;
769 
770  return 0;
771 }
772 
773 
774 // ************************************************************************* //
Foam::triSurface::writeStats
void writeStats(Ostream &os) const
Write some statistics.
Definition: triSurfaceIO.C:353
Foam::entry
A keyword and a list of tokens is an 'entry'.
Definition: entry.H:67
Foam::word::lessExt
word lessExt() const
Return word without extension (part before last .)
Definition: word.C:113
Foam::IOobject::NO_WRITE
Definition: IOobject.H:130
Foam::IOdictionary
IOdictionary is derived from dictionary and IOobject to give the dictionary automatic IO functionalit...
Definition: IOdictionary.H:54
runTime
engineTime & runTime
Definition: createEngineTime.H:13
Foam::autoPtr::reset
void reset(T *p=nullptr) noexcept
Delete managed object and set to new given pointer.
Definition: autoPtrI.H:109
Foam::IOobject
Defines the attributes of an object for which implicit objectRegistry management is supported,...
Definition: IOobject.H:104
meshTools.H
Foam::Switch
A simple wrapper around bool so that it can be read as a word: true/false, on/off,...
Definition: Switch.H:76
Foam::IOobject::AUTO_WRITE
Definition: IOobject.H:129
Foam::IOobject::name
const word & name() const
Return name.
Definition: IOobjectI.H:70
Foam::triSurfaceLoader::loadingOption
loadingOption
The file loading options for triSurfaceLoader.
Definition: triSurfaceLoader.H:67
Foam::word
A class for handling words, derived from Foam::string.
Definition: word.H:62
Foam::fileName
A class for handling file names.
Definition: fileName.H:69
Foam::OBJstream
OFstream that keeps track of vertices.
Definition: OBJstream.H:58
setSystemRunTimeDictionaryIO.H
Foam::tmp
A class for managing temporary objects.
Definition: PtrList.H:59
Foam::dictionary::found
bool found(const word &keyword, enum keyType::option matchOpt=keyType::REGEX) const
Search for an entry (const access) with the given keyword.
Definition: dictionary.C:364
Foam::vtk::surfaceWriter::beginCellData
virtual bool beginCellData(label nFields=0)
Begin CellData output section for specified number of fields.
Definition: foamVtkSurfaceWriter.C:457
surfaceFeaturesExtraction.H
point.H
Foam::treeBoundBox
Standard boundBox with extra functionality for use in octree.
Definition: treeBoundBox.H:87
Foam::objectRegistry::time
const Time & time() const
Return time.
Definition: objectRegistry.H:186
Foam::vtk::surfaceWriter::writeGeometry
virtual bool writeGeometry()
Write patch topology.
Definition: foamVtkSurfaceWriter.C:431
Foam::triSurfaceLoader::loadingOptionNames
static const Enum< loadingOption > loadingOptionNames
The loading enumeration names.
Definition: triSurfaceLoader.H:76
Foam::argList::addNote
static void addNote(const string &note)
Add extra notes for the usage information.
Definition: argList.C:413
dictName
const word dictName("blockMeshDict")
unitConversion.H
Unit conversion functions.
Foam::surfaceIntersection::intersectionType
intersectionType
Surface intersection types for classify, doCutEdges.
Definition: surfaceIntersection.H:135
Foam::autoPtr::valid
bool valid() const noexcept
True if the managed pointer is non-null.
Definition: autoPtr.H:148
Foam::triSurfaceTools::writeCurvature
static tmp< scalarField > writeCurvature(const Time &runTime, const word &basename, const triSurface &surf)
Write surface curvature at the vertex points and return the field.
Definition: triSurfaceCurvature.C:349
Foam::endl
Ostream & endl(Ostream &os)
Add newline and flush stream.
Definition: Ostream.H:350
Foam::dictionary::get
T get(const word &keyword, enum keyType::option matchOpt=keyType::REGEX) const
Definition: dictionaryTemplates.C:81
foamVtkSurfaceWriter.H
triSurface.H
Foam::triSurface::patches
const geometricSurfacePatchList & patches() const
Definition: triSurface.H:399
Foam::triSurfaceSearch
Helper class to search on triSurface.
Definition: triSurfaceSearch.H:58
Foam::TimePaths::constantPath
fileName constantPath() const
Return constant path.
Definition: TimePathsI.H:122
Foam::autoPtr::empty
bool empty() const noexcept
True if the managed pointer is null.
Definition: autoPtr.H:145
Foam::surfaceFeaturesExtraction::method::New
static autoPtr< method > New(const dictionary &dict)
Select constructed from dictionary.
extendedFeatureEdgeMesh.H
Foam::triSurfaceLoader::FILE_REGION
"file" = One region for each file
Definition: triSurfaceLoader.H:70
forAll
#define forAll(list, i)
Loop across all elements in list.
Definition: stdFoam.H:296
Foam::writeVTK
void writeVTK(OFstream &os, const Type &value)
surfaceIntersection.H
Foam::plane
Geometric class that creates a 3D plane and can return the intersection point between a line and the ...
Definition: plane.H:89
Foam::edgeMeshTools::writeFeatureProximity
tmp< scalarField > writeFeatureProximity(const Time &runTime, const word &basename, const extendedEdgeMesh &emesh, const triSurface &surf, const scalar searchDistance)
Calculate proximity of the features to the surface and write the field.
Definition: edgeMeshFeatureProximity.C:191
Foam::Time::printExecutionTime
Ostream & printExecutionTime(OSstream &os) const
Print the elapsed ExecutionTime (cpu-time), ClockTime.
Definition: TimeIO.C:603
Foam::TimePaths::relativePath
fileName relativePath(const fileName &input, const bool caseTag=false) const
Definition: TimePathsI.H:79
Foam::argList::noFunctionObjects
static void noFunctionObjects(bool addWithOption=false)
Remove '-noFunctionObjects' option and ignore any occurrences.
Definition: argList.C:454
Foam::vtk::fileWriter::output
const fileName & output() const
The current output file name.
Definition: foamVtkFileWriterI.H:92
Foam::word::hasExt
bool hasExt() const
Return true if it has an extension or simply ends with a '.'.
Definition: wordI.H:165
Foam::surfaceIntersection
Basic surface-surface intersection description. Constructed from two surfaces it creates a descriptio...
Definition: surfaceIntersection.H:130
plane.H
Foam::triSurface
Triangulated surface description with patch information.
Definition: triSurface.H:76
treeBoundBox.H
Foam::Info
messageStream Info
Information stream (uses stdout - output is on the master only)
Foam::vtk::surfaceWriter::write
void write(const word &fieldName, const UList< Type > &field)
Write a list of Cell (Face) or Point values.
Definition: foamVtkSurfaceWriterTemplates.C:59
argList.H
Foam::Enum::getOrDefault
EnumType getOrDefault(const word &key, const dictionary &dict, const EnumType deflt, const bool failsafe=false) const
Definition: Enum.C:190
Foam::surfaceIntersection::NONE
None = invalid (for input only)
Definition: surfaceIntersection.H:141
Foam::dictionary::subDict
const dictionary & subDict(const word &keyword, enum keyType::option matchOpt=keyType::REGEX) const
Find and return a sub-dictionary.
Definition: dictionary.C:528
Foam::surfaceFeatures
Holds feature edges/points of surface.
Definition: surfaceFeatures.H:73
patchNames
wordList patchNames(nPatches)
Foam::edgeMeshTools::writeStats
void writeStats(Ostream &os, const extendedFeatureEdgeMesh &emesh)
Write some information.
Definition: edgeMeshTools.C:36
Foam::dictionary::lookup
ITstream & lookup(const word &keyword, enum keyType::option matchOpt=keyType::REGEX) const
Definition: dictionary.C:424
dict
dictionary dict
Definition: searchingEngine.H:14
Foam::FatalError
error FatalError
Foam::dictionary
A list of keyword definitions, which are a keyword followed by a number of values (eg,...
Definition: dictionary.H:121
Foam::PrimitivePatch::points
const Field< point_type > & points() const
Return reference to global points.
Definition: PrimitivePatch.H:305
dictIO
IOobject dictIO
Definition: setConstantMeshDictionaryIO.H:1
Foam::Ostream::write
virtual bool write(const token &tok)=0
Write token to stream or otherwise handle it.
Foam
Namespace for OpenFOAM.
Definition: atmBoundaryLayer.C:33
Foam::triSurfaceLoader
Convenience class for loading single or multiple surface files from the constant/triSurface (or other...
Definition: triSurfaceLoader.H:62
Foam::exit
errorManipArg< error, int > exit(error &err, const int errNo=1)
Definition: errorManip.H:130
Foam::dictionary::isDict
bool isDict(const word &keyword, enum keyType::option matchOpt=keyType::REGEX) const
Check if entry is found and is a sub-dictionary.
Definition: dictionary.C:498
Time.H
Foam::autoPtr
Pointer management similar to std::unique_ptr, with some additional methods and type checking.
Definition: HashPtrTable.H:53
setRootCase.H
Foam::extendedEdgeMesh
Description of feature edges and points.
Definition: extendedEdgeMesh.H:85
Foam::surfaceIntersection::SELF_REGION
Self-intersection, region-wise only.
Definition: surfaceIntersection.H:140
FatalErrorInFunction
#define FatalErrorInFunction
Report an error message using Foam::FatalError.
Definition: error.H:372
Foam::triSurfaceTools::writeCloseness
static Pair< tmp< scalarField > > writeCloseness(const Time &runTime, const word &basename, const triSurface &surf, const scalar internalAngleTolerance=45, const scalar externalAngleTolerance=10)
Check and write internal/external closeness fields.
Definition: triSurfaceCloseness.C:96
Foam::nl
constexpr char nl
Definition: Ostream.H:385
Foam::Pair< label >
Foam::flatOutput
FlatOutput< Container > flatOutput(const Container &obj, label len=0)
Global flatOutput function.
Definition: FlatOutput.H:85
Foam::vtk::surfaceWriter
Write faces/points (optionally with fields) as a vtp file or a legacy vtk file.
Definition: foamVtkSurfaceWriter.H:68
Foam::extendedEdgeMesh::add
void add(const extendedEdgeMesh &fem)
Add extendedEdgeMesh. No filtering of duplicates.
Definition: extendedEdgeMesh.C:1030
Foam::List< face >
Foam::constant::electromagnetic::e
const dimensionedScalar e
Elementary charge.
Definition: createFields.H:11
Foam::wordRes
A List of wordRe with additional matching capabilities.
Definition: wordRes.H:51
Foam::Switch::OFF
Definition: Switch.H:91
createTime.H
edgeMeshTools.H
Foam::extendedFeatureEdgeMesh
extendedEdgeMesh + IO.
Definition: extendedFeatureEdgeMesh.H:56
patchId
label patchId(-1)
featureEdgeMesh.H
Foam::vtk::surfaceWriter::beginPointData
virtual bool beginPointData(label nFields=0)
Begin PointData for specified number of fields.
Definition: foamVtkSurfaceWriter.C:463
Foam::argList::noParallel
static void noParallel()
Remove the parallel options.
Definition: argList.C:491
Foam::triSurfaceLoader::OFFSET_REGION
"offset" = Offset regions per file
Definition: triSurfaceLoader.H:71
Foam::List::setSize
void setSize(const label newSize)
Alias for resize(const label)
Definition: ListI.H:146
Foam::TimePaths::constant
const word & constant() const
Return constant name.
Definition: TimePathsI.H:88
Foam::dictionary::getOrDefault
T getOrDefault(const word &keyword, const T &deflt, enum keyType::option matchOpt=keyType::REGEX) const
Definition: dictionaryTemplates.C:122
Foam::IOobject::NO_READ
Definition: IOobject.H:123
Foam::argList::addOption
static void addOption(const word &optName, const string &param="", const string &usage="", bool advanced=false)
Add an option to validOptions with usage information.
Definition: argList.C:336
Foam::mkDir
bool mkDir(const fileName &pathName, mode_t mode=0777)
Make a directory and return an error if it could not be created.
Definition: MSwindows.C:507
Foam::featureEdgeMesh
edgeMesh + IO.
Definition: featureEdgeMesh.H:54
triSurfaceMesh.H
triSurfaceTools.H
triSurfaceLoader.H
OBJstream.H
Foam::dictionary::readIfPresent
bool readIfPresent(const word &keyword, T &val, enum keyType::option matchOpt=keyType::REGEX) const
Definition: dictionaryTemplates.C:417
Foam::surfaceIntersection::selfIntersectionNames
static const Enum< intersectionType > selfIntersectionNames
The user-selectable self-intersection enumeration names.
Definition: surfaceIntersection.H:145
Foam::IOobject::MUST_READ
Definition: IOobject.H:120