00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021 #include <BoundingBox.h>
00022 #include "VertexOctree.h"
00023
00024
00025 using namespace std;
00026 namespace puma {
00027
00028
00029 VertexOctree::VertexOctree(
00030 const TriMesh* mesh,
00031 unsigned int maximum_depth,
00032 unsigned int min_entries)
00033 : m_mesh(mesh), m_current_depth(0), m_maximum_depth(maximum_depth), m_min_entries(min_entries)
00034 {
00035
00036 Point bbMin, bbMax;
00037 BoundingBox bb;
00038 bb.apply(*mesh,bbMin,bbMax);
00039
00040
00041 ConstVertexIter vIt(mesh->vertices_begin());
00042 ConstVertexIter vEnd(mesh->vertices_end());
00043 vector<VertexHandle> vertices;
00044 vertices.reserve(mesh->n_vertices());
00045 for (; vIt!=vEnd; ++vIt) {
00046 if(mesh->point(vIt)[2]<2.5)
00047 vertices.push_back(vIt.handle());
00048 }
00049
00050
00051 m_center = point_to_vec((bbMax+bbMin)/(float)2.0);
00052 m_radius = bbMax.max();
00053 m_parentIndex = 0;
00054 m_parentTree = NULL;
00055
00056
00057 initialize(vertices);
00058 }
00059
00060 VertexOctree::VertexOctree(
00061 const TriMesh* mesh,
00062 Vec3f center,
00063 float radius,
00064 unsigned int maximum_depth,
00065 unsigned int min_entries)
00066 : m_mesh(mesh), m_center(center), m_radius(radius), m_current_depth(0), m_maximum_depth(maximum_depth), m_min_entries(min_entries)
00067 {
00068
00069 ConstVertexIter vIt(mesh->vertices_begin());
00070 ConstVertexIter vEnd(mesh->vertices_end());
00071 vector<VertexHandle> vertices;
00072 vertices.reserve(mesh->n_vertices());
00073 for (; vIt!=vEnd; ++vIt) {
00074 vertices.push_back(vIt.handle());
00075 }
00076
00077
00078 m_parentIndex = 0;
00079 m_parentTree = NULL;
00080
00081
00082 initialize(vertices);
00083 }
00084
00085 VertexOctree::VertexOctree(
00086 const TriMesh* mesh,
00087 Vec3f center,
00088 float radius,
00089 unsigned int current_depth,
00090 std::vector<VertexHandle>& vertices,
00091 unsigned int maximum_depth,
00092 unsigned int min_entries,
00093 int parentIndex,
00094 VertexOctree* parentTree) :
00095 m_mesh(mesh), m_center(center), m_radius(radius), m_parentIndex(parentIndex),
00096 m_parentTree(parentTree), m_current_depth(current_depth), m_maximum_depth(maximum_depth), m_min_entries(min_entries)
00097 {
00098 initialize(vertices);
00099 }
00100
00101 void VertexOctree::
00102 initialize(vector<VertexHandle>& vertices)
00103 {
00104 bool subdivided=false;
00105 Vec3f vert;
00106 m_vertices.clear();
00107 m_isLeaf = false;
00108
00109
00110 if (vertices.size() <= m_min_entries || m_current_depth >= m_maximum_depth) {
00111 m_isLeaf = true;
00112 m_vertices = vertices;
00113 m_child[0] = m_child[1] = m_child[2] = m_child[3] = NULL;
00114 m_child[4] = m_child[5] = m_child[6] = m_child[7] = NULL;
00115 return;
00116 }
00117
00118
00119 float halfR = m_radius*.5;
00120 Vec3f childCtr(0.0);
00121
00122 vector<VertexHandle> xp, xm;
00123 vector<VertexHandle> yp, ym;
00124 vector<VertexHandle> zp, zm;
00125 xp.reserve(vertices.size());
00126 xm.reserve(vertices.size());
00127
00128
00129
00130 vector<VertexHandle>::const_iterator vIt, vIt_end;
00131 for(vIt=vertices.begin(), vIt_end=vertices.end(); vIt!=vIt_end; ++vIt)
00132 {
00133 vert = point_to_vec(m_mesh->point(*vIt));
00134 if (vert[0] >= m_center[0]) {
00135 xp.push_back(*vIt);
00136 } else {
00137 xm.push_back(*vIt);
00138 }
00139 }
00140
00141
00142 vector<VertexHandle> &xv = xm;
00143 vector<VertexHandle> &yv = ym;
00144 for (int i=0; i<2; i++) {
00145 childCtr[0] = m_center[0] + (i ? halfR : -halfR);
00146 if (i) xv = xp;
00147 else xv = xm;
00148 yp.clear(); yp.reserve(xv.size());
00149 ym.clear(); ym.reserve(xv.size());
00150
00151 for(vIt=xv.begin(), vIt_end=xv.end(); vIt!=vIt_end; ++vIt)
00152 {
00153 vert = point_to_vec(m_mesh->point(*vIt));
00154 if (vert[1] >= m_center[1]) {
00155 yp.push_back(*vIt);
00156 } else {
00157 ym.push_back(*vIt);
00158 }
00159 }
00160
00161
00162 for (int j=0; j<2; j++) {
00163 childCtr[1] = m_center[1] + (j ? halfR : -halfR);
00164 if (j) yv = yp;
00165 else yv = ym;
00166 zp.clear(); zp.reserve(yv.size());
00167 zm.clear(); zm.reserve(yv.size());
00168
00169 for(vIt=yv.begin(), vIt_end=yv.end(); vIt!=vIt_end; ++vIt)
00170 {
00171 vert = point_to_vec(m_mesh->point(*vIt));
00172 if (vert[2] >= m_center[2]) {
00173 zp.push_back(*vIt);
00174 } else {
00175 zm.push_back(*vIt);
00176 }
00177 }
00178
00179
00180 childCtr[2] = m_center[2] - halfR;
00181 int k = i+2*j;
00182 if (zm.size()>=m_min_entries) {
00183 m_child[k] = new VertexOctree(m_mesh, childCtr, halfR, m_current_depth+1, zm, m_maximum_depth, m_min_entries, k, this);
00184 subdivided = true;
00185 } else {
00186 m_child[k] = NULL;
00187 }
00188
00189 childCtr[2] = m_center[2] + halfR;
00190 k += 4;
00191 if (zp.size()>=m_min_entries) {
00192 m_child[k] = new VertexOctree(m_mesh, childCtr, halfR, m_current_depth+1, zp, m_maximum_depth, m_min_entries, k, this);
00193 subdivided = true;
00194 } else {
00195 m_child[k] = NULL;
00196 }
00197 }
00198 }
00199
00200
00201 if(!subdivided)
00202 {
00203 m_vertices = vertices;
00204 m_isLeaf = true;
00205 m_child[0] = m_child[1] = m_child[2] = m_child[3] = NULL;
00206 m_child[4] = m_child[5] = m_child[6] = m_child[7] = NULL;
00207 }
00208 }
00209
00210 void VertexOctree::
00211 refineTree()
00212 {
00213 if(m_isLeaf)
00214 {
00215 if(m_vertices.size()<=m_min_entries || m_current_depth >= m_maximum_depth)
00216 return;
00217
00218 vector<VertexHandle> vertices = m_vertices;
00219 initialize(vertices);
00220 return;
00221 }
00222
00223 for (int i=0; i<8; i++) {
00224 if (m_child[i])
00225 m_child[i]->refineTree();
00226 }
00227 }
00228
00229
00230 bool VertexOctree::
00231 searchNearest(const Vec3f &p, VertexHandle& vertex, float &distance)
00232 {
00233
00234 if (m_isLeaf) {
00235
00236 vector<VertexHandle>::const_iterator vIt, vIt_end;
00237 for(vIt=m_vertices.begin(), vIt_end=m_vertices.end(); vIt!=vIt_end; ++vIt)
00238 {
00239
00240 if(closerToVertex(p,*vIt,distance))
00241 vertex = *vIt;
00242 }
00243 return puma_ball_within_bounds(p, sqrtf(distance), m_center, m_radius);
00244 }
00245
00246
00247 int iChild = 4*(m_center[2]<p[2]) + 2*(m_center[1]<p[1]) + (m_center[0]<p[0]);
00248
00249
00250 if (m_child[iChild] && m_child[iChild]->searchNearest(p, vertex, distance)) return true;
00251
00252
00253 for (int i=0; i<8; i++) {
00254 if (i==iChild) continue;
00255 if (m_child[i] && puma_bounds_overlap_ball(p,sqrtf(distance),m_child[i]->m_center, m_child[i]->m_radius)) {
00256 if (m_child[i]->searchNearest(p, vertex, distance)) return true;
00257 }
00258 }
00259 return puma_ball_within_bounds(p, sqrtf(distance), m_center, m_radius);
00260 }
00261
00262 bool VertexOctree::
00263 closerToVertex(const Vec3f &p, const VertexHandle& vertex, float& distance)
00264 {
00265 float distance_temp = puma_dist2(p,point_to_vec(m_mesh->point(vertex)));
00266 if (distance_temp < distance) {
00267 distance = distance_temp;
00268 return true;
00269 }
00270 else {
00271 return false;
00272 }
00273 }
00274
00275 void VertexOctree::getPoints(vector<Vec3f> &p)
00276 {
00277 if (m_isLeaf) {
00278 p.push_back(m_center + Vec3f(-m_radius,-m_radius,-m_radius));
00279 p.push_back(m_center + Vec3f( m_radius,-m_radius,-m_radius));
00280 p.push_back(m_center + Vec3f(-m_radius, m_radius,-m_radius));
00281 p.push_back(m_center + Vec3f( m_radius, m_radius,-m_radius));
00282 p.push_back(m_center + Vec3f(-m_radius,-m_radius, m_radius));
00283 p.push_back(m_center + Vec3f( m_radius,-m_radius, m_radius));
00284 p.push_back(m_center + Vec3f(-m_radius, m_radius, m_radius));
00285 p.push_back(m_center + Vec3f( m_radius, m_radius, m_radius));
00286 return;
00287 }
00288 for (int i=0; i<8; i++) {
00289 if (m_child[i])
00290 m_child[i]->getPoints(p);
00291 }
00292
00293 }
00294
00295 void VertexOctree::getCubes(vector<Vec3f> &p, vector<int> &edgeVertices)
00296 {
00297 if (m_isLeaf && m_current_depth==m_maximum_depth) {
00298 int s = p.size();
00299 p.push_back(m_center + Vec3f(-m_radius,-m_radius,-m_radius));
00300 p.push_back(m_center + Vec3f( m_radius,-m_radius,-m_radius));
00301 p.push_back(m_center + Vec3f(-m_radius, m_radius,-m_radius));
00302 p.push_back(m_center + Vec3f( m_radius, m_radius,-m_radius));
00303 p.push_back(m_center + Vec3f(-m_radius,-m_radius, m_radius));
00304 p.push_back(m_center + Vec3f( m_radius,-m_radius, m_radius));
00305 p.push_back(m_center + Vec3f(-m_radius, m_radius, m_radius));
00306 p.push_back(m_center + Vec3f( m_radius, m_radius, m_radius));
00307
00308 edgeVertices.push_back(s+0);edgeVertices.push_back(s+1);
00309 edgeVertices.push_back(s+0);edgeVertices.push_back(s+4);
00310 edgeVertices.push_back(s+1);edgeVertices.push_back(s+3);
00311 edgeVertices.push_back(s+2);edgeVertices.push_back(s+0);
00312 edgeVertices.push_back(s+3);edgeVertices.push_back(s+2);
00313 edgeVertices.push_back(s+4);edgeVertices.push_back(s+6);
00314 edgeVertices.push_back(s+6);edgeVertices.push_back(s+2);
00315 edgeVertices.push_back(s+6);edgeVertices.push_back(s+7);
00316 edgeVertices.push_back(s+7);edgeVertices.push_back(s+3);
00317 edgeVertices.push_back(s+7);edgeVertices.push_back(s+5);
00318 edgeVertices.push_back(s+5);edgeVertices.push_back(s+1);
00319 edgeVertices.push_back(s+5);edgeVertices.push_back(s+4);
00320 return;
00321 }
00322 for (int i=0; i<8; i++) {
00323 if (m_child[i])
00324 m_child[i]->getCubes(p,edgeVertices);
00325 }
00326 }
00327
00328 void VertexOctree::getCubeCenters(vector<Vec3f> ¢ers)
00329 {
00330 if (m_isLeaf) {
00331 centers.push_back(m_center);
00332 return;
00333 }
00334 for (int i=0; i<8; i++) {
00335 if (m_child[i])
00336 m_child[i]->getCubeCenters(centers);
00337 }
00338 }
00339
00340 void VertexOctree::getVertices(vector<VertexHandle>& vertices)
00341 {
00342 if (m_isLeaf) {
00343 int nf = m_vertices.size();
00344 for(int i=0;i<nf;++i)
00345 vertices.push_back(m_vertices[i]);
00346 return;
00347 }
00348 for (int i=0; i<8; i++) {
00349 if (m_child[i])
00350 m_child[i]->getVertices(vertices);
00351 }
00352 }
00353
00354 void VertexOctree::getLeaves(vector<VertexOctree*>& leafes)
00355 {
00356 if (m_isLeaf) {
00357 leafes.push_back(this);
00358 return;
00359 }
00360 for (int i=0; i<8; i++) {
00361 if (m_child[i])
00362 m_child[i]->getLeaves(leafes);
00363 }
00364
00365 }
00366
00367
00368 }
00369