// Step across point to other edge on face Foam::label Foam::regionSide::otherEdge ( const primitiveMesh& mesh, const label faceI, const label edgeI, const label pointI ) { const edge& e = mesh.edges()[edgeI]; // Get other point on edge. label freePointI = e.otherVertex(pointI); const labelList& fEdges = mesh.faceEdges()[faceI]; forAll(fEdges, fEdgeI) { const label otherEdgeI = fEdges[fEdgeI]; const edge& otherE = mesh.edges()[otherEdgeI]; if ( ( otherE.start() == pointI && otherE.end() != freePointI ) || ( otherE.end() == pointI && otherE.start() != freePointI ) ) { // otherE shares one (but not two) points with e. return otherEdgeI; } } FatalErrorIn ( "regionSide::otherEdge(const primitiveMesh&, const label, const label" ", const label)" ) << "Cannot find other edge on face " << faceI << " that uses point " << pointI << " but not point " << freePointI << endl << "Edges on face:" << fEdges << " verts:" << UIndirectList<edge>(mesh.edges(), fEdges)() << " Vertices on face:" << mesh.faces()[faceI] << " Vertices on original edge:" << e << abort(FatalError); return -1; }
// Step across point to other edge on face Foam::label Foam::regionSide::otherEdge ( const primitiveMesh& mesh, const label faceI, const label edgeI, const label pointI ) { const edge& e = mesh.edges()[edgeI]; // Get other point on edge. label freePointI = e.otherVertex(pointI); const labelList& fEdges = mesh.faceEdges()[faceI]; forAll(fEdges, fEdgeI) { label otherEdgeI = fEdges[fEdgeI]; const edge& otherE = mesh.edges()[otherEdgeI]; if ( ( otherE.start() == pointI && otherE.end() != freePointI ) || ( otherE.end() == pointI && otherE.start() != freePointI ) ) { // otherE shares one (but not two) points with e. return otherEdgeI; } }
// Step from faceI (on side cellI) to connected face & cell without crossing // fenceEdges. void Foam::regionSide::visitConnectedFaces ( const primitiveMesh& mesh, const labelHashSet& region, const labelHashSet& fenceEdges, const label cellI, const label faceI, labelHashSet& visitedFace ) { if (!visitedFace.found(faceI)) { if (debug) { Info<< "visitConnectedFaces : cellI:" << cellI << " faceI:" << faceI << " isOwner:" << (cellI == mesh.faceOwner()[faceI]) << endl; } // Mark as visited visitedFace.insert(faceI); // Mark which side of face was visited. if (cellI == mesh.faceOwner()[faceI]) { sideOwner_.insert(faceI); } // Visit all neighbouring faces on faceSet. Stay on this 'side' of // face by doing edge-face-cell walk. const labelList& fEdges = mesh.faceEdges()[faceI]; forAll(fEdges, fEdgeI) { label edgeI = fEdges[fEdgeI]; if (!fenceEdges.found(edgeI)) { // Step along faces on edge from cell to cell until // we hit face on faceSet. // Find face reachable from edge label otherFaceI = otherFace(mesh, cellI, faceI, edgeI); if (mesh.isInternalFace(otherFaceI)) { label otherCellI = cellI; // Keep on crossing faces/cells until back on face on // surface while (!region.found(otherFaceI)) { visitedFace.insert(otherFaceI); if (debug) { Info<< "visitConnectedFaces : cellI:" << cellI << " found insideEdgeFace:" << otherFaceI << endl; } // Cross otherFaceI into neighbouring cell otherCellI = meshTools::otherCell ( mesh, otherCellI, otherFaceI ); otherFaceI = otherFace ( mesh, otherCellI, otherFaceI, edgeI ); } visitConnectedFaces ( mesh, region, fenceEdges, otherCellI, otherFaceI, visitedFace ); } } } }
// Coming from startEdgeI cross the edge to the other face // across to the next cut edge. bool Foam::cuttingPlane::walkCell ( const primitiveMesh& mesh, const UList<label>& edgePoint, const label cellI, const label startEdgeI, DynamicList<label>& faceVerts ) { label faceI = -1; label edgeI = startEdgeI; label nIter = 0; faceVerts.clear(); do { faceVerts.append(edgePoint[edgeI]); // Cross edge to other face faceI = meshTools::otherFace(mesh, cellI, faceI, edgeI); // Find next cut edge on face. const labelList& fEdges = mesh.faceEdges()[faceI]; label nextEdgeI = -1; //Note: here is where we should check for whether there are more // than 2 intersections with the face (warped/non-convex face). // If so should e.g. decompose the cells on both faces and redo // the calculation. forAll(fEdges, i) { label edge2I = fEdges[i]; if (edge2I != edgeI && edgePoint[edge2I] != -1) { nextEdgeI = edge2I; break; } } if (nextEdgeI == -1) { // Did not find another cut edge on faceI. Do what? WarningIn("Foam::cuttingPlane::walkCell") << "Did not find closed walk along surface of cell " << cellI << " starting from edge " << startEdgeI << " in " << nIter << " iterations." << nl << "Collected cutPoints so far:" << faceVerts << endl; return false; } edgeI = nextEdgeI; nIter++; if (nIter > 1000) { WarningIn("Foam::cuttingPlane::walkCell") << "Did not find closed walk along surface of cell " << cellI << " starting from edge " << startEdgeI << " in " << nIter << " iterations." << nl << "Collected cutPoints so far:" << faceVerts << endl; return false; } } while (edgeI != startEdgeI);