void do_insert_into_block( Block_2& block, const Polygon_2& bounds, const BLOCK_face_data& data) { edge_collector_t<Block_2> collector; collector.attach(block); CollectEdges(block, &collector, bounds, NULL); set<Block_2::Face_handle> faces; FindFacesForEdgeSet<Block_2>(collector.results, faces); for(set<Block_2::Face_handle>::iterator f = faces.begin(); f != faces.end(); ++f) (*f)->set_data(data); }
//////////////////////////////////////////////////////////////////////// // CollectSurfaceNeighborsSorted bool CollectSurfaceNeighborsSorted(std::vector<Vertex*>& vNeighborsOut, Grid& grid, Vertex* v) { vNeighborsOut.clear(); // the algorithm won't work if volumes are connected if(grid.num_volumes() > 0) { if(grid.associated_volumes_begin(v) != grid.associated_volumes_end(v)) return false; } // the algorithm won't work if no faces are connected if(grid.associated_faces_begin(v) == grid.associated_faces_end(v)) return false; grid.begin_marking(); if(grid.option_is_enabled(FACEOPT_AUTOGENERATE_EDGES) && grid.option_is_enabled(EDGEOPT_STORE_ASSOCIATED_FACES)) { // collect edges in this vector vector<Edge*> edges; // start with an arbitrary edge Edge* curEdge = *grid.associated_edges_begin(v); while(curEdge) { vNeighborsOut.push_back(GetConnectedVertex(curEdge, v)); grid.mark(curEdge); // get associated faces Face* f[2]; if(GetAssociatedFaces(f, grid, curEdge, 2) != 2) return false; curEdge = NULL; for(int i = 0; i < 2; ++i) { if(!grid.is_marked(f[i])) { CollectEdges(edges, grid, f[i]); for(size_t j = 0; j < edges.size(); ++j) { if(!grid.is_marked(edges[j])) { if(EdgeContains(edges[j], v)) { curEdge = edges[j]; break; } } } } } } } else { // we can't use GetAssociatedFaces here, since it uses Grid::mark itself if // EDGEOPT_STORE_ASSOCIATED_FACES is not enabled. // Start with an arbitrary face Face* f = *grid.associated_faces_begin(v); grid.mark(v); while(f) { grid.mark(f); // mark one of the edges that is connected to v by marking // the edges endpoints. Make sure that it was not already marked. size_t numVrts = f->num_vertices(); int vind = GetVertexIndex(f, v); Vertex* tvrt = f->vertex((vind + 1)%numVrts); if(grid.is_marked(tvrt)) tvrt = f->vertex((vind + numVrts - 1)%numVrts); if(grid.is_marked(tvrt)) throw(UGError("CollectSurfaceNeighborsSorted: unexpected exit.")); vNeighborsOut.push_back(tvrt); grid.mark(tvrt); // iterate through the faces associated with v and find an unmarked one that // contains two marked vertices f = NULL; Grid::AssociatedFaceIterator iterEnd = grid.associated_faces_end(v); for(Grid::AssociatedFaceIterator iter = grid.associated_faces_begin(v); iter != iterEnd; ++iter) { if(!grid.is_marked(*iter)) { f = *iter; size_t numMarked = 0; for(size_t i = 0; i < f->num_vertices(); ++i) { if(grid.is_marked(f->vertex(i))) ++numMarked; } if(numMarked == 2) break; else f = NULL; } } } } grid.end_marking(); return true; }
inline void CollectAssociated(std::vector<Edge*>& vEdgesOut, Grid& grid, Volume* v, bool clearContainer) { CollectEdges(vEdgesOut, grid, v, clearContainer); }
inline void CollectAssociated(std::vector<Edge*>& vEdgesOut, Grid& grid, Face* f, bool clearContainer) { CollectEdges(vEdgesOut, grid, f, clearContainer); }
inline void CollectAssociated(std::vector<Edge*>& vEdgesOut, Grid& grid, Vertex* vrt, bool clearContainer) { CollectEdges(vEdgesOut, grid, vrt, clearContainer); }
void MultiGridRefiner:: select_copy_elements(std::vector<Vertex*>& vVrts, int iFirst, int copyRange) { if(copyRange == -1) copyRange = get_copy_range(); vector<Edge*> vEdges;// vector used for temporary results vector<Face*> vFaces;// vector used for temporary results // regard the multi-grid as a grid Grid& grid =*static_cast<Grid*>(m_pMG); MultiGrid& mg = *m_pMG; // we'll collect unselected edges, faces and volumes that are in // a neighbourhood to the selection if(copyRange > 0){ // we have to make sure that we'll only collect copy-elements in // the correct neighbourhood. // After we processed all elements between iFirst and iEnd, the // first neighbourhood is done. We may then set iFirst to iEnd and // iEnd to vVrts.size(), to process the next neighbourhood. size_t iEnd = vVrts.size(); // iterate for each neighbourhood for(int iNbr = 0; iNbr < copyRange; ++iNbr) { // iterate over candidates for(size_t i = iFirst; i != iEnd; ++i){ Vertex* vrt = vVrts[i]; // check all associated elements. // If we can find an unselected, it is a copy-element. // we then have to add all its associated unselected vertices // to vVrts. // check edges { Grid::AssociatedEdgeIterator iterEnd = grid.associated_edges_end(vrt); for(Grid::AssociatedEdgeIterator iter = grid.associated_edges_begin(vrt); iter != iterEnd; ++iter) { Edge* e = *iter; if(!m_selMarks.is_selected(e) && (!mg.has_children(e))){ // we found a copy-element mark_for_refinement(e); set_rule(e, RM_COPY); // schedule associated unselected vertices for further checks for(size_t j = 0; j < 2; ++j){ if(!m_selMarks.is_selected(e->vertex(j))){ mark_for_refinement(e->vertex(j)); vVrts.push_back(e->vertex(j)); set_rule(e->vertex(j), RM_COPY); } } } } } // check faces { Grid::AssociatedFaceIterator iterEnd = grid.associated_faces_end(vrt); for(Grid::AssociatedFaceIterator iter = grid.associated_faces_begin(vrt); iter != iterEnd; ++iter) { Face* f = *iter; if(!m_selMarks.is_selected(f) && (!mg.has_children(f))){ // we found a copy-element mark_for_refinement(f); set_rule(f, RM_COPY); // schedule associated unselected vertices for further checks for(size_t j = 0; j < f->num_vertices(); ++j){ if(!m_selMarks.is_selected(f->vertex(j))){ mark_for_refinement(f->vertex(j)); vVrts.push_back(f->vertex(j)); set_rule(f->vertex(j), RM_COPY); } } // mark associated unselected edges as copy-edge CollectEdges(vEdges, grid, f); for(size_t j = 0; j < vEdges.size(); ++j){ Edge* e = vEdges[j]; if(!m_selMarks.is_selected(e) && (!mg.has_children(e))){ mark_for_refinement(e); set_rule(e, RM_COPY); } } } } } // check volumes { Grid::AssociatedVolumeIterator iterEnd = grid.associated_volumes_end(vrt); for(Grid::AssociatedVolumeIterator iter = grid.associated_volumes_begin(vrt); iter != iterEnd; ++iter) { Volume* v = *iter; if(!m_selMarks.is_selected(v) && (!mg.has_children(v))){ // we found a copy-element mark_for_refinement(v); set_rule(v, RM_COPY); // schedule associated unselected vertices for further checks for(size_t j = 0; j < v->num_vertices(); ++j){ if(!m_selMarks.is_selected(v->vertex(j))){ mark_for_refinement(v->vertex(j)); vVrts.push_back(v->vertex(j)); set_rule(v->vertex(j), RM_COPY); } } // mark associated unselected edges as copy-edge CollectEdges(vEdges, grid, v); for(size_t j = 0; j < vEdges.size(); ++j){ Edge* e = vEdges[j]; if(!m_selMarks.is_selected(e) && (!mg.has_children(e))){ mark_for_refinement(e); set_rule(e, RM_COPY); } } // mark associated unselected faces as copy-edge CollectFaces(vFaces, grid, v); for(size_t j = 0; j < vFaces.size(); ++j){ Face* f = vFaces[j]; if(!m_selMarks.is_selected(f) && (!mg.has_children(f))){ mark_for_refinement(f); set_rule(f, RM_COPY); } } } } } } // the neighbourhood is done. check the next neighbourhood. iFirst = iEnd; iEnd = vVrts.size(); } } }
void MultiGridRefiner:: select_closure(std::vector<Vertex*>& vVrts) { vector<Edge*> vEdges;// vector used for temporary results vector<Face*> vFaces;// vector used for temporary results vector<Volume*> vVolumes;// vector used for temporary results // regard the multi-grid as a grid Grid& grid =*static_cast<Grid*>(m_pMG); MultiGrid& mg = *m_pMG; // collect associated faces of refine-edges that will be used for the closure. // associated volumes will be collected implicitly later on from refine-faces. if(mg.num<Face>() > 0) { // store end-iterator so that newly marked edges won't be considered. for(EdgeIterator iter = m_selMarks.begin<Edge>(); iter != m_selMarks.end<Edge>(); ++iter) { // as soon as we encounter an edge that is scheduled for COPY, we're done in here if(get_rule(*iter) == RM_COPY) break; CollectFaces(vFaces, grid, *iter); for(size_t i = 0; i < vFaces.size(); ++i){ Face* f = vFaces[i]; if(!m_selMarks.is_selected(f) && (!mg.has_children(f))) { mark_for_refinement(f); // we now have to check all associated edges. // unselected ones will be added as copy-elements size_t numRegular = 0; CollectEdges(vEdges, grid, f); for(size_t j = 0; j < vEdges.size(); ++j){ Edge* e = vEdges[j]; if(m_selMarks.is_selected(e)){ if(get_rule(e) == RM_REFINE) ++numRegular; } else{ if(!mg.has_children(e)){ set_rule(e, RM_COPY); mark_for_refinement(e); } } } // set rule // if all associated edges are refined regular, // we'll refine the face regular, too. if(numRegular == vEdges.size()) set_rule(f, RM_REFINE); else set_rule(f, RM_IRREGULAR); // finally we have to make sure that all vertices are selected. for(size_t j = 0; j < f->num_vertices(); ++j) { if(!m_selMarks.is_selected(f->vertex(j))){ if(get_copy_range() > 0) vVrts.push_back(f->vertex(j)); mark_for_refinement(f->vertex(j)); set_rule(f->vertex(j), RM_COPY); } } } } } } // collect associated volumes of refine-faces that will be used for the closure. // we don't have to check associated volumes of refine-edges, since // those are associated volumes of refine-faces, too. if(mg.num<Volume>() > 0) { // store end-iterator so that newly marked faces won't be considered. for(FaceIterator iter = m_selMarks.begin<Face>(); iter != m_selMarks.end<Face>(); ++iter) { // as soon as we encounter a face that is scheduled for COPY, we're done in here if(get_rule(*iter) == RM_COPY) break; CollectVolumes(vVolumes, grid, *iter); for(size_t i = 0; i < vVolumes.size(); ++i){ Volume* v = vVolumes[i]; if(!m_selMarks.is_selected(v) && (!mg.has_children(v))) { mark_for_refinement(v); // we now have to check all associated faces. // unselected ones will be added as copy-elements. size_t numRegular = 0; CollectFaces(vFaces, grid, v); for(size_t j = 0; j < vFaces.size(); ++j){ Face* f = vFaces[j]; if(m_selMarks.is_selected(f)){ if(get_rule(f) == RM_REFINE) ++numRegular; } else{ if(!mg.has_children(f)){ set_rule(f, RM_COPY); mark_for_refinement(f); } } } // set rule // if all faces are refined regular, we'll refine the volume regular, too. if(numRegular == vFaces.size()) set_rule(v, RM_REFINE); else set_rule(v, RM_IRREGULAR); // we now have to check all associated edges. // unselected ones will be added as copy-elements. CollectEdges(vEdges, grid, v); for(size_t j = 0; j < vEdges.size(); ++j){ Edge* e = vEdges[j]; if(!m_selMarks.is_selected(e) && (!mg.has_children(e))) { if(!mg.has_children(e)){ set_rule(e, RM_COPY); mark_for_refinement(e); } } } // finally we have to make sure that all vertices are selected. for(size_t j = 0; j < v->num_vertices(); ++j) { if(!m_selMarks.is_selected(v->vertex(j))){ if(get_copy_range() > 0) vVrts.push_back(v->vertex(j)); mark_for_refinement(v->vertex(j)); set_rule(v->vertex(j), RM_COPY); } } } } } } }
void MultiGridRefiner:: adjust_initial_selection() { vector<Edge*> vEdges;// vector used for temporary results vector<Face*> vFaces;// vector used for temporary results // regard the multi-grid as a grid Grid& grid =*static_cast<Grid*>(m_pMG); MultiGrid& mg = *m_pMG; //////////////////////////////// // initial selection // select elements that are associated with volumes // make sure to deselect all elements that must not be refined. for(VolumeIterator iter = m_selMarks.begin<Volume>(); iter != m_selMarks.end<Volume>();) { Volume* v = *iter; ++iter;//iterator is incremented since it would be invalidated during deselect. if(mg.has_children(v)) { // the element has already been refined. // don't refine it again. m_selMarks.deselect(v); } else if(get_status(v) == SM_COPY){ // copy elements must not be refined in the current version LOG(" WARNING: copy-elements must not be refined in the current version!\n"); m_selMarks.deselect(v); } else if(get_status(v) == SM_IRREGULAR){ // irregular elements must not be refined in the current version LOG(" WARNING: irregular-elements must not be refined in the current version!\n"); m_selMarks.deselect(v); } else{ // mark it for regular refinement set_rule(v, RM_REFINE); // collect associated faces CollectFaces(vFaces, grid, v); for(uint i = 0; i < vFaces.size(); ++i) if(!mg.has_children(vFaces[i])) mark_for_refinement(vFaces[i]); } } // select elements that are associated with faces for(FaceIterator iter = m_selMarks.begin<Face>(); iter != m_selMarks.end<Face>();) { Face* f = *iter; ++iter; //iterator is incremented since it would be invalidated during deselect. if(mg.has_children(f)) { // the element has already been refined. // don't refine it again. m_selMarks.deselect(f); } else if(get_status(f) == SM_COPY){ // copy elements must not be refined in the current version LOG(" WARNING: copy-elements must not be refined in the current version!\n"); m_selMarks.deselect(f); } else if(get_status(f) == SM_IRREGULAR){ // irregular elements must not be refined in the current version LOG(" WARNING: irregular-elements must not be refined in the current version!\n"); m_selMarks.deselect(f); } else{ // mark it for regular refinement set_rule(f, RM_REFINE); // collect associated edges CollectEdges(vEdges, grid, f); for(uint i = 0; i < vEdges.size(); ++i) if(!mg.has_children(vEdges[i])) mark_for_refinement(vEdges[i]); } } // select elements that are associated with edges for(EdgeIterator iter = m_selMarks.begin<Edge>(); iter != m_selMarks.end<Edge>();) { Edge* e = *iter; ++iter; //iterator is incremented since it would be invalidated during deselect. if(mg.has_children(e)){ // the element has already been refined. // don't refine it again. m_selMarks.deselect(e); } else if(get_status(e) == SM_COPY){ // copy elements must not be refined in the current version LOG(" WARNING: copy-elements must not be refined in the current version!\n"); m_selMarks.deselect(e); } else if(get_status(e) == SM_IRREGULAR){ // irregular elements must not be refined in the current version LOG(" WARNING: irregular-elements must not be refined in the current version!\n"); m_selMarks.deselect(e); } else{ // mark it for regular refinement set_rule(e, RM_REFINE); // select associated vertices for(uint i = 0; i < e->num_vertices(); ++i) mark_for_refinement(e->vertex(i)); } } // set rule for all marked vertices for(VertexIterator iter = m_selMarks.begin<Vertex>(); iter != m_selMarks.end<Vertex>(); ++iter) { set_rule(*iter, RM_COPY); } }