surfaceFeatureExtract: Further refactoring to move the extract surface closeness functionality

to triSurfaceMesh
This commit is contained in:
Henry Weller
2018-04-17 00:16:12 +01:00
parent d2085c7420
commit 2730fbad5c
11 changed files with 432 additions and 457 deletions

View File

@ -1,5 +1,3 @@
surfaceExtractCloseness.C
surfaceExtractPointCloseness.C
surfaceFeatureExtractUtilities.C
surfaceFeatureExtract.C

View File

@ -1,291 +0,0 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / 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 <http://www.gnu.org/licenses/>.
\*---------------------------------------------------------------------------*/
#include "surfaceFeatureExtract.H"
#include "Time.H"
#include "triSurfaceMesh.H"
#include "vtkSurfaceWriter.H"
#include "meshTools.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
const Foam::scalar Foam::internalAngleTolerance(80);
const Foam::scalar Foam::internalToleranceCosAngle
(
cos(degToRad(180 - internalAngleTolerance))
);
const Foam::scalar Foam::externalAngleTolerance(10);
const Foam::scalar Foam::externalToleranceCosAngle
(
cos(degToRad(180 - externalAngleTolerance))
);
void Foam::drawHitProblem
(
const label fi,
const triSurface& surf,
const point& start,
const point& p,
const point& end,
const pointIndexHitList& hitInfo
)
{
Info<< nl << "# findLineAll did not hit its own face."
<< nl << "# fi " << fi
<< nl << "# start " << start
<< nl << "# point " << p
<< nl << "# end " << end
<< nl << "# hitInfo " << hitInfo
<< endl;
meshTools::writeOBJ(Info, start);
meshTools::writeOBJ(Info, p);
meshTools::writeOBJ(Info, end);
Info<< "l 1 2 3" << endl;
meshTools::writeOBJ(Info, surf.points()[surf[fi][0]]);
meshTools::writeOBJ(Info, surf.points()[surf[fi][1]]);
meshTools::writeOBJ(Info, surf.points()[surf[fi][2]]);
Info<< "f 4 5 6" << endl;
forAll(hitInfo, hi)
{
label hFI = hitInfo[hi].index();
meshTools::writeOBJ(Info, surf.points()[surf[hFI][0]]);
meshTools::writeOBJ(Info, surf.points()[surf[hFI][1]]);
meshTools::writeOBJ(Info, surf.points()[surf[hFI][2]]);
Info<< "f "
<< 3*hi + 7 << " "
<< 3*hi + 8 << " "
<< 3*hi + 9
<< endl;
}
}
void Foam::processHit
(
scalar& internalCloseness,
scalar& externalCloseness,
const label fi,
const triSurface& surf,
const point& start,
const point& p,
const point& end,
const vector& normal,
const vectorField& normals,
const pointIndexHitList& hitInfo
)
{
if (hitInfo.size() < 1)
{
drawHitProblem(fi, surf, start, p, end, hitInfo);
}
else if (hitInfo.size() == 1)
{
if (!hitInfo[0].hit())
{
}
else if (hitInfo[0].index() != fi)
{
drawHitProblem(fi, surf, start, p, end, hitInfo);
}
}
else
{
label ownHiti = -1;
forAll(hitInfo, hI)
{
// Find the hit on the triangle that launched the ray
if (hitInfo[hI].index() == fi)
{
ownHiti = hI;
break;
}
}
if (ownHiti < 0)
{
drawHitProblem(fi, surf, start, p, end, hitInfo);
}
else if (ownHiti == 0)
{
// There are no internal hits, the first hit is the
// closest external hit
if
(
(normal & normals[hitInfo[ownHiti + 1].index()])
< externalToleranceCosAngle
)
{
externalCloseness = min
(
externalCloseness,
mag(p - hitInfo[ownHiti + 1].hitPoint())
);
}
}
else if (ownHiti == hitInfo.size() - 1)
{
// There are no external hits, the last but one hit is
// the closest internal hit
if
(
(normal & normals[hitInfo[ownHiti - 1].index()])
< internalToleranceCosAngle
)
{
internalCloseness = min
(
internalCloseness,
mag(p - hitInfo[ownHiti - 1].hitPoint())
);
}
}
else
{
if
(
(normal & normals[hitInfo[ownHiti + 1].index()])
< externalToleranceCosAngle
)
{
externalCloseness = min
(
externalCloseness,
mag(p - hitInfo[ownHiti + 1].hitPoint())
);
}
if
(
(normal & normals[hitInfo[ownHiti - 1].index()])
< internalToleranceCosAngle
)
{
internalCloseness = min
(
internalCloseness,
mag(p - hitInfo[ownHiti - 1].hitPoint())
);
}
}
}
}
Foam::Pair<Foam::tmp<Foam::triSurfaceScalarField>> Foam::extractCloseness
(
const triSurfaceMesh& surf
)
{
const Time& runTime = surf.objectRegistry::time();
// Prepare start and end points for intersection tests
const vectorField& normals = surf.faceNormals();
const scalar span = surf.bounds().mag();
const pointField start(surf.faceCentres() - span*normals);
const pointField end(surf.faceCentres() + span*normals);
const pointField& faceCentres = surf.faceCentres();
List<List<pointIndexHit>> allHitinfo;
// Find all intersections (in order)
surf.findLineAll(start, end, allHitinfo);
scalarField internalCloseness(start.size(), great);
scalarField externalCloseness(start.size(), great);
forAll(allHitinfo, fi)
{
const List<pointIndexHit>& hitInfo = allHitinfo[fi];
processHit
(
internalCloseness[fi],
externalCloseness[fi],
fi,
surf,
start[fi],
faceCentres[fi],
end[fi],
normals[fi],
normals,
hitInfo
);
}
return Pair<tmp<triSurfaceScalarField>>
(
tmp<triSurfaceScalarField>
(
new triSurfaceScalarField
(
IOobject
(
surf.objectRegistry::name() + ".internalCloseness",
runTime.constant(),
"triSurface",
runTime
),
surf,
dimLength,
internalCloseness
)
),
tmp<triSurfaceScalarField>
(
new triSurfaceScalarField
(
IOobject
(
surf.objectRegistry::name() + ".externalCloseness",
runTime.constant(),
"triSurface",
runTime
),
surf,
dimLength,
externalCloseness
)
)
);
}
// ************************************************************************* //

