diff --git a/applications/utilities/surface/surfaceFeatures/Make/files b/applications/utilities/surface/surfaceFeatures/Make/files new file mode 100644 index 000000000..75ef45edf --- /dev/null +++ b/applications/utilities/surface/surfaceFeatures/Make/files @@ -0,0 +1,3 @@ +surfaceFeatures.C + +EXE = $(FOAM_APPBIN)/surfaceFeatures diff --git a/applications/utilities/surface/surfaceFeatures/Make/options b/applications/utilities/surface/surfaceFeatures/Make/options new file mode 100644 index 000000000..e96fbb368 --- /dev/null +++ b/applications/utilities/surface/surfaceFeatures/Make/options @@ -0,0 +1,11 @@ +EXE_INC = \ + -I$(LIB_SRC)/finiteVolume/lnInclude \ + -I$(LIB_SRC)/meshTools/lnInclude \ + -I$(LIB_SRC)/triSurface/lnInclude \ + -I$(LIB_SRC)/surfMesh/lnInclude \ + -I$(LIB_SRC)/sampling/lnInclude + +EXE_LIBS = \ + -lmeshTools \ + -ltriSurface \ + -lsampling diff --git a/applications/utilities/surface/surfaceFeatures/surfaceFeatures.C b/applications/utilities/surface/surfaceFeatures/surfaceFeatures.C new file mode 100644 index 000000000..b160331ab --- /dev/null +++ b/applications/utilities/surface/surfaceFeatures/surfaceFeatures.C @@ -0,0 +1,729 @@ +/*---------------------------------------------------------------------------*\ + ========= | + \\ / F ield | OpenFOAM: The Open Source CFD Toolbox + \\ / O peration | + \\ / A nd | Copyright (C) 2018 OpenFOAM Foundation + \\/ 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 "argList.H" +#include "Time.H" +#include "triSurfaceMesh.H" +#include "featureEdgeMesh.H" +#include "extendedFeatureEdgeMesh.H" +#include "surfaceFeatures.H" +#include "triSurfaceFields.H" +#include "vtkSurfaceWriter.H" +#include "IOdictionary.H" + +using namespace Foam; + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +namespace Foam +{ + autoPtr extractFromFile + ( + const fileName& featureEdgeFile, + const triSurface& surf, + const Switch& geometricTestOnly + ) + { + edgeMesh eMesh(featureEdgeFile); + + // Sometimes duplicate edges are present. Remove them. + eMesh.mergeEdges(); + + Info<< nl << "Reading existing feature edges from file " + << featureEdgeFile << nl + << "Selecting edges purely based on geometric tests: " + << geometricTestOnly.asText() << endl; + + return autoPtr + ( + new surfaceFeatures + ( + surf, + eMesh.points(), + eMesh.edges(), + 1e-6, + geometricTestOnly + ) + ); + } + + + autoPtr extractFromSurface + ( + const triSurface& surf, + const Switch& geometricTestOnly, + const scalar includedAngle + ) + { + Info<< nl + << "Constructing feature set from included angle " + << includedAngle << nl + << "Selecting edges purely based on geometric tests: " + << geometricTestOnly.asText() << endl; + + return autoPtr + ( + new surfaceFeatures + ( + surf, + includedAngle, + 0, + 0, + geometricTestOnly + ) + ); + } + + + autoPtr surfaceFeatureSet + ( + const fileName& surfaceFileName, + const triSurface& surf, + const dictionary& dict, + const scalar includedAngle + ) + { + const Switch geometricTestOnly = dict.lookupOrDefault + ( + "geometricTestOnly", + "no" + ); + + if (dict.found("files")) + { + HashTable fileNames(dict.lookup("files")); + + if (fileNames.found(surfaceFileName)) + { + return extractFromFile + ( + fileNames[surfaceFileName], + surf, + geometricTestOnly + ); + } + else + { + return extractFromSurface + ( + surf, + geometricTestOnly, + includedAngle + ); + } + } + else + { + return extractFromSurface + ( + surf, + geometricTestOnly, + includedAngle + ); + } + } + + + void extractFeatures + ( + const fileName& surfaceFileName, + const Time& runTime, + const dictionary& dict + ) + { + const fileName sFeatFileName = surfaceFileName.lessExt().name(); + + Info<< "Surface : " << surfaceFileName << nl << endl; + + const Switch writeVTK = + dict.lookupOrDefault("writeVTK", "off"); + const Switch writeObj = + dict.lookupOrDefault("writeObj", "off"); + const Switch verboseObj = + dict.lookupOrDefault("verboseObj", "off"); + + const Switch curvature = + dict.lookupOrDefault("curvature", "off"); + const Switch featureProximity = + dict.lookupOrDefault("featureProximity", "off"); + const Switch closeness = + dict.lookupOrDefault("closeness", "off"); + + + Info<< nl << "Feature line extraction is only valid on closed manifold " + << "surfaces." << endl; + + // Read + // ~~~~ + + triSurface surf(runTime.constantPath()/"triSurface"/surfaceFileName); + + Info<< "Statistics:" << endl; + surf.writeStats(Info); + Info<< endl; + + const faceList faces(surf.faces()); + + // Either construct features from surface & featureAngle or read set. + // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + + const scalar includedAngle = readScalar(dict.lookup("includedAngle")); + + autoPtr set + ( + surfaceFeatureSet + ( + surfaceFileName, + surf, + dict, + includedAngle + ) + ); + + // Trim set + // ~~~~~~~~ + + if (dict.isDict("trimFeatures")) + { + dictionary trimDict = dict.subDict("trimFeatures"); + + scalar minLen = + trimDict.lookupOrAddDefault("minLen", -great); + + label minElem = trimDict.lookupOrAddDefault