mirror of
https://develop.openfoam.com/Development/openfoam.git
synced 2025-11-28 03:28:01 +00:00
Creation of OpenFOAM-dev repository 15/04/2008
This commit is contained in:
@ -0,0 +1,740 @@
|
||||
/*---------------------------------------------------------------------------*\
|
||||
========= |
|
||||
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
|
||||
\\ / O peration |
|
||||
\\ / A nd | Copyright (C) 1991-2007 OpenCFD Ltd.
|
||||
\\/ 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 2 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, write to the Free Software Foundation,
|
||||
Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
|
||||
Description
|
||||
|
||||
\*---------------------------------------------------------------------------*/
|
||||
|
||||
#include "edgeIntersections.H"
|
||||
#include "triSurfaceSearch.H"
|
||||
#include "labelPairLookup.H"
|
||||
#include "OFstream.H"
|
||||
#include "HashSet.H"
|
||||
#include "labelHashSet.H"
|
||||
#include "triSurface.H"
|
||||
#include "pointIndexHit.H"
|
||||
#include "octreeDataTriSurface.H"
|
||||
#include "octree.H"
|
||||
#include "meshTools.H"
|
||||
#include "plane.H"
|
||||
#include "Random.H"
|
||||
#include "mathematicalConstants.H"
|
||||
#include "treeBoundBox.H"
|
||||
|
||||
// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
|
||||
|
||||
defineTypeNameAndDebug(Foam::edgeIntersections, 0);
|
||||
|
||||
Foam::scalar Foam::edgeIntersections::alignedCos_ =
|
||||
Foam::cos(89.0 * Foam::mathematicalConstant::pi/180.0);
|
||||
|
||||
|
||||
// * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * //
|
||||
|
||||
void Foam::edgeIntersections::checkEdges(const triSurface& surf)
|
||||
{
|
||||
const pointField& localPoints = surf.localPoints();
|
||||
const edgeList& edges = surf.edges();
|
||||
const labelListList& edgeFaces = surf.edgeFaces();
|
||||
|
||||
treeBoundBox bb(localPoints);
|
||||
|
||||
scalar minSize = SMALL*bb.minDim();
|
||||
|
||||
forAll(edges, edgeI)
|
||||
{
|
||||
const edge& e = edges[edgeI];
|
||||
|
||||
scalar eMag = e.mag(localPoints);
|
||||
|
||||
if (eMag < minSize)
|
||||
{
|
||||
WarningIn
|
||||
(
|
||||
"Foam::edgeIntersections::checkEdges(const triSurface& surf)"
|
||||
) << "Edge " << edgeI << " vertices " << e
|
||||
<< " coords:" << localPoints[e[0]] << ' '
|
||||
<< localPoints[e[1]] << " is very small compared to bounding"
|
||||
<< " box dimensions " << bb << endl
|
||||
<< "This might lead to problems in intersection"
|
||||
<< endl;
|
||||
}
|
||||
|
||||
if (edgeFaces[edgeI].size() == 1)
|
||||
{
|
||||
WarningIn
|
||||
(
|
||||
"Foam::edgeIntersections::checkEdges(const triSurface& surf)"
|
||||
) << "Edge " << edgeI << " vertices " << e
|
||||
<< " coords:" << localPoints[e[0]] << ' '
|
||||
<< localPoints[e[1]] << " has only one face connected to it:"
|
||||
<< edgeFaces[edgeI] << endl
|
||||
<< "This might lead to problems in intersection"
|
||||
<< endl;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// Update intersections for selected edges.
|
||||
void Foam::edgeIntersections::intersectEdges
|
||||
(
|
||||
const triSurface& surf1,
|
||||
const pointField& points1, // surf1 meshPoints (not localPoints!)
|
||||
const triSurfaceSearch& querySurf2,
|
||||
const scalarField& surf1PointTol, // surf1 tolerance per point
|
||||
const labelList& edgeLabels
|
||||
)
|
||||
{
|
||||
const triSurface& surf2 = querySurf2.surface();
|
||||
const vectorField& normals2 = surf2.faceNormals();
|
||||
|
||||
const labelList& meshPoints = surf1.meshPoints();
|
||||
|
||||
if (debug)
|
||||
{
|
||||
Pout<< "Calculating intersection of " << edgeLabels.size() << " edges"
|
||||
<< " out of " << surf1.nEdges() << " with " << surf2.size()
|
||||
<< " triangles ..." << endl;
|
||||
}
|
||||
|
||||
// Construct octree.
|
||||
const octree<octreeDataTriSurface>& tree = querySurf2.tree();
|
||||
|
||||
|
||||
label nHits = 0;
|
||||
|
||||
|
||||
// Go through all edges, calculate intersections
|
||||
forAll(edgeLabels, i)
|
||||
{
|
||||
label edgeI = edgeLabels[i];
|
||||
|
||||
if (debug && (i % 1000 == 0))
|
||||
{
|
||||
Pout<< "Intersecting edge " << edgeI << " with surface" << endl;
|
||||
}
|
||||
|
||||
const edge& e = surf1.edges()[edgeI];
|
||||
|
||||
const point& pStart = points1[meshPoints[e.start()]];
|
||||
const point& pEnd = points1[meshPoints[e.end()]];
|
||||
|
||||
const vector eVec(pEnd - pStart);
|
||||
const scalar eMag = mag(eVec);
|
||||
const vector n(eVec/(eMag + VSMALL));
|
||||
|
||||
// Smallish length for intersection calculation errors.
|
||||
const point tolVec = 1e-6*eVec;
|
||||
|
||||
// Start tracking somewhat before pStart and upto somewhat after p1.
|
||||
// Note that tolerances here are smaller than those used to classify
|
||||
// hit below.
|
||||
// This will cause this hit to be marked as degenerate and resolved
|
||||
// later on.
|
||||
point p0 = pStart - 0.5*surf1PointTol[e[0]]*n;
|
||||
const point p1 = pEnd + 0.5*surf1PointTol[e[1]]*n;
|
||||
const scalar maxS = mag(p1 - pStart);
|
||||
|
||||
// Get all intersections of the edge with the surface
|
||||
|
||||
DynamicList<pointIndexHit> currentIntersections(100);
|
||||
DynamicList<label> currentIntersectionTypes(100);
|
||||
|
||||
while (true)
|
||||
{
|
||||
pointIndexHit pHit = tree.findLine(p0, p1);
|
||||
|
||||
if (pHit.hit())
|
||||
{
|
||||
nHits++;
|
||||
|
||||
currentIntersections.append(pHit);
|
||||
|
||||
// Classify point on surface1 edge.
|
||||
label edgeEnd = -1;
|
||||
|
||||
if (mag(pHit.hitPoint() - pStart) < surf1PointTol[e[0]])
|
||||
{
|
||||
edgeEnd = 0;
|
||||
}
|
||||
else if (mag(pHit.hitPoint() - pEnd) < surf1PointTol[e[1]])
|
||||
{
|
||||
edgeEnd = 1;
|
||||
}
|
||||
else if (mag(n & normals2[pHit.index()]) < alignedCos_)
|
||||
{
|
||||
Pout<< "Flat angle edge:" << edgeI
|
||||
<< " face:" << pHit.index()
|
||||
<< " cos:" << mag(n & normals2[pHit.index()])
|
||||
<< endl;
|
||||
edgeEnd = 2;
|
||||
}
|
||||
|
||||
currentIntersectionTypes.append(edgeEnd);
|
||||
|
||||
if (edgeEnd == 1)
|
||||
{
|
||||
// Close to end
|
||||
break;
|
||||
}
|
||||
else
|
||||
{
|
||||
// Continue tracking. Shift by a small amount.
|
||||
p0 = pHit.hitPoint() + tolVec;
|
||||
|
||||
if (((p0-pStart) & n) >= maxS)
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// No hit.
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// Done current edge. Transfer all data into *this
|
||||
currentIntersections.shrink();
|
||||
currentIntersectionTypes.shrink();
|
||||
|
||||
operator[](edgeI).transfer(currentIntersections);
|
||||
classification_[edgeI].transfer(currentIntersectionTypes);
|
||||
|
||||
currentIntersections.clear();
|
||||
currentIntersectionTypes.clear();
|
||||
}
|
||||
|
||||
if (debug)
|
||||
{
|
||||
Pout<< "Found " << nHits << " intersections of edges with surface ..."
|
||||
<< endl;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
// If edgeI intersections are close to endpoint of edge shift endpoints
|
||||
// slightly along edge
|
||||
// Updates
|
||||
// - points1 with new endpoint position
|
||||
// - affectedEdges with all edges affected by moving the point
|
||||
// Returns true if changed anything.
|
||||
bool Foam::edgeIntersections::inlinePerturb
|
||||
(
|
||||
const triSurface& surf1,
|
||||
const scalarField& surf1PointTol, // surf1 tolerance per point
|
||||
const label edgeI,
|
||||
Random& rndGen,
|
||||
pointField& points1,
|
||||
boolList& affectedEdges
|
||||
) const
|
||||
{
|
||||
bool hasPerturbed = false;
|
||||
|
||||
// Check if edge close to endpoint. Note that we only have to check
|
||||
// the intersection closest to the edge endpoints (i.e. first and last in
|
||||
// edgeEdgs)
|
||||
|
||||
const labelList& edgeEnds = classification_[edgeI];
|
||||
|
||||
if (edgeEnds.size() > 0)
|
||||
{
|
||||
bool perturbStart = false;
|
||||
bool perturbEnd = false;
|
||||
|
||||
// Check first intersection.
|
||||
if (edgeEnds[0] == 0)
|
||||
{
|
||||
perturbStart = true;
|
||||
}
|
||||
|
||||
if (edgeEnds[edgeEnds.size()-1] == 1)
|
||||
{
|
||||
perturbEnd = true;
|
||||
}
|
||||
|
||||
|
||||
if (perturbStart || perturbEnd)
|
||||
{
|
||||
const edge& e = surf1.edges()[edgeI];
|
||||
|
||||
label v0 = surf1.meshPoints()[e[0]];
|
||||
label v1 = surf1.meshPoints()[e[1]];
|
||||
|
||||
vector eVec(points1[v1] - points1[v0]);
|
||||
vector n = eVec/mag(eVec);
|
||||
|
||||
if (perturbStart)
|
||||
{
|
||||
// Perturb with something (hopefully) larger than tolerance.
|
||||
scalar t = 4.0*(rndGen.scalar01() - 0.5);
|
||||
points1[v0] += t*surf1PointTol[e[0]]*n;
|
||||
|
||||
const labelList& pEdges = surf1.pointEdges()[e[0]];
|
||||
|
||||
forAll(pEdges, i)
|
||||
{
|
||||
affectedEdges[pEdges[i]] = true;
|
||||
}
|
||||
}
|
||||
if (perturbEnd)
|
||||
{
|
||||
// Perturb with something larger than tolerance.
|
||||
scalar t = 4.0*(rndGen.scalar01() - 0.5);
|
||||
points1[v1] += t*surf1PointTol[e[1]]*n;
|
||||
|
||||
const labelList& pEdges = surf1.pointEdges()[e[1]];
|
||||
|
||||
forAll(pEdges, i)
|
||||
{
|
||||
affectedEdges[pEdges[i]] = true;
|
||||
}
|
||||
}
|
||||
hasPerturbed = true;
|
||||
}
|
||||
}
|
||||
|
||||
return hasPerturbed;
|
||||
}
|
||||
|
||||
|
||||
// Perturb single edge endpoint when perpendicular to face
|
||||
bool Foam::edgeIntersections::rotatePerturb
|
||||
(
|
||||
const triSurface& surf1,
|
||||
const scalarField& surf1PointTol, // surf1 tolerance per point
|
||||
const label edgeI,
|
||||
|
||||
Random& rndGen,
|
||||
pointField& points1,
|
||||
boolList& affectedEdges
|
||||
) const
|
||||
{
|
||||
const labelList& meshPoints = surf1.meshPoints();
|
||||
|
||||
const labelList& edgeEnds = classification_[edgeI];
|
||||
|
||||
bool hasPerturbed = false;
|
||||
|
||||
forAll(edgeEnds, i)
|
||||
{
|
||||
if (edgeEnds[i] == 2)
|
||||
{
|
||||
const edge& e = surf1.edges()[edgeI];
|
||||
|
||||
// Endpoint to modify. Choose either start or end.
|
||||
label pointI = e[rndGen.bit()];
|
||||
//label pointI = e[0];
|
||||
|
||||
// Generate random vector slightly larger than tolerance.
|
||||
vector rndVec = rndGen.vector01() - vector(0.5, 0.5, 0.5);
|
||||
|
||||
// Make sure rndVec only perp to edge
|
||||
vector n(points1[meshPoints[e[1]]] - points1[meshPoints[e[0]]]);
|
||||
scalar magN = mag(n) + VSMALL;
|
||||
n /= magN;
|
||||
|
||||
rndVec -= n*(n & rndVec);
|
||||
|
||||
// Normalize
|
||||
rndVec /= mag(rndVec) + VSMALL;
|
||||
|
||||
// Scale to be moved by tolerance.
|
||||
rndVec *= 0.01*magN;
|
||||
|
||||
Pout<< "rotating: shifting endpoint " << meshPoints[pointI]
|
||||
<< " of edge:" << edgeI << " verts:"
|
||||
<< points1[meshPoints[e[0]]] << ' '
|
||||
<< points1[meshPoints[e[1]]]
|
||||
<< " by " << rndVec
|
||||
<< " tol:" << surf1PointTol[pointI] << endl;
|
||||
|
||||
points1[meshPoints[pointI]] += rndVec;
|
||||
|
||||
// Mark edges affected by change to point
|
||||
const labelList& pEdges = surf1.pointEdges()[pointI];
|
||||
|
||||
forAll(pEdges, i)
|
||||
{
|
||||
affectedEdges[pEdges[i]] = true;
|
||||
}
|
||||
|
||||
hasPerturbed = true;
|
||||
|
||||
// Enough done for current edge; no need to test other intersections
|
||||
// of this edge.
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return hasPerturbed;
|
||||
}
|
||||
|
||||
|
||||
// Perturb edge when close to face
|
||||
bool Foam::edgeIntersections::offsetPerturb
|
||||
(
|
||||
const triSurface& surf1,
|
||||
const triSurface& surf2,
|
||||
const label edgeI,
|
||||
|
||||
Random& rndGen,
|
||||
pointField& points1,
|
||||
boolList& affectedEdges
|
||||
) const
|
||||
{
|
||||
const labelList& meshPoints = surf1.meshPoints();
|
||||
|
||||
const edge& e = surf1.edges()[edgeI];
|
||||
|
||||
const List<pointIndexHit>& hits = operator[](edgeI);
|
||||
|
||||
|
||||
bool hasPerturbed = false;
|
||||
|
||||
// For all hits on edge
|
||||
forAll(hits, i)
|
||||
{
|
||||
const pointIndexHit& pHit = hits[i];
|
||||
|
||||
// Classify point on face of surface2
|
||||
label surf2FaceI = pHit.index();
|
||||
|
||||
const labelledTri& f2 = surf2.localFaces()[surf2FaceI];
|
||||
|
||||
const pointField& surf2Pts = surf2.localPoints();
|
||||
|
||||
label nearType;
|
||||
label nearLabel;
|
||||
|
||||
triPointRef tri
|
||||
(
|
||||
surf2Pts[f2[0]],
|
||||
surf2Pts[f2[1]],
|
||||
surf2Pts[f2[2]]
|
||||
);
|
||||
|
||||
point ctr = tri.centre();
|
||||
|
||||
// Get measure for tolerance.
|
||||
scalar tolDim = 0.001*mag(tri.a() - ctr);
|
||||
|
||||
tri.classify(pHit.hitPoint(), tolDim, nearType, nearLabel);
|
||||
|
||||
if (nearType == triPointRef::POINT || nearType == triPointRef::EDGE)
|
||||
{
|
||||
// Shift edge towards tri centre
|
||||
vector offset = 0.01*rndGen.scalar01()*(ctr - pHit.hitPoint());
|
||||
|
||||
// shift e[0]
|
||||
points1[meshPoints[e[0]]] += offset;
|
||||
|
||||
// Mark edges affected by change to e0
|
||||
const labelList& pEdges0 = surf1.pointEdges()[e[0]];
|
||||
|
||||
forAll(pEdges0, i)
|
||||
{
|
||||
affectedEdges[pEdges0[i]] = true;
|
||||
}
|
||||
|
||||
// shift e[1]
|
||||
points1[meshPoints[e[1]]] += offset;
|
||||
|
||||
// Mark edges affected by change to e1
|
||||
const labelList& pEdges1 = surf1.pointEdges()[e[1]];
|
||||
|
||||
forAll(pEdges1, i)
|
||||
{
|
||||
affectedEdges[pEdges1[i]] = true;
|
||||
}
|
||||
|
||||
hasPerturbed = true;
|
||||
|
||||
// No need to test any other hits on this edge
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return hasPerturbed;
|
||||
}
|
||||
|
||||
|
||||
// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
|
||||
|
||||
// Construct null
|
||||
Foam::edgeIntersections::edgeIntersections()
|
||||
:
|
||||
List<List<pointIndexHit> >(),
|
||||
classification_()
|
||||
{}
|
||||
|
||||
|
||||
// Construct from surface and tolerance
|
||||
Foam::edgeIntersections::edgeIntersections
|
||||
(
|
||||
const triSurface& surf1,
|
||||
const triSurfaceSearch& query2,
|
||||
const scalarField& surf1PointTol
|
||||
)
|
||||
:
|
||||
List<List<pointIndexHit> >(surf1.nEdges()),
|
||||
classification_(surf1.nEdges())
|
||||
{
|
||||
checkEdges(surf1);
|
||||
checkEdges(query2.surface());
|
||||
|
||||
// Current set of edges to test
|
||||
labelList edgesToTest(surf1.nEdges());
|
||||
|
||||
// Start off with all edges
|
||||
forAll(edgesToTest, i)
|
||||
{
|
||||
edgesToTest[i] = i;
|
||||
}
|
||||
|
||||
// Determine intersections for edgesToTest
|
||||
intersectEdges
|
||||
(
|
||||
surf1,
|
||||
surf1.points(), // surf1 meshPoints (not localPoints!)
|
||||
query2,
|
||||
surf1PointTol,
|
||||
edgesToTest
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
// Construct from components
|
||||
Foam::edgeIntersections::edgeIntersections
|
||||
(
|
||||
const List<List<pointIndexHit> >& intersections,
|
||||
const labelListList& classification
|
||||
)
|
||||
:
|
||||
List<List<pointIndexHit> >(intersections),
|
||||
classification_(classification)
|
||||
{}
|
||||
|
||||
|
||||
// * * * * * * * * * * * * * * * Static Functions * * * * * * * * * * * * * //
|
||||
|
||||
Foam::scalarField Foam::edgeIntersections::minEdgeLength(const triSurface& surf)
|
||||
{
|
||||
const pointField& localPoints = surf.localPoints();
|
||||
const labelListList& pointEdges = surf.pointEdges();
|
||||
const edgeList& edges = surf.edges();
|
||||
|
||||
scalarField minLen(localPoints.size());
|
||||
|
||||
forAll(minLen, pointI)
|
||||
{
|
||||
const labelList& pEdges = pointEdges[pointI];
|
||||
|
||||
scalar minDist = GREAT;
|
||||
|
||||
forAll(pEdges, i)
|
||||
{
|
||||
minDist = min(minDist, edges[pEdges[i]].mag(localPoints));
|
||||
}
|
||||
|
||||
minLen[pointI] = minDist;
|
||||
}
|
||||
return minLen;
|
||||
}
|
||||
|
||||
|
||||
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
|
||||
|
||||
Foam::label Foam::edgeIntersections::removeDegenerates
|
||||
(
|
||||
const label nIters,
|
||||
const triSurface& surf1,
|
||||
const triSurfaceSearch& query2,
|
||||
const scalarField& surf1PointTol,
|
||||
pointField& points1
|
||||
)
|
||||
{
|
||||
const triSurface& surf2 = query2.surface();
|
||||
|
||||
Random rndGen(356574);
|
||||
|
||||
// Current set of edges to (re)test
|
||||
labelList edgesToTest(surf1.nEdges());
|
||||
|
||||
// Start off with all edges
|
||||
forAll(edgesToTest, i)
|
||||
{
|
||||
edgesToTest[i] = i;
|
||||
}
|
||||
|
||||
|
||||
label iter = 0;
|
||||
|
||||
for (; iter < nIters; iter++)
|
||||
{
|
||||
// Go through all edges to (re)test and perturb points if they are
|
||||
// degenerate hits. Mark off edges that need to be recalculated.
|
||||
|
||||
boolList affectedEdges(surf1.nEdges(), false);
|
||||
label nShifted = 0;
|
||||
label nRotated = 0;
|
||||
label nOffset = 0;
|
||||
|
||||
forAll(edgesToTest, i)
|
||||
{
|
||||
label edgeI = edgesToTest[i];
|
||||
|
||||
// If edge not already marked for retesting
|
||||
if (!affectedEdges[edgeI])
|
||||
{
|
||||
// 1. Check edges close to endpoint and perturb if nessecary.
|
||||
|
||||
bool shiftedEdgeEndPoints =
|
||||
inlinePerturb
|
||||
(
|
||||
surf1,
|
||||
surf1PointTol,
|
||||
edgeI,
|
||||
rndGen,
|
||||
points1,
|
||||
affectedEdges
|
||||
);
|
||||
|
||||
nShifted += (shiftedEdgeEndPoints ? 1 : 0);
|
||||
|
||||
if (!shiftedEdgeEndPoints)
|
||||
{
|
||||
bool rotatedEdge =
|
||||
rotatePerturb
|
||||
(
|
||||
surf1,
|
||||
surf1PointTol,
|
||||
edgeI,
|
||||
rndGen,
|
||||
points1,
|
||||
affectedEdges
|
||||
);
|
||||
|
||||
nRotated += (rotatedEdge ? 1 : 0);
|
||||
|
||||
if (!rotatedEdge)
|
||||
{
|
||||
// 2. we're sure now that the edge actually pierces the
|
||||
// face. Now check the face for intersections close its
|
||||
// points/edges
|
||||
|
||||
bool offsetEdgePoints =
|
||||
offsetPerturb
|
||||
(
|
||||
surf1,
|
||||
surf2,
|
||||
edgeI,
|
||||
rndGen,
|
||||
points1,
|
||||
affectedEdges
|
||||
);
|
||||
|
||||
nOffset += (offsetEdgePoints ? 1 : 0);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (debug)
|
||||
{
|
||||
Pout<< "Edges to test : " << nl
|
||||
<< " total:" << edgesToTest.size() << nl
|
||||
<< " resolved by:" << nl
|
||||
<< " shifting : " << nShifted << nl
|
||||
<< " rotating : " << nRotated << nl
|
||||
<< " offsetting : " << nOffset << nl
|
||||
<< endl;
|
||||
}
|
||||
|
||||
|
||||
if (nShifted == 0 && nRotated == 0 && nOffset == 0)
|
||||
{
|
||||
// Nothing changed in current iteration. Current hit pattern is
|
||||
// without any degenerates.
|
||||
break;
|
||||
}
|
||||
|
||||
// Repack affected edges
|
||||
labelList newEdgesToTest(surf1.nEdges());
|
||||
label newEdgeI = 0;
|
||||
|
||||
forAll(affectedEdges, edgeI)
|
||||
{
|
||||
if (affectedEdges[edgeI])
|
||||
{
|
||||
newEdgesToTest[newEdgeI++] = edgeI;
|
||||
}
|
||||
}
|
||||
newEdgesToTest.setSize(newEdgeI);
|
||||
|
||||
if (debug)
|
||||
{
|
||||
Pout<< "Edges to test:" << nl
|
||||
<< " was : " << edgesToTest.size() << nl
|
||||
<< " is : " << newEdgesToTest.size() << nl
|
||||
<< endl;
|
||||
}
|
||||
|
||||
// Transfer and test.
|
||||
edgesToTest.transfer(newEdgesToTest);
|
||||
|
||||
if (edgesToTest.size() == 0)
|
||||
{
|
||||
FatalErrorIn("perturb") << "oops" << abort(FatalError);
|
||||
}
|
||||
|
||||
// Re intersect moved edges.
|
||||
intersectEdges
|
||||
(
|
||||
surf1,
|
||||
points1, // surf1 meshPoints (not localPoints!)
|
||||
query2,
|
||||
surf1PointTol,
|
||||
edgesToTest
|
||||
);
|
||||
}
|
||||
|
||||
return iter;
|
||||
}
|
||||
|
||||
|
||||
// * * * * * * * * * * * * * * * Member Operators * * * * * * * * * * * * * //
|
||||
|
||||
|
||||
// * * * * * * * * * * * * * * * Friend Functions * * * * * * * * * * * * * //
|
||||
|
||||
|
||||
// * * * * * * * * * * * * * * * Friend Operators * * * * * * * * * * * * * //
|
||||
|
||||
|
||||
// ************************************************************************* //
|
||||
@ -0,0 +1,211 @@
|
||||
/*---------------------------------------------------------------------------*\
|
||||
========= |
|
||||
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
|
||||
\\ / O peration |
|
||||
\\ / A nd | Copyright (C) 1991-2007 OpenCFD Ltd.
|
||||
\\/ 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 2 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, write to the Free Software Foundation,
|
||||
Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
|
||||
Class
|
||||
Foam::edgeIntersections
|
||||
|
||||
Description
|
||||
Holder of intersections of edges of a surface with another surface.
|
||||
Optionally shuffles around points on surface to resolve any 'conflicts'
|
||||
(edge hitting triangle edge, edge hitting point etc.).
|
||||
|
||||
SourceFiles
|
||||
edgeIntersections.C
|
||||
|
||||
\*---------------------------------------------------------------------------*/
|
||||
|
||||
#ifndef edgeIntersections_H
|
||||
#define edgeIntersections_H
|
||||
|
||||
#include "pointIndexHit.H"
|
||||
#include "scalarField.H"
|
||||
#include "pointField.H"
|
||||
#include "typeInfo.H"
|
||||
#include "boolList.H"
|
||||
|
||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||
|
||||
namespace Foam
|
||||
{
|
||||
|
||||
// Forward declaration of classes
|
||||
class triSurface;
|
||||
class triSurfaceSearch;
|
||||
class Random;
|
||||
class edge;
|
||||
|
||||
/*---------------------------------------------------------------------------*\
|
||||
Class edgeIntersections Declaration
|
||||
\*---------------------------------------------------------------------------*/
|
||||
|
||||
class edgeIntersections
|
||||
:
|
||||
public List<List<pointIndexHit> >
|
||||
{
|
||||
// Private data
|
||||
|
||||
//- For every entry in *this gives the edge classification result.
|
||||
// -1 : intersection not close to edge
|
||||
// 0 : intersection close to e[0]
|
||||
// 1 : intersection close to e[1]
|
||||
// 2 : edge aligned with intersection face
|
||||
labelListList classification_;
|
||||
|
||||
|
||||
// Private Member Functions
|
||||
|
||||
//- Check for too small edges
|
||||
static void checkEdges(const triSurface& surf);
|
||||
|
||||
//- Intersect selected surface edges (edgeLabels) with surface2.
|
||||
// Updates *this with pointHits and classification_ with status
|
||||
// of hitPoint compared to edge end points.
|
||||
void intersectEdges
|
||||
(
|
||||
const triSurface& surf1,
|
||||
const pointField& points1, // surf1 meshPoints
|
||||
const triSurfaceSearch& querySurf2,
|
||||
const scalarField& surf1PointTol, // surf1 tolerance per point
|
||||
const labelList& edgeLabels
|
||||
);
|
||||
|
||||
//- Perturb endpoints of edge if they are close to the intersection.
|
||||
// Move point (in points1) by factor*surf1PointTol in direction of
|
||||
// edge. Mark pointEdges of moved point in affectedEdges.
|
||||
// Return true if anything changed.
|
||||
bool inlinePerturb
|
||||
(
|
||||
const triSurface& surf1,
|
||||
const scalarField& surf1PointTol,
|
||||
const label edgeI,
|
||||
Random& rndGen,
|
||||
pointField& points1,
|
||||
boolList& affectedEdges
|
||||
) const;
|
||||
|
||||
//- Perturb single endpoint of edge if edge is algigned with face.
|
||||
// See inlinePerturb. Return true if anything changed.
|
||||
bool rotatePerturb
|
||||
(
|
||||
const triSurface& surf1,
|
||||
const scalarField& surf1PointTol,
|
||||
const label edgeI,
|
||||
Random& rndGen,
|
||||
pointField& points1,
|
||||
boolList& affectedEdges
|
||||
) const;
|
||||
|
||||
|
||||
//- Perturb edge by shifting in direction trianglecentre - intersection
|
||||
// when hits close to face. Update points, mark affected edges and
|
||||
// return true if anything changed.
|
||||
bool offsetPerturb
|
||||
(
|
||||
const triSurface& surf1,
|
||||
const triSurface& surf2,
|
||||
const label edgeI,
|
||||
|
||||
Random& rndGen,
|
||||
pointField& points1,
|
||||
boolList& affectedEdges
|
||||
) const;
|
||||
|
||||
public:
|
||||
|
||||
ClassName("edgeIntersections");
|
||||
|
||||
|
||||
// Static data members
|
||||
|
||||
//- cosine between edge and face normal when considered parallel
|
||||
// (note: should be private and make access- and set- function)
|
||||
static scalar alignedCos_;
|
||||
|
||||
|
||||
// Static Functions
|
||||
|
||||
//- Calculate min edge length for every surface point
|
||||
static scalarField minEdgeLength(const triSurface& surf);
|
||||
|
||||
|
||||
// Constructors
|
||||
|
||||
//- Construct null
|
||||
edgeIntersections();
|
||||
|
||||
//- Construct from surface and tolerance
|
||||
edgeIntersections
|
||||
(
|
||||
const triSurface& surf1,
|
||||
const triSurfaceSearch& query2,
|
||||
const scalarField& surf1PointTol
|
||||
);
|
||||
|
||||
//- Construct from components
|
||||
edgeIntersections
|
||||
(
|
||||
const List<List<pointIndexHit> >&,
|
||||
const labelListList&
|
||||
);
|
||||
|
||||
|
||||
// Member Functions
|
||||
|
||||
|
||||
// Access
|
||||
|
||||
//- For every intersection the classification status.
|
||||
const labelListList& classification() const
|
||||
{
|
||||
return classification_;
|
||||
}
|
||||
|
||||
|
||||
// Edit
|
||||
|
||||
//- Resolve ties. Shuffles points so all edge - face intersections
|
||||
// will be on the face interior.
|
||||
// Points will be the new surface points.
|
||||
// Returns number of iterations needed. (= nIters if still
|
||||
// has degenerate cuts)
|
||||
label removeDegenerates
|
||||
(
|
||||
const label nIters,
|
||||
const triSurface& surf1,
|
||||
const triSurfaceSearch& query2,
|
||||
const scalarField& surf1PointTol,
|
||||
pointField& points1
|
||||
);
|
||||
};
|
||||
|
||||
|
||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||
|
||||
} // End namespace Foam
|
||||
|
||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||
|
||||
#endif
|
||||
|
||||
// ************************************************************************* //
|
||||
File diff suppressed because it is too large
Load Diff
@ -0,0 +1,309 @@
|
||||
/*---------------------------------------------------------------------------*\
|
||||
========= |
|
||||
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
|
||||
\\ / O peration |
|
||||
\\ / A nd | Copyright (C) 1991-2007 OpenCFD Ltd.
|
||||
\\/ 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 2 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, write to the Free Software Foundation,
|
||||
Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
|
||||
Class
|
||||
Foam::surfaceIntersection
|
||||
|
||||
Description
|
||||
Basic surface-surface intersection description. Constructed from two
|
||||
surfaces it creates a description of the intersection.
|
||||
|
||||
The intersection information consists of the intersection line(s)
|
||||
with new points, new edges between points (note that these edges and
|
||||
points are on both surfaces) and various addressing from original
|
||||
surface faces/edges to intersection and vice versa.
|
||||
|
||||
Gets either precalculated intersection information or calculates it
|
||||
itself.
|
||||
Algorithm works by intersecting all edges of one surface with the other
|
||||
surface and storing a reference from both faces (one on surface1, one on
|
||||
surface 2) to the vertex. If the reference re-occurs we have the second
|
||||
hit of both faces and an edge is created between the retrieved vertex and
|
||||
the new one.
|
||||
|
||||
Note: when doing intersecting itself uses intersection::planarTol() as a
|
||||
fraction of
|
||||
current edge length to determine if intersection is a point-touching one
|
||||
instead of an edge-piercing action.
|
||||
|
||||
SourceFiles
|
||||
surfaceIntersection.C
|
||||
surfaceIntersectionFuncs.C
|
||||
surfaceIntersectionTemplates.C
|
||||
|
||||
\*---------------------------------------------------------------------------*/
|
||||
|
||||
#ifndef surfaceIntersection_H
|
||||
#define surfaceIntersection_H
|
||||
|
||||
#include "DynamicList.H"
|
||||
#include "point.H"
|
||||
#include "edge.H"
|
||||
#include "labelPairLookup.H"
|
||||
#include "typeInfo.H"
|
||||
#include "edgeList.H"
|
||||
#include "pointIndexHit.H"
|
||||
|
||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||
|
||||
namespace Foam
|
||||
{
|
||||
|
||||
// Forward declaration of classes
|
||||
class triSurfaceSearch;
|
||||
class triSurface;
|
||||
class edgeIntersections;
|
||||
|
||||
/*---------------------------------------------------------------------------*\
|
||||
Class surfaceIntersection Declaration
|
||||
\*---------------------------------------------------------------------------*/
|
||||
|
||||
class surfaceIntersection
|
||||
{
|
||||
// Private data
|
||||
|
||||
//- Newly introduced points.
|
||||
pointField cutPoints_;
|
||||
|
||||
//- Newly introduced edges (are on both surfaces). Reference into
|
||||
// cutPoints.
|
||||
edgeList cutEdges_;
|
||||
|
||||
//- From face on surf1 and face on surf2 to intersection point
|
||||
// (label in cutPoints)
|
||||
labelPairLookup facePairToVertex_;
|
||||
|
||||
//- From face on surf1 and face on surf2 to intersection edge
|
||||
// (label in cutEdges)
|
||||
labelPairLookup facePairToEdge_;
|
||||
|
||||
//- Edges on surf1 that are cut. From edge on surf1 to label in cutPoint
|
||||
// If multiple cuts:sorted from edge.start to edge.end
|
||||
labelListList surf1EdgeCuts_;
|
||||
|
||||
//- Edges on surf2 that are cut. From edge on surf2 to label in cutPoint
|
||||
// If multiple cuts:sorted from edge.start to edge.end
|
||||
labelListList surf2EdgeCuts_;
|
||||
|
||||
|
||||
// Private Member Functions
|
||||
|
||||
//- Write point in obj format.
|
||||
static void writeOBJ(const point& pt, Ostream& os);
|
||||
|
||||
//- Write points and edges in obj format
|
||||
static void writeOBJ
|
||||
(
|
||||
const List<point>&,
|
||||
const List<edge>&,
|
||||
Ostream&
|
||||
);
|
||||
|
||||
//- Transfer contents of DynamicList to straight List
|
||||
template<class T>
|
||||
static void transfer(DynamicList<T>&, List<T>&);
|
||||
|
||||
//- Transfer contents of List<DynamicList<..> > to List<List<..>>
|
||||
template<class T>
|
||||
static void transfer(List<DynamicList<T> >&, List<List<T> >&);
|
||||
|
||||
//- Get minimum length of all edges connected to point
|
||||
static scalar minEdgeLen(const triSurface& surf, const label pointI);
|
||||
|
||||
//- Get edge label of edge between face vertices fp and fp+1
|
||||
static label getEdge
|
||||
(
|
||||
const triSurface& surf,
|
||||
const label faceI,
|
||||
const label fp
|
||||
);
|
||||
|
||||
//- Remove duplicates from ordered dynamic list. Returns map from old
|
||||
// to new (-1 if element removed)
|
||||
static void removeDuplicates(const labelList& map, labelList& labels);
|
||||
|
||||
//- Apply map to elements of a labelList
|
||||
static void inlineRemap(const labelList& map, labelList& elems);
|
||||
|
||||
// Remove all duplicate and degenerate elements. Return unique elements
|
||||
// and map from old to new.
|
||||
static edgeList filterEdges(const edgeList&, labelList& map);
|
||||
|
||||
//- Remove all duplicate elements.
|
||||
static labelList filterLabels(const labelList& elems, labelList& map);
|
||||
|
||||
//- Do some checks if edge and face (resulting from hit)
|
||||
// should not be considered. Returns true if can be discarded.
|
||||
static bool excludeEdgeHit
|
||||
(
|
||||
const triSurface& surf,
|
||||
const label edgeI,
|
||||
const label faceI,
|
||||
const scalar tol
|
||||
);
|
||||
|
||||
////- Given edge (eStart - eEnd) and normal direction construct plane
|
||||
//// and intersect all edges of hitFace with it.
|
||||
//// Return the edge and coordinate of hit.
|
||||
//static pointIndexHit faceEdgeIntersection
|
||||
//(
|
||||
// const triSurface&,
|
||||
// const label hitFaceI,
|
||||
//
|
||||
// const vector& n,
|
||||
// const point& eStart,
|
||||
// const point& eEnd
|
||||
//);
|
||||
|
||||
|
||||
//- Debugging: Dump intersected edges to stream
|
||||
void writeIntersectedEdges
|
||||
(
|
||||
const triSurface& surf,
|
||||
const labelListList& edgeCutVerts,
|
||||
Ostream& os
|
||||
) const;
|
||||
|
||||
//- Detect if point close to edge of end. Returns -1: not close.
|
||||
// 0:close (within startTol) to start, 1:close (within endTol) to end
|
||||
static label classify
|
||||
(
|
||||
const scalar startTol,
|
||||
const scalar endTol,
|
||||
const point& p,
|
||||
const edge& e,
|
||||
const pointField& points
|
||||
);
|
||||
|
||||
//- Update reference between faceA and faceB. Updates facePairToVertex_
|
||||
// (first occurrence of face pair) and facePairToEdge_ (second occ.)
|
||||
void storeIntersection
|
||||
(
|
||||
const bool isFirstSurf,
|
||||
const labelList& facesA,
|
||||
const label faceB,
|
||||
DynamicList<edge>&,
|
||||
DynamicList<point>&
|
||||
);
|
||||
|
||||
//- Investigate pHit to whether is case of point hits point,
|
||||
// point hits edge, point hits face or edge hits face.
|
||||
void classifyHit
|
||||
(
|
||||
const triSurface& surf1,
|
||||
const scalarField& surf1PointTol,
|
||||
const triSurface& surf2,
|
||||
const bool isFirstSurf,
|
||||
const label edgeI,
|
||||
const scalar tolDim,
|
||||
const pointIndexHit& pHit,
|
||||
|
||||
DynamicList<edge>& allCutEdges,
|
||||
DynamicList<point>& allCutPoints,
|
||||
List<DynamicList<label> >& surfEdgeCuts
|
||||
);
|
||||
|
||||
//- Cut edges of surf1 with surface 2.
|
||||
void doCutEdges
|
||||
(
|
||||
const triSurface& surf1,
|
||||
const triSurfaceSearch& querySurf2,
|
||||
const bool isFirstSurf,
|
||||
const bool isSelfIntersection,
|
||||
|
||||
DynamicList<edge>& allCutEdges,
|
||||
DynamicList<point>& allCutPoints,
|
||||
List<DynamicList<label> >& surfEdgeCuts
|
||||
);
|
||||
|
||||
public:
|
||||
|
||||
ClassName("surfaceIntersection");
|
||||
|
||||
|
||||
// Constructors
|
||||
|
||||
//- Construct null
|
||||
surfaceIntersection();
|
||||
|
||||
//- Construct from precalculated intersection information.
|
||||
// Advantage: intersection information is guaranteed to have no
|
||||
// degenerate cuts.
|
||||
surfaceIntersection
|
||||
(
|
||||
const triSurface& surf1,
|
||||
const edgeIntersections& intersections1,
|
||||
const triSurface& surf2,
|
||||
const edgeIntersections& intersections2
|
||||
);
|
||||
|
||||
//- Construct from two surfaces. Does all its own cutting.
|
||||
// Has problems with degenerate cuts
|
||||
surfaceIntersection
|
||||
(
|
||||
const triSurfaceSearch& querySurf1,
|
||||
const triSurfaceSearch& querySurf2
|
||||
);
|
||||
|
||||
//- Special: intersect surface with itself. Used to check for
|
||||
// self-intersection.
|
||||
surfaceIntersection(const triSurfaceSearch& querySurf1);
|
||||
|
||||
|
||||
// Member Functions
|
||||
|
||||
const pointField& cutPoints() const;
|
||||
|
||||
const edgeList& cutEdges() const;
|
||||
|
||||
//const labelPairLookup& facePairToVertex() const;
|
||||
|
||||
const labelPairLookup& facePairToEdge() const;
|
||||
|
||||
//- Access either surf1EdgeCuts (isFirstSurface = true) or
|
||||
// surf2EdgeCuts
|
||||
const labelListList& edgeCuts(const bool) const;
|
||||
|
||||
const labelListList& surf1EdgeCuts() const;
|
||||
|
||||
const labelListList& surf2EdgeCuts() const;
|
||||
|
||||
};
|
||||
|
||||
|
||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||
|
||||
} // End namespace Foam
|
||||
|
||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||
|
||||
#ifdef NoRepository
|
||||
# include "surfaceIntersectionTemplates.C"
|
||||
#endif
|
||||
|
||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||
|
||||
#endif
|
||||
|
||||
// ************************************************************************* //
|
||||
@ -0,0 +1,341 @@
|
||||
/*---------------------------------------------------------------------------*\
|
||||
========= |
|
||||
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
|
||||
\\ / O peration |
|
||||
\\ / A nd | Copyright (C) 1991-2007 OpenCFD Ltd.
|
||||
\\/ 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 2 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, write to the Free Software Foundation,
|
||||
Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
|
||||
Description
|
||||
|
||||
\*---------------------------------------------------------------------------*/
|
||||
|
||||
#include "surfaceIntersection.H"
|
||||
#include "triSurfaceSearch.H"
|
||||
#include "labelPairLookup.H"
|
||||
#include "OFstream.H"
|
||||
#include "HashSet.H"
|
||||
#include "labelHashSet.H"
|
||||
#include "triSurface.H"
|
||||
#include "pointIndexHit.H"
|
||||
#include "octreeDataTriSurface.H"
|
||||
#include "octree.H"
|
||||
#include "meshTools.H"
|
||||
|
||||
// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
|
||||
|
||||
|
||||
// * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * //
|
||||
|
||||
void Foam::surfaceIntersection::writeOBJ(const point& pt, Ostream& os)
|
||||
{
|
||||
os << "v " << pt.x() << ' ' << pt.y() << ' ' << pt.z() << endl;
|
||||
}
|
||||
|
||||
|
||||
void Foam::surfaceIntersection::writeOBJ
|
||||
(
|
||||
const List<point>& pts,
|
||||
const List<edge>& edges,
|
||||
Ostream& os
|
||||
)
|
||||
{
|
||||
forAll(pts, i)
|
||||
{
|
||||
writeOBJ(pts[i], os);
|
||||
}
|
||||
forAll(edges, i)
|
||||
{
|
||||
const edge& e = edges[i];
|
||||
|
||||
os << "l " << e.start()+1 << ' ' << e.end()+1 << endl;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// Get minimum length of all edges connected to point
|
||||
Foam::scalar Foam::surfaceIntersection::minEdgeLen
|
||||
(
|
||||
const triSurface& surf,
|
||||
const label pointI
|
||||
)
|
||||
{
|
||||
const labelList& pEdges = surf.pointEdges()[pointI];
|
||||
|
||||
scalar minLen = GREAT;
|
||||
|
||||
forAll(pEdges, pEdgeI)
|
||||
{
|
||||
const edge& e = surf.edges()[pEdges[pEdgeI]];
|
||||
|
||||
minLen = min(minLen, e.mag(surf.localPoints()));
|
||||
}
|
||||
|
||||
return minLen;
|
||||
}
|
||||
|
||||
|
||||
// Get edge between fp and fp+1 on faceI.
|
||||
Foam::label Foam::surfaceIntersection::getEdge
|
||||
(
|
||||
const triSurface& surf,
|
||||
const label faceI,
|
||||
const label fp
|
||||
)
|
||||
{
|
||||
const labelledTri& f = surf.localFaces()[faceI];
|
||||
|
||||
edge faceEdge(f[fp], f[(fp+1) % 3]);
|
||||
|
||||
const labelList& eLabels = surf.faceEdges()[faceI];
|
||||
|
||||
forAll(eLabels, eI)
|
||||
{
|
||||
const label edgeI = eLabels[eI];
|
||||
|
||||
if (surf.edges()[edgeI] == faceEdge)
|
||||
{
|
||||
return edgeI;
|
||||
}
|
||||
}
|
||||
|
||||
FatalErrorIn
|
||||
(
|
||||
"surfaceIntersection::getEdge(const triSurface&"
|
||||
", const label, const label"
|
||||
) << "Problem:: Cannot find edge with vertices " << faceEdge
|
||||
<< " in face " << faceI
|
||||
<< abort(FatalError);
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
||||
// Given a map remove all consecutive duplicate elements.
|
||||
void Foam::surfaceIntersection::removeDuplicates
|
||||
(
|
||||
const labelList& map,
|
||||
labelList& elems
|
||||
)
|
||||
{
|
||||
bool hasDuplicate = false;
|
||||
|
||||
label prevVertI = -1;
|
||||
|
||||
forAll(elems, elemI)
|
||||
{
|
||||
label newVertI = map[elems[elemI]];
|
||||
|
||||
if (newVertI == prevVertI)
|
||||
{
|
||||
hasDuplicate = true;
|
||||
|
||||
break;
|
||||
}
|
||||
prevVertI = newVertI;
|
||||
}
|
||||
|
||||
if (hasDuplicate)
|
||||
{
|
||||
// Create copy
|
||||
labelList oldElems(elems);
|
||||
|
||||
label elemI = 0;
|
||||
|
||||
// Insert first
|
||||
elems[elemI++] = map[oldElems[0]];
|
||||
|
||||
for(label vertI = 1; vertI < oldElems.size(); vertI++)
|
||||
{
|
||||
// Insert others only if they differ from one before
|
||||
label newVertI = map[oldElems[vertI]];
|
||||
|
||||
if (newVertI != elems[elems.size()-1])
|
||||
{
|
||||
elems[elemI++] = newVertI;
|
||||
}
|
||||
}
|
||||
elems.setSize(elemI);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// Remap.
|
||||
void Foam::surfaceIntersection::inlineRemap
|
||||
(
|
||||
const labelList& map,
|
||||
labelList& elems
|
||||
)
|
||||
{
|
||||
forAll(elems, elemI)
|
||||
{
|
||||
elems[elemI] = map[elems[elemI]];
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// Remove all duplicate and degenerate elements. Return unique elements and
|
||||
// map from old to new.
|
||||
Foam::edgeList Foam::surfaceIntersection::filterEdges
|
||||
(
|
||||
const edgeList& edges,
|
||||
labelList& map
|
||||
)
|
||||
{
|
||||
HashSet<edge, Hash<edge> > uniqueEdges(10*edges.size());
|
||||
|
||||
edgeList newEdges(edges.size());
|
||||
|
||||
map.setSize(edges.size());
|
||||
map = -1;
|
||||
|
||||
label newEdgeI = 0;
|
||||
|
||||
forAll(edges, edgeI)
|
||||
{
|
||||
const edge& e = edges[edgeI];
|
||||
|
||||
if
|
||||
(
|
||||
(e.start() != e.end())
|
||||
&& (uniqueEdges.find(e) == uniqueEdges.end())
|
||||
)
|
||||
{
|
||||
// Edge is -non degenerate and -not yet seen.
|
||||
uniqueEdges.insert(e);
|
||||
|
||||
map[edgeI] = newEdgeI;
|
||||
|
||||
newEdges[newEdgeI++] = e;
|
||||
}
|
||||
}
|
||||
|
||||
newEdges.setSize(newEdgeI);
|
||||
|
||||
return newEdges;
|
||||
}
|
||||
|
||||
|
||||
// Remove all duplicate elements.
|
||||
Foam::labelList Foam::surfaceIntersection::filterLabels
|
||||
(
|
||||
const labelList& elems,
|
||||
labelList& map
|
||||
)
|
||||
{
|
||||
labelHashSet uniqueElems(10*elems.size());
|
||||
|
||||
labelList newElems(elems.size());
|
||||
|
||||
map.setSize(elems.size());
|
||||
map = -1;
|
||||
|
||||
label newElemI = 0;
|
||||
|
||||
forAll(elems, elemI)
|
||||
{
|
||||
label elem = elems[elemI];
|
||||
|
||||
if (uniqueElems.find(elem) == uniqueElems.end())
|
||||
{
|
||||
// First time elem is seen
|
||||
uniqueElems.insert(elem);
|
||||
|
||||
map[elemI] = newElemI;
|
||||
|
||||
newElems[newElemI++] = elem;
|
||||
}
|
||||
}
|
||||
|
||||
newElems.setSize(newElemI);
|
||||
|
||||
return newElems;
|
||||
}
|
||||
|
||||
|
||||
void Foam::surfaceIntersection::writeIntersectedEdges
|
||||
(
|
||||
const triSurface& surf,
|
||||
const labelListList& edgeCutVerts,
|
||||
Ostream& os
|
||||
) const
|
||||
{
|
||||
// Dump all points (surface followed by cutPoints)
|
||||
const pointField& pts = surf.localPoints();
|
||||
|
||||
forAll(pts, pointI)
|
||||
{
|
||||
writeOBJ(pts[pointI], os);
|
||||
}
|
||||
forAll(cutPoints(), cutPointI)
|
||||
{
|
||||
writeOBJ(cutPoints()[cutPointI], os);
|
||||
}
|
||||
|
||||
forAll(edgeCutVerts, edgeI)
|
||||
{
|
||||
const labelList& extraVerts = edgeCutVerts[edgeI];
|
||||
|
||||
if (extraVerts.size() != 0)
|
||||
{
|
||||
const edge& e = surf.edges()[edgeI];
|
||||
|
||||
// Start of original edge to first extra point
|
||||
os << "l " << e.start()+1 << ' '
|
||||
<< extraVerts[0] + surf.nPoints() + 1 << endl;
|
||||
|
||||
for(label i = 1; i < extraVerts.size(); i++)
|
||||
{
|
||||
os << "l " << extraVerts[i-1] + surf.nPoints() + 1 << ' '
|
||||
<< extraVerts[i] + surf.nPoints() + 1 << endl;
|
||||
}
|
||||
|
||||
os << "l " << extraVerts[extraVerts.size()-1] + surf.nPoints() + 1
|
||||
<< ' ' << e.end()+1 << endl;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// Return 0 (p close to start), 1(close to end) or -1.
|
||||
Foam::label Foam::surfaceIntersection::classify
|
||||
(
|
||||
const scalar startTol,
|
||||
const scalar endTol,
|
||||
const point& p,
|
||||
const edge& e,
|
||||
const pointField& points
|
||||
)
|
||||
{
|
||||
if (mag(p - points[e.start()]) < startTol)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
else if (mag(p - points[e.end()]) < endTol)
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// ************************************************************************* //
|
||||
@ -0,0 +1,64 @@
|
||||
/*---------------------------------------------------------------------------*\
|
||||
========= |
|
||||
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
|
||||
\\ / O peration |
|
||||
\\ / A nd | Copyright (C) 1991-2007 OpenCFD Ltd.
|
||||
\\/ 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 2 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, write to the Free Software Foundation,
|
||||
Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
|
||||
Description
|
||||
|
||||
\*---------------------------------------------------------------------------*/
|
||||
|
||||
#include "surfaceIntersection.H"
|
||||
|
||||
// * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * //
|
||||
|
||||
// Transfer contents of DynamicList to List
|
||||
template<class T>
|
||||
void Foam::surfaceIntersection::transfer
|
||||
(
|
||||
DynamicList<T>& dList,
|
||||
List<T>& lList
|
||||
)
|
||||
{
|
||||
dList.shrink();
|
||||
lList.transfer(dList);
|
||||
dList.clear();
|
||||
}
|
||||
|
||||
|
||||
// Transfer contents of DynamicList to List
|
||||
template<class T>
|
||||
void Foam::surfaceIntersection::transfer
|
||||
(
|
||||
List<DynamicList<T> >& dList,
|
||||
List<List<T> >& lList
|
||||
)
|
||||
{
|
||||
lList.setSize(dList.size());
|
||||
|
||||
forAll(dList, elemI)
|
||||
{
|
||||
transfer(dList[elemI], lList[elemI]);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// ************************************************************************* //
|
||||
Reference in New Issue
Block a user