Exemple #1
0
 // 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");
 }
Exemple #2
0
    /* 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;
    }
Exemple #3
0
    // Subdivides only the edges on the boundary.
    WingedEdge WingedEdge::BoundaryTrianglularSubdivide(float min_len)
    {
        
        WingedEdge mesh;// = *this;

        
        for (auto face_iter = faceList.begin(); face_iter != faceList.end(); ++face_iter)
        {
            const Face face = face_iter -> first;
            
            
            /* massive assumption that there is 3 edges in our face */
            Edge e1 = face.E1();
            Edge e2 = face.E2();
            Edge e3 = face.E3();
            
            // Compute the vertices opposite the cooresponding indiced edges.
            bool success = true;
            Vertex v1 = GetAdjacentVertex(face, e1, success);
            Vertex v2 = GetAdjacentVertex(face, e2, success);
            Vertex v3 = GetAdjacentVertex(face, e3, success);
            
            if(!success)
            {
                throw new RuntimeError("Error : Winged Edge topology is malformed!");
            }
            
            // -- Compute boundary predicates that answer whether or not an edge should be divided.
            bool b1, b2, b3;
            b1 = getNumAdjacentFaces(e1) == 1;
            b2 = getNumAdjacentFaces(e2) == 1;
            b3 = getNumAdjacentFaces(e3) == 1;
            
            // Non Boundary --> do not subdivide the face.
            if(!(b1 || b2 || b3))
            {
                
                e1 = mesh.AddEdge(e1);
                e2 = mesh.AddEdge(e2);
                e2 = mesh.AddEdge(e2);
                
                mesh.AddFace(e1, e2, e3);
                
                continue;
            }
            
            
            // FIXME : Only compute butterfly midpoints, if the original predicate is true.
            
            // Compute interpolated midpoints.
            Vertex mid_b1, mid_b2, mid_b3;
            mid_b1 = SubdivideEdge(face, e1, v1, false);
            mid_b2 = SubdivideEdge(face, e2, v2, false);
            mid_b3 = SubdivideEdge(face, e3, v3, false);
            
            
            // Bound the change in midpoint.
            if(min_len > 0)
            {
                // Compute linear mid points.
                Vertex mid_l1, mid_l2, mid_l3;
                mid_l1 = SubdivideEdge(face, e1, v1, true);
                mid_l2 = SubdivideEdge(face, e2, v2, true);
                mid_l3 = SubdivideEdge(face, e3, v3, true);
                
                float sqr_len_min = min_len > 1 ? min_len*min_len : min_len;
                
                b1 = b1 && computeSqrOffset(mid_b1, mid_l1) > sqr_len_min;
                b2 = b2 && computeSqrOffset(mid_b2, mid_l2) > sqr_len_min;
                b3 = b3 && computeSqrOffset(mid_b3, mid_l3) > sqr_len_min;
            }
            
            
            
            // -- Count the number of edges that are on the boundary.
            int boundary_count = 0;
            boundary_count = b1 ? boundary_count + 1 : boundary_count;
            boundary_count = b2 ? boundary_count + 1 : boundary_count;
            boundary_count = b3 ? boundary_count + 1 : boundary_count;
     
            // Non Boundary --> do not subdivide the face.
            if(boundary_count == 0)
            {
                e1 = mesh.AddEdge(e1);
                e2 = mesh.AddEdge(e2);
                e2 = mesh.AddEdge(e2);
                
                mesh.AddFace(e1, e2, e3);
                continue;
            }
            
            
            // 1 boundary --> subdivide into 2 vertices.
            if(boundary_count == 1)
            {
                
                Vertex v_new, v_old1, v_old2, v_old3;
                
                if(b1)
                {
                    v_new = mid_b1;
                    v_old1 = v1;
                    v_old2 = v2;
                    v_old3 = v3;
                }
                else if(b2)
                {
                    v_new = mid_b2;
                    v_old1 = v2;
                    v_old2 = v3;
                    v_old3 = v1;
                }
                else
                {
                    v_new = mid_b3;
                    v_old1 = v3;
                    v_old2 = v1;
                    v_old3 = v2;
                }
                
                // face1
                e1 = mesh.AddEdge(v_new, v_old1);
                e2 = mesh.AddEdge(v_new, v_old2);
                e3 = mesh.AddEdge(v_old1, v_old2);
                mesh.AddFace(e1, e2, e3);
                
                // Face 2.
                e2 = mesh.AddEdge(v_new, v_old3);
                e3 = mesh.AddEdge(v_old1, v_old3);
                mesh.AddFace(e1, e2, e3);
                
                continue;
            }
            
            // 2 - 3 boundaries. Perform the full 4 face triangulation.
            
            if(boundary_count == 3)
            {
                performTriangulation(mesh,
                                     v1, v2, v3,
                                     mid_b1, mid_b2, mid_b3);
                
                continue;
            }
            
            if(boundary_count > 3)
            {
                throw new RuntimeError("Face has more than 3 edges. This is not a triangle!");
            }
            
            // -- 2 boundary case. Subdivide into 3 triangles.
            Vertex v_new1, v_new2, v_old1, v_old2, v_old3;
            
            if(!b1)
            {
                v_old1 = v1;
                v_old2 = v2;
                v_old3 = v3;
                v_new1 = mid_b2;
                v_new2 = mid_b3;
            }
            else if(!b2)
            {
                v_old1 = v2;
                v_old2 = v3;
                v_old3 = v1;
                v_new1 = mid_b3;
                v_new2 = mid_b1;
            }
            else
            {
                v_old1 = v3;
                v_old2 = v1;
                v_old3 = v2;
                v_new1 = mid_b1;
                v_new2 = mid_b2;
            }

            
            // Boundary triangles.
            e1 = mesh.AddEdge(v_old1, v_new1);
            e2 = mesh.AddEdge(v_old1, v_new2);
            e3 = mesh.AddEdge(v_new1, v_new2);
            mesh.AddFace(e1, e2, e3);
            
            
            e1 = mesh.AddEdge(v_old3, v_new1);
            e2 = mesh.AddEdge(v_old3, v_new2);
            e3 = mesh.AddEdge(v_new1, v_new2);
            mesh.AddFace(e1, e2, e3);
            
            // Constant edge triangle.
            e1 = mesh.AddEdge(v_old2, v_new2);
            e2 = mesh.AddEdge(v_old3, v_new2);
            e3 = mesh.AddEdge(v_old3, v_old2);
            mesh.AddFace(e1, e2, e3);
            
        }
       
        return mesh;
    }
Exemple #4
0
 /* 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;
 }