Exemplo n.º 1
0
void LS_Surface::Subdivide()
{
	subdivisionLevel++;
	// Linear subdivision of edges
	LS_EdgeList::iterator edge_itr = edges.begin();
	int numEdges = edges.size();
	int numVertices = vertices.size();
	//TimeHandle t = TimeBegin();
	for( int i = 0; i < numEdges; i++, edge_itr++ )
	{
		// Only subdivide old edges (ones not attached to a new vertex)
		if ( (*edge_itr)->vertices[0]->creationLevel != subdivisionLevel
					&& (*edge_itr)->vertices[1]->creationLevel != subdivisionLevel )
			SubdivideEdge( *edge_itr );
	}
	//printf("Subdivide Edge Time = %lf\n", TimeSlice(t));
	// Create the new faces / Connect the new vertices
	LS_FaceList::iterator face_itr = faces.begin();
	int orinumfaces = faces.size();
	//t = TimeBegin();
	for( int i = 0; i < orinumfaces; i++, face_itr++ )
	{
		// Connect the new vertices into faces
		SubdivideFace( *face_itr );
	}
	//printf("Subdivide Face Time = %lf\n", TimeSlice(t));
	// Reposition new vertices
	LS_VertexList::iterator vertex_itr = vertices.begin();
	//t = TimeBegin();
	for( int i = 0; i < vertices.size(); i++, vertex_itr++ )
	{
		RepositionVertex( *vertex_itr );
	}
	//printf("Reposition Time = %lf\n", TimeSlice(t));
	vertex_itr = vertices.begin();
	//t = TimeBegin();
	for( int i = 0; i < vertices.size(); i++, vertex_itr++ )
		(*vertex_itr)->pos = (*vertex_itr)->newPos;
	//printf("Other Time = %lf\n", TimeSlice(t));
	//UpdateNormals();
}
Exemplo n.º 2
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;
    }
Exemplo n.º 3
0
 // Private work function.
 WingedEdge WingedEdge::Subdivide(bool linear, bool pascal, std::map<Vertex, std::vector<Vertex> > &derivations)
 {
     WingedEdge mesh;
     std::set<Edge> edges;
     
     for (auto face = faceList.begin(); face != faceList.end(); ++face)
     {
         
         /* massive assumption that there is 3 edges in our face */
         Edge e1 = face -> first.E1();
         Edge e2 = face -> first.E2();
         Edge e3 = face -> first.E3();
         
         /* might need to verify this doesn't pick duplicates */
         Vertex v1 = e1.V1();
         Vertex v2 = e1.V2();
         Vertex v3 = (e2.V1() == v1 || e2.V1() == v2) ? e2.V2() : e2.V1();
         
         /* guarantee we know what e2 is */
         if (v1 == e3.V1() || v1 == e3.V2())
         {
             Edge tmp = e3;
             e3 = e2;
             e2 = tmp;
         }
         
         int f1, f2, f3;
         f1 = getNumAdjacentFaces(e1);
         f2 = getNumAdjacentFaces(e2);
         f3 = getNumAdjacentFaces(e3);
         
         // Do not subdivide and do not incorporate non boundary faces.
         // This is the part the creates the pascal behavior,
         if(pascal && f1 == 2 && f2 == 2 && f3 == 2)
         {
             continue;
         }
         
         bool success = true;
         Vertex v4 = SubdivideEdge(face->first, e1, GetAdjacentVertex(face->first, e1, success), linear, derivations);
         Vertex v5 = SubdivideEdge(face->first, e2, GetAdjacentVertex(face->first, e2, success), linear, derivations);
         Vertex v6 = SubdivideEdge(face->first, e3, GetAdjacentVertex(face->first, e3, success), linear, derivations);
         
         // A half hearted success check.
         if(!success)
         {
             throw RuntimeError("WindgedEdge Error: Something is wrong with the mesh to be subdivided.");
         }
         
         {
             e1 = mesh.AddEdge(v1, v4);
             e2 = mesh.AddEdge(v1, v5);
             e3 = mesh.AddEdge(v5, v4);
             mesh.AddFace(e1, e2, e3);
         }
         
         {
             e1 = mesh.AddEdge(v4, v2);
             e2 = mesh.AddEdge(v4, v6);
             e3 = mesh.AddEdge(v6, v2);
             mesh.AddFace(e1, e2, e3);
         }
         
         {
             e1 = mesh.AddEdge(v5, v6);
             e2 = mesh.AddEdge(v5, v3);
             e3 = mesh.AddEdge(v3, v6);
             mesh.AddFace(e1, e2, e3);
         }
         
         {
             e1 = mesh.AddEdge(v6, v5);
             e2 = mesh.AddEdge(v6, v4);
             e3 = mesh.AddEdge(v4, v5);
             mesh.AddFace(e1, e2, e3);
         }
         
     }
     
     /*
      std::cout << "Subdivide info: " << std::endl;
      std::cout << "VertexList: " << mesh.NumVertices() << std::endl;
      std::cout << "EdgeList: " << mesh.NumEdges() << std::endl;
      std::cout << "FaceList: " << mesh.NumFaces() << std::endl;
      */
     
     return mesh;
 }