Add the OpenFOAM source tree
This commit is contained in:
3
applications/utilities/surface/surfaceSubset/Make/files
Normal file
3
applications/utilities/surface/surfaceSubset/Make/files
Normal file
@ -0,0 +1,3 @@
|
||||
surfaceSubset.C
|
||||
|
||||
EXE = $(FOAM_APPBIN)/surfaceSubset
|
||||
@ -0,0 +1,8 @@
|
||||
EXE_INC = \
|
||||
-I$(LIB_SRC)/triSurface/lnInclude \
|
||||
-I$(LIB_SRC)/meshTools/lnInclude
|
||||
|
||||
EXE_LIBS = \
|
||||
-lmeshTools \
|
||||
-ltriSurface
|
||||
|
||||
394
applications/utilities/surface/surfaceSubset/surfaceSubset.C
Normal file
394
applications/utilities/surface/surfaceSubset/surfaceSubset.C
Normal file
@ -0,0 +1,394 @@
|
||||
/*---------------------------------------------------------------------------*\
|
||||
========= |
|
||||
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
|
||||
\\ / O peration |
|
||||
\\ / A nd | Copyright (C) 2011-2013 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 <http://www.gnu.org/licenses/>.
|
||||
|
||||
Application
|
||||
surfaceSubset
|
||||
|
||||
Description
|
||||
A surface analysis tool which sub-sets the triSurface
|
||||
to choose only a part of interest. Based on subsetMesh.
|
||||
|
||||
\*---------------------------------------------------------------------------*/
|
||||
|
||||
#include "triSurface.H"
|
||||
#include "triSurfaceSearch.H"
|
||||
#include "argList.H"
|
||||
#include "OFstream.H"
|
||||
#include "IFstream.H"
|
||||
#include "Switch.H"
|
||||
#include "IOdictionary.H"
|
||||
#include "boundBox.H"
|
||||
#include "indexedOctree.H"
|
||||
#include "treeDataTriSurface.H"
|
||||
#include "Random.H"
|
||||
#include "volumeType.H"
|
||||
#include "plane.H"
|
||||
|
||||
using namespace Foam;
|
||||
|
||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
argList::noParallel();
|
||||
argList::validArgs.append("surfaceSubsetDict");
|
||||
argList::validArgs.append("surfaceFile");
|
||||
argList::validArgs.append("output surfaceFile");
|
||||
argList args(argc, argv);
|
||||
|
||||
Info<< "Reading dictionary " << args[1] << " ..." << endl;
|
||||
IFstream dictFile(args[1]);
|
||||
dictionary meshSubsetDict(dictFile);
|
||||
|
||||
Info<< "Reading surface " << args[2] << " ..." << endl;
|
||||
triSurface surf1(args[2]);
|
||||
|
||||
const fileName outFileName(args[3]);
|
||||
|
||||
|
||||
Info<< "Original:" << endl;
|
||||
surf1.writeStats(Info);
|
||||
Info<< endl;
|
||||
|
||||
|
||||
labelList markedPoints
|
||||
(
|
||||
meshSubsetDict.lookup("localPoints")
|
||||
);
|
||||
|
||||
labelList markedEdges
|
||||
(
|
||||
meshSubsetDict.lookup("edges")
|
||||
);
|
||||
|
||||
labelList markedFaces
|
||||
(
|
||||
meshSubsetDict.lookup("faces")
|
||||
);
|
||||
|
||||
pointField markedZone
|
||||
(
|
||||
meshSubsetDict.lookup("zone")
|
||||
);
|
||||
|
||||
if (markedZone.size() && markedZone.size() != 2)
|
||||
{
|
||||
FatalErrorIn(args.executable())
|
||||
<< "zone specification should be two points, min and max of "
|
||||
<< "the boundingbox" << endl
|
||||
<< "zone:" << markedZone
|
||||
<< exit(FatalError);
|
||||
}
|
||||
|
||||
Switch addFaceNeighbours
|
||||
(
|
||||
meshSubsetDict.lookup("addFaceNeighbours")
|
||||
);
|
||||
|
||||
const bool invertSelection =
|
||||
meshSubsetDict.lookupOrDefault("invertSelection", false);
|
||||
|
||||
// Mark the cells for the subset
|
||||
|
||||
// Faces to subset
|
||||
boolList facesToSubset(surf1.size(), false);
|
||||
|
||||
|
||||
//
|
||||
// pick up faces connected to "localPoints"
|
||||
//
|
||||
|
||||
if (markedPoints.size())
|
||||
{
|
||||
Info<< "Found " << markedPoints.size() << " marked point(s)." << endl;
|
||||
|
||||
// pick up cells sharing the point
|
||||
|
||||
forAll(markedPoints, pointI)
|
||||
{
|
||||
if
|
||||
(
|
||||
markedPoints[pointI] < 0
|
||||
|| markedPoints[pointI] >= surf1.nPoints()
|
||||
)
|
||||
{
|
||||
FatalErrorIn(args.executable())
|
||||
<< "localPoint label " << markedPoints[pointI]
|
||||
<< "out of range."
|
||||
<< " The mesh has got "
|
||||
<< surf1.nPoints() << " localPoints."
|
||||
<< exit(FatalError);
|
||||
}
|
||||
|
||||
const labelList& curFaces =
|
||||
surf1.pointFaces()[markedPoints[pointI]];
|
||||
|
||||
forAll(curFaces, i)
|
||||
{
|
||||
facesToSubset[curFaces[i]] = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
//
|
||||
// pick up faces connected to "edges"
|
||||
//
|
||||
|
||||
if (markedEdges.size())
|
||||
{
|
||||
Info<< "Found " << markedEdges.size() << " marked edge(s)." << endl;
|
||||
|
||||
// pick up cells sharing the edge
|
||||
|
||||
forAll(markedEdges, edgeI)
|
||||
{
|
||||
if
|
||||
(
|
||||
markedEdges[edgeI] < 0
|
||||
|| markedEdges[edgeI] >= surf1.nEdges()
|
||||
)
|
||||
{
|
||||
FatalErrorIn(args.executable())
|
||||
<< "edge label " << markedEdges[edgeI]
|
||||
<< "out of range."
|
||||
<< " The mesh has got "
|
||||
<< surf1.nEdges() << " edges."
|
||||
<< exit(FatalError);
|
||||
}
|
||||
|
||||
const labelList& curFaces = surf1.edgeFaces()[markedEdges[edgeI]];
|
||||
|
||||
forAll(curFaces, i)
|
||||
{
|
||||
facesToSubset[curFaces[i]] = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//
|
||||
// pick up faces with centre inside "zone"
|
||||
//
|
||||
|
||||
if (markedZone.size() == 2)
|
||||
{
|
||||
const point& min = markedZone[0];
|
||||
const point& max = markedZone[1];
|
||||
|
||||
Info<< "Using zone min:" << min << " max:" << max << endl;
|
||||
|
||||
forAll(surf1, faceI)
|
||||
{
|
||||
const point centre = surf1[faceI].centre(surf1.points());
|
||||
|
||||
if
|
||||
(
|
||||
(centre.x() >= min.x())
|
||||
&& (centre.y() >= min.y())
|
||||
&& (centre.z() >= min.z())
|
||||
&& (centre.x() <= max.x())
|
||||
&& (centre.y() <= max.y())
|
||||
&& (centre.z() <= max.z())
|
||||
)
|
||||
{
|
||||
facesToSubset[faceI] = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//
|
||||
// pick up faces on certain side of surface
|
||||
//
|
||||
|
||||
if (meshSubsetDict.found("surface"))
|
||||
{
|
||||
const dictionary& surfDict = meshSubsetDict.subDict("surface");
|
||||
|
||||
fileName surfName(surfDict.lookup("name"));
|
||||
|
||||
Switch outside(surfDict.lookup("outside"));
|
||||
|
||||
if (outside)
|
||||
{
|
||||
Info<< "Selecting all triangles with centre outside surface "
|
||||
<< surfName << endl;
|
||||
}
|
||||
else
|
||||
{
|
||||
Info<< "Selecting all triangles with centre inside surface "
|
||||
<< surfName << endl;
|
||||
}
|
||||
|
||||
// Read surface to select on
|
||||
triSurface selectSurf(surfName);
|
||||
|
||||
triSurfaceSearch searchSelectSurf
|
||||
(
|
||||
selectSurf,
|
||||
indexedOctree<treeDataTriSurface>::perturbTol(),
|
||||
8
|
||||
);
|
||||
|
||||
const indexedOctree<treeDataTriSurface>& selectTree =
|
||||
searchSelectSurf.tree();
|
||||
|
||||
// Check if face (centre) is in outside or inside.
|
||||
forAll(facesToSubset, faceI)
|
||||
{
|
||||
if (!facesToSubset[faceI])
|
||||
{
|
||||
const point fc(surf1[faceI].centre(surf1.points()));
|
||||
|
||||
volumeType t = selectTree.getVolumeType(fc);
|
||||
|
||||
if
|
||||
(
|
||||
outside
|
||||
? (t == volumeType::OUTSIDE)
|
||||
: (t == volumeType::INSIDE)
|
||||
)
|
||||
{
|
||||
facesToSubset[faceI] = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if (meshSubsetDict.found("plane"))
|
||||
{
|
||||
const dictionary& planeDict = meshSubsetDict.subDict("plane");
|
||||
|
||||
const plane pl(planeDict);
|
||||
const scalar distance(readScalar(planeDict.lookup("distance")));
|
||||
const scalar cosAngle(readScalar(planeDict.lookup("cosAngle")));
|
||||
|
||||
// Select all triangles that are close to the plane and
|
||||
// whose normal aligns with the plane as well.
|
||||
|
||||
forAll(surf1.faceCentres(), faceI)
|
||||
{
|
||||
const point& fc = surf1.faceCentres()[faceI];
|
||||
const point& nf = surf1.faceNormals()[faceI];
|
||||
|
||||
if (pl.distance(fc) < distance && mag(pl.normal() & nf) > cosAngle)
|
||||
{
|
||||
facesToSubset[faceI] = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
//
|
||||
// pick up specified "faces"
|
||||
//
|
||||
|
||||
// Number of additional faces picked up because of addFaceNeighbours
|
||||
label nFaceNeighbours = 0;
|
||||
|
||||
if (markedFaces.size())
|
||||
{
|
||||
Info<< "Found " << markedFaces.size() << " marked face(s)." << endl;
|
||||
|
||||
// Check and mark faces to pick up
|
||||
forAll(markedFaces, faceI)
|
||||
{
|
||||
if
|
||||
(
|
||||
markedFaces[faceI] < 0
|
||||
|| markedFaces[faceI] >= surf1.size()
|
||||
)
|
||||
{
|
||||
FatalErrorIn(args.executable())
|
||||
<< "Face label " << markedFaces[faceI] << "out of range."
|
||||
<< " The mesh has got "
|
||||
<< surf1.size() << " faces."
|
||||
<< exit(FatalError);
|
||||
}
|
||||
|
||||
// Mark the face
|
||||
facesToSubset[markedFaces[faceI]] = true;
|
||||
|
||||
// mark its neighbours if requested
|
||||
if (addFaceNeighbours)
|
||||
{
|
||||
const labelList& curFaces =
|
||||
surf1.faceFaces()[markedFaces[faceI]];
|
||||
|
||||
forAll(curFaces, i)
|
||||
{
|
||||
label faceI = curFaces[i];
|
||||
|
||||
if (!facesToSubset[faceI])
|
||||
{
|
||||
facesToSubset[faceI] = true;
|
||||
nFaceNeighbours++;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (addFaceNeighbours)
|
||||
{
|
||||
Info<< "Added " << nFaceNeighbours
|
||||
<< " faces because of addFaceNeighbours" << endl;
|
||||
}
|
||||
|
||||
|
||||
if (invertSelection)
|
||||
{
|
||||
Info<< "Inverting selection." << endl;
|
||||
|
||||
forAll(facesToSubset, i)
|
||||
{
|
||||
facesToSubset[i] = facesToSubset[i] ? false : true;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// Create subsetted surface
|
||||
labelList pointMap;
|
||||
labelList faceMap;
|
||||
triSurface surf2
|
||||
(
|
||||
surf1.subsetMesh(facesToSubset, pointMap, faceMap)
|
||||
);
|
||||
|
||||
Info<< "Subset:" << endl;
|
||||
surf2.writeStats(Info);
|
||||
Info<< endl;
|
||||
|
||||
Info<< "Writing surface to " << outFileName << endl;
|
||||
|
||||
surf2.write(outFileName);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
// ************************************************************************* //
|
||||
@ -0,0 +1,68 @@
|
||||
/*--------------------------------*- C++ -*----------------------------------*\
|
||||
| ========= | |
|
||||
| \\ / F ield | OpenFOAM: The Open Source CFD Toolbox |
|
||||
| \\ / O peration | Version: dev |
|
||||
| \\ / A nd | Web: www.OpenFOAM.org |
|
||||
| \\/ M anipulation | |
|
||||
\*---------------------------------------------------------------------------*/
|
||||
FoamFile
|
||||
{
|
||||
version 2.0;
|
||||
format ascii;
|
||||
class dictionary;
|
||||
object surfaceSubsetDict;
|
||||
}
|
||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||
|
||||
// Select triangles by label
|
||||
faces #include "badFaces";
|
||||
|
||||
// Select triangles using given points (local point numbering)
|
||||
localPoints ( );
|
||||
|
||||
// Select triangles using given edges
|
||||
edges ();
|
||||
|
||||
// Select triangles (with face centre) inside box
|
||||
zone
|
||||
(
|
||||
(0 -10000 125)
|
||||
(10000 10000 10000)
|
||||
);
|
||||
|
||||
// Select triangles (with face centre) inside or outside of another surface.
|
||||
// (always selects triangles that are 'on' other surface)
|
||||
surface
|
||||
{
|
||||
name "sphere.stl";
|
||||
outside yes;
|
||||
}
|
||||
|
||||
// Select triangles on plane
|
||||
plane
|
||||
{
|
||||
planeType embeddedPoints;
|
||||
embeddedPointsDict
|
||||
{
|
||||
//point1 (-937.259845440205 160.865349115986 240.738791238078);
|
||||
//point2 (-934.767379895778 9.63875523747379 14.412359671298);
|
||||
//point3 (44.4744688899417 121.852927962709 182.352485273106);
|
||||
point1 (-957.895294591874 242.865936478961 162.286611511875);
|
||||
point2 (-961.43140327772 4.53895551562943 3.04159982093444);
|
||||
point3 (91.2414146173805 72.1504381996692 48.2181961945329);
|
||||
}
|
||||
|
||||
// Distance from plane
|
||||
distance 0.1;
|
||||
// Normal difference to plane
|
||||
cosAngle 0.99;
|
||||
}
|
||||
|
||||
|
||||
// Extend selection with edge neighbours
|
||||
addFaceNeighbours no;
|
||||
|
||||
// Invert selection
|
||||
invertSelection false;
|
||||
|
||||
// ************************************************************************* //
|
||||
Reference in New Issue
Block a user