Feature edge reading and construction with nearestFeatureEdge query test code.

This commit is contained in:
graham
2009-04-23 18:23:58 +01:00
parent cf10cbbd6f
commit 7e5a42cc26
7 changed files with 349 additions and 41 deletions

View File

@ -28,6 +28,7 @@ License
#include "initialPointsMethod.H"
#include "uint.H"
#include "ulong.H"
#include "surfaceFeatures.H"
// * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * //
@ -72,7 +73,7 @@ bool Foam::conformalVoronoiMesh::dualCellSurfaceIntersection
}
// Check for the edge passing through a surface
if (geometryToConformTo_.findAnyIntersection(dE0, dE1))
if (geometryToConformTo_.findSurfaceAnyIntersection(dE0, dE1))
{
return true;
}
@ -132,7 +133,7 @@ void Foam::conformalVoronoiMesh::calcDualMesh
)
);
scalar minEdgeLenSqr = Foam::sqr(defaultCellSize*minimumEdgeLengthCoeff);
scalar minEdgeLenSqr = sqr(defaultCellSize*minimumEdgeLengthCoeff);
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
@ -774,7 +775,7 @@ Foam::conformalVoronoiMesh::conformalVoronoiMesh
{
timeCheck();
insertFeaturePoints();
conformToFeaturePoints();
timeCheck();
insertInitialPoints();
@ -846,9 +847,11 @@ void Foam::conformalVoronoiMesh::insertSurfacePointPairs
}
void Foam::conformalVoronoiMesh::insertFeaturePoints()
void Foam::conformalVoronoiMesh::conformToFeaturePoints()
{
Info<< nl << "Inserting feature points" << endl;
Info<< nl << "Conforming to feature points" << endl;
Info<< " Conforming to " << "XXX" << " feature locations" << nl
<< " Inserting " << "YYY" << " points" << endl;
@ -942,7 +945,11 @@ void Foam::conformalVoronoiMesh::conformToSurface()
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
for(label iterationNo = 0; iterationNo < 1; iterationNo++)
// Surface protrusion conformation
label nIterations = 1;
for(label iterationNo = 0; iterationNo < nIterations; iterationNo++)
{
DynamicList<scalar> surfacePpDist;
DynamicList<point> surfacePoints;
@ -963,14 +970,11 @@ void Foam::conformalVoronoiMesh::conformToSurface()
// TODO Need to have a function to recover the local cell size,
// use the defaultCellSize for the moment
scalar searchDistanceSqr = Foam::sqr
(
defaultCellSize*surfDepthCoeff
);
scalar searchDistanceSqr = sqr(defaultCellSize*surfDepthCoeff);
pointIndexHit pHit;
vector normal;
geometryToConformTo_.findNearestAndNormal
geometryToConformTo_.findSurfaceNearestAndNormal
(
vert,
searchDistanceSqr,
@ -984,6 +988,10 @@ void Foam::conformalVoronoiMesh::conformToSurface()
if (dualCellSurfaceIntersection(vit))
{
// If the point is within a given distance of a feature
// edge, shift it to being an edge control point
// instead, this will prevent "pits" forming.
surfacePpDist.append(defaultCellSize*ppDistCoeff);
surfacePoints.append(pHit.hitPoint());
surfaceNormals.append(normal);
@ -992,9 +1000,9 @@ void Foam::conformalVoronoiMesh::conformToSurface()
}
}
Info<< nl <<iterationNo << ": "
<< number_of_vertices() << ": "
<< surfacePoints.size() << endl;
Info<< nl <<" iterationNo " << iterationNo << nl
<< " number_of_vertices " << number_of_vertices() << nl
<< " surfacePoints.size() " << surfacePoints.size() << endl;
insertSurfacePointPairs
(
@ -1006,6 +1014,51 @@ void Foam::conformalVoronoiMesh::conformToSurface()
"surfaceConformationLocations_" + name(iterationNo) + ".obj"
)
);
// Feature edge conformation.
geometryToConformTo_.findEdgeNearest
(
pointField(surfacePoints),
scalarField
(
surfacePoints.size(),
sqr(defaultCellSize*surfDepthCoeff)
)
);
// After the surface conformation points are added, any points that are
// still protruding the surface may be protruding from edges, so
// identify the points and test if they are close to a feature edge
DynamicList<point> edgeGenerationPoints;
for
(
Triangulation::Finite_vertices_iterator vit =
finite_vertices_begin();
vit != finite_vertices_end();
vit++
)
{
if (vit->nearBoundary())
{
if (dualCellSurfaceIntersection(vit))
{
// Test to see if near to an edge, conform to the nearest
// point on that edge if so.
edgeGenerationPoints.append(topoint(vit->point()));
}
}
}
writePoints
(
"edgeGenerationLocations_" + name(iterationNo) + ".obj",
edgeGenerationPoints
);
}
}

