/*---------------------------------------------------------------------------*\ ========= | \\ / F ield | OpenFOAM: The Open Source CFD Toolbox \\ / O peration | Website: https://openfoam.org \\ / A nd | Copyright (C) 2011-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 . Description Identifies features in a surface geometry and writes them to file. This utility is deprecated, having been replaced by surfaceFeatures \*---------------------------------------------------------------------------*/ #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 { void writeStats(const extendedFeatureEdgeMesh& fem, Ostream& os) { os << " points : " << fem.points().size() << nl << " of which" << nl << " convex : " << fem.concaveStart() << nl << " concave : " << (fem.mixedStart() - fem.concaveStart()) << nl << " mixed : " << (fem.nonFeatureStart() - fem.mixedStart()) << nl << " non-feature : " << (fem.points().size() - fem.nonFeatureStart()) << nl << " edges : " << fem.edges().size() << nl << " of which" << nl << " external edges : " << fem.internalStart() << nl << " internal edges : " << (fem.flatStart() - fem.internalStart()) << nl << " flat edges : " << (fem.openStart() - fem.flatStart()) << nl << " open edges : " << (fem.multipleStart() - fem.openStart()) << nl << " multiply connected : " << (fem.edges().size() - fem.multipleStart()) << endl; } } // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // int main(int argc, char *argv[]) { argList::addNote ( "extract and write surface features to file" ); argList::noParallel(); #include "addDictOption.H" #include "setRootCase.H" #include "createTime.H" const word dictName("surfaceFeatureExtractDict"); #include "setSystemRunTimeDictionaryIO.H" Info<< "Reading " << dictName << nl << endl; const IOdictionary dict(dictIO); forAllConstIter(dictionary, dict, iter) { if (!iter().isDict()) { continue; } const dictionary& surfaceDict = iter().dict(); if (!surfaceDict.found("extractionMethod")) { continue; } const word extractionMethod = surfaceDict.lookup("extractionMethod"); const fileName surfFileName = iter().keyword(); const fileName sFeatFileName = surfFileName.lessExt().name(); Info<< "Surface : " << surfFileName << nl << endl; const Switch writeVTK = surfaceDict.lookupOrDefault("writeVTK", "off"); const Switch writeObj = surfaceDict.lookupOrDefault("writeObj", "off"); const Switch curvature = surfaceDict.lookupOrDefault("curvature", "off"); const Switch featureProximity = surfaceDict.lookupOrDefault("featureProximity", "off"); const Switch closeness = surfaceDict.lookupOrDefault("closeness", "off"); Info<< nl << "Feature line extraction is only valid on closed manifold " << "surfaces." << endl; // Read // ~~~~ triSurface surf(runTime.constantPath()/"triSurface"/surfFileName); Info<< "Statistics:" << endl; surf.writeStats(Info); Info<< endl; const faceList faces(surf.faces()); // Either construct features from surface & featureAngle or read set. // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ autoPtr set; scalar includedAngle = 0.0; if (extractionMethod == "extractFromFile") { const dictionary& extractFromFileDict = surfaceDict.subDict("extractFromFileCoeffs"); const fileName featureEdgeFile = extractFromFileDict.lookup("featureEdgeFile"); const Switch geometricTestOnly = extractFromFileDict.lookupOrDefault ( "geometricTestOnly", "no" ); 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; set.set ( new surfaceFeatures ( surf, eMesh.points(), eMesh.edges(), 1e-6, geometricTestOnly ) ); } else if (extractionMethod == "extractFromSurface") { const dictionary& extractFromSurfaceDict = surfaceDict.subDict("extractFromSurfaceCoeffs"); includedAngle = readScalar(extractFromSurfaceDict.lookup("includedAngle")); const Switch geometricTestOnly = extractFromSurfaceDict.lookupOrDefault ( "geometricTestOnly", "no" ); Info<< nl << "Constructing feature set from included angle " << includedAngle << nl << "Selecting edges purely based on geometric tests: " << geometricTestOnly.asText() << endl; set.set ( new surfaceFeatures ( surf, includedAngle, 0, 0, geometricTestOnly ) ); } else { FatalErrorInFunction << "No initial feature set. Provide either one" << " of extractFromFile (to read existing set)" << nl << " or extractFromSurface (to construct new set from angle)" << exit(FatalError); } // Trim set // ~~~~~~~~ if (surfaceDict.isDict("trimFeatures")) { dictionary trimDict = surfaceDict.subDict("trimFeatures"); scalar minLen = trimDict.lookupOrAddDefault("minLen", -great); label minElem = trimDict.lookupOrAddDefault