// construct Skin::Skin(const res::Mesh &mesh, const attrib::Pose &pose) { // copy vertices vertices.reserve(mesh.vertices.size()); for (res::Mesh::Vertices::const_iterator meshVertex(mesh.vertices.begin()); meshVertex != mesh.vertices.end(); ++meshVertex) { Vertex vertex = { meshVertex->co, meshVertex->no }; // copy influences vertex.influences.reserve(meshVertex->influences.size()); for (res::Mesh::Vertex::Influences::const_iterator meshInfluence(meshVertex->influences.begin()); meshInfluence != meshVertex->influences.end(); ++meshInfluence) { const attrib::Pose::Bone *bone(pose.GetBone(*meshInfluence->bone)); if (bone) { Vertex::Influence influence = { bone, meshInfluence->weight }; vertex.influences.push_back(influence); } } vertices.push_back(vertex); } }
//----------------------------------------------------------------------- //mesh square parameterize //----------------------------------------------------------------------- void OMPmodel::Param(const char *infile, const char *outfile, int solveType, int outType) { // read mesh from file if (!OpenMesh::IO::read_mesh(mesh, infile)) { std::cerr << "Error: Cannot read mesh from " << infile << std::endl; } // this vertex property stores the vertex id OpenMesh::VPropHandleT<uint> vertexID; mesh.add_property(vertexID); uint i = 0; for (MyMesh::VertexIter v_it = mesh.vertices_begin(); v_it != mesh.vertices_end(); ++v_it) { mesh.property(vertexID, *v_it) = i; ++i; } //find a boundary half edge MyMesh::HalfedgeHandle heh, heh_init; for (MyMesh::HalfedgeIter h_it = mesh.halfedges_begin(); h_it != mesh.halfedges_end(); ++h_it) { if (mesh.is_boundary(*h_it)) { heh_init = *h_it; heh = heh_init; break; } } //mesh.property(vertexID, mesh.from_vertex_handle(heh)); //mesh.point(mesh.from_vertex_handle(heh)); //push first boundary vertex meshBoundryStatus.push_back(meshBoundary(mesh.property(vertexID, mesh.from_vertex_handle(heh)), mesh.point(mesh.from_vertex_handle(heh)))); heh = mesh.next_halfedge_handle(heh); // push all boundary vertex while (heh != heh_init) { meshBoundryStatus.push_back(meshBoundary(mesh.property(vertexID, mesh.from_vertex_handle(heh)), mesh.point(mesh.from_vertex_handle(heh)))); heh = mesh.next_halfedge_handle(heh); } //caculate length OpenMesh::Vec3d vec; for (i = 0; i < meshBoundryStatus.size() - 1; ++i) { vec = meshBoundryStatus[i + 1].position - meshBoundryStatus[i].position; meshBoundryStatus[i].distanceToNext = vec.norm(); tLen += meshBoundryStatus[i].distanceToNext; } vec = meshBoundryStatus[0].position - meshBoundryStatus[i].position; meshBoundryStatus[i].distanceToNext = vec.norm(); tLen += meshBoundryStatus[i].distanceToNext; //get other information mesh.request_vertex_status(); meshVetexNum = mesh.n_vertices(); mesh.request_face_status(); meshFaceNum = mesh.n_faces(); mesh.release_face_status(); mesh.release_vertex_status(); cout << "#vertices: " << meshVetexNum << endl; cout << "#faces: " << meshFaceNum << endl; cout << "#boundary vertices: " << meshBoundryStatus.size() << endl; cout << "coner vertices: " << meshBoundryStatus[0].vertexID << " " << meshBoundryStatus[meshBoundryStatus.size()/3].vertexID<<" "; cout << meshBoundryStatus[meshBoundryStatus.size() * 2 / 3].vertexID <<" "<< meshBoundryStatus[meshBoundryStatus.size() - 1].vertexID << endl; cout << "Total length: " << tLen << endl; //map interior vertex //resize A and b A.resize(meshVetexNum, meshVetexNum); Bu.resize(meshVetexNum); Bv.resize(meshVetexNum); u.resize(meshVetexNum); v.resize(meshVetexNum); A.setZero(); Bu.setZero(); Bv.setZero(); vector<meshVertex> oneRing; typedef Eigen::Triplet<double> T; std::vector<T> tripletList; for (MyMesh::VertexIter v_it = mesh.vertices_begin(); v_it != mesh.vertices_end(); ++v_it) { oneRing.clear(); if (!mesh.is_boundary(*v_it)) { for (MyMesh::VertexVertexIter vv_it = mesh.vv_iter(*v_it); vv_it.is_valid(); ++vv_it) { oneRing.push_back(meshVertex(mesh.property(vertexID, *vv_it), mesh.point(*vv_it))); } double wij = 0; double sumWij = 0; double cotaij = 0; double cotbij = 0; OpenMesh::Vec3d vi_12vi, vi_12v, vi12vi, vi12v; for (int i = 0; i < oneRing.size(); ++i) { if (i == 0) { vi_12v = mesh.point(*v_it) - oneRing[oneRing.size() - 1].position; vi_12vi = oneRing[0].position - oneRing[oneRing.size() - 1].position; vi12v = mesh.point(*v_it) - oneRing[i + 1].position; vi12vi = oneRing[i].position - oneRing[i + 1].position; } else if (i == oneRing.size() - 1) { vi_12v = mesh.point(*v_it) - oneRing[i - 1].position; vi_12vi = oneRing[i].position - oneRing[i - 1].position; vi12v = mesh.point(*v_it) - oneRing[0].position; vi12vi = oneRing[i].position - oneRing[0].position; } else { vi_12v = mesh.point(*v_it) - oneRing[i - 1].position; vi_12vi = oneRing[i].position - oneRing[i - 1].position; vi12v = mesh.point(*v_it) - oneRing[i + 1].position; vi12vi = oneRing[i].position - oneRing[i + 1].position; } vi_12v.normalize(); vi_12vi.normalize(); vi12v.normalize(); vi12vi.normalize(); cotaij = cot(acos(dot(vi_12v, vi_12vi))); cotbij = cot(acos(dot(vi12v, vi12vi))); wij = 0.5 * (cotaij + cotbij); sumWij += wij; //insert tripletList.push_back(T(mesh.property(vertexID, *v_it), oneRing[i].vertexID, wij));//insert wij (i != j) } tripletList.push_back(T(mesh.property(vertexID, *v_it), mesh.property(vertexID, *v_it), - sumWij));//when i = j } else { tripletList.push_back(T(mesh.property(vertexID, *v_it), mesh.property(vertexID, *v_it), 1));// add boundary } } A.setFromTriplets(tripletList.begin(), tripletList.end()); //debug << A << endl; //map boundary to a unit square BoundaryMap(); Solve(solveType); //change the mesh and output if (outType == 1) { i = 0; for (MyMesh::VertexIter v_it = mesh.vertices_begin(); v_it != mesh.vertices_end(); ++v_it) { mesh.set_point(*v_it, MyMesh::Point(u[i], v[i], 0)); ++i; } // write mesh to output.* OpenMesh::IO::write_mesh(mesh, outfile); } else { mesh.request_vertex_texcoords2D(); i = 0; for (MyMesh::VertexIter v_it = mesh.vertices_begin(); v_it != mesh.vertices_end(); ++v_it) { mesh.set_texcoord2D(*v_it, MyMesh::TexCoord2D(u[i], v[i])); ++i; } // write mesh to output.* OpenMesh::IO::Options wopt; wopt += OpenMesh::IO::Options::VertexTexCoord; OpenMesh::IO::write_mesh(mesh, outfile, wopt); mesh.release_vertex_texcoords2D(); } }