// Computes interpolated vertices. Vertex WingedEdge::SubdivideBoundaryEdge(Edge& e, std::map<Vertex, std::vector<Vertex> > &derivations) { /* * Proceed with boundary case. */ // Extract the 4 vertices. Vertex v1, v2, v3, v4; v1 = e.V1(); v2 = e.V2(); v3 = getOtherBoundaryVertice(v1, e); v4 = getOtherBoundaryVertice(v2, e); Vertex result = (v1*9 + v2*9 - v3 - v4)/16.0; // Store the derivation data. std::vector<Vertex> v; v.push_back(v1); v.push_back(v2); v.push_back(v3); v.push_back(v4); derivations[result] = v; return result; }
// Returns. the vertice on the face that is not in the given edge. // FIXME : Do we really need to check successes? This should be guranteed. Vertex WingedEdge::GetAdjacentVertex(const Face& face, const Edge& edge, bool &success) { success = true; if (face.E1() != edge) return (face.E1().V1() == edge.V1()) ? face.E1().V2() : face.E1().V1(); else if (face.E2() != edge) return (face.E2().V1() == edge.V1()) ? face.E2().V2() : face.E2().V1(); else if (face.E3() != edge) return (face.E3().V1() == edge.V1()) ? face.E3().V2() : face.E3().V1(); // Bugus return. success = false; return edge.V1(); //throw RuntimeError("Couldn't find Adjacent Vertex"); }
Face WingedEdge::AddFace(const Edge& e1, const Edge& e2, const Edge& e3) { Face f(e1, e2, e3); /* ensure below */ AddEdge(e1.V1(), e1.V2()); AddEdge(e2.V1(), e2.V2()); AddEdge(e3.V1(), e3.V2()); /* edit face lists */ faceList[f].insert(e1); faceList[f].insert(e2); faceList[f].insert(e3); edgeListMap[e1].faces.insert(f); edgeListMap[e2].faces.insert(f); edgeListMap[e3].faces.insert(f); edgeListMap[e1].vertices.insert(e1.V1()); edgeListMap[e1].vertices.insert(e1.V2()); edgeListMap[e2].vertices.insert(e2.V1()); edgeListMap[e2].vertices.insert(e2.V2()); edgeListMap[e3].vertices.insert(e3.V1()); edgeListMap[e3].vertices.insert(e3.V2()); return f; }
Vertex WingedEdge::GetAdjacentFaceVertex(const Face& face, const Edge& edge, bool &success) { success = true; Face f2 = GetAdjacentFace(face, edge, success); // Bogus return with false success flag. if(!success) { return edge.V1(); } return GetAdjacentVertex(f2, edge, success); }
/* This functions computes the new butterfly vertices based on the points in the stencil of the given edge. *FIXME : http://mrl.nyu.edu/~dzorin/papers/zorin1996ism.pdf Page 3. * The special internal cases still need to be implemented. * * Only the degree 6 vertice cases and boundary cases have been implemented for butterfly. * * FIXME : add a type variable to determine what type of interpolation should be used for the edges. * Currently it always uses the butterfly scheme. * * REQUIRES : e is in f1. b1 is in f1. b1 is not in e. * */ Vertex WingedEdge::SubdivideEdge(const Face& f1, Edge& e, Vertex b1, bool linear, std::map<Vertex, std::vector<Vertex> > &derivations) { // Initialize the derivation structure. std::vector<Vertex> derive_indices; // Find 'a' points. Vertex a1 = e.V1(); Vertex a2 = e.V2(); // Add 'a' points to the derivation vector. derive_indices.push_back(a1); derive_indices.push_back(a2); /* get our a midpoint */ Vertex v; v = a1 / 2.0; v = v + (a2 / 2.0); if(linear) { derivations[v] = derive_indices; return v; } // Flag for whether we are in theboundary case or not. bool boundary = false; do { bool success = true; Face f2 = GetAdjacentFace(f1, e, success); if(!success) { boundary = true; break; } /* get our opposing face's b point */ Vertex b2 = GetAdjacentVertex(f2, e, success); if(!success) { boundary = true; break; } v = v + (b1/8.0); v = v + (b2/8.0); // Add 'b' points to the derivation vector. derive_indices.push_back(b1); derive_indices.push_back(b2); /* time to get our c points */ std::set<Edge> edges; edges.insert(f1.E1()); edges.insert(f1.E2()); edges.insert(f1.E3()); for (auto edge = edges.begin(); edge != edges.end(); ++edge) { if (*edge != e) { Vertex c = GetAdjacentFaceVertex(f1, *edge, success); v = v - (c/16.0); if(derive_indices.size() < 8) { derive_indices.push_back(c); } if(!success) { boundary = true; break; } } } edges.erase(edges.begin(), edges.end()); edges.insert(f2.E1()); edges.insert(f2.E2()); edges.insert(f2.E3()); for (auto edge = edges.begin(); edge != edges.end(); ++edge) { if (*edge != e) { Vertex c = GetAdjacentFaceVertex(f2, *edge, success); v = v - (c/16.0); if(derive_indices.size() < 8) { derive_indices.push_back(c); } if(!success) { boundary = true; break; } } } } while(false); if(boundary) { /* * Proceed with boundary case. */ // Extract the 4 vertices. Vertex v1, v2, v3, v4; v1 = e.V1(); v2 = e.V2(); v3 = getOtherBoundaryVertice(v1, e); v4 = getOtherBoundaryVertice(v2, e); // For the boundary case, we will will ignore the derive_indices vector, // and just compute a new vector with the 4 indices. std::vector<Vertex> boundary_indices; boundary_indices.push_back(v1); boundary_indices.push_back(v2); boundary_indices.push_back(v3); boundary_indices.push_back(v4); Vertex output = (v1*9 + v2*9 - v3 - v4)/16.0; derivations[output] = boundary_indices; return output; } derivations[v] = derive_indices; return v; }
Vertex WingedEdge::getOtherVertex(Edge &edge, Vertex &v) { Vertex v1 = edge.V1(); return v1 == v ? edge.V2() : v1; }
/* This functions computes the new butterfly vertices based on the points in the stencil of the given edge. *FIXME : http://mrl.nyu.edu/~dzorin/papers/zorin1996ism.pdf Page 3. * The special internal cases still need to be implemented. * * Only the degree 6 vertice cases and boundary cases have been implemented for butterfly. * * FIXME : add a type variable to determine what type of interpolation should be used for the edges. * Currently it always uses the butterfly scheme. * * REQUIRES : e is in f1. b1 is in f1. b1 is not in e. * */ Vertex WingedEdge::SubdivideEdge(const Face& f1, Edge& e, Vertex b1, bool linear) { /* get our a midpoint */ Vertex v; v = e.V1() / 2.0; v = v + (e.V2() / 2.0); if(linear) { return v; } // Flag for whether we are in theboundary case or not. bool boundary = false; do { bool success = true; Face f2 = GetAdjacentFace(f1, e, success); if(!success) { boundary = true; break; } /* get our opposing face's b point */ Vertex b2 = GetAdjacentVertex(f2, e, success); if(!success) { boundary = true; break; } v = v + (b1/8.0); v = v + (b2/8.0); /* time to get our c points */ std::set<Edge> edges; edges.insert(f1.E1()); edges.insert(f1.E2()); edges.insert(f1.E3()); for (auto edge = edges.begin(); edge != edges.end(); ++edge) { if (*edge != e) { v = v - (GetAdjacentFaceVertex(f1, *edge, success)/16.0); if(!success) { boundary = true; break; } } } edges.erase(edges.begin(), edges.end()); edges.insert(f2.E1()); edges.insert(f2.E2()); edges.insert(f2.E3()); for (auto edge = edges.begin(); edge != edges.end(); ++edge) { if (*edge != e) { v = v - (GetAdjacentFaceVertex(f2, *edge, success)/16.0); if(!success) { boundary = true; break; } } } } while(false); if(boundary) { /* * Proceed with boundary case. */ // Extract the 4 vertices. Vertex v1, v2, v3, v4; v1 = e.V1(); v2 = e.V2(); v3 = getOtherBoundaryVertice(v1, e); v4 = getOtherBoundaryVertice(v2, e); return (v1*9 + v2*9 - v3 - v4)/16.0; } return v; }
Edge WingedEdge::AddEdge(const Edge& e) { return AddEdge(e.V1(), e.V2()); }