00001
00002
00003
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
00028 attachAttribute(surInt,std::string("SurfaceInterrogator"));
00029
00030 ParticleBehavior::attachAttributes();
00031 }
00032
00033 void ClusterMeshInterrogator::cleanup()
00034 {
00035
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
00057 if (phase==INITIALIZE)
00058 {
00059
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
00068 phase=ASSIGNNEWCENTERS;
00069 }
00070 else if (phase==ASSIGNNEWCENTERS)
00071 {
00072 cm->removeCluster();
00073 lastFaceInCluster.clear();
00074 costHeap.clear();
00075
00076 ps->clear();
00077
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
00085 costHeap.push_back(fh);
00086 lastFaceInCluster.push_back(fh);
00087
00088 mesh.face(fh).cost=0;
00089 mesh.face(fh).cluster=j;
00090 }
00091
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
00100 phase=FINDCLUSTERCENTERS;
00101 }
00102 else
00103 {
00104
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
00112 ClusterOpenMesh::HalfedgeHandle endhe=mesh.halfedge_handle(fh);
00113 ClusterOpenMesh::HalfedgeHandle he=endhe;
00114 do
00115 {
00116
00117 if (mesh.is_boundary(he))
00118 continue;
00119
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
00137 phase=ASSIGNNEWCENTERS;
00138 --iteration;
00139
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
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
00155 for(unsigned int i=0;i<ps->size();i++)
00156 center[i]=center[i]/count[i];
00157
00158 for(unsigned int i=0;i<ps->size();i++)
00159 {
00160 float min=std::numeric_limits<float>::max();
00161
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
00174 if (clusterCenters.size()<maxClusters)
00175 {
00176 clusterCenters.push_back(lastFace);
00177 }
00178
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 }