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

View File

@ -39,12 +39,6 @@ Description
namespace Foam 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. //- Deletes all edges inside/outside bounding box from set.
void deleteBox void deleteBox
( (
@ -62,18 +56,6 @@ namespace Foam
List<surfaceFeatures::edgeStatus>& edgeStat 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 void deleteNonManifoldEdges
( (
const triSurface& surf, const triSurface& surf,
@ -83,41 +65,6 @@ namespace Foam
); );
void writeStats(const extendedFeatureEdgeMesh& fem, Ostream& os); 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 void Foam::deleteNonManifoldEdges

View File

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

View File

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

View File

@ -2,7 +2,7 @@
========= | ========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox \\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration | \\ / O peration |
\\ / A nd | Copyright (C) 2011-2017 OpenFOAM Foundation \\ / A nd | Copyright (C) 2011-2018 OpenFOAM Foundation
\\/ M anipulation | \\/ M anipulation |
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
License License
@ -51,6 +51,8 @@ SourceFiles
#include "EdgeMap.H" #include "EdgeMap.H"
#include "triSurface.H" #include "triSurface.H"
#include "triSurfaceRegionSearch.H" #include "triSurfaceRegionSearch.H"
#include "triSurfaceFieldsFwd.H"
#include "pointIndexHitList.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
@ -131,6 +133,30 @@ class triSurfaceMesh
DynamicList<pointIndexHit, 1, 1>& hits 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 //- Disallow default bitwise copy construct
triSurfaceMesh(const triSurfaceMesh&); triSurfaceMesh(const triSurfaceMesh&);
@ -290,6 +316,18 @@ public:
// indices) get the specified field. Misses do not get set. // indices) get the specified field. Misses do not get set.
virtual void getField(const List<pointIndexHit>&, labelList&) const; 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 // 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 \\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration | \\ / O peration |
\\ / A nd | Copyright (C) 2011-2016 OpenFOAM Foundation \\ / A nd | Copyright (C) 2011-2018 OpenFOAM Foundation
\\/ M anipulation | \\/ M anipulation |
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
License License
@ -32,13 +32,11 @@ Description
externalStart_ .. internalStart_-1 : external edges externalStart_ .. internalStart_-1 : external edges
internalStart_ .. size-1 : internal edges internalStart_ .. size-1 : internal edges
NOTE: angle is included angle, not feature angle and is in degrees. NOTE: angle is included angle, not feature angle and is in degrees.
The included angle is the smallest angle between two planes. For coplanar 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 faces it is 180, for straight angles it is 90. To pick up straight edges
only use included angle of 91 degrees only use included angle of 91 degrees
SourceFiles SourceFiles
surfaceFeatures.C surfaceFeatures.C
@ -418,11 +416,22 @@ public:
// Member Operators // Member Operators
void operator=(const surfaceFeatures&); 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 } // End namespace Foam