OpenMesh::FaceHandle faceClosestToPoint(TriMesh& mesh, OpenMesh::Vec3f& P) { // return a handle to the face that is closes to a give point. // distance is measured as sum of Euclidean distances from the 3 vertices to the point. vector<MyREAL> dist(mesh.n_vertices()); unsigned int i = 0; TriMesh::VertexIter v_it, v_end(mesh.vertices_end()); for (v_it = mesh.vertices_begin(); v_it!=v_end; ++v_it) { dist[v_it->idx()]=(P-mesh.point(v_it)).length(); } TriMesh::FaceIter f_it, f_end(mesh.faces_end()); TriMesh::ConstFaceVertexIter cfvIt; double d, mind=10000000000; OpenMesh::FaceHandle mindHandle; for (f_it = mesh.faces_begin(); f_it!=f_end; ++f_it) { cfvIt = mesh.cfv_iter(f_it); d = dist[ cfvIt.handle().idx()]; d += dist[ (++cfvIt).handle().idx()]; d += dist[ (++cfvIt).handle().idx()]; if (d<mind) { mind = d; mindHandle = f_it.handle(); } } //for (f_it = mesh.faces_begin(); f_it!=f_end; ++f_it) return mindHandle ; } // OpenMesh::FaceHandle faceClosestToPoint(TriMesh& mesh, OpenMesh::Vec3f& P)
void MeshDenoisingBase::getFaceCentroid(TriMesh &mesh, std::vector<TriMesh::Point> ¢roid) { centroid.resize(mesh.n_faces(), TriMesh::Point(0.0, 0.0, 0.0)); for(TriMesh::FaceIter f_it = mesh.faces_begin(); f_it != mesh.faces_end(); f_it++) { TriMesh::Point pt = mesh.calc_face_centroid(*f_it); centroid[(*f_it).idx()] = pt; } }
void MeshDenoisingBase::getAllFaceNeighbor(TriMesh &mesh, std::vector<std::vector<TriMesh::FaceHandle> > &all_face_neighbor, FaceNeighborType face_neighbor_type, bool include_central_face) { all_face_neighbor.resize(mesh.n_faces()); for(TriMesh::FaceIter f_it = mesh.faces_begin(); f_it != mesh.faces_end(); f_it++) { std::vector<TriMesh::FaceHandle> face_neighbor; getFaceNeighbor(mesh, *f_it, face_neighbor_type, face_neighbor); if(include_central_face) face_neighbor.push_back(*f_it); all_face_neighbor[f_it->idx()] = face_neighbor; } }
void MeshDenoisingBase::getFaceNormal(TriMesh &mesh, std::vector<TriMesh::Normal> &normals) { mesh.request_face_normals(); mesh.update_face_normals(); normals.resize(mesh.n_faces()); for(TriMesh::FaceIter f_it = mesh.faces_begin(); f_it != mesh.faces_end(); f_it++) { TriMesh::Normal n = mesh.normal(*f_it); normals[f_it->idx()] = n; } }
void MeshDenoisingBase::getFaceArea(TriMesh &mesh, std::vector<double> &area) { area.resize(mesh.n_faces()); for(TriMesh::FaceIter f_it = mesh.faces_begin(); f_it != mesh.faces_end(); f_it++) { std::vector<TriMesh::Point> point; point.resize(3); int index = 0; for(TriMesh::FaceVertexIter fv_it = mesh.fv_iter(*f_it); fv_it.is_valid(); fv_it++) { point[index] = mesh.point(*fv_it); index++; } TriMesh::Point edge1 = point[1] - point[0]; TriMesh::Point edge2 = point[1] - point[2]; double S = 0.5 * (edge1 % edge2).length(); area[(*f_it).idx()] = S; } }
double MeshDenoisingBase::getMeanSquareAngleError(TriMesh &DenoisedMesh, TriMesh &OriginalMesh) { DenoisedMesh.request_face_normals(); DenoisedMesh.update_face_normals(); OriginalMesh.request_face_normals(); OriginalMesh.update_face_normals(); double mean_square_angle_error = 0.0; for (TriMesh::FaceIter f_it1 = DenoisedMesh.faces_begin(), f_it2 = OriginalMesh.faces_begin(); f_it1 != DenoisedMesh.faces_end(); f_it1++, f_it2++ ) { TriMesh::Normal normal1 = DenoisedMesh.normal(*f_it1); TriMesh::Normal normal2 = OriginalMesh.normal(*f_it2); double cross_value = normal1 | normal2; cross_value = std::min(1.0, std::max(cross_value, -1.0)); mean_square_angle_error += std::acos(cross_value) * 180.0 / M_PI; } return mean_square_angle_error / (double)DenoisedMesh.n_faces(); }
bool computeNormals(TriMesh mesh) { OpenMesh::FPropHandleT<TriMesh::Point> trueNormals; OpenMesh::FPropHandleT<TriMesh::Point> approxNormals; mesh.add_property(trueNormals); mesh.add_property(approxNormals); TriMesh::FaceIter f_it, f_end(mesh.faces_end()); double valence; TriMesh::FaceVertexIter fv_it; for (f_it=mesh.faces_begin(); f_it!=f_end; ++f_it) { mesh.property(trueNormals,f_it).vectorize(0.0f); valence = 0; for (fv_it=mesh.fv_iter( f_it ); fv_it; ++fv_it) { mesh.property(approxNormals,fv_it) += mesh.point( fv_it ); ++valence; } mesh.property(approxNormals,f_it) /= valence; } return true; } // bool computeNormals(TriMesh mesh)
double meshVolume(TriMesh& mesh) { mesh.request_face_normals(); mesh.update_normals(); double vol = 0; double surf = 0; //iterate through all faces; TriMesh::FaceIter f_it, f_end(mesh.faces_end()); OpenMesh::Vec3f pointA , pointB , pointC; TriMesh::ConstFaceVertexIter cfvIt; for (f_it = mesh.faces_begin(); f_it!=f_end; ++f_it) { cfvIt = mesh.cfv_iter(f_it); pointA = mesh.point(cfvIt.handle()); pointB = mesh.point((++cfvIt).handle()); pointC = mesh.point((++cfvIt).handle()); surf += area(pointA, pointB, pointC); vol += volume(pointA, pointB, pointC); } return vol; } // double meshVolume(TriMesh& mesh)