diff --git a/applications/test/surfaceIntersection/Make/files b/applications/test/surfaceIntersection/Make/files new file mode 100644 index 0000000000..e0516a472c --- /dev/null +++ b/applications/test/surfaceIntersection/Make/files @@ -0,0 +1,3 @@ +Test-surfaceIntersection.C + +EXE = $(FOAM_USER_APPBIN)/Test-surfaceIntersection diff --git a/applications/test/surfaceIntersection/Make/options b/applications/test/surfaceIntersection/Make/options new file mode 100644 index 0000000000..6ae6c04df1 --- /dev/null +++ b/applications/test/surfaceIntersection/Make/options @@ -0,0 +1,9 @@ +EXE_INC = \ + -I$(LIB_SRC)/finiteVolume/lnInclude \ + -I$(LIB_SRC)/edgeMesh/lnInclude \ + -I$(LIB_SRC)/meshTools/lnInclude \ + -I$(LIB_SRC)/triSurface/lnInclude + +EXE_LIBS = \ + -lfiniteVolume \ + -lmeshTools -ledgeMesh diff --git a/applications/test/surfaceIntersection/Test-surfaceIntersection.C b/applications/test/surfaceIntersection/Test-surfaceIntersection.C new file mode 100644 index 0000000000..8c0f83f641 --- /dev/null +++ b/applications/test/surfaceIntersection/Test-surfaceIntersection.C @@ -0,0 +1,234 @@ +/*---------------------------------------------------------------------------*\ + ========= | + \\ / F ield | OpenFOAM: The Open Source CFD Toolbox + \\ / O peration | + \\ / A nd | Copyright (C) 2017 OpenCFD Ltd. + \\/ M anipulation | +------------------------------------------------------------------------------- +License + This file is part of OpenFOAM. + + OpenFOAM is free software: you can redistribute it and/or modify it + under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + OpenFOAM is distributed in the hope that it will be useful, but WITHOUT + ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + for more details. + + You should have received a copy of the GNU General Public License + along with OpenFOAM. If not, see . + +Application + Test-surfaceIntersection + +Description + Test surface-surface intersection + +\*---------------------------------------------------------------------------*/ + +#include "argList.H" +#include "Time.H" +#include "triSurface.H" +#include "triSurfaceMesh.H" +#include "surfaceIntersection.H" +#include "OFstream.H" + +using namespace Foam; + +autoPtr loadSurface +( + const Foam::Time& runTime, + const fileName& surfName +) +{ + Info<< "Reading surface " << surfName << endl; + + const fileName fallback = + runTime.constantPath()/triSurfaceMesh::meshSubDir/surfName; + + autoPtr surfPtr; + if (isFile(surfName)) + { + surfPtr.set(new triSurface(surfName)); + } + else if (isFile(fallback)) + { + surfPtr.set(new triSurface(fallback)); + } + else + { + FatalErrorInFunction + << "No such file:" << surfName << exit(FatalError); + } + + return surfPtr; +} + + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +int main(int argc, char *argv[]) +{ + argList::addNote + ( + "Intersection of two surfaces. Writes obj file" + ); + argList::addBoolOption + ( + "debug2", + "set surfaceIntersection debug=2" + ); + argList::addBoolOption + ( + "debug4", + "set surfaceIntersection debug=4" + ); + argList::addBoolOption + ( + "print", + "print information about cuts, etc" + ); + argList::addBoolOption + ( + "mergeEdges", + "merge duplicate edges" + ); + argList::addOption + ( + "mergePoints", + "mergeTol", + "merge points (and edges) using the specified tolerance" + ); + + #include "addDictOption.H" + + argList::addNote + ( + "test intersect of two surfaces. Writes obj file" + ); + argList::noParallel(); + argList::noFunctionObjects(); + argList::validArgs.append("surface file"); + argList::validArgs.append("surface file"); + + #include "setRootCase.H" + #include "createTime.H" + + const word outputFile(args.executable() + ".obj"); + + const fileName surf1Name(args[1]); + triSurface surf1 = loadSurface(runTime, surf1Name)(); + Info<< surf1Name << " statistics:" << endl; + surf1.writeStats(Info); + Info<< endl; + + const fileName surf2Name(args[2]); + triSurface surf2 = loadSurface(runTime, surf2Name)(); + Info<< surf2Name << " statistics:" << endl; + surf2.writeStats(Info); + Info<< endl; + + + if (args.optionFound("debug2")) + { + surfaceIntersection::debug |= 2; + } + if (args.optionFound("debug4")) + { + surfaceIntersection::debug |= 4; + } + const bool optPrint = args.optionFound("print"); + + dictionary intersectOptions; + if (args.optionFound("dict")) + { + intersectOptions = IOdictionary + ( + IOobject + ( + args["dict"], + runTime, + IOobject::MUST_READ_IF_MODIFIED, + IOobject::NO_WRITE + ) + ); + } + + intersectOptions.writeEntry("intersectOptions", Info); + Info<< endl; + + triSurfaceSearch query1(surf1); + triSurfaceSearch query2(surf2); + surfaceIntersection cuts(query1, query2, intersectOptions); + + Info<<"intersection " + << cuts.cutPoints().size() << " points " + << cuts.cutEdges().size() << " edges" << nl; + + if (optPrint) + { + Info<< "surf1-cuts: " << cuts.surf1EdgeCuts() << nl + << "surf2-cuts: " << cuts.surf2EdgeCuts() << nl + << "face-pairs: " << cuts.facePairToEdge() << nl + << "edges: " << cuts.cutEdges() << nl; + } + + word mergeOp; + if (args.optionFound("mergePoints")) + { + cuts.mergePoints(args.optionRead("mergePoints")); + mergeOp = "mergePoints"; + } + else if (args.optionFound("mergeEdges")) + { + cuts.mergeEdges(); + mergeOp = "mergeEdges"; + } + + if (!mergeOp.empty()) + { + Info<< mergeOp << ": " + << cuts.cutPoints().size() << " points " + << cuts.cutEdges().size() << " edges" << nl; + + if (optPrint) + { + Info<< "surf1-cuts: " << cuts.surf1EdgeCuts() << nl + << "surf2-cuts: " << cuts.surf2EdgeCuts() << nl + << "face-pairs: " << cuts.facePairToEdge() << nl + << "edges: " << cuts.cutEdges() << nl; + } + } + + const pointField& points = cuts.cutPoints(); + const edgeList& edges = cuts.cutEdges(); + + if (points.size() || edges.size()) + { + Info<<"write to " << outputFile << nl; + + OFstream os(outputFile); + + forAll(points, pointi) + { + const point& pt = points[pointi]; + os << "v " << pt.x() << ' ' << pt.y() << ' ' << pt.z() << nl; + } + + forAll(edges, edgei) + { + const edge& e = edges[edgei]; + os << "l " << e.start()+1 << ' ' << e.end()+1 << nl; + } + } + + Info<< "End\n" << endl; + + return 0; +} + + +// ************************************************************************* // diff --git a/applications/utilities/surface/surfaceFeatureExtract/Allwclean b/applications/utilities/surface/surfaceFeatureExtract/Allwclean new file mode 100755 index 0000000000..421b6686c4 --- /dev/null +++ b/applications/utilities/surface/surfaceFeatureExtract/Allwclean @@ -0,0 +1,7 @@ +#!/bin/sh +cd ${0%/*} || exit 1 # Run from this directory + +wclean libso extractionMethod +wclean . + +#------------------------------------------------------------------------------ diff --git a/applications/utilities/surface/surfaceFeatureExtract/Allwmake b/applications/utilities/surface/surfaceFeatureExtract/Allwmake new file mode 100755 index 0000000000..ee26d27fc3 --- /dev/null +++ b/applications/utilities/surface/surfaceFeatureExtract/Allwmake @@ -0,0 +1,9 @@ +#!/bin/sh +cd ${0%/*} || exit 1 # Run from this directory + +# Parse arguments for library compilation +. $WM_PROJECT_DIR/wmake/scripts/AllwmakeParseArguments + +(wmake libso extractionMethod && wmake) + +#------------------------------------------------------------------------------ diff --git a/applications/utilities/surface/surfaceFeatureExtract/extractionMethod/Make/files b/applications/utilities/surface/surfaceFeatureExtract/extractionMethod/Make/files index 29dd2b73eb..8c9bb27660 100644 --- a/applications/utilities/surface/surfaceFeatureExtract/extractionMethod/Make/files +++ b/applications/utilities/surface/surfaceFeatureExtract/extractionMethod/Make/files @@ -1,6 +1,7 @@ method = . $(method)/surfaceFeaturesExtraction.C -$(method)/extractFromSurface.C $(method)/extractFromFile.C +$(method)/extractFromNone.C +$(method)/extractFromSurface.C LIB = $(FOAM_LIBBIN)/libsurfaceFeatureExtract diff --git a/applications/utilities/surface/surfaceFeatureExtract/extractionMethod/extractFromFile.C b/applications/utilities/surface/surfaceFeatureExtract/extractionMethod/extractFromFile.C index 437024fbac..d9fb9b1dde 100644 --- a/applications/utilities/surface/surfaceFeatureExtract/extractionMethod/extractFromFile.C +++ b/applications/utilities/surface/surfaceFeatureExtract/extractionMethod/extractFromFile.C @@ -24,7 +24,6 @@ License \*---------------------------------------------------------------------------*/ #include "extractFromFile.H" -#include "ListOps.H" #include "edgeMesh.H" #include "addToRunTimeSelectionTable.H" diff --git a/applications/utilities/surface/surfaceFeatureExtract/extractionMethod/extractFromNone.C b/applications/utilities/surface/surfaceFeatureExtract/extractionMethod/extractFromNone.C new file mode 100644 index 0000000000..887e9a4d65 --- /dev/null +++ b/applications/utilities/surface/surfaceFeatureExtract/extractionMethod/extractFromNone.C @@ -0,0 +1,81 @@ +/*---------------------------------------------------------------------------*\ + ========= | + \\ / F ield | OpenFOAM: The Open Source CFD Toolbox + \\ / O peration | + \\ / A nd | Copyright (C) 2017 OpenCFD Ltd. + \\/ M anipulation | +------------------------------------------------------------------------------- +License + This file is part of OpenFOAM. + + OpenFOAM is free software: you can redistribute it and/or modify it + under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + OpenFOAM is distributed in the hope that it will be useful, but WITHOUT + ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + for more details. + + You should have received a copy of the GNU General Public License + along with OpenFOAM. If not, see . + +\*---------------------------------------------------------------------------*/ + +#include "extractFromNone.H" +#include "addToRunTimeSelectionTable.H" + +// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * // + +namespace Foam +{ +namespace surfaceFeaturesExtraction +{ + addNamedToRunTimeSelectionTable + ( + method, + extractFromNone, + dictionary, + none + ); +} +} + + +// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * // + +Foam::surfaceFeaturesExtraction::extractFromNone::extractFromNone +( + const dictionary& dict +) +: + method() +{ + const dictionary& coeffDict = dict.subOrEmptyDict("extractFromNoneCoeffs"); + + coeffDict.readIfPresent("includedAngle", includedAngle_); + coeffDict.readIfPresent("geometricTestOnly", geometricTestOnly_); +} + + +// * * * * * * * * * * * * * * * * Destructor * * * * * * * * * * * * * * * // + +Foam::surfaceFeaturesExtraction::extractFromNone::~extractFromNone() +{} + + +// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * // + + +Foam::autoPtr +Foam::surfaceFeaturesExtraction::extractFromNone::features +( + const triSurface& surf +) const +{ + return autoPtr(new surfaceFeatures(surf)); +} + + +// ************************************************************************* // diff --git a/applications/utilities/surface/surfaceFeatureExtract/extractionMethod/extractFromNone.H b/applications/utilities/surface/surfaceFeatureExtract/extractionMethod/extractFromNone.H new file mode 100644 index 0000000000..da80a3c624 --- /dev/null +++ b/applications/utilities/surface/surfaceFeatureExtract/extractionMethod/extractFromNone.H @@ -0,0 +1,91 @@ +/*---------------------------------------------------------------------------*\ + ========= | + \\ / F ield | OpenFOAM: The Open Source CFD Toolbox + \\ / O peration | + \\ / A nd | Copyright (C) 2017 OpenCFD Ltd. + \\/ M anipulation | +------------------------------------------------------------------------------- +License + This file is part of OpenFOAM. + + OpenFOAM is free software: you can redistribute it and/or modify it + under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + OpenFOAM is distributed in the hope that it will be useful, but WITHOUT + ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + for more details. + + You should have received a copy of the GNU General Public License + along with OpenFOAM. If not, see . + +Class + Foam::surfaceFeaturesExtraction::extractFromNone + +Description + Run-time selectable surface feature extraction. + +SourceFiles + extractionMethod.C + +\*---------------------------------------------------------------------------*/ + +#ifndef surfaceFeaturesExtraction_extractFromNone_H +#define surfaceFeaturesExtraction_extractFromNone_H + +#include "surfaceFeaturesExtraction.H" +#include "dictionary.H" +#include "Switch.H" +#include "triSurface.H" +#include "edgeIntersections.H" + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +namespace Foam +{ +namespace surfaceFeaturesExtraction +{ + +/*---------------------------------------------------------------------------*\ + Class surfaceFeaturesExtraction::extractFromNone Declaration +\*---------------------------------------------------------------------------*/ + +class extractFromNone +: + public method +{ + +public: + + // Constructors + + //- Construct from dictionary + extractFromNone(const dictionary& dict); + + + //- Destructor + virtual ~extractFromNone(); + + + //- Extracted features from surface (no-op) + virtual autoPtr features + ( + const triSurface& surf + ) const override; + + +}; + + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +} // End namespace surfaceFeaturesExtraction +} // End namespace Foam + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +#endif + +// ************************************************************************* // diff --git a/applications/utilities/surface/surfaceFeatureExtract/extractionMethod/extractFromSurface.C b/applications/utilities/surface/surfaceFeatureExtract/extractionMethod/extractFromSurface.C index f590bb707a..6621d6c931 100644 --- a/applications/utilities/surface/surfaceFeatureExtract/extractionMethod/extractFromSurface.C +++ b/applications/utilities/surface/surfaceFeatureExtract/extractionMethod/extractFromSurface.C @@ -26,12 +26,6 @@ License #include "extractFromSurface.H" #include "addToRunTimeSelectionTable.H" -#include "triSurface.H" -#include "triSurfaceSearch.H" -#include "scalarField.H" -#include "edgeIntersections.H" - - // * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * // namespace Foam diff --git a/applications/utilities/surface/surfaceFeatureExtract/extractionMethod/extractFromSurface.H b/applications/utilities/surface/surfaceFeatureExtract/extractionMethod/extractFromSurface.H index 980db47b14..e007a8d3b9 100644 --- a/applications/utilities/surface/surfaceFeatureExtract/extractionMethod/extractFromSurface.H +++ b/applications/utilities/surface/surfaceFeatureExtract/extractionMethod/extractFromSurface.H @@ -56,10 +56,6 @@ class extractFromSurface : public method { - - bool selfIntersection_; - - public: // Constructors diff --git a/applications/utilities/surface/surfaceFeatureExtract/surfaceFeatureExtract.C b/applications/utilities/surface/surfaceFeatureExtract/surfaceFeatureExtract.C index 9dcaae6b63..3ae006e69d 100644 --- a/applications/utilities/surface/surfaceFeatureExtract/surfaceFeatureExtract.C +++ b/applications/utilities/surface/surfaceFeatureExtract/surfaceFeatureExtract.C @@ -29,12 +29,17 @@ Group Description Extracts and writes surface features to file. All but the basic feature - extraction is WIP. + extraction is a work-in-progress. - Curvature calculation is an implementation of the algorithm from: - - "Estimating Curvatures and their Derivatives on Triangle Meshes" - by S. Rusinkiewicz + The curvature calculation is an implementation of the algorithm from: + \verbatim + "Estimating Curvatures and their Derivatives on Triangle Meshes" + by S. Rusinkiewicz + 3DPVT'04 Proceedings of the 3D Data Processing, + Visualization, and Transmission, 2nd International Symposium + Pages 486-493 + http://gfx.cs.princeton.edu/pubs/_2004_ECA/curvpaper.pdf + \endverbatim \*---------------------------------------------------------------------------*/ @@ -60,6 +65,7 @@ Description #include "point.H" #include "triadField.H" #include "transform.H" +#include "triSurfaceLoader.H" using namespace Foam; @@ -367,23 +373,6 @@ triSurfacePointScalarField calcCurvature } -bool edgesConnected(const edge& e1, const edge& e2) -{ - if - ( - e1.start() == e2.start() - || e1.start() == e2.end() - || e1.end() == e2.start() - || e1.end() == e2.end() - ) - { - return true; - } - - return false; -} - - scalar calcProximityOfFeaturePoints ( const List& hitList, @@ -462,7 +451,7 @@ scalar calcProximityOfFeatureEdges const edge& e2 = efem.edges()[pHit2.index()]; // Don't refine if the edges are connected to each other - if (!edgesConnected(e1, e2)) + if (!e1.connects(e2)) { scalar curDist = mag(pHit1.hitPoint() - pHit2.hitPoint()); @@ -480,25 +469,12 @@ scalar calcProximityOfFeatureEdges void dumpBox(const treeBoundBox& bb, const fileName& fName) { - OFstream str(fName); + OFstream os(fName); Info<< "Dumping bounding box " << bb << " as lines to obj file " - << str.name() << endl; + << os.name() << endl; - - pointField boxPoints(bb.points()); - - forAll(boxPoints, i) - { - meshTools::writeOBJ(str, boxPoints[i]); - } - - forAll(treeBoundBox::edges, i) - { - const edge& e = treeBoundBox::edges[i]; - - str<< "l " << e[0]+1 << ' ' << e[1]+1 << nl; - } + meshTools::writeOBJ(os, bb); } @@ -866,62 +842,6 @@ void writeStats(const extendedFeatureEdgeMesh& fem, Ostream& os) } -// Read and combine all surfaces into a single one - -autoPtr loadSurfaces(Time& runTime, const wordList& surfNames) -{ - List faces; - pointField points; - label regoff = 0; // region offset - - forAll(surfNames, surfi) - { - const word& surfName = surfNames[surfi]; - - triSurface addsurf(runTime.constantPath()/"triSurface"/surfName); - - List addfaces(addsurf.xferFaces()); - List addpoints(addsurf.xferPoints()); - - if (surfi) - { - const label ptoff = points.size(); // point offset - - forAll(addfaces, facei) - { - labelledTri& f = addfaces[facei]; - forAll(f, fi) - { - f[fi] += ptoff; - } - f.region() += regoff; - } - - faces.append(addfaces); - points.append(addpoints); - } - else - { - faces.transfer(addfaces); - points.transfer(addpoints); - } - - regoff += addsurf.patches().size(); - } - - return autoPtr - ( - new triSurface - ( - faces, - geometricSurfacePatchList(), - points, - true - ) - ); -} - - int main(int argc, char *argv[]) { argList::addNote @@ -939,25 +859,15 @@ int main(int argc, char *argv[]) const word dictName("surfaceFeatureExtractDict"); #include "setSystemRunTimeDictionaryIO.H" - // Will be using triSurface, so filter according to what is supported - fileNameList validSurfaceFiles = readDir - ( - runTime.path()/runTime.constant()/"triSurface", - fileName::FILE - ); - inplaceSubsetList - ( - validSurfaceFiles, - [](const fileName& f){ return triSurface::canRead(f); } - ); - - // sort and eliminate duplicates (eg, files with/without .gz) - inplaceUniqueSort(validSurfaceFiles); - Info<< "Reading " << dictName << nl << endl; - const IOdictionary dict(dictIO); + // Loader for available triSurface surface files + triSurfaceLoader loader(runTime); + + // Where to write VTK output files + const fileName vtkOutputDir = runTime.constantPath()/"triSurface"; + forAllConstIter(dictionary, dict, iter) { if (!iter().isDict()) @@ -972,115 +882,88 @@ int main(int argc, char *argv[]) continue; } - autoPtr extractPtr = + autoPtr extractor = surfaceFeaturesExtraction::method::New ( surfaceDict ); - const surfaceFeaturesExtraction::method& extract = extractPtr(); - - // Output name, cleansed of extensions - const word sFeatFileName = + // The output name, cleansed of extensions + // Optional "output" entry, or the dictionary name. + const word outputName = fileName ( surfaceDict.lookupOrDefault("output", iter().keyword()) ).lessExt(); - wordList surfFileNames; - + // The "surfaces" entry is normally optional, but if the sub-dictionary + // is itself called "surfaces", then this becomes mandatory. + // This provides a simple means of handling both situations without an + // additional switch. if ( - iter().keyword() == "surfaces" // mandatory - || surfaceDict.found("surfaces") // or optional + iter().keyword() == "surfaces" // mandatory + || surfaceDict.found("surfaces") // or optional ) { - wordReList regexs(surfaceDict.lookup("surfaces")); - - labelList selected = findStrings(regexs, validSurfaceFiles); - surfFileNames.setSize(selected.size()); - forAll(selected, i) - { - surfFileNames[i] = validSurfaceFiles[selected[i]].name(); - } - - if (surfFileNames.empty()) - { - FatalErrorInFunction - << "No surfaces specified/found for entry: " - << iter().keyword() - << exit(FatalError); - } + loader.select(wordReList(surfaceDict.lookup("surfaces"))); } else { - surfFileNames.setSize(1); - surfFileNames[0] = iter().keyword(); - - const fileName file - ( - runTime.constantPath()/"triSurface"/surfFileNames[0] - ); - - if (!isFile(file)) - { - FatalErrorInFunction - << "No surface: " << file.name() - << exit(FatalError); - } + loader.select(iter().keyword()); } - // DebugVar(surfFileNames); - // DebugVar(sFeatFileName); + if (loader.selected().empty()) + { + FatalErrorInFunction + << "No surfaces specified/found for entry: " + << iter().keyword() << exit(FatalError); + } + // DebugVar(loader.available()); + // DebugVar(outputName); + Info<< "Surfaces : "; - if (surfFileNames.size() == 1) + if (loader.selected().size() == 1) { - Info<< surfFileNames[0] << nl; + Info<< loader.selected()[0] << nl; } else { - Info<< flatOutput(surfFileNames) << nl; + Info<< flatOutput(loader.selected()) << nl; + } + Info<< "Output : " << outputName << nl; + + // Load a single file, or load and combine multiple selected files + autoPtr surfPtr = loader.load(); + if (!surfPtr.valid() || surfPtr().empty()) + { + FatalErrorInFunction + << "Problem loading surface(s) for entry: " + << iter().keyword() << exit(FatalError); } - Info<< "Output : " << sFeatFileName << nl; + triSurface surf = surfPtr(); const Switch writeVTK = surfaceDict.lookupOrDefault ( - "writeVTK", Switch::OFF + "writeVTK", + Switch::OFF ); const Switch writeObj = surfaceDict.lookupOrDefault ( - "writeObj", Switch::OFF - ); - - const Switch curvature = surfaceDict.lookupOrDefault - ( - "curvature", Switch::OFF - ); - const Switch featureProximity = surfaceDict.lookupOrDefault - ( - "featureProximity", Switch::OFF - ); - const Switch closeness = surfaceDict.lookupOrDefault - ( - "closeness", Switch::OFF + "writeObj", + Switch::OFF ); Info<< "write VTK: " << writeVTK << nl; - Info<< nl << "Feature line extraction is only valid on closed manifold " - << "surfaces." << endl; + Info<< "Feature line extraction is only valid on closed manifold " + << "surfaces." << nl; - - // Read and combine all surfaces into a single one - - autoPtr surfPtr = loadSurfaces(runTime, surfFileNames); - triSurface surf = surfPtr(); - - Info<< "Statistics:" << endl; + Info<< nl << "Statistics:" << nl; surf.writeStats(Info); - Info<< endl; + Info<< nl; // need plain faces if outputting VTK format faceList faces; @@ -1097,19 +980,19 @@ int main(int argc, char *argv[]) // Either construct features from surface & featureAngle or read set. // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - autoPtr set = extract.features(surf); + autoPtr features = extractor().features(surf); // Trim set // ~~~~~~~~ if (surfaceDict.isDict("trimFeatures")) { - dictionary trimDict = surfaceDict.subDict("trimFeatures"); - const scalar minLen = - trimDict.lookupOrAddDefault("minLen", -GREAT); + const dictionary& trimDict = surfaceDict.subDict("trimFeatures"); + const scalar minLen = + trimDict.lookupOrDefault("minLen", 0); const label minElem = - trimDict.lookupOrAddDefault