/*---------------------------------------------------------------------------*\ ========= | \\ / F ield | OpenFOAM: The Open Source CFD Toolbox \\ / O peration | \\ / A nd | Copyright (C) 2011-2016 OpenFOAM Foundation \\/ M anipulation | Copyright (C) 2015-2017 OpenCFD Ltd. ------------------------------------------------------------------------------- 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 surfaceFeatureExtract Group grpSurfaceUtilities Description Extracts and writes surface features to file. All but the basic feature extraction is a work-in-progress. \*---------------------------------------------------------------------------*/ #include "argList.H" #include "Time.H" #include "triSurface.H" #include "triSurfaceTools.H" #include "edgeMeshTools.H" #include "surfaceFeaturesExtraction.H" #include "surfaceIntersection.H" #include "featureEdgeMesh.H" #include "extendedFeatureEdgeMesh.H" #include "treeBoundBox.H" #include "meshTools.H" #include "OBJstream.H" #include "triSurfaceMesh.H" #include "vtkSurfaceWriter.H" #include "unitConversion.H" #include "plane.H" #include "point.H" #include "triSurfaceLoader.H" using namespace Foam; // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // int main(int argc, char *argv[]) { argList::addNote ( "extract and write surface features to file" ); argList::noParallel(); argList::noFunctionObjects(); #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); // 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) { const word& dictName = iter().keyword(); if (!iter().isDict()) { continue; } const dictionary& surfaceDict = iter().dict(); if (!surfaceDict.found("extractionMethod")) { continue; } autoPtr extractor = surfaceFeaturesExtraction::method::New ( surfaceDict ); // The output name, cleansed of extensions // Optional "output" entry, or the dictionary name. const word outputName = fileName ( surfaceDict.lookupOrDefault("output", dictName) ).lessExt(); // 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 ( dictName == "surfaces" // mandatory || surfaceDict.found("surfaces") // or optional ) { loader.select(wordReList(surfaceDict.lookup("surfaces"))); } else { loader.select(dictName); } if (loader.selected().empty()) { FatalErrorInFunction << "No surfaces specified/found for entry: " << dictName << exit(FatalError); } // DebugVar(loader.available()); // DebugVar(outputName); Info<< "Surfaces : "; if (loader.selected().size() == 1) { Info<< loader.selected()[0] << nl; } else { 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: " << dictName << exit(FatalError); } triSurface surf = surfPtr(); const Switch writeVTK = surfaceDict.lookupOrDefault ( "writeVTK", Switch::OFF ); const Switch writeObj = surfaceDict.lookupOrDefault ( "writeObj", Switch::OFF ); Info<< "write VTK: " << writeVTK << nl; Info<< "Feature line extraction is only valid on closed manifold " << "surfaces." << nl; Info<< nl << "Statistics:" << nl; surf.writeStats(Info); Info<< nl; // Need a copy as plain faces if outputting VTK format faceList faces; if (writeVTK) { faces.setSize(surf.size()); forAll(surf, fi) { faces[fi] = surf[fi].triFaceFace(); } } // // Extract features using the preferred extraction method // autoPtr features = extractor().features(surf); // Trim set // ~~~~~~~~ // Option: "trimFeatures" (dictionary) if (surfaceDict.isDict("trimFeatures")) { const dictionary& trimDict = surfaceDict.subDict("trimFeatures"); const scalar minLen = trimDict.lookupOrDefault("minLen", 0); const label minElem = trimDict.lookupOrDefault