Main Page | Namespace List | Class Hierarchy | Alphabetical List | Class List | File List | Class Members | File Members | Related Pages

ClusterMesh.cpp

Go to the documentation of this file.
00001 /*
00002 @file ClusterMesh.cpp
00003 @author wensu
00004 @date 2003-11-23
00005 This is for maintain clusters on a mesh.
00006 */
00007 
00008 #include "ClusterMesh.h"
00009 #include <cmath>
00010 #include <limits>
00011 
00012 std::string ClusterMesh::registry_name = "ClusterMesh";
00013 
00014 ClusterMesh::ClusterMesh()
00015 :Surface()
00016 {
00017 }
00018 
00019 bool ClusterMesh::readFile(const char* filename)
00020 {
00021         if (filename==NULL)
00022                 return false;
00023         mesh.clear();
00024         bool result=OpenMesh::MeshIO::read_mesh(mesh, filename);
00025 
00026         // some debug information
00027         std::cout << "faces: "<< mesh.n_faces()<<std::endl;
00028         std::cout << "vertices: "<< mesh.n_vertices()<<std::endl;
00029         std::cout << "edges: "<< mesh.n_edges()<<std::endl;
00030 
00031         // precomputing step
00032         removeCluster();
00033         mesh.update_face_normals();
00034         mesh.update_vertex_normals();
00035         computeBoundingBox();
00036         computeFaceCenter();
00037         computeDualEdgeLength();
00038         computeEdgeAngle();
00039         computeEdgeCost();
00040         return result;
00041 }
00042 
00043 void ClusterMesh::assignRandomCluster(int n)
00044 {
00045         int base=mesh.n_faces()/n;
00046         int i=0;
00047         for (ClusterOpenMesh::FaceIter fit = mesh.faces_begin(); fit != mesh.faces_end(); ++fit)
00048         {
00049                 fit->cluster=i++/base;
00050         }
00051 }
00052 
00053 void ClusterMesh::removeCluster()
00054 {
00055         for (ClusterOpenMesh::FaceIter fit = mesh.faces_begin(); fit != mesh.faces_end(); ++fit)
00056         {
00057                 fit->cost=std::numeric_limits<float>::max();
00058                 fit->cluster=-1;
00059         }
00060 }
00061 
00062 void ClusterMesh::computeBoundingBox()
00063 {
00064         ClusterOpenMesh::VertexIter vit = mesh.vertices_begin(), vend = mesh.vertices_end();
00065 
00066         if (vit == vend)
00067                 return;
00068 
00069         ClusterOpenMesh::Point firstPoint = mesh.point(*vit);
00070         bbox_min = bbox_max = firstPoint;
00071 
00072         for ( ; vit != vend; ++vit)
00073         {               
00074                 ClusterOpenMesh::Point p = mesh.point(*vit);
00075                 for (int i=0; i < 3; i++)
00076                 {
00077                         bbox_min[i] = bbox_min[i]<p[i]?bbox_min[i]:p[i];
00078                         bbox_max[i] = bbox_max[i]>p[i]?bbox_min[i]:p[i];
00079                 }
00080         }
00081 }
00082 
00083 void ClusterMesh::computeFaceCenter()
00084 {
00085         for (ClusterOpenMesh::FaceIter fit = mesh.faces_begin(); fit != mesh.faces_end(); ++fit)
00086         {
00087                 ClusterOpenMesh::Point center(0,0,0);
00088                 for (ClusterOpenMesh::FaceVertexIter fv_it=mesh.fv_iter(fit.handle()); fv_it ; ++fv_it)
00089                 {
00090                         center+=mesh.point(*fv_it);
00091                 }
00092                 fit->center=center/3;
00093         }
00094 }
00095         
00096 void ClusterMesh::computeDualEdgeLength()
00097 {
00098         // boundaries edge is 0
00099         for (ClusterOpenMesh::EdgeIter eit = mesh.edges_begin(); eit != mesh.edges_end(); ++eit)
00100         {
00101                 if (mesh.is_boundary(eit.handle()))
00102                 {
00103                         eit->dualEdgeLength=0;
00104                         continue;
00105                 }
00106                 ClusterOpenMesh::HalfedgeHandle he=mesh.halfedge_handle(eit.handle(), 0);
00107                 ClusterOpenMesh::HalfedgeHandle ohe=mesh.halfedge_handle(eit.handle(), 1);
00108                 ClusterOpenMesh::Point from(mesh.face(mesh.face_handle(he)).center);
00109                 ClusterOpenMesh::Point to(mesh.face(mesh.face_handle(ohe)).center);
00110                 ClusterOpenMesh::Point distance(from-to);
00111                 eit->dualEdgeLength=distance.length();
00112         }
00113 }
00114 
00115 void ClusterMesh::computeEdgeAngle()
00116 {
00117         for (ClusterOpenMesh::EdgeIter eit = mesh.edges_begin(); eit != mesh.edges_end(); ++eit)
00118         {
00119                 if (mesh.is_boundary(eit.handle()))
00120                 {
00121                         eit->dualEdgeLength=0;
00122                         continue;
00123                 }
00124                 ClusterOpenMesh::HalfedgeHandle he=mesh.halfedge_handle(eit.handle(), 0);
00125                 ClusterOpenMesh::HalfedgeHandle ohe=mesh.halfedge_handle(eit.handle(), 1);
00126                 ClusterOpenMesh::Point from(mesh.face(mesh.face_handle(he)).normal());
00127                 ClusterOpenMesh::Point to(mesh.face(mesh.face_handle(ohe)).normal());
00128                 // all normal are unit vectors so n.v=cos alpha
00129                 eit->angle=(from[0]*to[0]+from[1]*to[1]+from[2]*to[2]);
00130         }
00131 }
00132 
00133 void ClusterMesh::computeEdgeCost()
00134 {
00135         for (ClusterOpenMesh::EdgeIter eit = mesh.edges_begin(); eit != mesh.edges_end(); ++eit)
00136         {
00137                 eit->cost=(1-eit->angle)*(eit->dualEdgeLength);
00138                 //std::cout << eit->angle << " " << eit->dualEdgeLength << " " << eit->cost <<std::endl;
00139         }
00140 }

Generated on Mon Jun 28 14:58:13 2004 for Advanced Surface Library by doxygen 1.3.4