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,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

View File

@ -114,6 +114,7 @@ searchableSurfaces/searchableSurfaces/searchableSurfaces.C
searchableSurfaces/searchableSurfacesQueries/searchableSurfacesQueries.C
searchableSurfaces/searchableSurfaceWithGaps/searchableSurfaceWithGaps.C
searchableSurfaces/triSurfaceMesh/triSurfaceMesh.C
searchableSurfaces/triSurfaceMesh/extractCloseness.C
searchableSurfaces/closedTriSurfaceMesh/closedTriSurfaceMesh.C
searchableSurfaces/searchableExtrudedCircle/searchableExtrudedCircle.C

View File

@ -2,7 +2,7 @@
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | Copyright (C) 2011-2018 OpenFOAM Foundation
\\ / A nd | Copyright (C) 2018 OpenFOAM Foundation
\\/ M anipulation |
-------------------------------------------------------------------------------
License
@ -23,36 +23,26 @@ License
\*---------------------------------------------------------------------------*/
#include "surfaceFeatureExtract.H"
#include "Time.H"
#include "triSurfaceMesh.H"
#include "vtkSurfaceWriter.H"
#include "triSurfaceFields.H"
#include "meshTools.H"
#include "Time.H"
#include "unitConversion.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
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
void Foam::triSurfaceMesh::drawHitProblem
(
const label fi,
const triSurface& surf,
const point& start,
const point& p,
const point& end,
const pointIndexHitList& hitInfo
)
) const
{
const List<labelledTri>& tris = *this;
const pointField& points = this->points();
Info<< nl << "# findLineAll did not hit its own face."
<< nl << "# fi " << fi
<< nl << "# start " << start
@ -67,19 +57,19 @@ void Foam::drawHitProblem
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]]);
meshTools::writeOBJ(Info, points[tris[fi][0]]);
meshTools::writeOBJ(Info, points[tris[fi][1]]);
meshTools::writeOBJ(Info, points[tris[fi][2]]);
Info<< "f 4 5 6" << endl;
forAll(hitInfo, hi)
{
label hFI = hitInfo[hi].index();
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]]);
meshTools::writeOBJ(Info, points[tris[hfi][0]]);
meshTools::writeOBJ(Info, points[tris[hfi][1]]);
meshTools::writeOBJ(Info, points[tris[hfi][2]]);
Info<< "f "
<< 3*hi + 7 << " "
@ -90,23 +80,24 @@ void Foam::drawHitProblem
}
void Foam::processHit
void Foam::triSurfaceMesh::processHit
(
scalar& internalCloseness,
scalar& externalCloseness,
const scalar internalToleranceCosAngle,
const scalar externalToleranceCosAngle,
const label fi,
const triSurface& surf,
const point& start,
const point& p,
const point& end,
const vector& normal,
const vectorField& normals,
const pointIndexHitList& hitInfo
)
) const
{
if (hitInfo.size() < 1)
{
drawHitProblem(fi, surf, start, p, end, hitInfo);
drawHitProblem(fi, start, p, end, hitInfo);
}
else if (hitInfo.size() == 1)
{
@ -115,7 +106,7 @@ void Foam::processHit
}
else if (hitInfo[0].index() != fi)
{
drawHitProblem(fi, surf, start, p, end, hitInfo);
drawHitProblem(fi, start, p, end, hitInfo);
}
}
else
@ -135,7 +126,7 @@ void Foam::processHit
if (ownHiti < 0)
{
drawHitProblem(fi, surf, start, p, end, hitInfo);
drawHitProblem(fi, start, p, end, hitInfo);
}
else if (ownHiti == 0)
{
@ -205,27 +196,39 @@ void Foam::processHit
}
Foam::Pair<Foam::tmp<Foam::triSurfaceScalarField>> Foam::extractCloseness
Foam::Pair<Foam::tmp<Foam::triSurfaceScalarField>>
Foam::triSurfaceMesh::extractCloseness
(
const triSurfaceMesh& surf
)
const scalar internalAngleTolerance,
const scalar externalAngleTolerance
) const
{
const Time& runTime = surf.objectRegistry::time();
const scalar internalToleranceCosAngle
(
cos(degToRad(180 - internalAngleTolerance))
);
const scalar externalToleranceCosAngle
(
cos(degToRad(180 - externalAngleTolerance))
);
const Time& runTime = objectRegistry::time();
// Prepare start and end points for intersection tests
const vectorField& normals = surf.faceNormals();
const vectorField& normals = faceNormals();
const scalar span = surf.bounds().mag();
const scalar span = bounds().mag();
const pointField start(surf.faceCentres() - span*normals);
const pointField end(surf.faceCentres() + span*normals);
const pointField& faceCentres = surf.faceCentres();
const pointField start(faceCentres() - span*normals);
const pointField end(faceCentres() + span*normals);
const pointField& faceCentres = this->faceCentres();
List<List<pointIndexHit>> allHitinfo;
// Find all intersections (in order)
surf.findLineAll(start, end, allHitinfo);
findLineAll(start, end, allHitinfo);
scalarField internalCloseness(start.size(), great);
scalarField externalCloseness(start.size(), great);
@ -238,8 +241,9 @@ Foam::Pair<Foam::tmp<Foam::triSurfaceScalarField>> Foam::extractCloseness
(
internalCloseness[fi],
externalCloseness[fi],
internalToleranceCosAngle,
externalToleranceCosAngle,
fi,
surf,
start[fi],
faceCentres[fi],
end[fi],
@ -257,12 +261,12 @@ Foam::Pair<Foam::tmp<Foam::triSurfaceScalarField>> Foam::extractCloseness
(
IOobject
(
surf.objectRegistry::name() + ".internalCloseness",
objectRegistry::name() + ".internalCloseness",
runTime.constant(),
"triSurface",
runTime
),
surf,
*this,
dimLength,
internalCloseness
)
@ -274,12 +278,142 @@ Foam::Pair<Foam::tmp<Foam::triSurfaceScalarField>> Foam::extractCloseness
(
IOobject
(
surf.objectRegistry::name() + ".externalCloseness",
objectRegistry::name() + ".externalCloseness",
runTime.constant(),
"triSurface",
runTime
),
surf,
*this,
dimLength,
externalCloseness
)
)
);
}
Foam::Pair<Foam::tmp<Foam::triSurfacePointScalarField>>
Foam::triSurfaceMesh::extractPointCloseness
(
const scalar internalAngleTolerance,
const scalar externalAngleTolerance
) const
{
const scalar internalToleranceCosAngle
(
cos(degToRad(180 - internalAngleTolerance))
);
const scalar externalToleranceCosAngle
(
cos(degToRad(180 - externalAngleTolerance))
);
const Time& runTime = objectRegistry::time();
// Prepare start and end points for intersection tests
const pointField& points = this->points();
const labelList& meshPoints = this->meshPoints();
const pointField& faceCentres = this->faceCentres();
const vectorField& normals = this->faceNormals();
const labelListList& pointFaces = this->pointFaces();
const scalar span = 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)
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],
internalToleranceCosAngle,
externalToleranceCosAngle,
fi,
start[i],
facePoints[i],
end[i],
normals[fi],
normals,
hitInfo
);
i++;
}
}
return Pair<tmp<triSurfacePointScalarField>>
(
tmp<triSurfacePointScalarField>
(
new triSurfacePointScalarField
(
IOobject
(
objectRegistry::name() + ".internalPointCloseness",
runTime.constant(),
"triSurface",
runTime
),
*this,
dimLength,
internalCloseness
)
),
tmp<triSurfacePointScalarField>
(
new triSurfacePointScalarField
(
IOobject
(
objectRegistry::name() + ".externalPointCloseness",
runTime.constant(),
"triSurface",
runTime
),
*this,
dimLength,
externalCloseness
)

View File

@ -794,6 +794,37 @@ void Foam::triSurfaceMesh::getNormal
}
void Foam::triSurfaceMesh::getVolumeType
(
const pointField& points,
List<volumeType>& volType
) const
{
volType.setSize(points.size());
scalar oldTol = indexedOctree<treeDataTriSurface>::perturbTol();
indexedOctree<treeDataTriSurface>::perturbTol() = tolerance();
forAll(points, pointi)
{
const point& pt = points[pointi];
if (!tree().bb().contains(pt))
{
// Have to calculate directly as outside the octree
volType[pointi] = tree().shapes().getVolumeType(tree(), pt);
}
else
{
// - use cached volume type per each tree node
volType[pointi] = tree().getVolumeType(pt);
}
}
indexedOctree<treeDataTriSurface>::perturbTol() = oldTol;
}
void Foam::triSurfaceMesh::setField(const labelList& values)
{
autoPtr<triSurfaceLabelField> fldPtr
@ -846,37 +877,6 @@ void Foam::triSurfaceMesh::getField
}
void Foam::triSurfaceMesh::getVolumeType
(
const pointField& points,
List<volumeType>& volType
) const
{
volType.setSize(points.size());
scalar oldTol = indexedOctree<treeDataTriSurface>::perturbTol();
indexedOctree<treeDataTriSurface>::perturbTol() = tolerance();
forAll(points, pointi)
{
const point& pt = points[pointi];
if (!tree().bb().contains(pt))
{
// Have to calculate directly as outside the octree
volType[pointi] = tree().shapes().getVolumeType(tree(), pt);
}
else
{
// - use cached volume type per each tree node
volType[pointi] = tree().getVolumeType(pt);
}
}
indexedOctree<treeDataTriSurface>::perturbTol() = oldTol;
}
bool Foam::triSurfaceMesh::writeObject
(
IOstream::streamFormat fmt,

View File

@ -2,7 +2,7 @@
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | Copyright (C) 2011-2017 OpenFOAM Foundation
\\ / A nd | Copyright (C) 2011-2018 OpenFOAM Foundation
\\/ M anipulation |
-------------------------------------------------------------------------------
License
@ -51,6 +51,8 @@ SourceFiles
#include "EdgeMap.H"
#include "triSurface.H"
#include "triSurfaceRegionSearch.H"
#include "triSurfaceFieldsFwd.H"
#include "pointIndexHitList.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
@ -131,6 +133,30 @@ class triSurfaceMesh
DynamicList<pointIndexHit, 1, 1>& hits
);
void drawHitProblem
(
const label fi,
const point& start,
const point& p,
const point& end,
const pointIndexHitList& hitInfo
) const;
void processHit
(
scalar& internalCloseness,
scalar& externalCloseness,
const scalar internalToleranceCosAngle,
const scalar externalToleranceCosAngle,
const label fi,
const point& start,
const point& p,
const point& end,
const vector& normal,
const vectorField& normals,
const pointIndexHitList& hitInfo
) const;
//- Disallow default bitwise copy construct
triSurfaceMesh(const triSurfaceMesh&);
@ -290,6 +316,18 @@ public:
// indices) get the specified field. Misses do not get set.
virtual void getField(const List<pointIndexHit>&, labelList&) const;
Pair<tmp<triSurfaceScalarField>> extractCloseness
(
const scalar internalAngleTolerance = 80,
const scalar externalAngleTolerance = 10
) const;
Pair<tmp<triSurfacePointScalarField>> extractPointCloseness
(
const scalar internalAngleTolerance = 80,
const scalar externalAngleTolerance = 10
) const;
// regIOobject implementation

View File

@ -1499,4 +1499,167 @@ void Foam::surfaceFeatures::operator=(const surfaceFeatures& rhs)
}
// * * * * * * * * * * * * * * * Global Functions * * * * * * * * * * * * * //
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;
}
}
// ************************************************************************* //

View File

@ -2,7 +2,7 @@
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | Copyright (C) 2011-2016 OpenFOAM Foundation
\\ / A nd | Copyright (C) 2011-2018 OpenFOAM Foundation
\\/ M anipulation |
-------------------------------------------------------------------------------
License
@ -32,13 +32,11 @@ Description
externalStart_ .. internalStart_-1 : external edges
internalStart_ .. size-1 : internal edges
NOTE: angle is included angle, not feature angle and is in degrees.
The included angle is the smallest angle between two planes. For coplanar
faces it is 180, for straight angles it is 90. To pick up straight edges
only use included angle of 91 degrees
SourceFiles
surfaceFeatures.C
@ -418,11 +416,22 @@ public:
// Member Operators
void operator=(const surfaceFeatures&);
};
//- 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
);
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
} // End namespace Foam