void practice_1(const Mesh& mesh) {

  // Print vertex information.
  std::cout << "** Vertex Information **" << std::endl;
  for (Mesh::ConstVertexIter v_it = mesh.vertices_begin(); v_it != mesh.vertices_end(); ++v_it) {
    const Mesh::VertexHandle vh(*v_it);
    const int vid = vh.idx();
    std::cout << "vid: [" << vid << "]" << std::endl;

    // Check whether it is on boundary.
    std::cout << "  - boundary: ";
    if (mesh.is_boundary(vh)) std::cout << "yes" << std::endl;
    else std::cout << "no" << std::endl;

    // Print vertex position and normal.
    const Vec3f p = mesh.point(vh);
    std::cout << "  - position: (" << p[0] << ", " << p[1] << ", " << p[2] << ")" << std::endl;
    const Vec3f n = mesh.normal(vh);
    std::cout << "  - normal: (" << n[0] << ", " << n[1] << ", " << n[2] << ")" << std::endl;

    // Print neighbor vertex indices.
    std::cout << "  - neighbors vertices: ";
    for (Mesh::ConstVertexVertexIter vv_it = mesh.cvv_begin(vh); vv_it != mesh.cvv_end(vh); ++vv_it) {
      const Mesh::VertexHandle n_vh(*vv_it);
      const int n_vid = n_vh.idx();
      std::cout << n_vid << " ";
    }
    std::cout << std::endl;

    // NOTE:
    // This is the same loop with the above.
    for (Mesh::ConstVertexVertexIter vv_it = mesh.cvv_iter(vh); vv_it.is_valid(); ++vv_it) {
      const Mesh::VertexHandle n_vh(*vv_it);
      // Do something.
    }

    // Print neighbor face indices.
    std::cout << "  - neighbors faces: ";
    for (Mesh::ConstVertexFaceIter vf_it = mesh.cvf_begin(vh); vf_it != mesh.cvf_end(vh); ++vf_it) {
      const Mesh::FaceHandle n_fh(*vf_it);
      const int n_fid = n_fh.idx();
      std::cout << n_fid << " ";
    }
    std::cout << std::endl;
  }
  std::cout << std::endl;
}
void practice_3(const Mesh& mesh) {

  // Print face information.
  std::cout << "** Face Information **" << std::endl;
  for (Mesh::ConstFaceIter f_it = mesh.faces_begin(); f_it != mesh.faces_end(); ++f_it) {
    const Mesh::FaceHandle fh(*f_it);
    const int fid = fh.idx();
    std::cout << "fid: [" << fid << "]" << std::endl;

    // Print face centroid.
    const Vec3f c = mesh.calc_face_centroid(fh);
    std::cout << "  - centroid: (" << c[0] << ", " << c[1] << ", " << c[2] << ")" << std::endl;


    // Print face area.
    // You can make your own method for computing face area.
    // Here 'calc_sector_area()' function is used with an incident halfedge.
    const Mesh::EdgeHandle eh(*mesh.cfe_begin(fh));

    // Two halfedges.
    const Mesh::HalfedgeHandle heh_0 = mesh.halfedge_handle(eh, 0);
    const Mesh::HalfedgeHandle heh_1 = mesh.halfedge_handle(eh, 1);
    float area = 0;

    if (mesh.face_handle(heh_0) == fh) area = mesh.calc_sector_area(heh_0);
    else if (mesh.face_handle(heh_1) == fh) area = mesh.calc_sector_area(heh_1);
    else assert(false);
    std::cout << "  - area: " << area << std::endl;


    // Print neighbor vertex indices.
    std::cout << "  - neighbors vertices: ";
    for (Mesh::ConstFaceVertexIter fv_it = mesh.cfv_begin(fh); fv_it != mesh.cfv_end(fh); ++fv_it) {
      const Mesh::VertexHandle n_vh(*fv_it);
      const int n_vid = n_vh.idx();
      std::cout << n_vid << " ";
    }
    std::cout << std::endl;
  }
  std::cout << std::endl;
}
void practice_2(const Mesh& mesh) {

  // Print connectivity information.
  std::cout << "** Connectivity Information **" << std::endl;

  // For each vertex, print its connected edge information.
  for (Mesh::ConstVertexIter v_it = mesh.vertices_begin(); v_it != mesh.vertices_end(); ++v_it) {
    const Mesh::VertexHandle vh(*v_it);
    const int vid = vh.idx();
    std::cout << "vid: [" << vid << "]" << std::endl;

    // Print connected edge information.
    std::cout << "  - connected edges: " << std::endl;
    for (Mesh::ConstVertexOHalfedgeIter vohe_it = mesh.cvoh_begin(vh); vohe_it != mesh.cvoh_end(vh); ++vohe_it) {
      const Mesh::HalfedgeHandle ohe(*vohe_it);

      // Get from and to vertices.
      const Mesh::VertexHandle from_vh = mesh.from_vertex_handle(ohe);
      const Mesh::VertexHandle to_vh = mesh.to_vertex_handle(ohe);
      assert(from_vh == vh);

      // Get the opposite halfedge.
      const Mesh::HalfedgeHandle ihe = mesh.opposite_halfedge_handle(ohe);

      // Get incident faces.
      const Mesh::FaceHandle n_fh_0 = mesh.face_handle(ohe);
      const Mesh::FaceHandle n_fh_1 = mesh.face_handle(ihe);

      // Compute edge length.
      const float length = mesh.calc_edge_length(ohe);

      std::cout << "    to_vid = " << to_vh.idx() << ", n_fid = (" <<
        n_fh_0.idx() << ", " << n_fh_1.idx() << "), length = " << length << std::endl;
    }
  }
  std::cout << std::endl;
}
Beispiel #4
0
	bool operator()(Mesh::VertexHandle _v0, Mesh::VertexHandle _v1) const {
		Mesh &mesh = *meshPtr;
		// std::set needs UNIQUE keys -> handle equal priorities
		return ((priority(mesh,_v0) == priority(mesh,_v1)) ?
				(_v0.idx() < _v1.idx()) : (priority(mesh,_v0) < priority(mesh,_v1)));
	}
