void Foam::CV2D::fast_restore_Delaunay(Vertex_handle vh) { int i; Face_handle f = vh->face(), next, start(f); do { i=f->index(vh); if (!is_infinite(f)) { if (!internal_flip(f, cw(i))) external_flip(f, i); if (f->neighbor(i) == start) start = f; } f = f->neighbor(cw(i)); } while (f != start); }
void findOutsideSegment( Triangulation &t, Face_handle fh, int currentSegment, int commingFromIndex, int &outsideSegment ) { // if the face is an infinite face // then we know the outside segment which is the // current segment if( t.is_infinite(fh) ) { if( (outsideSegment != -1)&&(outsideSegment != currentSegment) ) printf( "error : different outsideSegments detected during triangulation (edgeloop not closed?)\n" ); outsideSegment = currentSegment; return; } // if there is already a segment identifier, then we know that // the face has already been visited if( fh->info() != -1 ) return; fh->info() = currentSegment; for( int i=0; i<3; ++i ) { // get edge associated with the index i std::pair<Face_handle, int> edge = std::make_pair( fh, i ); if( i == commingFromIndex ) continue; // if the edge is a constrained edge, then we know this is the border if(t.is_constrained(edge)) { //...and we have to pass a madified currentSegment value findOutsideSegment( t, fh->neighbor(i), (currentSegment+1)%2, t.mirror_index( fh, i), outsideSegment ); }else //...else we recurse and leave the currentSegment value untouched findOutsideSegment( t, fh->neighbor(i), currentSegment, t.mirror_index( fh, i), outsideSegment ); } }
void Foam::CV2D::external_flip(Face_handle& f, int i) { Face_handle n = f->neighbor(i); if ( CGAL::ON_POSITIVE_SIDE != side_of_oriented_circle(n, f->vertex(i)->point()) ) return; flip(f, i); i = n->index(f->vertex(i)); external_flip(n, i); }
bool recurse(Face_handle current_face, long d, vector<Face_handle>& visited, Triangulation t) { // Remember we visited this node visited.push_back(current_face); cout << "Recursion at: " << t.dual(current_face) << endl; // Base of recursion: check if we are free if(t.is_infinite(current_face)) { cout << "Infinite face!" << endl; return true; } for(int neighbor_num=0; neighbor_num<3; neighbor_num++) { Face_handle neighbor_face = current_face->neighbor(neighbor_num); //cout << (current_face == neighbor_face) << endl; cout << "\tChecking neighbor of vertex " << current_face->vertex(neighbor_num)->point() << endl; cout << "\tPoints: "; for(int j=0; j<3; j++) { cout << neighbor_face->vertex(j)->point() << ", "; } cout << endl; // If we already visited if(find(visited.begin(), visited.end(), current_face) != visited.end()) { continue; } Vertex_handle border_endpoint1 = current_face->vertex((neighbor_num + 1) % 3); Vertex_handle border_endpoint2 = current_face->vertex((neighbor_num + 2) % 3); K::FT border_length_sq = CGAL::squared_distance(border_endpoint1->point(), border_endpoint2->point()); if(CGAL::to_double(border_length_sq) >= 4 * d) { // If we can fit through that edge // cout << "can fit through edge " << neighbor_num << endl; // New search starting from neighbor if(recurse(neighbor_face, d, visited, t)) { return true; } } else { cout << "cannot fit through edge :S" << endl; } } return false; }
bool Foam::CV2D::internal_flip(Face_handle& f, int i) { Face_handle n = f->neighbor(i); if ( CGAL::ON_POSITIVE_SIDE != side_of_oriented_circle(n, f->vertex(i)->point()) ) { return false; } flip(f, i); return true; }
void discoverInfiniteComponent(const CDT & ct) { //when this function is called, all faces are set "in_domain" Face_handle start = ct.infinite_face(); std::list<Face_handle> queue; queue.push_back(start); while(! queue.empty()) { Face_handle fh = queue.front(); queue.pop_front(); fh->set_in_domain(false); for(int i = 0; i < 3; i++) { Face_handle fi = fh->neighbor(i); if(fi->is_in_domain() && !ct.is_constrained(CDT::Edge(fh,i))) queue.push_back(fi); } } }
void Foam::CV2D::extractPatches ( wordList& patchNames, labelList& patchSizes, EdgeMap<label>& mapEdgesRegion, EdgeMap<label>& indirectPatchEdge ) const { label nPatches = qSurf_.patchNames().size() + 1; label defaultPatchIndex = qSurf_.patchNames().size(); patchNames.setSize(nPatches); patchSizes.setSize(nPatches, 0); mapEdgesRegion.clear(); const wordList& existingPatches = qSurf_.patchNames(); forAll(existingPatches, sP) { patchNames[sP] = existingPatches[sP]; } patchNames[defaultPatchIndex] = "CV2D_default_patch"; for ( Triangulation::Finite_edges_iterator eit = finite_edges_begin(); eit != finite_edges_end(); ++eit ) { Face_handle fOwner = eit->first; Face_handle fNeighbor = fOwner->neighbor(eit->second); Vertex_handle vA = fOwner->vertex(cw(eit->second)); Vertex_handle vB = fOwner->vertex(ccw(eit->second)); if ( (vA->internalOrBoundaryPoint() && !vB->internalOrBoundaryPoint()) || (vB->internalOrBoundaryPoint() && !vA->internalOrBoundaryPoint()) ) { point ptA = toPoint3D(vA->point()); point ptB = toPoint3D(vB->point()); label patchIndex = qSurf_.findPatch(ptA, ptB); if (patchIndex == -1) { patchIndex = defaultPatchIndex; WarningInFunction << "Dual face found that is not on a surface " << "patch. Adding to CV2D_default_patch." << endl; } edge e(fOwner->faceIndex(), fNeighbor->faceIndex()); patchSizes[patchIndex]++; mapEdgesRegion.insert(e, patchIndex); if (!pointPair(*vA, *vB)) { indirectPatchEdge.insert(e, 1); } } } }