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

ClusterMeshInterrogator.cpp

Go to the documentation of this file.
00001 /*
00002 @file ClusterMeshInterrogator.cpp
00003 @author Wen Su
00004 */
00005 
00006 #include "ClusterMeshInterrogator.h"
00007 #include "ParticlePosition.h"
00008 #include <ctime>
00009 #include <limits>
00010 #include <queue>
00011 #include <functional>
00012 
00013 REGISTER_PARTICLESTUFF(ClusterMeshInterrogator,"Behavior:ClusterMeshInterrogator");
00014 
00015 ClusterMeshInterrogator::ClusterMeshInterrogator(Particles *ps)
00016         : ParticleBehavior(ps, std::string("ClusterMeshInterrogator"))
00017 {
00018         iteration=10;
00019         minClusters=2;
00020         maxClusters=5;
00021         restartAlgorithm=0;
00022         phase=INITIALIZE;
00023 }
00024 
00025 void ClusterMeshInterrogator::attachAttributes()
00026 {
00027         // find the cluster mash
00028         attachAttribute(surInt,std::string("SurfaceInterrogator"));
00029 
00030         ParticleBehavior::attachAttributes();
00031 }
00032 
00033 void ClusterMeshInterrogator::cleanup()
00034 {
00035         // number of iteration for the clustering algorithm
00036         if (iteration==0)
00037                 return;
00038 
00039         if (position==NULL)
00040                 return;
00041         if (surInt==NULL)
00042                 return;
00043         ClusterMesh *cm=dynamic_cast<ClusterMesh *>(surInt->surface);
00044         if (cm==NULL)
00045                 return;
00046         ClusterOpenMesh &mesh=cm->mesh;
00047 
00048         if (restartAlgorithm)
00049         {
00050                 restartAlgorithm=0;
00051                 ps->clear();
00052                 clusterCenters.clear();
00053                 phase=INITIALIZE;
00054         }
00055 
00056         // four phases of the algorithm
00057         if (phase==INITIALIZE)
00058         {
00059                 // assign a default center randomly
00060                 srand(time(NULL));
00061                 for(unsigned int i=0;i<minClusters;i++)
00062                 {
00063                         unsigned int j=rand()%mesh.n_faces();
00064                         ClusterOpenMesh::FaceHandle fh(j);
00065                         clusterCenters.push_back(fh);
00066                 }
00067                 // next phase
00068                 phase=ASSIGNNEWCENTERS;
00069         }
00070         else if (phase==ASSIGNNEWCENTERS)
00071         {
00072                 cm->removeCluster();
00073                 lastFaceInCluster.clear();
00074                 costHeap.clear();
00075                 // clear the old positions
00076                 ps->clear();
00077                 // reinsert the new clusters
00078                 for(unsigned int i=0;i<clusterCenters.size(); i++)
00079                 {
00080                         ClusterOpenMesh::FaceHandle &fh=clusterCenters[i];
00081                         ClusterOpenMesh::Point &c(mesh.face(fh).center);
00082                         unsigned int j=ps->addParticle();
00083                         position->setPosition(j, gmVector3(c[0],c[1],c[2]));
00084                         // change in heap
00085                         costHeap.push_back(fh);
00086                         lastFaceInCluster.push_back(fh);
00087                         // assign cluster
00088                         mesh.face(fh).cost=0;
00089                         mesh.face(fh).cluster=j;
00090                 }
00091                 // make heap really does not do anything because all cost is 0
00092                 std::make_heap(costHeap.begin(),costHeap.end(),FaceCostLessThan<ClusterOpenMesh>(mesh));
00093                 phase=EXPANDCLUSTERS;
00094         }
00095         else if (phase==EXPANDCLUSTERS)
00096         {
00097                 if (costHeap.size()==0)
00098                 {
00099                         // this phase is done
00100                         phase=FINDCLUSTERCENTERS;
00101                 }
00102                 else 
00103                 {
00104                         // fh is the current face
00105                         std::pop_heap(costHeap.begin(),costHeap.end(),FaceCostLessThan<ClusterOpenMesh>(mesh));
00106                         ClusterOpenMesh::FaceHandle fh=costHeap.back();
00107                         lastFace=fh;
00108                         lastFaceInCluster[mesh.face(fh).cluster]=fh;
00109                         costHeap.pop_back();
00110                         float currentCost=mesh.face(fh).cost;
00111                         // for each edge neighbor of face
00112                         ClusterOpenMesh::HalfedgeHandle endhe=mesh.halfedge_handle(fh);
00113                         ClusterOpenMesh::HalfedgeHandle he=endhe;
00114                         do
00115                         {
00116                                 // if it is not boundary
00117                                 if (mesh.is_boundary(he))
00118                                         continue;
00119                                 // the neighbor face
00120                                 ClusterOpenMesh::Face &face=mesh.face(mesh.face_handle(mesh.opposite_halfedge_handle(he)));
00121                                 float newCost=currentCost+mesh.edge(mesh.edge_handle(he)).cost;
00122                                 if (newCost<face.cost)
00123                                 {
00124                                         face.cost=newCost;
00125                                         face.cluster=mesh.face(fh).cluster;
00126                                         costHeap.push_back(mesh.handle(face));
00127                                         std::push_heap(costHeap.begin(),costHeap.end(),FaceCostLessThan<ClusterOpenMesh>(mesh));
00128                                 }
00129                                 he=mesh.next_halfedge_handle(he);
00130                         }
00131                         while (he!=endhe);
00132                 }
00133         }
00134         else if (phase==FINDCLUSTERCENTERS)
00135         {
00136                 // next phase
00137                 phase=ASSIGNNEWCENTERS;
00138                 --iteration;
00139                 // store new positions
00140                 std::vector <ClusterOpenMesh::Point> center;
00141                 std::vector <unsigned int> count;
00142                 for(unsigned int i=0;i<ps->size();i++)
00143                 {
00144                         center.push_back(ClusterOpenMesh::Point(0,0,0));
00145                         count.push_back(0);
00146                 }
00147                 // find new center
00148                 for (ClusterOpenMesh::FaceIter f_it=mesh.faces_begin(); f_it!=mesh.faces_end();++f_it)
00149                 {
00150                         int id=f_it->cluster;
00151                         count[id]=count[id]+1;
00152                         center[id]=center[id]+f_it->center;
00153                 }
00154                 // find average position
00155                 for(unsigned int i=0;i<ps->size();i++)
00156                         center[i]=center[i]/count[i];
00157                 // find the new face center by finding the geomtric center of the faces
00158                 for(unsigned int i=0;i<ps->size();i++)
00159                 {
00160                         float min=std::numeric_limits<float>::max();
00161                         // all face and this center
00162                         for (ClusterOpenMesh::FaceIter f_it=mesh.faces_begin(); f_it!=mesh.faces_end();++f_it)
00163                         {
00164                                 ClusterOpenMesh::Point vec(f_it->center-center[i]);
00165                                 float dist=vec.length();
00166                                 if (dist<min)
00167                                 {
00168                                         min=dist;
00169                                         clusterCenters[i]=f_it.handle();
00170                                 }
00171                         }
00172                 }
00173                 // add the last face found as the new cluster center
00174                 if (clusterCenters.size()<maxClusters)
00175                 {
00176                         clusterCenters.push_back(lastFace);
00177                 }
00178                 // print some debug info
00179                 std::cout<<"iteration: "<<iteration<<std::endl;
00180                 std::cout<<"last face costs: "<<mesh.face(lastFace).cost<<std::endl;
00181                 for(unsigned int i=0;i<lastFaceInCluster.size();i++)
00182                 {
00183                         std::cout<<"cluster: "<<i<< " last face cost: " << mesh.face(lastFaceInCluster[i]).cost<<std::endl;
00184                 }
00185         }
00186 }
00187 
00188 int ClusterMeshInterrogator::qlen()
00189 {
00190         return 4;
00191 }
00192 void ClusterMeshInterrogator::getq(double *q)
00193 {
00194         q[0] = minClusters;
00195         q[1] = maxClusters;
00196         q[2] = restartAlgorithm;
00197         q[3] = iteration;
00198 }
00199 void ClusterMeshInterrogator::setq(double *q)
00200 {
00201         minClusters = q[0];
00202         maxClusters = q[1];
00203         restartAlgorithm = q[2];
00204         iteration = q[3];
00205 }
00206 void ClusterMeshInterrogator::qname(char **qn)
00207 {
00208         qn[0] = "minClusters";
00209         qn[1] = "maxClusters";
00210         qn[2] = "restartAlgorithm";
00211         qn[3] = "iteration";
00212 }

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