View File

@ -1,150 +0,0 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / 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 <http://www.gnu.org/licenses/>.
\*---------------------------------------------------------------------------*/
#include "surfaceFeatureExtract.H"
#include "Time.H"
#include "vtkSurfaceWriter.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
Foam::Pair<Foam::tmp<Foam::triSurfacePointScalarField>>
Foam::extractPointCloseness
(
const triSurfaceMesh& surf
)
{
const Time& runTime = surf.objectRegistry::time();
// Prepare start and end points for intersection tests
const pointField& points = surf.points();
const labelList& meshPoints = surf.meshPoints();
const pointField& faceCentres = surf.faceCentres();
const vectorField& normals = surf.faceNormals();
const labelListList& pointFaces = surf.pointFaces();
const scalar span = surf.bounds().mag();
label nPointFaces = 0;
forAll(pointFaces, pfi)
{
nPointFaces += pointFaces[pfi].size();
}
pointField facePoints(nPointFaces);
pointField start(nPointFaces);
pointField end(nPointFaces);
label i = 0;
forAll(points, pi)
{
forAll(pointFaces[pi], pfi)
{
const label fi = pointFaces[pi][pfi];
facePoints[i] = (0.9*points[meshPoints[pi]] + 0.1*faceCentres[fi]);
const vector& n = normals[fi];
start[i] = facePoints[i] - span*n;
end[i] = facePoints[i] + span*n;
i++;
}
}
List<pointIndexHitList> allHitinfo;
// Find all intersections (in order)
surf.findLineAll(start, end, allHitinfo);
scalarField internalCloseness(points.size(), great);
scalarField externalCloseness(points.size(), great);
i = 0;
forAll(points, pi)
{
forAll(pointFaces[pi], pfi)
{
const label fi = pointFaces[pi][pfi];
const pointIndexHitList& hitInfo = allHitinfo[i];
processHit
(
internalCloseness[pi],
externalCloseness[pi],
fi,
surf,
start[i],
facePoints[i],
end[i],
normals[fi],
normals,
hitInfo
);
i++;
}
}
return Pair<tmp<triSurfacePointScalarField>>
(
tmp<triSurfacePointScalarField>
(
new triSurfacePointScalarField
(
IOobject
(
surf.objectRegistry::name() + ".internalPointCloseness",
runTime.constant(),
"triSurface",
runTime
),
surf,
dimLength,
internalCloseness
)
),
tmp<triSurfacePointScalarField>
(
new triSurfacePointScalarField
(
IOobject
(
surf.objectRegistry::name() + ".externalPointCloseness",
runTime.constant(),
"triSurface",
runTime
),
surf,
dimLength,
externalCloseness
)
)
);
}
// ************************************************************************* //

