float Acos(OpenMesh::Vec3f vec1, OpenMesh::Vec3f vec2, OpenMesh::Vec3f vec3) { float c = vec3.norm(); float b = vec2.norm(); float a = vec1.norm(); float costheta = (a*a + b*b - c*c) / (2 * a * b); return acos(costheta); }
//----------------------------------------------------------------------- //read mesh from file //----------------------------------------------------------------------- void OMmodel::OpenMeshReadFile(const char * filename) { // request vertex normals, so the mesh reader can use normal information // if available mesh.request_vertex_normals(); // request face normals, mesh.request_face_normals(); //request vertex color mesh.request_vertex_colors(); // assure we have vertex normals if (!mesh.has_vertex_normals()) { std::cerr << "ERROR: Standard vertex property 'Normals' not available!\n"; } OpenMesh::IO::Options opt; // read mesh from file if (!OpenMesh::IO::read_mesh(mesh, filename, opt)) { std::cerr << "Error: Cannot read mesh from " << filename << std::endl; } // If the file did not provide vertex normals, then calculate them if (!opt.check(OpenMesh::IO::Options::VertexNormal)) { // let the mesh update the normals mesh.update_normals(); } // this vertex property stores the computed mean curvature OpenMesh::VPropHandleT<double> HCurvature; mesh.add_property(HCurvature); //store valence OpenMesh::VPropHandleT<int> valence; mesh.add_property(valence); //store gaussian curvature OpenMesh::VPropHandleT<double> GCurvature; mesh.add_property(GCurvature); //caculate curvature and valence vector<MyMesh::Point> oneRing; float maxCur = 0; float minCur = 0; float maxGCur = 0; float minGCur = 0; int val = 0; for (MyMesh::VertexIter v_it = mesh.vertices_begin(); v_it != mesh.vertices_end(); ++v_it) { oneRing.clear(); for (MyMesh::VertexVertexIter vv_it = mesh.vv_iter(*v_it); vv_it.is_valid(); ++vv_it) { ++val; oneRing.push_back(mesh.point(*vv_it)); } OpenMesh::Vec3f H = OpenMesh::Vec3f(0.0f, 0.0f, 0.0f); float A = 0; float Gcurvature = 0; float Hcurvature = 0; float theta = 0; float alpha = 0; float beta = 0; float arccosAlpha = 0; float arccosBeta = 0; float arccosTheta = 0; float cotAlpha = 0; float cotBeta = 0; for (int i = 0; i < val; ++i) { OpenMesh::Vec3f Vvtovi, Vvtovi1, Vvi_1tovi, Vvi_1tov, Vvi1tovi, Vvi1tov, Vvitovi1; MyMesh::Point PositionV = mesh.point(*v_it); Vvtovi = oneRing[i] - PositionV; OpenMesh::Vec3f nVvtovi = Vvtovi.normalized(); if (i == 0) { Vvi_1tovi = oneRing[0] - oneRing[val - 1]; Vvi_1tov = PositionV - oneRing[val - 1]; Vvi_1tovi.normalize(); Vvi_1tov.normalize(); } else { Vvi_1tovi = oneRing[i] - oneRing[i - 1]; Vvi_1tov = PositionV - oneRing[i - 1]; Vvi_1tovi.normalize(); Vvi_1tov.normalize(); } if (i == val - 1) { Vvtovi1 = oneRing[0] - PositionV; Vvi1tovi = oneRing[i] - oneRing[0]; Vvi1tov = PositionV - oneRing[0]; Vvtovi1.normalize(); Vvi1tovi.normalize(); Vvi1tov.normalize(); } else { Vvtovi1 = oneRing[i + 1] - PositionV; Vvi1tovi = oneRing[i] - oneRing[i + 1]; Vvi1tov = PositionV - oneRing[i + 1]; Vvtovi1.normalize(); Vvi1tovi.normalize(); Vvi1tov.normalize(); } alpha = dot(Vvi_1tovi, Vvi_1tov); beta = dot(Vvi1tov, Vvi1tovi); arccosAlpha = acos(alpha); arccosBeta = acos(beta); cotAlpha = cot(arccosAlpha); cotBeta = cot(arccosBeta); A += ((cotAlpha + cotBeta) * Vvtovi.sqrnorm()); H += ((cotAlpha + cotBeta) * Vvtovi); //theta += Acos(Vvtovi, Vvtovi1, Vvi1tovi); theta = dot(nVvtovi, Vvtovi1); //debug2 << nVvtovi.sqrnorm()<<" "<<acos(theta) << endl; arccosTheta += acos(theta); } //debug << arccosTheta << " " << H << " " << A << endl;; A = A / 8.0f; H = 2.0f * (H / A); Hcurvature = 0.5f * H.norm(); Gcurvature = ((2.0f * M_PI) - arccosTheta)/ A; maxCur = max(Hcurvature, maxCur); minCur = min(Hcurvature, minCur); if (Gcurvature < 1000000) maxGCur = max(Gcurvature, maxGCur); minGCur = min(Gcurvature, minGCur); mesh.property(valence, *v_it) = val; mesh.property(HCurvature, *v_it) = Hcurvature; mesh.property(GCurvature, *v_it) = Gcurvature; //debug << val << " " << Hcurvature << " " << Gcurvature << endl; val = 0; } //std::cout << 2.0f * M_PI << endl; //std::cout << maxCur << " " << minCur <<endl; //std::cout << maxGCur << " " << minGCur << endl; for (MyMesh::FaceIter f_it = mesh.faces_begin(); f_it != mesh.faces_end(); ++f_it) { for (MyMesh::FaceVertexIter fv_it = mesh.fv_iter(*f_it); fv_it.is_valid(); ++fv_it) { int value = mesh.property(valence, *fv_it); if (value <= 4) { meshVertexColorBuffer.push_back(OpenMesh::Vec3f(0.0f, 0.0f, 1.0f)); } if (value >= 5 && value <= 7) { meshVertexColorBuffer.push_back(OpenMesh::Vec3f(0.0f, 1.0f, 0.0f)); } if (value >= 8) { meshVertexColorBuffer.push_back(OpenMesh::Vec3f(1.0f, 0.0f, 0.0f)); } //cout << mesh.property(curvature, *fv_it) << endl; meshCurColorBuffer.push_back(interporlationColor(maxCur, minCur, mesh.property(HCurvature, *fv_it), 1)); meshGCurColorBuffer.push_back(interporlationColor(maxGCur, minGCur, mesh.property(GCurvature, *fv_it), 10)); meshVertexBuffer.push_back(mesh.point(*fv_it)); meshVertexNormalBuffer.push_back(mesh.normal(*fv_it)); meshFaceNormalBuffer.push_back(mesh.normal(*f_it)); } } // don't need the normals anymore? Remove them! mesh.release_vertex_normals(); // dispose the face normals, as we don't need them anymore mesh.release_face_normals(); //release color mesh.release_vertex_colors(); mesh.request_vertex_status(); meshVetexNum = mesh.n_vertices(); mesh.request_face_status(); meshFaceNum = mesh.n_faces(); mesh.request_halfedge_status(); meshHalfEdgeNum = mesh.n_halfedges(); // iterate over all halfedges for (MyMesh::HalfedgeIter h_it = mesh.halfedges_begin(); h_it != mesh.halfedges_end(); ++h_it) { if (!mesh.face_handle(*h_it).is_valid()) { ++meshBoundryEdgeNum; } } mesh.release_face_status(); mesh.release_vertex_status(); mesh.release_halfedge_status(); }