static triSurface pack ( const triSurface& surf, const pointField& localPoints, const labelList& pointMap ) { List<labelledTri> newTriangles(surf.size()); label newTriangleI = 0; forAll(surf, faceI) { const labelledTri& f = surf.localFaces()[faceI]; label newA = pointMap[f[0]]; label newB = pointMap[f[1]]; label newC = pointMap[f[2]]; if ((newA != newB) && (newA != newC) && (newB != newC)) { newTriangles[newTriangleI++] = labelledTri(newA, newB, newC, f.region()); } } newTriangles.setSize(newTriangleI); return triSurface(newTriangles, surf.patches(), localPoints); }
//- Sets point neighbours of face to val static void markPointNbrs ( const triSurface& surf, const label faceI, const bool val, boolList& okToCollapse ) { const triSurface::FaceType& f = surf.localFaces()[faceI]; forAll(f, fp) { const labelList& pFaces = surf.pointFaces()[f[fp]]; forAll(pFaces, i) { okToCollapse[pFaces[i]] = false; } } }
// Checks if there exists a special topological situation that causes // edge and the face it hit not to be recognized. // // For now if the face shares a point with the edge bool Foam::surfaceIntersection::excludeEdgeHit ( const triSurface& surf, const label edgeI, const label faceI, const scalar ) { const labelledTri& f = surf.localFaces()[faceI]; const edge& e = surf.edges()[edgeI]; if ( (f[0] == e.start()) || (f[0] == e.end()) || (f[1] == e.start()) || (f[1] == e.end()) || (f[2] == e.start()) || (f[2] == e.end()) ) { return true; // // Get edge vector // vector eVec = e.vec(surf.localPoints()); // eVec /= mag(eVec) + VSMALL; // // const labelList& eLabels = surf.faceEdges()[faceI]; // // // Get edge vector of 0th edge of face // vector e0Vec = surf.edges()[eLabels[0]].vec(surf.localPoints()); // e0Vec /= mag(e0Vec) + VSMALL; // // vector n = e0Vec ^ eVec; // // if (mag(n) < SMALL) // { // // e0 is aligned with e. Choose next edge of face. // vector e1Vec = surf.edges()[eLabels[1]].vec(surf.localPoints()); // e1Vec /= mag(e1Vec) + VSMALL; // // n = e1Vec ^ eVec; // // if (mag(n) < SMALL) // { // // Problematic triangle. Two edges aligned with edgeI. Give // // up. // return true; // } // } // // // Check if same as faceNormal // if (mag(n & surf.faceNormals()[faceI]) > 1-tol) // { // // Pout<< "edge:" << e << " face:" << faceI // << " e0Vec:" << e0Vec << " n:" << n // << " normalComponent:" << (n & surf.faceNormals()[faceI]) // << " tol:" << tol << endl; // // return true; // } // else // { // return false; // } } else { return false; } }
// Collapses small edge to point, thus removing triangle. label collapseEdge(triSurface& surf, const scalar minLen) { label nTotalCollapsed = 0; while (true) { const pointField& localPoints = surf.localPoints(); const List<labelledTri>& localFaces = surf.localFaces(); // Mapping from old to new points labelList pointMap(surf.nPoints()); forAll(pointMap, i) { pointMap[i] = i; } // Storage for new points. pointField newPoints(localPoints); // To protect neighbours of collapsed faces. boolList okToCollapse(surf.size(), true); label nCollapsed = 0; forAll(localFaces, faceI) { if (okToCollapse[faceI]) { // Check edge lengths. const triSurface::FaceType& f = localFaces[faceI]; forAll(f, fp) { label v = f[fp]; label v1 = f[f.fcIndex(fp)]; if (mag(localPoints[v1] - localPoints[v]) < minLen) { // Collapse f[fp1] onto f[fp]. pointMap[v1] = v; newPoints[v] = 0.5*(localPoints[v1] + localPoints[v]); Pout<< "Collapsing triange " << faceI << " to edge mid " << newPoints[v] << endl; nCollapsed++; okToCollapse[faceI] = false; // Protect point neighbours from collapsing. markPointNbrs(surf, faceI, false, okToCollapse); break; } } } } Pout<< "collapseEdge : collapsing " << nCollapsed << " triangles" << endl; nTotalCollapsed += nCollapsed; if (nCollapsed == 0) { break; } // Pack the triangles surf = pack(surf, newPoints, pointMap); }
Foam::labelList Foam::orientedSurface::edgeToFace ( const triSurface& s, const labelList& changedEdges, labelList& flip ) { labelList changedFaces(2*changedEdges.size()); label changedI = 0; // 1.6.x merge: using local faces. Reconsider // Rewrite uses cached local faces for efficiency // HJ, 24/Aug/2010 const List<labelledTri> lf = s.localFaces(); forAll(changedEdges, i) { label edgeI = changedEdges[i]; const labelList& eFaces = s.edgeFaces()[edgeI]; if (eFaces.size() < 2) { // Do nothing, faces was already visited. } else if (eFaces.size() == 2) { label face0 = eFaces[0]; label face1 = eFaces[1]; const labelledTri& f0 = lf[face0]; const labelledTri& f1 = lf[face1]; // Old. HJ, 24/Aug/2010 // const labelledTri& f0 = s[face0]; // const labelledTri& f1 = s[face1]; if (flip[face0] == UNVISITED) { if (flip[face1] == UNVISITED) { FatalErrorIn("orientedSurface::edgeToFace") << "Problem" << abort(FatalError); } else { // Face1 has a flip state, face0 hasn't if (consistentEdge(s.edges()[edgeI], f0, f1)) { // Take over flip status flip[face0] = (flip[face1] == FLIP ? FLIP : NOFLIP); } else { // Invert flip[face0] = (flip[face1] == FLIP ? NOFLIP : FLIP); } changedFaces[changedI++] = face0; } } else { if (flip[face1] == UNVISITED) { // Face0 has a flip state, face1 hasn't if (consistentEdge(s.edges()[edgeI], f0, f1)) { flip[face1] = (flip[face0] == FLIP ? FLIP : NOFLIP); } else { flip[face1] = (flip[face0] == FLIP ? NOFLIP : FLIP); } changedFaces[changedI++] = face1; } } } else { // Multiply connected. Do what? } }