205 using namespace Foam;
209 int main(
int argc,
char *argv[])
213 "Extract and write surface feature lines to file.\n" 214 "Feature line extraction only valid on closed manifold surfaces." 224 "Read surfaceFeatureExtractDict from specified location" 232 <<
"Feature line extraction only valid on closed manifold surfaces" 249 if (!dEntry.isDict())
258 const dictionary& surfaceDict = dEntry.dict();
260 if (!surfaceDict.
found(
"extractionMethod"))
280 "intersectionMethod",
296 loader.select(surfaceDict.
get<
wordRes>(
"surfaces"));
306 if (loader.selected().empty())
309 <<
"No surfaces specified/found for entry: " 313 Info<<
"Surfaces : ";
314 if (loader.selected().size() == 1)
316 Info<< loader.selected().first() <<
nl;
337 Info<<
"Load options : " 340 <<
" writeObj=" << writeObj
343 scalar scaleFactor = -1;
345 if (surfaceDict.
readIfPresent(
"scale", scaleFactor) && scaleFactor > 0)
347 Info<<
"Scaling : " << scaleFactor <<
nl;
352 if (!surfPtr || surfPtr->
empty())
355 <<
"Problem loading surface(s) for entry: " 362 <<
"Statistics:" <<
nl;
372 faces[fi] = surf[fi];
388 if ((subDictPtr = surfaceDict.
findDict(
"trimFeatures")) !=
nullptr)
392 const scalar minLen =
394 const label minElem =
398 if (minLen > 0 || minElem > 0)
402 Info<<
"Removing features of length < " 407 Info<<
"Removing features with number of edges < " 411 features().trimFeatures
413 minLen, minElem, extractor().includedAngle()
425 if ((subDictPtr = surfaceDict.
findDict(
"subsetFeatures")) !=
nullptr)
434 Info<<
"Subset edges inside box " << bb <<
endl;
435 features().subsetBox(edgeStat, bb);
440 Info<<
"Dumping bounding box " << bb
441 <<
" as lines to obj file " 450 Info<<
"Exclude edges outside box " << bb <<
endl;
451 features().excludeBox(edgeStat, bb);
456 Info<<
"Dumping bounding box " << bb
457 <<
" as lines to obj file " 467 Info<<
"Removing all non-manifold edges" 468 <<
" (edges with > 2 connected faces) unless they" 469 <<
" cross multiple regions" <<
endl;
471 features().checkFlatRegionEdge
475 extractor().includedAngle()
482 Info<<
"Removing all open edges" 483 <<
" (edges with 1 connected face)" <<
endl;
485 features().excludeOpen(edgeStat);
489 if (subsetDict.
found(
"plane"))
493 Info<<
"Only include feature edges that intersect the plane" 494 <<
" with normal " << cutPlane.normal()
495 <<
" and origin " << cutPlane.origin() <<
endl;
497 features().subsetPlane(edgeStat, cutPlane);
502 newSet.setFromStatus(edgeStat, extractor().includedAngle());
505 newSet.writeStats(
Info);
508 if (surfaceDict.
found(
"baffles"))
520 for (
const label
patchId : indices)
522 surfBaffleRegions[
patchId] =
true;
527 Info<<
"Adding " << indices.size() <<
" baffle regions: (";
529 forAll(surfBaffleRegions, patchi)
531 if (surfBaffleRegions[patchi])
550 if ((subDictPtr = surfaceDict.
findDict(
"addFeatures")) !=
nullptr)
552 const dictionary& addFeaturesDict = *subDictPtr;
554 const word addFeName = addFeaturesDict.
get<
word>(
"name");
556 Info<<
"Adding (without merging) features from " << addFeName
565 "extendedFeatureEdgeMesh",
571 Info<<
"Read " << addFeMesh.name() <<
nl;
574 feMesh.add(addFeMesh);
585 intersect.mergePoints(10*SMALL);
589 intersect.cutPoints().size(),
590 intersect.cutEdges().size()
593 if (intersect.cutEdges().size())
597 intersect.cutPoints(),
603 sizeInfo[0] = addMesh.points().size();
604 sizeInfo[1] = addMesh.edges().size();
610 <<
" points : " << sizeInfo[0] <<
nl 611 <<
" edges : " << sizeInfo[1] <<
nl;
617 Info<<
nl <<
"Writing extendedFeatureEdgeMesh to " 618 << feMesh.objectPath() <<
endl;
620 mkDir(feMesh.path());
649 Info<<
nl <<
"Writing featureEdgeMesh to " 650 << bfeMesh.objectPath() <<
endl;
652 bfeMesh.regIOobject::write();
658 const bool optCloseness =
661 const bool optProximity =
664 const bool optCurvature =
674 if (optCloseness || optProximity || optCurvature)
691 Info<<
"Writing VTK to " 717 vtkWriter->
write(
"internalCloseness", tcloseness[0]());
718 vtkWriter->
write(
"externalCloseness", tcloseness[1]());
725 const scalar maxProximity =
726 surfaceDict.
getOrDefault<scalar>(
"maxFeatureProximity", 1);
741 vtkWriter->
write(
"featureProximity", tproximity());
759 vtkWriter->
write(
"curvature", tcurvature());
ITstream & lookup(const word &keyword, enum keyType::option matchOpt=keyType::REGEX) const
Find and return an entry data stream. FatalIOError if not found, or not a stream. ...
static void noFunctionObjects(bool addWithOption=false)
Remove '-noFunctionObjects' option and ignore any occurrences.
static void addNote(const string ¬e)
Add extra notes for the usage information.
void size(const label n)
Older name for setAddressableSize.
fileName constantPath() const
Return constant path.
A class for handling file names.
errorManipArg< error, int > exit(error &err, const int errNo=1)
virtual Ostream & write(const char c) override
Write character.
void writeStats(Ostream &os) const
Write some statistics.
error FatalError
Error stream (stdout output on all processes), with additional 'FOAM FATAL ERROR' header text and sta...
A list of keyword definitions, which are a keyword followed by a number of values (eg...
#define FatalErrorInFunction
Report an error message using Foam::FatalError.
virtual const fileName & name() const override
Read/write access to the name of the stream.
const word & name() const noexcept
Return the object name.
Unit conversion functions.
constexpr char nl
The newline '\n' character (0x0a)
Basic surface-surface intersection description. Constructed from two surfaces it creates a descriptio...
Description of feature edges and points.
bool empty() const noexcept
True if List is empty (ie, size() is zero)
Write faces/points (optionally with fields) as a vtp file or a legacy vtk file.
const word dictName("faMeshDefinition")
Ostream & endl(Ostream &os)
Add newline and flush stream.
A simple wrapper around bool so that it can be read as a word: true/false, on/off, yes/no, any/none. Also accepts 0/1 as a string and shortcuts t/f, y/n.
fileName relativePath(const fileName &input, const bool caseTag=false) const
Return the input relative to the globalPath by stripping off a leading value of the globalPath...
static void noParallel()
Remove the parallel options.
Ignore writing from objectRegistry::writeObject()
Geometric class that creates a 3D plane and can return the intersection point between a line and the ...
T get(const word &keyword, enum keyType::option matchOpt=keyType::REGEX) const
Find and return a T. FatalIOError if not found, or if the number of tokens is incorrect.
void write(const word &fieldName, const UList< Type > &field)
Write primitive field of CellData (Poly or Line) or PointData values.
void add(const extendedEdgeMesh &fem)
Add extendedEdgeMesh. No filtering of duplicates.
EnumType getOrDefault(const word &key, const dictionary &dict, const EnumType deflt, const bool warnOnly=false) const
Find the key in the dictionary and return the corresponding enumeration element based on its name...
"offset" = Offset regions per file
bool found(const word &keyword, enum keyType::option matchOpt=keyType::REGEX) const
Find an entry (const access) with the given keyword.
IOdictionary is derived from dictionary and IOobject to give the dictionary automatic IO functionalit...
#define forAll(list, i)
Loop across all elements in list.
void reset(T *p=nullptr) noexcept
Delete managed object and set to new given pointer.
Helper class to search on triSurface.
virtual bool beginPointData(label nFields=0)
Begin PointData for specified number of fields.
const geometricSurfacePatchList & patches() const noexcept
word outputName("finiteArea-edges.obj")
const dimensionedScalar e
Elementary charge.
void setSize(const label n)
Alias for resize()
bool mkDir(const fileName &pathName, mode_t mode=0777)
Make a directory and return an error if it could not be created.
bool has_ext() const
Various checks for extensions.
A class for handling words, derived from Foam::string.
const Time & time() const noexcept
Return time registry.
Self-intersection, region-wise only.
wordList patchNames(nPatches)
word lessExt() const
Return word without extension (part before last .)
A List of wordRe with additional matching capabilities.
static void addOption(const word &optName, const string ¶m="", const string &usage="", bool advanced=false)
Add an option to validOptions with usage information.
const Field< point_type > & points() const noexcept
Return reference to global points.
virtual bool beginCellData(label nFields=0)
Begin CellData output section for specified number of fields.
An OFstream that keeps track of vertices and provides convenience output methods for OBJ files...
const word & constant() const noexcept
Return constant name.
bool readIfPresent(const word &keyword, T &val, enum keyType::option matchOpt=keyType::REGEX) const
Find an entry if present, and assign to T val. FatalIOError if it is found and the number of tokens i...
OBJstream os(runTime.globalPath()/outputName)
Ostream & printExecutionTime(OSstream &os) const
Print the elapsed ExecutionTime (cpu-time), ClockTime.
"file" = One region for each file
loadingOption
The file loading options for triSurfaceLoader.
Standard boundBox with extra functionality for use in octree.
messageStream Info
Information stream (stdout output on master, null elsewhere)
intersectionType
Surface intersection types for classify, doCutEdges.
None = invalid (for input only)
Pointer management similar to std::unique_ptr, with some additional methods and type checking...
T getOrDefault(const word &keyword, const T &deflt, enum keyType::option matchOpt=keyType::REGEX) const
Find and return a T, or return the given default value. FatalIOError if it is found and the number of...
virtual bool writeGeometry()
Write patch topology.
void writeVTK(OFstream &os, const Type &value)
A class for managing temporary objects.
const fileName & output() const noexcept
The current output file name.
Convenience class for loading single or multiple surface files from the constant/triSurface (or other...
Triangulated surface description with patch information.
static const Enum< loadingOption > loadingOptionNames
The loading enumeration names.
Defines the attributes of an object for which implicit objectRegistry management is supported...
Do not request registration (bool: false)
Holds feature edges/points of surface.
A keyword and a list of tokens is an 'entry'.
static const Enum< intersectionType > selfIntersectionNames
The user-selectable self-intersection enumeration names.
FlatOutput::OutputAdaptor< Container, Delimiters > flatOutput(const Container &obj, Delimiters delim)
Global flatOutput() function with specified output delimiters.
const dictionary * findDict(const word &keyword, enum keyType::option matchOpt=keyType::REGEX) const
Find and return a sub-dictionary pointer if present (and it is a dictionary) otherwise return nullptr...