49 const Switch& geometricTestOnly
57 Info<<
nl <<
"Reading existing feature edges from file "
58 << featureEdgeFile <<
nl
59 <<
"Selecting edges purely based on geometric tests: "
79 const Switch& geometricTestOnly,
80 const scalar includedAngle
84 <<
"Constructing feature set from included angle "
85 << includedAngle <<
nl
86 <<
"Selecting edges purely based on geometric tests: "
108 const scalar includedAngle
121 if (fileNames.found(surfaceFileName))
123 return extractFromFile
125 fileNames[surfaceFileName],
132 return extractFromSurface
142 return extractFromSurface
161 Info<<
"Surface : " << surfaceFileName <<
nl <<
endl;
172 const Switch featureProximity =
176 Info<<
nl <<
"Feature line extraction is only valid on closed manifold "
177 <<
"surfaces." <<
endl;
199 const scalar includedAngle =
226 if (minElem > 0 || minLen > 0)
228 Info<<
"Removing features of length < "
230 Info<<
"Removing features with number of edges < "
233 set().trimFeatures(minLen, minElem, includedAngle);
251 if (subsetDict.
found(
"insideBox"))
255 Info<<
indent <<
"Selecting edges inside bb " << bb;
258 Info <<
" see insideBox.obj";
259 bb.writeOBJ(
"insideBox.obj");
265 else if (subsetDict.
found(
"outsideBox"))
269 Info<<
"Removing all edges inside bb " << bb;
272 Info<<
" see outsideBox.obj" <<
endl;
273 bb.writeOBJ(
"outsideBox.obj");
280 const Switch nonManifoldEdges =
283 if (!nonManifoldEdges)
285 Info<<
"Removing all non-manifold edges"
286 <<
" (edges with > 2 connected faces) unless they"
287 <<
" cross multiple regions" <<
endl;
297 Info<<
"Removing all open edges"
298 <<
" (edges with 1 connected face)" <<
endl;
309 if (subsetDict.
found(
"plane"))
315 Info<<
"Only edges that intersect the plane with normal "
317 <<
" and base point " << cutPlane.refPoint()
318 <<
" will be included as feature edges."<<
endl;
324 newSet.setFromStatus(edgeStat, includedAngle);
327 <<
"Initial feature set:" <<
nl
328 <<
" feature points : " << newSet.featurePoints().size() <<
nl
329 <<
" feature edges : " << newSet.featureEdges().size() <<
nl
331 <<
" region edges : " << newSet.nRegionEdges() <<
nl
332 <<
" external edges : " << newSet.nExternalEdges() <<
nl
333 <<
" internal edges : " << newSet.nInternalEdges() <<
nl
348 surfBaffleRegions[pI] =
true;
357 sFeatFileName +
".extendedFeatureEdgeMesh",
365 Info<<
"Adding (without merging) features from " << addFeName
374 "extendedFeatureEdgeMesh",
380 Info<<
"Read " << addFeMesh.name() <<
nl;
381 addFeMesh.writeStats(
Info);
383 feMesh.add(addFeMesh);
388 <<
"Final feature set:" <<
nl;
389 feMesh.writeStats(
Info);
391 Info<<
nl <<
"Writing extendedFeatureEdgeMesh to "
392 << feMesh.relativeObjectPath() <<
endl;
394 mkDir(feMesh.path());
424 Info<<
nl <<
"Writing featureEdgeMesh to "
425 << bfeMesh.relativeObjectPath() <<
endl;
427 bfeMesh.regIOobject::write();
431 boolList writeVTKFieldIsPointValues;
432 #define DeclareWriteVTKFieldTypeValues(Type, nullArg) \
433 PtrList<const Field<Type>> writeVTKField##Type##Values;
435 #undef DeclareWriteVTKFieldTypeValues
440 Info<<
nl <<
"Extracting internal and external closeness of "
441 <<
"surface." <<
endl;
445 const Switch faceCloseness =
447 const Switch pointCloseness =
450 const scalar internalAngleTolerance
454 "internalAngleTolerance",
460 const scalar externalAngleTolerance
464 "externalAngleTolerance",
475 sFeatFileName +
".closeness",
487 searchSurf.extractCloseness
489 internalAngleTolerance,
490 externalAngleTolerance
495 << closenessFields.first()->name() <<
endl;
496 closenessFields.first()->
write();
499 << closenessFields.second()->name() <<
endl;
500 closenessFields.second()->
write();
504 writeVTKFieldNames.
append(
"internalCloseness");
505 writeVTKFieldIsPointValues.
append(
false);
506 writeVTKFieldscalarValues.append
511 writeVTKFieldNames.
append(
"externalCloseness");
512 writeVTKFieldIsPointValues.
append(
false);
513 writeVTKFieldscalarValues.append
524 searchSurf.extractPointCloseness
526 internalAngleTolerance,
527 externalAngleTolerance
532 << closenessFields.first()->name() <<
endl;
533 closenessFields.first()->
write();
536 << closenessFields.second()->name() <<
endl;
537 closenessFields.second()->
write();
541 const faceList faces(searchSurf.faces());
542 const Map<label>& meshPointMap = searchSurf.meshPointMap();
545 internalClosenessPointField = closenessFields.
first();
548 externalClosenessPointField = closenessFields.second();
550 scalarField internalCloseness(searchSurf.nPoints(), great);
551 scalarField externalCloseness(searchSurf.nPoints(), great);
555 internalCloseness[
pi] =
556 internalClosenessPointField[meshPointMap[
pi]];
558 externalCloseness[
pi] =
559 externalClosenessPointField[meshPointMap[
pi]];
562 writeVTKFieldNames.
append(
"internalPointCloseness");
563 writeVTKFieldIsPointValues.
append(
true);
564 writeVTKFieldscalarValues.append
569 writeVTKFieldNames.
append(
"externalPointCloseness");
570 writeVTKFieldIsPointValues.
append(
true);
571 writeVTKFieldscalarValues.append
582 Info<<
nl <<
"Extracting curvature of surface at the points."
589 sFeatFileName +
".curvature",
601 writeVTKFieldNames.
append(
"curvature");
602 writeVTKFieldIsPointValues.
append(
true);
608 if (featureProximity)
610 Info<<
nl <<
"Extracting proximity of close feature points and "
611 <<
"edges to the surface" <<
endl;
613 const scalar searchDistance =
624 if (crSqr.
second() < 0)
continue;
627 const scalar rSqr =
min(16*crSqr.
second(),
sqr(searchDistance));
631 feMesh.allNearestFeatureEdges(
c, rSqr, hitList);
632 featureProximity[fi] =
min
634 feMesh.minDisconnectedDist(hitList),
638 feMesh.allNearestFeaturePoints(
c, rSqr, hitList);
639 featureProximity[fi] =
min
650 sFeatFileName +
".featureProximity",
660 featureProximityField.write();
664 writeVTKFieldNames.
append(
"featureProximity");
665 writeVTKFieldIsPointValues.
append(
false);
666 writeVTKFieldscalarValues.append
675 #define WriteVTKResizeFieldTypeValues(Type, nullArg) \
676 writeVTKField##Type##Values.resize(writeVTKFieldNames.size());
678 #undef WriteVTKResizeFieldTypeValues
685 /sFeatFileName +
"Features.vtk",
693 writeVTKFieldIsPointValues,
695 #define WriteVTKFieldTypeValuesParameter(Type, nullArg) \
698 #undef WriteVTKFieldTypeValuesParameter
713 forAll(surfaceFileNames, i)
715 extractFeatures(surfaceFileNames[i], runTime,
dict);
723 int main(
int argc,
char *argv[])
727 "extract and write surface features to file"
751 if (!iter().isDict())
#define forAll(list, i)
Loop across all elements in list.
#define forAllConstIter(Container, container, iter)
Iterate across all elements in the container object of type.
An STL-conforming hash table.
A primitive field of type <Type> with automated input and output.
IOobject defines the attributes of an object for which implicit objectRegistry management is supporte...
void append(const T &)
Append an element at the end of the list.
void size(const label)
Override size to be inconsistent with allocated storage.
virtual Ostream & write(const token &)
Write token.
An ordered pair of two objects of type <Type> with first() and second() elements.
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,...
const char * asText() const
Return a text representation of the Switch.
static const word & constant()
Return constant name.
Class to control time during OpenFOAM simulations that is also the top-level objectRegistry.
fileName path() const
Explicitly inherit path from TimePaths to disambiguate from.
IOstream::streamFormat writeFormat() const
Default write format.
A 2-tuple for storing two objects of different types.
const Type2 & second() const
Return second.
const Type1 & first() const
Return first.
T & first()
Return the first element of the list.
A templated 1D list of pointers to objects of type <T>, where the size of the array is known and used...
static void addNote(const string &)
Add extra notes for the usage information.
static void noParallel()
Remove the parallel options.
An auto-pointer similar to the STL auto_ptr but with automatic casting to a reference to the type and...
time_t elapsedClockTime() const
Returns wall-clock time from clock instantiation.
double elapsedCpuTime() const
Return CPU time (in seconds) from the start.
A list of keywords followed by any number of values (e.g. words and numbers) or sub-dictionaries.
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.
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.
const dictionary & subDict(const word &) const
Find and return a sub-dictionary.
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.
Points connected by edges.
A class for handling file names.
word name() const
Return file name (part beyond last /)
fileName lessExt() const
Return file name without extension (part before last .)
const Time & time() const
Return time.
Geometric class that creates a 2D plane and can return the intersection point between a line and the ...
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.
label size() const
Return size.
Triangulated surface description with patch information.
tmp< scalarField > curvature() const
Return the curvature of surface at the points.
const geometricSurfacePatchList & patches() const
void writeStats(Ostream &) const
Write some statistics.
faceList faces() const
Return the list of triangles as a faceList.
A triangle primitive used to calculate face areas and swept volumes.
Tuple2< Point, scalar > circumCircleSqr() const
Return the circum-centre and radius-squared.
A class for handling words, derived from string.
int main(int argc, char *argv[])
const dimensionedScalar c
Speed of light in a vacuum.
const unitSet & lookup(const word &unitName)
Lookup and return the named unit from the table.
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.
List< fileName > fileNameList
A List of fileNames.
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.
bool mkDir(const fileName &, mode_t=0777)
Make a directory and return an error if it could not be created.
Ostream & endl(Ostream &os)
Add newline and flush stream.
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)
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.
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 ®ionName=polyMesh::defaultRegion, const fileName &path=fileName::null)
Ostream & indent(Ostream &os)
Indent stream.
Foam::argList args(argc, argv)