Added to smooth surface faces function to only operate on

perpendicular faces.

Added code to attempt to determine the collapse direction of a face by
detemining the shorted distance across each triangle.  Not working,
commited for reference.

Made some functions const.
This commit is contained in:
graham
2009-12-06 12:07:39 +00:00
parent e00078aa01
commit 241f6a07d4
2 changed files with 204 additions and 34 deletions

View File

@ -2063,6 +2063,7 @@ void Foam::conformalVoronoiMesh::calcDualMesh
// Assess close points to be merged // Assess close points to be merged
{
Info<< nl << " Merging close points" << endl; Info<< nl << " Merging close points" << endl;
label nPtsMerged = 0; label nPtsMerged = 0;
@ -2078,6 +2079,7 @@ void Foam::conformalVoronoiMesh::calcDualMesh
reindexDualVertices(dualPtIndexMap); reindexDualVertices(dualPtIndexMap);
} while (nPtsMerged > 0); } while (nPtsMerged > 0);
}
// Smooth the surface of the mesh // Smooth the surface of the mesh
@ -2091,13 +2093,32 @@ void Foam::conformalVoronoiMesh::calcDualMesh
nSmoothedVertices = smoothSurfaceDualFaces(points, dualPtIndexMap); nSmoothedVertices = smoothSurfaceDualFaces(points, dualPtIndexMap);
Info<< " Smoothed " << nPtsMerged << " points (0 HARD CODED)" Info<< " Smoothed " << nSmoothedVertices
<< " points (0 HARD CODED)"
<< endl; << endl;
reindexDualVertices(dualPtIndexMap); reindexDualVertices(dualPtIndexMap);
} while (nSmoothedVertices > 0); } while (nSmoothedVertices > 0);
{
Info<< nl << " Merging close points" << endl;
label nPtsMerged = 0;
do
{
Map<label> dualPtIndexMap;
nPtsMerged = mergeCloseDualVertices(points, dualPtIndexMap);
Info<< " Merged " << nPtsMerged << " points" << endl;
reindexDualVertices(dualPtIndexMap);
} while (nPtsMerged > 0);
}
// Assess faces for collapse // Assess faces for collapse
Info<< nl << " Collapsing unnecessary faces" << endl; Info<< nl << " Collapsing unnecessary faces" << endl;
@ -2387,7 +2408,7 @@ Foam::label Foam::conformalVoronoiMesh::mergeCloseDualVertices
( (
const pointField& pts, const pointField& pts,
Map<label>& dualPtIndexMap Map<label>& dualPtIndexMap
) ) const
{ {
label nPtsMerged = 0; label nPtsMerged = 0;
@ -2438,10 +2459,12 @@ Foam::label Foam::conformalVoronoiMesh::smoothSurfaceDualFaces
( (
pointField& pts, pointField& pts,
Map<label>& dualPtIndexMap Map<label>& dualPtIndexMap
) ) const
{ {
label nSmoothedVertices = 0; label nSmoothedVertices = 0;
const scalar cosPerpendicularToleranceAngle = cos(degToRad(80));
for for
( (
Triangulation::Finite_edges_iterator eit = finite_edges_begin(); Triangulation::Finite_edges_iterator eit = finite_edges_begin();
@ -2477,29 +2500,59 @@ Foam::label Foam::conformalVoronoiMesh::smoothSurfaceDualFaces
continue; continue;
} }
forAll(dualFace, fPtI)
{
label ptI = dualFace[fPtI];
point& pt = pts[ptI];
pointIndexHit surfHit; pointIndexHit surfHit;
label hitSurface; label hitSurface;
geometryToConformTo_.findSurfaceNearest geometryToConformTo_.findSurfaceNearest
( (
pt, dualFace.centre(pts),
cvMeshControls().spanSqr(), cvMeshControls().spanSqr(),
surfHit, surfHit,
hitSurface hitSurface
); );
if (surfHit.hit()) vectorField norm(1);
{
pt = surfHit.hitPoint();
// dualPtIndexMap.insert(ptI, ptI); allGeometry_[hitSurface].getNormal
} (
List<pointIndexHit>(1, surfHit),
norm
);
const vector& surfaceNormal = norm[0];
vector faceNormal = dualFace.normal(pts);
faceNormal /= mag(faceNormal);
if ((faceNormal & surfaceNormal) < cosPerpendicularToleranceAngle)
{
collapseFaceToEdge(dualFace, pts, dualPtIndexMap);
// forAll(dualFace, fPtI)
// {
// label ptI = dualFace[fPtI];
// point& pt = pts[ptI];
// pointIndexHit surfHit;
// label hitSurface;
// geometryToConformTo_.findSurfaceNearest
// (
// pt,
// cvMeshControls().spanSqr(),
// surfHit,
// hitSurface
// );
// if (surfHit.hit())
// {
// pt = surfHit.hitPoint();
// // dualPtIndexMap.insert(ptI, ptI);
// }
// }
} }
} }
} }
@ -2512,7 +2565,7 @@ Foam::label Foam::conformalVoronoiMesh::collapseFaces
( (
pointField& pts, pointField& pts,
Map<label>& dualPtIndexMap Map<label>& dualPtIndexMap
) ) const
{ {
label nCollapsedFaces = 0; label nCollapsedFaces = 0;
@ -2750,6 +2803,115 @@ Foam::label Foam::conformalVoronoiMesh::collapseFaces
} }
void Foam::conformalVoronoiMesh::collapseFaceToEdge
(
const face& f,
pointField& pts,
Map<label>& dualPtIndexMap
) const
{
const vector fC = f.centre(pts);
const edgeList& faceEds = f.edges();
const scalar fArea = f.mag(pts);
scalar averageQuality = 0.0;
vector faceCollapseDirection = vector::zero;
forAll(faceEds, edI)
{
const edge e = faceEds[edI];
triPointRef tri(pts[e.start()], pts[e.end()], fC);
scalar triArea = tri.mag();
if (triArea < SMALL)
{
// Sliver triangle, do not consider
continue;
}
// 0.7697997 converts from a quality being 1 for an area ratio
// of an equilateral triangle (4*pi/(3*sqrt(3))) to the
// quality being 1 for an area ratio of a quarter of a square
// (pi), i.e. (4*pi/(3*sqrt(3)))/pi = 0.7697997
scalar triQuality = tri.quality()*0.7697997;
// Weight the quality by the tri area
averageQuality += triQuality*triArea;
// find the longest edge vector, and one of the other edges
// that isn't the longest
vector longestEdge = tri.b() - tri.a();
vector otherEdge = tri.c() - tri.a();
scalar longestEdgeMagSqr = magSqr(longestEdge);
if (magSqr(tri.c() - tri.b()) > longestEdgeMagSqr)
{
longestEdge = tri.c() - tri.b();
otherEdge = tri.a() - tri.b();
longestEdgeMagSqr = magSqr(longestEdgeMagSqr);
}
if (magSqr(tri.a() - tri.c()) > longestEdgeMagSqr)
{
longestEdge = tri.a() - tri.c();
otherEdge = tri.b() - tri.c();
longestEdgeMagSqr = magSqr(longestEdgeMagSqr);
}
vector triCollapseDirection =
(otherEdge & longestEdge)*longestEdge/longestEdgeMagSqr
- otherEdge;
triCollapseDirection /= mag(triCollapseDirection);
// Add the triCollapseDirection so that it is constructive
if
(
magSqr(faceCollapseDirection + triCollapseDirection)
> magSqr(faceCollapseDirection)
)
{
faceCollapseDirection += triCollapseDirection;
// faceCollapseDirection += triCollapseDirection/triQuality;
}
else
{
faceCollapseDirection -= triCollapseDirection;
// faceCollapseDirection -= triCollapseDirection/triQuality;
}
}
faceCollapseDirection /= mag(faceCollapseDirection);
averageQuality /= fArea;
vector collapseAxis = (faceCollapseDirection ^ (f.normal(pts)/fArea));
Info<< nl << "# averageQuality " << averageQuality << endl;
forAll(f, fPtI)
{
meshTools::writeOBJ(Info, pts[f[fPtI]]);
}
collapseAxis *= 3.0*mag(pts[f[0]] - fC);
faceCollapseDirection *= 3.0*mag(pts[f[0]] - fC);
meshTools::writeOBJ(Info, fC + faceCollapseDirection);
meshTools::writeOBJ(Info, fC - faceCollapseDirection);
meshTools::writeOBJ(Info, fC + collapseAxis);
meshTools::writeOBJ(Info, fC - collapseAxis);
}
void Foam::conformalVoronoiMesh::reindexDualVertices void Foam::conformalVoronoiMesh::reindexDualVertices
( (
const Map<label>& dualPtIndexMap const Map<label>& dualPtIndexMap

View File

@ -468,7 +468,7 @@ private:
( (
const pointField& pts, const pointField& pts,
Map<label>& dualPtIndexMap Map<label>& dualPtIndexMap
); ) const;
//- Smooth the dual vertices of the dual faces on the boundary //- Smooth the dual vertices of the dual faces on the boundary
// so that they conform to the surface and remove any // so that they conform to the surface and remove any
@ -477,7 +477,7 @@ private:
( (
pointField& pts, pointField& pts,
Map<label>& dualPtIndexMap Map<label>& dualPtIndexMap
); ) const;
//- Collapse a face to a point or an edge, modifying and //- Collapse a face to a point or an edge, modifying and
// mapping the points, returns the true if the face was // mapping the points, returns the true if the face was
@ -486,7 +486,15 @@ private:
( (
pointField& pts, pointField& pts,
Map<label>& dualPtIndexMap Map<label>& dualPtIndexMap
); ) const;
//- Collapse a face to an edge, updating the point and point map
void collapseFaceToEdge
(
const face& f,
pointField& pts,
Map<label>& dualPtIndexMap
) const;
//- Re-index all of the the Delaunay cells //- Re-index all of the the Delaunay cells
void reindexDualVertices(const Map<label>& dualPtIndexMap); void reindexDualVertices(const Map<label>& dualPtIndexMap);