diff --git a/src/meshTools/triSurface/booleanOps/surfaceIntersection/surfaceIntersection.C b/src/meshTools/triSurface/booleanOps/surfaceIntersection/surfaceIntersection.C index a98dd53e91..4eca27e13d 100644 --- a/src/meshTools/triSurface/booleanOps/surfaceIntersection/surfaceIntersection.C +++ b/src/meshTools/triSurface/booleanOps/surfaceIntersection/surfaceIntersection.C @@ -40,6 +40,8 @@ namespace Foam defineTypeNameAndDebug(surfaceIntersection, 0); } +const Foam::scalar Foam::surfaceIntersection::defaultTolerance = 1e-3; + // * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * // @@ -60,7 +62,7 @@ bool Foam::surfaceIntersection::excludeEdgeHit forAll(f, fp) { - if (f[0] == e.start() || f[0] == e.end()) + if (f[fp] == e.start() || f[fp] == e.end()) { return true; } @@ -194,29 +196,52 @@ bool Foam::surfaceIntersection::excludeEdgeHit void Foam::surfaceIntersection::storeIntersection ( - const bool isFirstSurf, + const enum originatingType cutFrom, const labelList& facesA, const label faceB, DynamicList& allCutEdges, DynamicList& allCutPoints ) { + // Our lookup for two faces - populate with faceB (invariant) + // Normally always have face from the first surface as first element + labelPair twoFaces(faceB, faceB); + + const label pointId = allCutPoints.size()-1; + forAll(facesA, facesAI) { - label faceA = facesA[facesAI]; + const label faceA = facesA[facesAI]; - // Combine two faces. Always make sure the face from the first surface - // is element 0. - FixedList twoFaces; - if (isFirstSurf) + switch (cutFrom) { - twoFaces[0] = faceA; - twoFaces[1] = faceB; - } - else - { - twoFaces[0] = faceB; - twoFaces[1] = faceA; + case surfaceIntersection::FIRST: + { + // faceA from 1st, faceB from 2nd + twoFaces.first() = faceA; + break; + } + case surfaceIntersection::SECOND: + { + // faceA from 2nd, faceB from 1st + twoFaces.second() = faceA; + break; + } + case surfaceIntersection::SELF: + { + // Lookup should be commutativity - use sorted order + if (faceA < faceB) + { + twoFaces.first() = faceA; + twoFaces.second() = faceB; + } + else + { + twoFaces.first() = faceB; + twoFaces.second() = faceA; + } + break; + } } labelPairLookup::const_iterator iter = facePairToVertex_.find(twoFaces); @@ -224,7 +249,7 @@ void Foam::surfaceIntersection::storeIntersection if (iter == facePairToVertex_.end()) { // New intersection. Store face-face intersection. - facePairToVertex_.insert(twoFaces, allCutPoints.size()-1); + facePairToVertex_.insert(twoFaces, pointId); } else { @@ -240,18 +265,17 @@ void Foam::surfaceIntersection::storeIntersection { WarningInFunction << "Encountered degenerate edge between face " - << twoFaces[0] << " on first surface" - << " and face " << twoFaces[1] << " on second surface" - << endl + << twoFaces[0] << " on first surface and face " + << twoFaces[1] << " on second surface" << endl << "Point on first surface:" << prevHit << endl << "Point on second surface:" << thisHit << endl << endl; } else { - allCutEdges.append(edge(*iter, allCutPoints.size()-1)); + allCutEdges.append(edge(*iter, pointId)); - // Remember face on surf + // Record intersection of faces on surf facePairToEdge_.insert(twoFaces, allCutEdges.size()-1); } } @@ -274,9 +298,8 @@ void Foam::surfaceIntersection::classifyHit const triSurface& surf1, const scalarField& surf1PointTol, const triSurface& surf2, - const bool isFirstSurf, + const enum originatingType cutFrom, const label edgeI, - const scalar tolDim, const pointIndexHit& pHit, DynamicList& allCutEdges, @@ -301,7 +324,7 @@ void Foam::surfaceIntersection::classifyHit f2.nearestPointClassify(pHit.hitPoint(), surf2Pts, nearType, nearLabel); // Classify points on edge of surface1 - label edgeEnd = + const label edgeEnd = classify ( surf1PointTol[e.start()], @@ -344,7 +367,7 @@ void Foam::surfaceIntersection::classifyHit { storeIntersection ( - isFirstSurf, + cutFrom, facesA, facesB[faceBI], allCutEdges, @@ -362,7 +385,7 @@ void Foam::surfaceIntersection::classifyHit label edge2I = getEdge(surf2, surf2Facei, nearLabel); const edge& e2 = surf2.edges()[edge2I]; - if (debug&2) + if (debug & 2) { Pout<< pHit.hitPoint() << " is surf1:" << " end point of edge " << e @@ -382,7 +405,7 @@ void Foam::surfaceIntersection::classifyHit label edge2I = getEdge(surf2, surf2Facei, nearLabel); const edge& e2 = surf2.edges()[edge2I]; - if (debug&2) + if (debug & 2) { Pout<< pHit.hitPoint() << " is surf1:" << " somewhere on edge " << e @@ -396,7 +419,7 @@ void Foam::surfaceIntersection::classifyHit // edge hits all faces on surf2 connected to the edge - if (isFirstSurf) + if (cutFrom == surfaceIntersection::FIRST) { // edge-edge intersection is symmetric, store only // once. @@ -409,7 +432,7 @@ void Foam::surfaceIntersection::classifyHit { storeIntersection ( - isFirstSurf, + cutFrom, facesA, facesB[faceBI], allCutEdges, @@ -425,7 +448,7 @@ void Foam::surfaceIntersection::classifyHit { // 5. Point hits face. Do what? Introduce // point & triangulation in face? - if (debug&2) + if (debug & 2) { Pout<< pHit.hitPoint() << " is surf1:" << " end point of edge " << e @@ -438,36 +461,23 @@ void Foam::surfaceIntersection::classifyHit // inside of surf2 (i.e. on opposite side of normal) // - // Vertex on/near surf2 - label nearVert = -1; - - if (edgeEnd == 0) - { - nearVert = e.start(); - } - else - { - nearVert = e.end(); - } - - const point& nearPt = surf1.localPoints()[nearVert]; - - // Vertex away from surf2 - label otherVert = e.otherVertex(nearVert); + // Vertex on/near surf2; vertex away from surf2 + const label nearVert = (edgeEnd == 0 ? e.start() : e.end()); + const label otherVert = (edgeEnd == 0 ? e.end() : e.start()); + const point& nearPt = surf1.localPoints()[nearVert]; const point& otherPt = surf1.localPoints()[otherVert]; - if (debug) { Pout << pHit.hitPoint() << " is surf1:" << " end point of edge " << e << " coord:" - << surf1.localPoints()[nearVert] + << nearPt << " surf2: face " << surf2Facei << endl; } - vector eVec = otherPt - nearPt; + const vector eVec = otherPt - nearPt; if ((surf2.faceNormals()[surf2Facei] & eVec) > 0) { @@ -477,7 +487,7 @@ void Foam::surfaceIntersection::classifyHit //point hitPt = nearPt + 0.1*eVec; point hitPt = nearPt; - if (debug&2) + if (debug & 2) { Pout<< "Shifted " << pHit.hitPoint() << " to " << hitPt @@ -494,7 +504,7 @@ void Foam::surfaceIntersection::classifyHit // edge hits single face only storeIntersection ( - isFirstSurf, + cutFrom, facesA, surf2Facei, allCutEdges, @@ -503,7 +513,7 @@ void Foam::surfaceIntersection::classifyHit } else { - if (debug&2) + if (debug & 2) { Pout<< "Discarding " << pHit.hitPoint() << " since edge " << e << " on inside of surf2." @@ -515,7 +525,7 @@ void Foam::surfaceIntersection::classifyHit else { // 6. Edge pierces face. 'Normal' situation. - if (debug&2) + if (debug & 2) { Pout<< pHit.hitPoint() << " is surf1:" << " somewhere on edge " << e @@ -530,7 +540,7 @@ void Foam::surfaceIntersection::classifyHit // edge hits single face only storeIntersection ( - isFirstSurf, + cutFrom, facesA, surf2Facei, allCutEdges, @@ -538,7 +548,7 @@ void Foam::surfaceIntersection::classifyHit ); } } - if (debug&2) + if (debug & 2) { Pout<< endl; } @@ -557,15 +567,14 @@ void Foam::surfaceIntersection::doCutEdges ( const triSurface& surf1, const triSurfaceSearch& querySurf2, - const bool isFirstSurf, - const bool isSelfIntersection, + const enum originatingType cutFrom, DynamicList& allCutEdges, DynamicList& allCutPoints, List>& surfEdgeCuts ) { - scalar oldTol = intersection::setPlanarTol(1e-3); + const scalar oldTol = intersection::setPlanarTol(planarTol_); const pointField& surf1Pts = surf1.localPoints(); @@ -579,113 +588,119 @@ void Foam::surfaceIntersection::doCutEdges * minEdgeLen(surf1, pointi); } - const triSurface& surf2 = querySurf2.surface(); + const indexedOctree>& searchTree + = querySurf2.tree(); - forAll(surf1.edges(), edgeI) + if (cutFrom == surfaceIntersection::SELF) { - const edge& e = surf1.edges()[edgeI]; + // An edge may intersect multiple faces + // - mask out faces that have already been hit before trying again + // - never intersect with faces attached to the edge itself + DynamicList