/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | Copyright (C) 2011-2012 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 .
\*---------------------------------------------------------------------------*/
#include "edgeIntersections.H"
#include "triSurfaceSearch.H"
#include "labelPairLookup.H"
#include "OFstream.H"
#include "HashSet.H"
#include "triSurface.H"
#include "pointIndexHit.H"
#include "treeDataTriSurface.H"
#include "indexedOctree.H"
#include "meshTools.H"
#include "plane.H"
#include "Random.H"
#include "unitConversion.H"
#include "treeBoundBox.H"
// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
defineTypeNameAndDebug(Foam::edgeIntersections, 0);
Foam::scalar Foam::edgeIntersections::alignedCos_ = Foam::cos(degToRad(89.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 indexedOctree& 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 currentIntersections(100);
DynamicList