Go to the documentation of this file.
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];
385 if (surfaceDict.
isDict(
"trimFeatures"))
389 const scalar minLen =
391 const label minElem =
395 if (minLen > 0 || minElem > 0)
399 Info<<
"Removing features of length < "
404 Info<<
"Removing features with number of edges < "
408 features().trimFeatures
410 minLen, minElem, extractor().includedAngle()
422 if (surfaceDict.
isDict(
"subsetFeatures"))
430 if (subsetDict.
found(
"insideBox"))
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 "
448 else if (subsetDict.
found(
"outsideBox"))
452 Info<<
"Exclude edges outside box " << bb <<
endl;
453 features().excludeBox(edgeStat, bb);
458 Info<<
"Dumping bounding box " << bb
459 <<
" as lines to obj file "
469 Info<<
"Removing all non-manifold edges"
470 <<
" (edges with > 2 connected faces) unless they"
471 <<
" cross multiple regions" <<
endl;
473 features().checkFlatRegionEdge
477 extractor().includedAngle()
484 Info<<
"Removing all open edges"
485 <<
" (edges with 1 connected face)" <<
endl;
487 features().excludeOpen(edgeStat);
491 if (subsetDict.
found(
"plane"))
495 Info<<
"Only include feature edges that intersect the plane"
496 <<
" with normal " << cutPlane.normal()
497 <<
" and origin " << cutPlane.origin() <<
endl;
499 features().subsetPlane(edgeStat, cutPlane);
504 newSet.setFromStatus(edgeStat, extractor().includedAngle());
507 newSet.writeStats(
Info);
510 if (surfaceDict.
found(
"baffles"))
522 for (
const label
patchId : indices)
524 surfBaffleRegions[
patchId] =
true;
529 Info<<
"Adding " << indices.size() <<
" baffle regions: (";
531 forAll(surfBaffleRegions, patchi)
533 if (surfBaffleRegions[patchi])
552 if (surfaceDict.
isDict(
"addFeatures"))
559 Info<<
"Adding (without merging) features from " << addFeName
568 "extendedFeatureEdgeMesh",
574 Info<<
"Read " << addFeMesh.name() <<
nl;
577 feMesh.add(addFeMesh);
588 intersect.mergePoints(10*SMALL);
592 intersect.cutPoints().size(),
593 intersect.cutEdges().size()
596 if (intersect.cutEdges().size())
600 intersect.cutPoints(),
606 sizeInfo[0] = addMesh.points().size();
607 sizeInfo[1] = addMesh.edges().size();
613 <<
" points : " << sizeInfo[0] <<
nl
614 <<
" edges : " << sizeInfo[1] <<
nl;
620 Info<<
nl <<
"Writing extendedFeatureEdgeMesh to "
621 << feMesh.objectPath() <<
endl;
623 mkDir(feMesh.path());
652 Info<<
nl <<
"Writing featureEdgeMesh to "
653 << bfeMesh.objectPath() <<
endl;
655 bfeMesh.regIOobject::write();
661 const bool optCloseness =
664 const bool optProximity =
667 const bool optCurvature =
677 if (optCloseness || optProximity || optCurvature)
692 vtkWriter->writeGeometry();
694 Info<<
"Writing VTK to "
719 vtkWriter->beginCellData();
720 vtkWriter->write(
"internalCloseness", tcloseness[0]());
721 vtkWriter->write(
"externalCloseness", tcloseness[1]());
728 const scalar maxProximity =
729 surfaceDict.
getOrDefault<scalar>(
"maxFeatureProximity", 1);
743 vtkWriter->beginCellData();
744 vtkWriter->write(
"featureProximity", tproximity());
761 vtkWriter->beginPointData();
762 vtkWriter->write(
"curvature", tcurvature());
void writeStats(Ostream &os) const
const Field< point_type > & points() const noexcept
A keyword and a list of tokens is an 'entry'.
IOdictionary is derived from dictionary and IOobject to give the dictionary automatic IO functionalit...
Defines the attributes of an object for which implicit objectRegistry management is supported,...
A simple wrapper around bool so that it can be read as a word: true/false, on/off,...
A class for handling words, derived from Foam::string.
A class for handling file names.
OFstream that keeps track of vertices.
virtual const fileName & name() const
A class for managing temporary objects.
bool found(const word &keyword, enum keyType::option matchOpt=keyType::REGEX) const
Standard boundBox with extra functionality for use in octree.
const word dictName("faMeshDefinition")
static const Enum< loadingOption > loadingOptionNames
static void addNote(const string ¬e)
Unit conversion functions.
Ostream & endl(Ostream &os)
T get(const word &keyword, enum keyType::option matchOpt=keyType::REGEX) const
virtual Ostream & write(const char c)
const geometricSurfacePatchList & patches() const noexcept
Helper class to search on triSurface.
fileName constantPath() const
bool empty() const noexcept
@ FILE_REGION
"file" = One region for each file
void writeVTK(OFstream &os, const Type &value)
Geometric class that creates a 3D plane and can return the intersection point between a line and the ...
word outputName("finiteArea-edges.obj")
Ostream & printExecutionTime(OSstream &os) const
fileName relativePath(const fileName &input, const bool caseTag=false) const
static void noFunctionObjects(bool addWithOption=false)
Basic surface-surface intersection description. Constructed from two surfaces it creates a descriptio...
Triangulated surface description with patch information.
void setSize(const label n)
EnumType getOrDefault(const word &key, const dictionary &dict, const EnumType deflt, const bool failsafe=false) const
@ NONE
None = invalid (for input only)
const dictionary & subDict(const word &keyword, enum keyType::option matchOpt=keyType::REGEX) const
Holds feature edges/points of surface.
wordList patchNames(nPatches)
ITstream & lookup(const word &keyword, enum keyType::option matchOpt=keyType::REGEX) const
A list of keyword definitions, which are a keyword followed by a number of values (eg,...
OBJstream os(runTime.globalPath()/outputName)
FlatOutput::OutputAdaptor< Container, Delimiters > flatOutput(const Container &obj, Delimiters delim)
Convenience class for loading single or multiple surface files from the constant/triSurface (or other...
errorManipArg< error, int > exit(error &err, const int errNo=1)
bool isDict(const word &keyword, enum keyType::option matchOpt=keyType::REGEX) const
void reset(autoPtr< T > &&other) noexcept
const word & name() const noexcept
Pointer management similar to std::unique_ptr, with some additional methods and type checking.
Description of feature edges and points.
@ SELF_REGION
Self-intersection, region-wise only.
#define FatalErrorInFunction
An ordered pair of two objects of type <T> with first() and second() elements.
Write faces/points (optionally with fields) as a vtp file or a legacy vtk file.
A 1D array of objects of type <T>, where the size of the vector is known and used for subscript bound...
const dimensionedScalar e
A List of wordRe with additional matching capabilities.
@ OFFSET_REGION
"offset" = Offset regions per file
const word & constant() const
T getOrDefault(const word &keyword, const T &deflt, enum keyType::option matchOpt=keyType::REGEX) const
static void addOption(const word &optName, const string ¶m="", const string &usage="", bool advanced=false)
bool mkDir(const fileName &pathName, mode_t mode=0777)
const Time & time() const noexcept
bool readIfPresent(const word &keyword, T &val, enum keyType::option matchOpt=keyType::REGEX) const
static const Enum< intersectionType > selfIntersectionNames