//////////////////////////////////////////////////////////////////////// // 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(); }
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; }
bool ContainsPoint(Volume* vol, const vector3& p, TAAPos aaPos) { // iterate over face descriptors of the sides and check whether the point // lies inside or outside FaceDescriptor fd; vector3 n, dir; // to minimize rounding errors we'll compare against a small-constant which is // relative to the first edge of the examined volume. EdgeDescriptor ed; vol->edge_desc(0, ed); number len = EdgeLength(&ed, aaPos); // the constant should be relative to the same geometric measure as what it is // compared against later on, i.e. length*area, since otherwise problems arise // with geometries scaled to very small extensions; // which is why I changed sqrt(lenSq) to lenSq^1.5 (mbreit, 2015-05-11) const number locSmall = len * len * len * SMALL; for(size_t i = 0; i < vol->num_faces(); ++i){ vol->face_desc(i, fd); CalculateNormalNoNormalize(n, &fd, aaPos); VecSubtract(dir, aaPos[fd.vertex(0)], p); if(VecDot(dir, n) < -locSmall) return false; } return true; }
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); }