/*---------------------------------------------------------------------------*\
========= |
\\ / 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