View File

@ -94,7 +94,7 @@ class conformalVoronoiMesh
//- Store the feature constraining points to be reinserted after a
//- triangulation clear
List<Vb> featureConstrainingVertices_;
List<Vb> featureVertices_;
//- Method for inserting initial points. Runtime selectable.
autoPtr<initialPointsMethod> initialPointsMethod_;
@ -134,7 +134,7 @@ class conformalVoronoiMesh
);
//- Insert point groups at the feature points.
void insertFeaturePoints();
void conformToFeaturePoints();
//- Reinsert stored feature point defining points.
void reinsertFeaturePoints();

View File

@ -107,7 +107,6 @@ void Foam::conformalVoronoiMesh::writeMesh()
Info<< nl << "Writing polyMesh to constant." << endl;
polyMesh pMesh
(
io,

View File

@ -191,6 +191,12 @@ public:
return type_ <= INTERNAL_POINT;
}
//- Set the point to be internal
inline void setInternal()
{
type_ = INTERNAL_POINT;
}
//- Is point internal and near the boundary
inline bool nearBoundary() const
{

View File

@ -38,22 +38,10 @@ Foam::conformationSurfaces::conformationSurfaces
:
cvMesh_(cvMesh),
allGeometry_(allGeometry),
features_
(
IOobject
(
"features",
cvMesh_.time().constant(),
"featureEdgeMesh",
cvMesh_.time(),
IOobject::NO_READ,
IOobject::NO_WRITE
),
pointField(0),
edgeList(0)
),
features_(),
locationInMesh_(surfaceConformationDict.lookup("locationInMesh")),
surfaces_(0),
surfaces_(),
baffleSurfaces_(),
bounds_()
{
const dictionary& surfacesDict
@ -61,13 +49,21 @@ Foam::conformationSurfaces::conformationSurfaces
surfaceConformationDict.subDict("geometryToConformTo")
);
Info<< nl << "Reading geometryToConformTo." << endl;
surfaces_.setSize(surfacesDict.size());
baffleSurfaces_.setSize(surfacesDict.size());
features_.setSize(surfacesDict.size());
label surfI = 0;
forAllConstIter(dictionary, surfacesDict, iter)
{
surfaces_[surfI] = allGeometry_.findSurfaceID(iter().keyword());
word surfaceName = iter().keyword();
surfaces_[surfI] = allGeometry_.findSurfaceID(surfaceName);
if (surfaces_[surfI] < 0)
{
@ -77,10 +73,87 @@ Foam::conformationSurfaces::conformationSurfaces
<< exit(FatalError);
}
const dictionary& surfaceSubDict(surfacesDict.subDict(surfaceName));
baffleSurfaces_[surfI] = Switch
(
surfaceSubDict.lookupOrDefault("baffleSurface", false)
);
word featureMethod = surfaceSubDict.lookupOrDefault
(
"featureMethod",
word("none")
);
if (featureMethod == "featureEdgeMesh")
{
fileName feMeshName(surfaceSubDict.lookup("featureEdgeMesh"));
features_.set
(
surfI,
new featureEdgeMesh
(
IOobject
(
feMeshName,
cvMesh_.time().findInstance
(
"featureEdgeMesh", feMeshName
),
"featureEdgeMesh",
cvMesh_.time(),
IOobject::MUST_READ,
IOobject::NO_WRITE
)
)
);
}
else if (featureMethod == "extractFeatures")
{
notImplemented
(
"conformationSurfaces::conformationSurfaces, "
"else if (featureMethod == \"extractFeatures\")"
);
}
else if (featureMethod == "none")
{
fileName feMeshName(surfaceSubDict.lookup("featureEdgeMesh"));
features_.set
(
surfI,
new featureEdgeMesh
(
IOobject
(
feMeshName,
cvMesh_.time().constant(),
"featureEdgeMesh",
cvMesh_.time(),
IOobject::NO_READ,
IOobject::NO_WRITE,
false
)
)
);
}
else
{
FatalErrorIn("Foam::conformationSurfaces::conformationSurfaces")
<< "No valid featureMethod found for surface " << surfaceName
<< nl << "Use \"featureEdgeMesh\" or \"extractFeatures\"."
<< exit(FatalError);
}
surfI++;
}
bounds_ = searchableSurfacesQueries::bounds(allGeometry_, surfaces_);
writeFeatureObj("cvMesh");
}
@ -233,7 +306,7 @@ Foam::Field<bool> Foam::conformationSurfaces::wellOutside
}
bool Foam::conformationSurfaces::findAnyIntersection
bool Foam::conformationSurfaces::findSurfaceAnyIntersection
(
point start,
point end
@ -256,7 +329,7 @@ bool Foam::conformationSurfaces::findAnyIntersection
}
void Foam::conformationSurfaces::findNearestAndNormal
void Foam::conformationSurfaces::findSurfaceNearestAndNormal
(
const point& sample,
scalar nearestDistSqr,
@ -294,4 +367,150 @@ void Foam::conformationSurfaces::findNearestAndNormal
}
void Foam::conformationSurfaces::findSurfaceNearestAndNormal
(
const pointField& samples,
scalarField nearestDistSqr,
List<pointIndexHit>& hitInfo,
vectorField& normals
) const
{
labelList hitSurfaces;
searchableSurfacesQueries::findNearest
(
allGeometry_,
surfaces_,
samples,
nearestDistSqr,
hitSurfaces,
hitInfo
);
forAll(hitInfo, i)
{
const pointIndexHit& pHit(hitInfo[i]);
if (pHit.hit())
{
// hitSurfaces has returned the index of the entry in surfaces_ that
// was found, not the index of the surface in allGeometry_,
// translating this to the surface in allGeometry_ for the normal
// lookup.
hitSurfaces[i] = surfaces_[hitSurfaces[i]];
vectorField norm(1);
allGeometry_[hitSurfaces[i]].getNormal
(
List<pointIndexHit>(1, pHit),
norm
);
normals[i] = norm[0];
}
}
}
void Foam::conformationSurfaces::findEdgeNearest
(
const pointField& samples,
const scalarField& nearestDistSqr
) const
{
labelList nearestSurfaces;
List<pointIndexHit> nearestInfo;
// Initialise
nearestSurfaces.setSize(samples.size());
nearestSurfaces = -1;
nearestInfo.setSize(samples.size());
// Work arrays
scalarField minDistSqr(nearestDistSqr);
List<pointIndexHit> hitInfo(samples.size());
forAll(features_, testI)
{
features_[testI].nearestFeatureEdge
(
samples,
minDistSqr,
hitInfo
);
// Update minDistSqr and arguments
forAll(hitInfo, pointI)
{
if (hitInfo[pointI].hit())
{
minDistSqr[pointI] = magSqr
(
hitInfo[pointI].hitPoint()
- samples[pointI]
);
nearestInfo[pointI] = hitInfo[pointI];
nearestSurfaces[pointI] = testI;
}
}
}
OFstream edgeNearestStr("testFindEdgeNearest.obj");
Pout<< "Writing edge nearest points to " << edgeNearestStr.name() << endl;
forAll(nearestInfo, i)
{
if (nearestInfo[i].hit())
{
meshTools::writeOBJ(edgeNearestStr, nearestInfo[i].hitPoint());
}
}
// labelList& edgeLabel;
// pointField& edgePoint;
// List<vectorField>& adjacentNormals;
// edgeLabel.setSize(samples.size());
// edgePoint.setSize(samples.size());
// adjacentNormals.setSize(samples.size());
// edgeLabel[i] = pHit.index();
// edgePoint[i] = pHit.hitPoint();
// adjacentNormals[i] = edgeNormals(edgeLabel[i]);
}
void Foam::conformationSurfaces::writeFeatureObj
(
const fileName& prefix
) const
{
OFstream ftStr(prefix + "_allFeatures.obj");
Pout<< nl << "Writing all features to " << ftStr.name() << endl;
label verti = 0;
forAll(features_, i)
{
const featureEdgeMesh& fEM(features_[i]);
const pointField pts(fEM.points());
const edgeList eds(fEM.edges());
ftStr << "g " << fEM.name() << endl;
forAll(eds, j)
{
const edge& e = eds[j];
meshTools::writeOBJ(ftStr, pts[e[0]]); verti++;
meshTools::writeOBJ(ftStr, pts[e[1]]); verti++;
ftStr << "l " << verti-1 << ' ' << verti << endl;
}
}
}
// ************************************************************************* //