int main(int argc, char **argv) {

    // Define the mesh type. Here we use OpenMesh defaults.
    typedef OpenMesh::TriMesh_ArrayKernelT<> Mesh;

    
    // Load the triangulated sphere.
    std::string pathToSource = std::string(DEFORM_ETC_DIR) + std::string("/sphere.obj");
    
    Mesh mesh;
    if (!OpenMesh::IO::read_mesh(mesh, pathToSource)) {
        std::cerr << "Failed to read mesh" << std::endl;
        return -1;
    }
    
  
    // Mesh-deform is independent of the types used to represent triangular surfaces.
    // We need to provide an adapter so that Mesh-deform is able to handle OpenMesh.
    // For OpenMesh a ready-to-use adapter is provided.
    
    typedef deform::OpenMeshAdapter<> Adapter;
    Adapter ma(mesh);
    
    // Instance the deformation algorithm.
    deform::AsRigidAsPossibleDeformation<Adapter> arap(ma);
    
    // Set anchors. Semantically anchors are vertices that are pinned to a specific location.
    // Here we just pin one vertex to its initial location.
    
    Mesh::VertexHandle va = mesh.vertex_handle(37);
    arap.setConstraint(va.idx(), deform::convert::toEigen(mesh.point(va)));
    
    // Motion related variables
    
    Mesh::Point p = mesh.point(mesh.vertex_handle(32));
    double pi = -M_PI_2;
    double add = 0.01;
    
    // Create an OSG viewer to visualize incremental deformation.
    deform::example::OSGViewer viewer(mesh, {37}, {32});
    viewer.onFrame([&p, &pi, &add, &arap](Mesh &mesh, double time) {
        
        // Update motion
        
        pi += add;
        if (std::abs(pi) > M_PI_2) {
            add *= -1.0;
            pi += add;
        }
        
        // Set handles. Semantically handles are vertices that are dragged around by some motion. Note,
        // although semantically they have a different meaning conceptually its the same as pinning a vertex
        // to a location.
        
        Mesh::VertexHandle vh = mesh.vertex_handle(32);
        arap.setConstraint(vh.idx(), deform::convert::toEigen(p + Mesh::Point(0, 0, (float)(std::sin(pi)))));
        
        // Run the algorithm for 5 iterations. Usually enough when the target constrain locations are not
        // far from the initial locations. Mesh is automatically updated when method completes.
        
        arap.deform(5);
        
        return true;
    });
    viewer.run();
    
    return 0;

}