View File

@ -399,11 +399,6 @@ int main(int argc, char *argv[])
Info<< nl << "Extracting internal and external closeness of "
<< "surface." << endl;
Info<< "externalToleranceCosAngle: " << externalToleranceCosAngle
<< nl
<< "internalToleranceCosAngle: " << internalToleranceCosAngle
<< endl;
// Searchable triSurface
const triSurfaceMesh searchSurf
(
@ -420,7 +415,7 @@ int main(int argc, char *argv[])
{
Pair<tmp<triSurfaceScalarField>> closenessFields
(
extractCloseness(searchSurf)
searchSurf.extractCloseness()
);
closenessFields.first()->write();
@ -459,7 +454,7 @@ int main(int argc, char *argv[])
{
Pair<tmp<triSurfacePointScalarField >> closenessFields
(
extractPointCloseness(searchSurf)
searchSurf.extractPointCloseness()
);
closenessFields.first()->write();

View File

@ -39,12 +39,6 @@ Description
namespace Foam
{
extern const scalar internalAngleTolerance;
extern const scalar internalToleranceCosAngle;
extern const scalar externalAngleTolerance;
extern const scalar externalToleranceCosAngle;
//- Deletes all edges inside/outside bounding box from set.
void deleteBox
(
@ -62,18 +56,6 @@ namespace Foam
List<surfaceFeatures::edgeStatus>& edgeStat
);
//- Divide into multiple normal bins
// - return REGION if != 2 normals
// - return REGION if 2 normals that make feature angle
// - otherwise return NONE and set normals,bins
surfaceFeatures::edgeStatus checkNonManifoldEdge
(
const triSurface& surf,
const scalar tol,
const scalar includedAngle,
const label edgei
);
void deleteNonManifoldEdges
(
const triSurface& surf,
@ -83,41 +65,6 @@ namespace Foam
);
void writeStats(const extendedFeatureEdgeMesh& fem, Ostream& os);
void drawHitProblem
(
const label fi,
const triSurface& surf,
const point& start,
const point& p,
const point& end,
const pointIndexHitList& hitInfo
);
void processHit
(
scalar& internalCloseness,
scalar& externalCloseness,
const label fi,
const triSurface& surf,
const point& start,
const point& p,
const point& end,
const vector& normal,
const vectorField& normals,
const pointIndexHitList& hitInfo
);
Pair<tmp<triSurfaceScalarField>> extractCloseness
(
const triSurfaceMesh& surf
);
Pair<tmp<triSurfacePointScalarField>> extractPointCloseness
(
const triSurfaceMesh& surf
);
}

View File

@ -87,166 +87,6 @@ void Foam::deleteEdges
}
Foam::surfaceFeatures::edgeStatus Foam::checkNonManifoldEdge
(
const triSurface& surf,
const scalar tol,
const scalar includedAngle,
const label edgei
)
{
const edge& e = surf.edges()[edgei];
const labelList& eFaces = surf.edgeFaces()[edgei];
// Bin according to normal
DynamicList<Foam::vector> normals(2);
DynamicList<labelList> bins(2);
forAll(eFaces, eFacei)
{
const Foam::vector& n = surf.faceNormals()[eFaces[eFacei]];
// Find the normal in normals
label index = -1;
forAll(normals, normalI)
{
if (mag(n&normals[normalI]) > (1-tol))
{
index = normalI;
break;
}
}
if (index != -1)
{
bins[index].append(eFacei);
}
else if (normals.size() >= 2)
{
// Would be third normal. Mark as feature.
//Pout<< "** at edge:" << surf.localPoints()[e[0]]
// << surf.localPoints()[e[1]]
// << " have normals:" << normals
// << " and " << n << endl;
return surfaceFeatures::REGION;
}
else
{
normals.append(n);
bins.append(labelList(1, eFacei));
}
}
// Check resulting number of bins
if (bins.size() == 1)
{
// Note: should check here whether they are two sets of faces
// that are planar or indeed 4 faces al coming together at an edge.
//Pout<< "** at edge:"
// << surf.localPoints()[e[0]]
// << surf.localPoints()[e[1]]
// << " have single normal:" << normals[0]
// << endl;
return surfaceFeatures::NONE;
}
else
{
// Two bins. Check if normals make an angle
//Pout<< "** at edge:"
// << surf.localPoints()[e[0]]
// << surf.localPoints()[e[1]] << nl
// << " normals:" << normals << nl
// << " bins :" << bins << nl
// << endl;
if (includedAngle >= 0)
{
scalar minCos = Foam::cos(degToRad(180.0 - includedAngle));
forAll(eFaces, i)
{
const Foam::vector& ni = surf.faceNormals()[eFaces[i]];
for (label j=i+1; j<eFaces.size(); j++)
{
const Foam::vector& nj = surf.faceNormals()[eFaces[j]];
if (mag(ni & nj) < minCos)
{
//Pout<< "have sharp feature between normal:" << ni
// << " and " << nj << endl;
// Is feature. Keep as region or convert to
// feature angle? For now keep as region.
return surfaceFeatures::REGION;
}
}
}
}
// So now we have two normals bins but need to make sure both
// bins have the same regions in it.
// 1. store + or - region number depending
// on orientation of triangle in bins[0]
const labelList& bin0 = bins[0];
labelList regionAndNormal(bin0.size());
forAll(bin0, i)
{
const labelledTri& t = surf.localFaces()[eFaces[bin0[i]]];
int dir = t.edgeDirection(e);
if (dir > 0)
{
regionAndNormal[i] = t.region()+1;
}
else if (dir == 0)
{
FatalErrorInFunction
<< exit(FatalError);
}
else
{
regionAndNormal[i] = -(t.region()+1);
}
}
// 2. check against bin1
const labelList& bin1 = bins[1];
labelList regionAndNormal1(bin1.size());
forAll(bin1, i)
{
const labelledTri& t = surf.localFaces()[eFaces[bin1[i]]];
int dir = t.edgeDirection(e);
label myRegionAndNormal;
if (dir > 0)
{
myRegionAndNormal = t.region()+1;
}
else
{
myRegionAndNormal = -(t.region()+1);
}
regionAndNormal1[i] = myRegionAndNormal;
label index = findIndex(regionAndNormal, -myRegionAndNormal);
if (index == -1)
{
// Not found.
//Pout<< "cannot find region " << myRegionAndNormal
// << " in regions " << regionAndNormal << endl;
return surfaceFeatures::REGION;
}
}
return surfaceFeatures::NONE;
}
}
void Foam::deleteNonManifoldEdges