View File

@ -65,8 +65,8 @@ class conformationSurfaces
//- Reference to the searchableSurfaces object holding all geometry data
const searchableSurfaces& allGeometry_;
//- Feature Edges and points
featureEdgeMesh features_;
//- A list of featureEdge meshes
PtrList<featureEdgeMesh> features_;
//- The location in the mesh that specifies which portion of surfaces is
// to be meshed.
@ -75,6 +75,10 @@ class conformationSurfaces
//- Indices of surfaces in allGeometry that are to be conformed to
labelList surfaces_;
//- A boolean value for each surface to be conformed to specifying if it
// is to be treated as a baffle
boolList baffleSurfaces_;
//- The overall boundBox of all of the surfaces to be conformed to
boundBox bounds_;
@ -113,6 +117,9 @@ public:
// of the geometry
inline const searchableSurfaces& geometry() const;
//- Return the object holding the feature points and edges
inline const PtrList<featureEdgeMesh>& features() const;
//- Return the surface indices
inline const labelList& surfaces() const;
@ -145,11 +152,11 @@ public:
) const;
// Finding if the line joining start and end intersects the surface
bool findAnyIntersection(point start, point end) const;
bool findSurfaceAnyIntersection(point start, point end) const;
//- Find the nearest point to the sample and return it to the
// pointIndexHit, and the normal at the hit location, if found.
void findNearestAndNormal
void findSurfaceNearestAndNormal
(
const point& sample,
scalar nearestDistSqr,
@ -157,8 +164,25 @@ public:
vector& normal
) const;
void findSurfaceNearestAndNormal
(
const pointField& sample,
scalarField nearestDistSqr,
List<pointIndexHit>& pHit,
vectorField& normal
) const;
// Member Operators
//- Find the nearest point on any feature edge
void findEdgeNearest
(
const pointField& samples,
const scalarField& nearestDistSqr
) const;
// Write
//- Write all components of all the featureEdgeMeshes as an obj file
void writeFeatureObj(const fileName& prefix) const;
};

View File

@ -26,7 +26,7 @@ License
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
// * * * * * * * * * * * * * * * Member Operators * * * * * * * * * * * * * //
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
const Foam::searchableSurfaces& Foam::conformationSurfaces::geometry() const
{
@ -34,6 +34,13 @@ const Foam::searchableSurfaces& Foam::conformationSurfaces::geometry() const
}
const Foam::PtrList<Foam::featureEdgeMesh>&
Foam::conformationSurfaces::features() const
{
return features_;
}
const Foam::labelList& Foam::conformationSurfaces::surfaces() const
{
return surfaces_;