UG_API bool OrientationMatches(FaceVertices* fv, Volume* v) { // find the matching face desc and compare FaceDescriptor fd; for(size_t iface = 0; iface < v->num_faces(); ++iface){ v->face_desc(iface, fd); if(CompareVertices(fv, &fd)){ // check if their orientation matches // find the first vertex of fv in f size_t i; for(i = 0; i < fd.num_vertices(); ++i) { if(fd.vertex(i) == fv->vertex(0)) break; } if(i < fd.num_vertices()) { // the first one has been found. // check whether the second vertex of ed is the // same as the next vertex of f if(fv->vertex(1) == fd.vertex((i+1) % fd.num_vertices())) return true;// the orientation is the same } // the orientation is not the same. return false; } } // the orientation is not the same. return false; }
void InsertCenterVertex(Grid& g, Volume* vol, Vertex* vrt, bool eraseOldVol) { // get the sides of the volume and create new elements FaceDescriptor fd; for(size_t i = 0; i < vol->num_faces(); ++i){ vol->face_desc(i, fd); if(fd.num_vertices() == 3){ // create a tetrahedron g.create<Tetrahedron>(TetrahedronDescriptor(fd.vertex(2), fd.vertex(1), fd.vertex(0), vrt), vol); } else if(fd.num_vertices() == 4){ // create a pyramid g.create<Pyramid>(PyramidDescriptor(fd.vertex(3), fd.vertex(2), fd.vertex(1), fd.vertex(0), vrt), vol); } else{ UG_THROW("Unsupported face type in InsertCenterVertex (#Corners " << fd.num_vertices() << ")"); } } if(eraseOldVol) g.erase(vol); }
//////////////////////////////////////////////////////////////////////// // GetNeighbours - sreiter void GetNeighbours(std::vector<Volume*>& vVolsOut, Grid& grid, Volume* v, int side, bool clearContainer) { if(clearContainer) vVolsOut.clear(); // if VOLOPT_AUTOGENERATE_FACES and FACEOPT_STORE_ASSOCIATED_VOLUMES are // activated, we may use them to find the connected volume quite fast. if(grid.option_is_enabled(VOLOPT_AUTOGENERATE_FACES | FACEOPT_STORE_ASSOCIATED_VOLUMES)) { Face* f = grid.get_face(v, side); Grid::AssociatedVolumeIterator iterEnd = grid.associated_volumes_end(f); for(Grid::AssociatedVolumeIterator iter = grid.associated_volumes_begin(f); iter != iterEnd; ++iter) { if(*iter != v) vVolsOut.push_back(*iter); } return; } // we can't assume that associated faces exist. // we have to find the neighbour by hand. // mark all vertices of the side grid.begin_marking(); FaceDescriptor fd; v->face_desc(side, fd); uint numFaceVrts = fd.num_vertices(); for(uint i = 0; i < numFaceVrts; ++ i) grid.mark(fd.vertex(i)); // iterate over associated volumes of the first vertex and count // the number of marked vertices it contains. Vertex* vrt = fd.vertex(0); Grid::AssociatedVolumeIterator iterEnd = grid.associated_volumes_end(vrt); for(Grid::AssociatedVolumeIterator iter = grid.associated_volumes_begin(vrt); iter != iterEnd; ++iter) { Volume* vol = *iter; if(vol != v){ size_t count = 0; uint numVrts = vol->num_vertices(); for(uint i = 0; i < numVrts; ++i){ if(grid.is_marked(vol->vertex(i))) ++count; } // if the number of marked vertices in vol matches the // number of vertices of the specified side, we consider // the volume to be a neighbout of that side. if(count == numFaceVrts) vVolsOut.push_back(vol); } } grid.end_marking(); }
void MultiGridRefiner::refine() { assert(m_pMG && "refiner not has to be assigned to a multi-grid!"); if(!m_pMG) return; // the multi-grid MultiGrid& mg = *m_pMG; // make sure that the required options are enabled. if(!mg.option_is_enabled(GRIDOPT_FULL_INTERCONNECTION)) { LOG("WARNING in MultiGridRefiner::refine(): auto-enabling GRIDOPT_FULL_INTERCONNECTION.\n"); mg.enable_options(GRIDOPT_FULL_INTERCONNECTION); } // access position attachments Grid::VertexAttachmentAccessor<APosition> aaPos; if(mg.has_vertex_attachment(aPosition)) aaPos.access(mg, aPosition); // collect objects for refine collect_objects_for_refine(); // notify derivates that refinement begins refinement_step_begins(); // cout << "num marked edges: " << m_selMarks.num<Edge>() << endl; // cout << "num marked faces: " << m_selMarks.num<Face>() << endl; // we want to add new elements in a new layer. bool bHierarchicalInsertionWasEnabled = mg.hierarchical_insertion_enabled(); if(!bHierarchicalInsertionWasEnabled) mg.enable_hierarchical_insertion(true); // some buffers vector<Vertex*> vVrts; vector<Vertex*> vEdgeVrts; vector<Edge*> vEdges; vector<Face*> vFaces; // some repeatedly used objects EdgeDescriptor ed; FaceDescriptor fd; VolumeDescriptor vd; //LOG("creating new vertices\n"); // create new vertices from marked vertices for(VertexIterator iter = m_selMarks.begin<Vertex>(); iter != m_selMarks.end<Vertex>(); ++iter) { Vertex* v = *iter; if(!mg.get_child_vertex(v)) { // create a new vertex in the next layer. Vertex* nVrt = *mg.create_by_cloning(v, v); if(aaPos.valid()) { aaPos[nVrt] = aaPos[v]; // change z-coord to visualise the hierarchy //aaPos[nVrt].z() += 0.01; } } } //LOG("creating new edges\n"); // create new vertices and edges from marked edges for(EdgeIterator iter = m_selMarks.begin<Edge>(); iter != m_selMarks.end<Edge>(); ++iter) { // collect_objects_for_refine removed all edges that already were // refined. No need to check that again. Edge* e = *iter; int rule = get_rule(e); switch(rule) { case RM_COPY: { // clone the edge. ed.set_vertices(mg.get_child_vertex(e->vertex(0)), mg.get_child_vertex(e->vertex(1))); Edge* newEdge = *mg.create_by_cloning(e, ed, e); set_status(newEdge, SM_COPY); }break; default: { // create two new edges by edge-split RegularVertex* nVrt = *mg.create<RegularVertex>(e); Vertex* substituteVrts[2]; substituteVrts[0] = mg.get_child_vertex(e->vertex(0)); substituteVrts[1] = mg.get_child_vertex(e->vertex(1)); if(aaPos.valid()) { VecScaleAdd(aaPos[nVrt], 0.5, aaPos[e->vertex(0)], 0.5, aaPos[e->vertex(1)]); // change z-coord to visualise the hierarchy //aaPos[nVrt].z() += 0.01; } // split the edge e->refine(vEdges, nVrt, substituteVrts); assert((vEdges.size() == 2) && "RegularEdge refine produced wrong number of edges."); mg.register_element(vEdges[0], e); mg.register_element(vEdges[1], e); set_status(vEdges[0], SM_REGULAR); set_status(vEdges[1], SM_REGULAR); }break; } } //LOG("creating new faces\n"); // create new vertices and faces from marked faces for(FaceIterator iter = m_selMarks.begin<Face>(); iter != m_selMarks.end<Face>(); ++iter) { Face* f = *iter; int rule = get_rule(f); switch(rule) { case RM_COPY: { // clone the face. if(fd.num_vertices() != f->num_vertices()) fd.set_num_vertices(f->num_vertices()); for(size_t i = 0; i < fd.num_vertices(); ++i) fd.set_vertex(i, mg.get_child_vertex(f->vertex(i))); Face* nf = *mg.create_by_cloning(f, fd, f); set_status(nf, SM_COPY); }break; default: { // collect child-vertices vVrts.clear(); for(uint j = 0; j < f->num_vertices(); ++j){ vVrts.push_back(mg.get_child_vertex(f->vertex(j))); } // collect the associated edges vEdgeVrts.clear(); //bool bIrregular = false; for(uint j = 0; j < f->num_edges(); ++j){ Vertex* vrt = mg.get_child_vertex(mg.get_edge(f, j)); vEdgeVrts.push_back(vrt); //if(!vrt) // bIrregular = true; } /* if(bIrregular){ assert((get_rule(f) != RM_REFINE) && "Bad refinement-rule set during collect_objects_for_refine!"); //TODO: care about anisotropy set_rule(f, RM_IRREGULAR); } */ Vertex* newVrt; if(f->refine(vFaces, &newVrt, &vEdgeVrts.front(), NULL, &vVrts.front())){ // if a new vertex was generated, we have to register it if(newVrt){ mg.register_element(newVrt, f); if(aaPos.valid()){ aaPos[newVrt] = CalculateCenter(f, aaPos); // change z-coord to visualise the hierarchy //aaPos[newVrt].z() += 0.01; } } int oldRule = get_rule(f); // register the new faces and assign status for(size_t j = 0; j < vFaces.size(); ++j){ mg.register_element(vFaces[j], f); switch(oldRule) { case RM_REFINE: set_status(vFaces[j], SM_REGULAR); break; case RM_IRREGULAR: set_status(vFaces[j], SM_IRREGULAR); break; default: assert((oldRule == RM_REFINE) && "rule not yet handled.");//always fails. break; } } } else{ LOG(" WARNING in Refine: could not refine face.\n"); } } } } // done - clean up if(!bHierarchicalInsertionWasEnabled) mg.enable_hierarchical_insertion(false); m_selMarks.clear(); // notify derivates that refinement ends refinement_step_ends(); }