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() || dEntry.keyword().isPattern())
255 const dictionary& surfaceDict = dEntry.dict();
257 if (!surfaceDict.
found(
"extractionMethod"))
277 "intersectionMethod",
293 loader.select(surfaceDict.
get<
wordRes>(
"surfaces"));
303 if (loader.selected().empty())
306 <<
"No surfaces specified/found for entry: "
310 Info<<
"Surfaces : ";
311 if (loader.selected().size() == 1)
313 Info<< loader.selected().first() <<
nl;
319 Info<<
"Output : " << outputName <<
nl;
334 Info<<
"Load options : "
337 <<
" writeObj=" << writeObj
340 scalar scaleFactor = -1;
342 if (surfaceDict.
readIfPresent(
"scale", scaleFactor) && scaleFactor > 0)
344 Info<<
"Scaling : " << scaleFactor <<
nl;
352 <<
"Problem loading surface(s) for entry: "
359 <<
"Statistics:" <<
nl;
369 faces[fi] = surf[fi];
382 if (surfaceDict.
isDict(
"trimFeatures"))
386 const scalar minLen =
388 const label minElem =
392 if (minLen > 0 || minElem > 0)
396 Info<<
"Removing features of length < "
401 Info<<
"Removing features with number of edges < "
405 features().trimFeatures
407 minLen, minElem, extractor().includedAngle()
419 if (surfaceDict.
isDict(
"subsetFeatures"))
427 if (subsetDict.
found(
"insideBox"))
431 Info<<
"Subset edges inside box " << bb <<
endl;
432 features().subsetBox(edgeStat, bb);
437 Info<<
"Dumping bounding box " << bb
438 <<
" as lines to obj file "
439 << os.name() <<
endl;
445 else if (subsetDict.
found(
"outsideBox"))
449 Info<<
"Exclude edges outside box " << bb <<
endl;
450 features().excludeBox(edgeStat, bb);
455 Info<<
"Dumping bounding box " << bb
456 <<
" as lines to obj file "
457 << os.name() <<
endl;
466 Info<<
"Removing all non-manifold edges"
467 <<
" (edges with > 2 connected faces) unless they"
468 <<
" cross multiple regions" <<
endl;
470 features().checkFlatRegionEdge
474 extractor().includedAngle()
481 Info<<
"Removing all open edges"
482 <<
" (edges with 1 connected face)" <<
endl;
484 features().excludeOpen(edgeStat);
488 if (subsetDict.
found(
"plane"))
492 Info<<
"Only include feature edges that intersect the plane"
493 <<
" with normal " << cutPlane.normal()
494 <<
" and origin " << cutPlane.origin() <<
endl;
496 features().subsetPlane(edgeStat, cutPlane);
501 newSet.setFromStatus(edgeStat, extractor().includedAngle());
504 newSet.writeStats(
Info);
507 if (surfaceDict.
found(
"baffles"))
519 for (
const label
patchId : indices)
521 surfBaffleRegions[
patchId] =
true;
526 Info<<
"Adding " << indices.size() <<
" baffle regions: (";
528 forAll(surfBaffleRegions, patchi)
530 if (surfBaffleRegions[patchi])
544 outputName +
".extendedFeatureEdgeMesh",
549 if (surfaceDict.
isDict(
"addFeatures"))
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());
624 feMesh.writeObj(feMesh.path()/outputName);
637 outputName +
".eMesh",
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)
684 (vtkOutputDir / outputName),
691 Info<<
"Writing VTK to "
714 if (vtkWriter.
valid())
717 vtkWriter->
write(
"internalCloseness", tcloseness[0]());
718 vtkWriter->
write(
"externalCloseness", tcloseness[1]());
725 const scalar maxProximity =
726 surfaceDict.
getOrDefault<scalar>(
"maxFeatureProximity", 1);
738 if (vtkWriter.
valid())
741 vtkWriter->
write(
"featureProximity", tproximity());
756 if (vtkWriter.
valid())
759 vtkWriter->
write(
"curvature", tcurvature());
void writeStats(Ostream &os) const
Write some statistics.
A keyword and a list of tokens is an 'entry'.
word lessExt() const
Return word without extension (part before last .)
IOdictionary is derived from dictionary and IOobject to give the dictionary automatic IO functionalit...
void reset(T *p=nullptr) noexcept
Delete managed object and set to new given pointer.
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,...
const word & name() const
Return name.
loadingOption
The file loading options for triSurfaceLoader.
A class for handling words, derived from Foam::string.
A class for handling file names.
OFstream that keeps track of vertices.
A class for managing temporary objects.
bool found(const word &keyword, enum keyType::option matchOpt=keyType::REGEX) const
Search for an entry (const access) with the given keyword.
virtual bool beginCellData(label nFields=0)
Begin CellData output section for specified number of fields.
Standard boundBox with extra functionality for use in octree.
const Time & time() const
Return time.
virtual bool writeGeometry()
Write patch topology.
static const Enum< loadingOption > loadingOptionNames
The loading enumeration names.
static void addNote(const string ¬e)
Add extra notes for the usage information.
const word dictName("blockMeshDict")
Unit conversion functions.
intersectionType
Surface intersection types for classify, doCutEdges.
bool valid() const noexcept
True if the managed pointer is non-null.
Ostream & endl(Ostream &os)
Add newline and flush stream.
T get(const word &keyword, enum keyType::option matchOpt=keyType::REGEX) const
const geometricSurfacePatchList & patches() const
Helper class to search on triSurface.
fileName constantPath() const
Return constant path.
bool empty() const noexcept
True if the managed pointer is null.
"file" = One region for each file
#define forAll(list, i)
Loop across all elements in list.
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 ...
Ostream & printExecutionTime(OSstream &os) const
Print the elapsed ExecutionTime (cpu-time), ClockTime.
fileName relativePath(const fileName &input, const bool caseTag=false) const
static void noFunctionObjects(bool addWithOption=false)
Remove '-noFunctionObjects' option and ignore any occurrences.
const fileName & output() const
The current output file name.
bool hasExt() const
Return true if it has an extension or simply ends with a '.'.
Basic surface-surface intersection description. Constructed from two surfaces it creates a descriptio...
Triangulated surface description with patch information.
messageStream Info
Information stream (uses stdout - output is on the master only)
void write(const word &fieldName, const UList< Type > &field)
Write a list of Cell (Face) or Point values.
EnumType getOrDefault(const word &key, const dictionary &dict, const EnumType deflt, const bool failsafe=false) const
None = invalid (for input only)
const dictionary & subDict(const word &keyword, enum keyType::option matchOpt=keyType::REGEX) const
Find and return a sub-dictionary.
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,...
const Field< point_type > & points() const
Return reference to global points.
virtual bool write(const token &tok)=0
Write token to stream or otherwise handle it.
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
Check if entry is found and is a sub-dictionary.
Pointer management similar to std::unique_ptr, with some additional methods and type checking.
Description of feature edges and points.
Self-intersection, region-wise only.
#define FatalErrorInFunction
Report an error message using Foam::FatalError.
FlatOutput< Container > flatOutput(const Container &obj, label len=0)
Global flatOutput function.
Write faces/points (optionally with fields) as a vtp file or a legacy vtk file.
void add(const extendedEdgeMesh &fem)
Add extendedEdgeMesh. No filtering of duplicates.
const dimensionedScalar e
Elementary charge.
A List of wordRe with additional matching capabilities.
virtual bool beginPointData(label nFields=0)
Begin PointData for specified number of fields.
static void noParallel()
Remove the parallel options.
"offset" = Offset regions per file
void setSize(const label newSize)
Alias for resize(const label)
const word & constant() const
Return constant name.
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)
Add an option to validOptions with usage information.
bool mkDir(const fileName &pathName, mode_t mode=0777)
Make a directory and return an error if it could not be created.
bool readIfPresent(const word &keyword, T &val, enum keyType::option matchOpt=keyType::REGEX) const
static const Enum< intersectionType > selfIntersectionNames
The user-selectable self-intersection enumeration names.