00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037 #ifndef SOFA_COMPONENT_CONTAINER_SPATIALGRIDCONTAINER_INL
00038 #define SOFA_COMPONENT_CONTAINER_SPATIALGRIDCONTAINER_INL
00039
00040 #include <sofa/component/container/SpatialGridContainer.h>
00041
00042 #include <sofa/component/topology/PointSetTopologyChange.h>
00043 #include <sofa/component/topology/PointSetTopologyModifier.h>
00044
00045 #include <sofa/simulation/common/AnimateBeginEvent.h>
00046 #include <sofa/simulation/common/AnimateEndEvent.h>
00047 #include <sofa/helper/system/gl.h>
00048 #include <sofa/component/MechanicalObject.h>
00049
00050
00051 namespace sofa
00052 {
00053
00054 namespace component
00055 {
00056
00057 namespace container
00058 {
00059
00060 using namespace sofa::helper;
00061
00062 template<class DataTypes>
00063 typename SpatialGrid<DataTypes>::Grid SpatialGrid<DataTypes>::emptyGrid;
00064
00065 template<class DataTypes>
00066 SpatialGrid<DataTypes>::SpatialGrid(Real cellWidth)
00067 : cellWidth(cellWidth), invCellWidth(1/cellWidth)
00068 {
00069 }
00070
00071 template<class DataTypes>
00072 const typename SpatialGrid<DataTypes>::Grid* SpatialGrid<DataTypes>::findGrid(const Key& k) const
00073 {
00074 typename Map::const_iterator it = map.find(k);
00075 if (it == map.end()) return &emptyGrid;
00076 else return it->second;
00077 }
00078
00079 template<class DataTypes>
00080 typename SpatialGrid<DataTypes>::Grid* SpatialGrid<DataTypes>::getGrid(const Key& k)
00081 {
00082 Grid* & g = map[k];
00083 if (g == NULL)
00084 {
00085 g = new Grid;
00086 Grid* g2;
00087 typename Map::const_iterator it;
00088 typename Map::const_iterator end = map.end();
00089 it = map.find(Key(k[0]-1, k[1] , k[2] ));
00090 if (it != end)
00091 {
00092 g2 = it->second;
00093 g->neighbors[0] = g2; g2->neighbors[1] = g;
00094 }
00095 else
00096 g->neighbors[0] = &emptyGrid;
00097 it = map.find(Key(k[0]+1, k[1] , k[2] ));
00098 if (it != end)
00099 {
00100 g2 = it->second;
00101 g->neighbors[1] = g2; g2->neighbors[0] = g;
00102 }
00103 else
00104 g->neighbors[1] = &emptyGrid;
00105 it = map.find(Key(k[0] , k[1]-1, k[2] ));
00106 if (it != end)
00107 {
00108 g2 = it->second;
00109 g->neighbors[2] = g2; g2->neighbors[3] = g;
00110 }
00111 else
00112 g->neighbors[2] = &emptyGrid;
00113 it = map.find(Key(k[0] , k[1]+1, k[2] ));
00114 if (it != end)
00115 {
00116 g2 = it->second;
00117 g->neighbors[3] = g2; g2->neighbors[2] = g;
00118 }
00119 else
00120 g->neighbors[3] = &emptyGrid;
00121 it = map.find(Key(k[0] , k[1] , k[2]-1));
00122 if (it != end)
00123 {
00124 g2 = it->second;
00125 g->neighbors[4] = g2; g2->neighbors[5] = g;
00126 }
00127 else
00128 g->neighbors[4] = &emptyGrid;
00129 it = map.find(Key(k[0] , k[1] , k[2]+1));
00130 if (it != end)
00131 {
00132 g2 = it->second;
00133 g->neighbors[5] = g2; g2->neighbors[4] = g;
00134 }
00135 else
00136 g->neighbors[5] = &emptyGrid;
00137 }
00138 return g;
00139 }
00140
00141 template<class DataTypes>
00142 typename SpatialGrid<DataTypes>::Cell* SpatialGrid<DataTypes>::getCell(const Coord& x)
00143 {
00144 int ix = rfloor(x[0]*invCellWidth);
00145 int iy = rfloor(x[1]*invCellWidth);
00146 int iz = rfloor(x[2]*invCellWidth);
00147 Key k(ix >> GRIDDIM_LOG2, iy >> GRIDDIM_LOG2, iz >> GRIDDIM_LOG2);
00148 ix &= GRIDDIM-1;
00149 iy &= GRIDDIM-1;
00150 iz &= GRIDDIM-1;
00151 Grid* g = getGrid(k);
00152 return g->cell+(ix+GRIDDIM*iy+GRIDDIM*GRIDDIM*iz);
00153 }
00154
00155 template<class DataTypes>
00156 const typename SpatialGrid<DataTypes>::Cell* SpatialGrid<DataTypes>::getCell(const Grid* g, int x, int y, int z)
00157 {
00158 if (x<0)
00159 {
00160 g = g->neighbors[0];
00161 x += GRIDDIM;
00162 }
00163 else if (x >= GRIDDIM)
00164 {
00165 g = g->neighbors[1];
00166 x -= GRIDDIM;
00167 }
00168 if (y<0)
00169 {
00170 g = g->neighbors[2];
00171 y += GRIDDIM;
00172 }
00173 else if (y >= GRIDDIM)
00174 {
00175 g = g->neighbors[3];
00176 y -= GRIDDIM;
00177 }
00178 if (z<0)
00179 {
00180 g = g->neighbors[4];
00181 z += GRIDDIM;
00182 }
00183 else if (z >= GRIDDIM)
00184 {
00185 g = g->neighbors[5];
00186 z -= GRIDDIM;
00187 }
00188 return g->cell + (x*DX + y*DY + z*DZ);
00189 }
00190
00191 template<class DataTypes> template<class NeighborListener>
00192 void SpatialGrid<DataTypes>::findNeighbors(NeighborListener* dest, const Real dist2, const Cell** cellsBegin, const Cell** cellsEnd)
00193 {
00194 const Cell* c0 = *cellsBegin;
00195 const typename std::list<Entry>::const_iterator end = c0->plist.end();
00196 for (typename std::list<Entry>::const_iterator it = c0->plist.begin(); it != end; it++)
00197 {
00198 const Entry& p1 = *it;
00199 typename std::list<Entry>::const_iterator it2 = it;
00200 ++it2;
00201 for (; it2 != end; it2++)
00202 {
00203 const Entry& p2 = *it2;
00204 const Real r2 = (p2.pos - p1.pos).norm2();
00205 if (r2 < dist2)
00206 dest->addNeighbor(p1.index, p2.index, r2, dist2);
00207 }
00208 for (const Cell** c = cellsBegin+1; c != cellsEnd; ++c)
00209 {
00210 const typename std::list<Entry>::const_iterator end2 = (*c)->plist.end();
00211 for (typename std::list<Entry>::const_iterator it2 = (*c)->plist.begin(); it2 != end2; it2++)
00212 {
00213 const Entry& p2 = *it2;
00214 const Real r2 = (p2.pos - p1.pos).norm2();
00215 if (r2 < dist2)
00216 {
00217 dest->addNeighbor(p1.index, p2.index, r2, dist2);
00218 }
00219 }
00220 }
00221 }
00222 }
00223
00224 template<class DataTypes> template<class NeighborListener>
00225 void SpatialGrid<DataTypes>::findNeighbors(NeighborListener* dest, Real dist)
00226 {
00227 const Real dist2 = dist*dist;
00228 for (typename Map::iterator itg = map.begin();itg != map.end(); itg++)
00229 {
00230 Grid* g = itg->second;
00231 if (g->empty) continue;
00232 const Cell* cell[14];
00233 int ic = 0;
00234 int x,y,z;
00235 cell[0] = g->cell;
00236 for (z = 0; z<GRIDDIM; z++)
00237 {
00238 for (y = 0; y<GRIDDIM; y++)
00239 {
00240 cell[ 0] = g->cell+ic;
00241 cell[ 2] = getCell(g, 0, y+1, z );
00242 cell[ 4] = getCell(g, 0, y , z+1);
00243 cell[ 6] = getCell(g, 0, y+1, z+1);
00244 cell[ 8] = getCell(g, -1, y+1, z );
00245 cell[ 9] = getCell(g, -1, y , z+1);
00246 cell[10] = getCell(g, -1, y+1, z+1);
00247 cell[11] = getCell(g, -1, y-1, z+1);
00248 cell[12] = getCell(g, 0, y-1, z+1);
00249 for (x = 0; x<GRIDDIM-1; x++)
00250 {
00251 cell[ 1] = cell[ 0] + DX;
00252 cell[ 3] = cell[ 2] + DX;
00253 cell[ 5] = cell[ 4] + DX;
00254 cell[ 7] = cell[ 6] + DX;
00255 cell[13] = cell[12] + DX;
00256 if (!cell[0]->plist.empty())
00257 this->findNeighbors(dest, dist2, cell, cell+14);
00258 cell[ 8] = cell[ 2];
00259 cell[ 9] = cell[ 4];
00260 cell[10] = cell[ 6];
00261 cell[11] = cell[12];
00262 cell[12] = cell[13];
00263 cell[ 0] = cell[ 1];
00264 cell[ 2] = cell[ 3];
00265 cell[ 4] = cell[ 5];
00266 cell[ 6] = cell[ 7];
00267 ++ic;
00268 }
00269 if (!cell[0]->plist.empty())
00270 {
00271 cell[ 1] = g->neighbors[1]->cell+(ic - (GRIDDIM-1)*DX);
00272 cell[ 3] = getCell(g, GRIDDIM, y+1, z );
00273 cell[ 5] = getCell(g, GRIDDIM, y , z+1);
00274 cell[ 7] = getCell(g, GRIDDIM, y+1, z+1);
00275 cell[13] = getCell(g, GRIDDIM, y-1, z+1);
00276 this->findNeighbors(dest, dist2, cell, cell+14);
00277 }
00278 ++ic;
00279 }
00280 }
00281 }
00282 }
00283
00284 template<class DataTypes>
00285 void SpatialGrid<DataTypes>::computeField(ParticleField* field, Real dist)
00286 {
00287
00288 const Real dist2 = dist*dist;
00289 const int r = rceil(dist/cellWidth)+1;
00290 int x,y,z;
00291 int x2,y2,z2;
00292 if (r > GRIDDIM)
00293 {
00294 std::cerr << "Distance too large in SpatialGrid::computeField ("<<r<<" > "<<GRIDDIM<<")\n";
00295 return;
00296 }
00297
00298 for (typename Map::iterator itg = map.begin();itg != map.end(); itg++)
00299 {
00300 Grid* g = itg->second;
00301 Coord pos;
00302 pos[0] = (Real)(itg->first[0]*GRIDDIM);
00303 pos[1] = (Real)(itg->first[1]*GRIDDIM);
00304 pos[2] = (Real)(itg->first[2]*GRIDDIM);
00305 if (!g->empty)
00306 {
00307 Cell* c;
00308 Cell* c2;
00309 for (z = 0, c = g->cell; z<GRIDDIM; z++)
00310 {
00311 int z0 = (z<r)?0:z-r+1;
00312 int z1 = (z>GRIDDIM-1-r)?GRIDDIM-1:z+r;
00313 for (y = 0; y<GRIDDIM; y++)
00314 {
00315 int y0 = (y<r)?0:y-r+1;
00316 int y1 = (y>GRIDDIM-1-r)?GRIDDIM-1:y+r;
00317 for (x = 0; x<GRIDDIM; x++, c++)
00318 {
00319 if (!c->plist.empty())
00320 {
00321 int x0 = (x<r)?0:x-r+1;
00322 int x1 = (x>GRIDDIM-1-r)?GRIDDIM-1:x+r;
00323 typename std::list<Entry>::const_iterator begin = c->plist.begin();
00324 typename std::list<Entry>::const_iterator end = c->plist.end();
00325 typename std::list<Entry>::const_iterator it;
00326
00327 c2 = g->cell+(x0*DX+y0*DY+z0*DZ);
00328 const int dy = DY-(x1-x0+1)*DX;
00329 const int dz = DZ-(y1-y0+1)*DY;
00330 Coord p;
00331 for (z2 = z0; z2<=z1; z2++, c2+=dz)
00332 {
00333 p[2] = (pos[2]+z2)*cellWidth;
00334 for (y2 = y0; y2<=y1; y2++, c2+=dy)
00335 {
00336 p[1] = (pos[1]+y2)*cellWidth;
00337 for (x2 = x0; x2<=x1; x2++, c2+=DX)
00338 {
00339 p[0] = (pos[0]+x2)*cellWidth;
00340 for (it=begin; it != end; ++it)
00341 {
00342 Real r2 = (it->pos-p).norm2();
00343 if (r2 < dist2)
00344 c2->data.add(field, it->index, r2, dist2);
00345 }
00346 }
00347 }
00348 }
00349 }
00350 }
00351 }
00352 }
00353 }
00354 for (int gz=-1; gz<=1; gz++)
00355 {
00356 for (int gy=-1; gy<=1; gy++)
00357 {
00358 for (int gx=-1; gx<=1; gx++)
00359 {
00360 const Grid* g2 = g;
00361 if (gx==-1) g2 = g2->neighbors[0]; else if (gx==1) g2 = g2->neighbors[1];
00362 if (gy==-1) g2 = g2->neighbors[2]; else if (gy==1) g2 = g2->neighbors[3];
00363 if (gz==-1) g2 = g2->neighbors[4]; else if (gz==1) g2 = g2->neighbors[5];
00364 if (g2 == g) continue;
00365 if (!g2->empty)
00366 {
00367 int g2_x0 = 0, g2_x1 = GRIDDIM-1;
00368 int g2_y0 = 0, g2_y1 = GRIDDIM-1;
00369 int g2_z0 = 0, g2_z1 = GRIDDIM-1;
00370
00371 if (gx<0) { g2_x0 = GRIDDIM-r; }
00372 else if (gx>0) { g2_x1 = r-1; }
00373
00374 if (gy<0) { g2_y0 = GRIDDIM-r; }
00375 else if (gy>0) { g2_y1 = r-1; }
00376
00377 if (gz<0) { g2_z0 = GRIDDIM-r; }
00378 else if (gz>0) { g2_z1 = r-1; }
00379
00380
00381
00382
00383 const Cell* cz = g2->cell+(g2_x0*DX+g2_y0*DY+g2_z0*DZ);
00384 for (z = g2_z0; z<=g2_z1; z++, cz+=DZ)
00385 {
00386
00387
00388 const Cell* cy = cz;
00389 for (y = g2_y0; y<=g2_y1; y++, cy+=DY)
00390 {
00391
00392
00393 const Cell* c = cy;
00394 for (x = g2_x0; x<=g2_x1; x++, c++)
00395 {
00396 if (!c->plist.empty())
00397 {
00398 typename std::list<Entry>::const_iterator begin = c->plist.begin();
00399 typename std::list<Entry>::const_iterator end = c->plist.end();
00400 typename std::list<Entry>::const_iterator it;
00401 int x0 = x + gx*GRIDDIM - r+1; if (x0<0) x0 = 0;
00402 int x1 = x + gx*GRIDDIM + r; if (x1>GRIDDIM-1) x1 = GRIDDIM-1;
00403 int y0 = y + gy*GRIDDIM - r+1; if (y0<0) y0 = 0;
00404 int y1 = y + gy*GRIDDIM + r; if (y1>GRIDDIM-1) y1 = GRIDDIM-1;
00405 int z0 = z + gz*GRIDDIM - r+1; if (z0<0) z0 = 0;
00406 int z1 = z + gz*GRIDDIM + r; if (z1>GRIDDIM-1) z1 = GRIDDIM-1;
00407
00408 Cell* c2 = g->cell+(x0*DX+y0*DY+z0*DZ);
00409 const int dy = DY-(x1-x0+1)*DX;
00410 const int dz = DZ-(y1-y0+1)*DY;
00411 Coord p;
00412 for (z2 = z0; z2<=z1; z2++, c2+=dz)
00413 {
00414 p[2] = (pos[2]+z2)*cellWidth;
00415 for (y2 = y0; y2<=y1; y2++, c2+=dy)
00416 {
00417 p[1] = (pos[1]+y2)*cellWidth;
00418 for (x2 = x0; x2<=x1; x2++, c2+=DX)
00419 {
00420 p[0] = (pos[0]+x2)*cellWidth;
00421 for (it=begin; it != end; ++it)
00422 {
00423 Real r2 = (it->pos-p).norm2();
00424 if (r2 < dist2)
00425 c2->data.add(field, it->index, r2, dist2);
00426 }
00427 }
00428 }
00429 }
00430 }
00431 }
00432 }
00433 }
00434 }
00435 }
00436 }
00437 }
00438 }
00439 }
00440
00441 template<class DataTypes>
00442 void SpatialGrid<DataTypes>::begin()
00443 {
00444 for (typename Map::iterator itg = map.begin();itg != map.end(); itg++)
00445 {
00446 Grid* g = itg->second;
00447
00448 delete g;
00449 }
00450 map.clear();
00451 }
00452
00453 template<class DataTypes>
00454 void SpatialGrid<DataTypes>::add(int i, const Coord& pos, bool allNeighbors)
00455 {
00456 int ix = rfloor(pos[0]*invCellWidth);
00457 int iy = rfloor(pos[1]*invCellWidth);
00458 int iz = rfloor(pos[2]*invCellWidth);
00459 Key k(ix >> GRIDDIM_LOG2, iy >> GRIDDIM_LOG2, iz >> GRIDDIM_LOG2);
00460 ix &= GRIDDIM-1;
00461 iy &= GRIDDIM-1;
00462 iz &= GRIDDIM-1;
00463 Grid* g = getGrid(k);
00464 if (g->empty)
00465 {
00466 g->empty = false;
00467
00468 if (g->neighbors[0] == &emptyGrid) getGrid(Key(k[0]-1, k[1] , k[2] ));
00469 if (g->neighbors[1] == &emptyGrid) getGrid(Key(k[0]+1, k[1] , k[2] ));
00470 if (g->neighbors[2] == &emptyGrid) getGrid(Key(k[0] , k[1]-1, k[2] ));
00471 if (g->neighbors[3] == &emptyGrid) getGrid(Key(k[0] , k[1]+1, k[2] ));
00472 if (g->neighbors[4] == &emptyGrid) getGrid(Key(k[0] , k[1] , k[2]-1));
00473 if (g->neighbors[5] == &emptyGrid) getGrid(Key(k[0] , k[1] , k[2]+1));
00474 if (allNeighbors)
00475 {
00476 if (g->neighbors[0]->neighbors[2] == &emptyGrid) getGrid(Key(k[0]-1, k[1]-1, k[2] ));
00477 if (g->neighbors[1]->neighbors[2] == &emptyGrid) getGrid(Key(k[0]+1, k[1]-1, k[2] ));
00478 if (g->neighbors[0]->neighbors[3] == &emptyGrid) getGrid(Key(k[0]-1, k[1]+1, k[2] ));
00479 if (g->neighbors[1]->neighbors[3] == &emptyGrid) getGrid(Key(k[0]+1, k[1]+1, k[2] ));
00480 if (g->neighbors[0]->neighbors[4] == &emptyGrid) getGrid(Key(k[0]-1, k[1] , k[2]-1));
00481 if (g->neighbors[1]->neighbors[4] == &emptyGrid) getGrid(Key(k[0]+1, k[1] , k[2]-1));
00482 if (g->neighbors[0]->neighbors[5] == &emptyGrid) getGrid(Key(k[0]-1, k[1] , k[2]+1));
00483 if (g->neighbors[1]->neighbors[5] == &emptyGrid) getGrid(Key(k[0]+1, k[1] , k[2]+1));
00484 if (g->neighbors[2]->neighbors[4] == &emptyGrid) getGrid(Key(k[0] , k[1]-1, k[2]-1));
00485 if (g->neighbors[3]->neighbors[4] == &emptyGrid) getGrid(Key(k[0] , k[1]+1, k[2]-1));
00486 if (g->neighbors[2]->neighbors[5] == &emptyGrid) getGrid(Key(k[0] , k[1]-1, k[2]+1));
00487 if (g->neighbors[3]->neighbors[5] == &emptyGrid) getGrid(Key(k[0] , k[1]+1, k[2]+1));
00488
00489 if (g->neighbors[0]->neighbors[2]->neighbors[4] == &emptyGrid) getGrid(Key(k[0]-1, k[1]-1, k[2]-1));
00490 if (g->neighbors[1]->neighbors[2]->neighbors[4] == &emptyGrid) getGrid(Key(k[0]+1, k[1]-1, k[2]-1));
00491 if (g->neighbors[0]->neighbors[3]->neighbors[4] == &emptyGrid) getGrid(Key(k[0]-1, k[1]+1, k[2]-1));
00492 if (g->neighbors[1]->neighbors[3]->neighbors[4] == &emptyGrid) getGrid(Key(k[0]+1, k[1]+1, k[2]-1));
00493 if (g->neighbors[0]->neighbors[2]->neighbors[5] == &emptyGrid) getGrid(Key(k[0]-1, k[1]-1, k[2]+1));
00494 if (g->neighbors[1]->neighbors[2]->neighbors[5] == &emptyGrid) getGrid(Key(k[0]+1, k[1]-1, k[2]+1));
00495 if (g->neighbors[0]->neighbors[3]->neighbors[5] == &emptyGrid) getGrid(Key(k[0]-1, k[1]+1, k[2]+1));
00496 if (g->neighbors[1]->neighbors[3]->neighbors[5] == &emptyGrid) getGrid(Key(k[0]+1, k[1]+1, k[2]+1));
00497 }
00498 }
00499 g->cell[ix+GRIDDIM*iy+GRIDDIM*GRIDDIM*iz].plist.push_back(Entry(i,pos));
00500 }
00501
00502 template<class DataTypes>
00503 void SpatialGrid<DataTypes>::end()
00504 {
00505
00506
00507
00508
00509
00510
00511
00512
00513
00514
00515
00516
00517
00518
00519
00520
00521 }
00522
00526 template<class DataTypes>
00527 void SpatialGrid<DataTypes>::reorderIndices(helper::vector<unsigned int>* old2new, helper::vector<unsigned int>* new2old)
00528 {
00529 unsigned int next = 0;
00530 for (typename Map::iterator itg = map.begin();itg != map.end(); itg++)
00531 {
00532 Key k = itg->first;
00533 Grid* g = itg->second;
00534 if (g->empty) continue;
00535 for (int i=0; i<NCELL; ++i)
00536 {
00537 int j=0;
00538 for (int s=0;s<GRIDDIM_LOG2;++s)
00539 for(int c=0;c<3;++c)
00540 j += ((i>>(3*s+c))&1)<<(GRIDDIM_LOG2*c+s);
00541 Cell* c = g->cell+j;
00542 for (typename std::list<Entry>::iterator it = c->plist.begin(), itend = c->plist.end(); it != itend; ++it)
00543 {
00544 unsigned int old = it->index;
00545 if (old2new != NULL)
00546 {
00547 if (old >= old2new->size()) old2new->resize(old+1);
00548 (*old2new)[old] = next;
00549 }
00550 if (new2old != NULL)
00551 {
00552 if (next >= new2old->size()) new2old->resize(next+1);
00553 (*new2old)[next] = old;
00554 }
00555 it->index = next;
00556 ++next;
00557 }
00558 }
00559 }
00560 }
00561
00562 template<class DataTypes>
00563 void SpatialGrid<DataTypes>::draw()
00564 {
00565 const float cscale = (float)(cellWidth);
00566 const float gscale = (float)(cellWidth*GRIDDIM);
00567 glBegin(GL_LINES);
00568 for (typename Map::iterator itg = map.begin();itg != map.end(); itg++)
00569 {
00570 Key k = itg->first;
00571 Grid* g = itg->second;
00572 glColor3f(1,1,1);
00573 glVertex3f((k[0] )*gscale, (k[1] )*gscale, (k[2] )*gscale);
00574 glVertex3f((k[0]+1)*gscale, (k[1] )*gscale, (k[2] )*gscale);
00575 glVertex3f((k[0] )*gscale, (k[1]+1)*gscale, (k[2] )*gscale);
00576 glVertex3f((k[0]+1)*gscale, (k[1]+1)*gscale, (k[2] )*gscale);
00577 glVertex3f((k[0] )*gscale, (k[1] )*gscale, (k[2]+1)*gscale);
00578 glVertex3f((k[0]+1)*gscale, (k[1] )*gscale, (k[2]+1)*gscale);
00579 glVertex3f((k[0] )*gscale, (k[1]+1)*gscale, (k[2]+1)*gscale);
00580 glVertex3f((k[0]+1)*gscale, (k[1]+1)*gscale, (k[2]+1)*gscale);
00581
00582 glVertex3f((k[0] )*gscale, (k[1] )*gscale, (k[2] )*gscale);
00583 glVertex3f((k[0] )*gscale, (k[1]+1)*gscale, (k[2] )*gscale);
00584 glVertex3f((k[0]+1)*gscale, (k[1] )*gscale, (k[2] )*gscale);
00585 glVertex3f((k[0]+1)*gscale, (k[1]+1)*gscale, (k[2] )*gscale);
00586 glVertex3f((k[0] )*gscale, (k[1] )*gscale, (k[2]+1)*gscale);
00587 glVertex3f((k[0] )*gscale, (k[1]+1)*gscale, (k[2]+1)*gscale);
00588 glVertex3f((k[0]+1)*gscale, (k[1] )*gscale, (k[2]+1)*gscale);
00589 glVertex3f((k[0]+1)*gscale, (k[1]+1)*gscale, (k[2]+1)*gscale);
00590
00591 glVertex3f((k[0] )*gscale, (k[1] )*gscale, (k[2] )*gscale);
00592 glVertex3f((k[0] )*gscale, (k[1] )*gscale, (k[2]+1)*gscale);
00593 glVertex3f((k[0] )*gscale, (k[1]+1)*gscale, (k[2] )*gscale);
00594 glVertex3f((k[0] )*gscale, (k[1]+1)*gscale, (k[2]+1)*gscale);
00595 glVertex3f((k[0]+1)*gscale, (k[1] )*gscale, (k[2] )*gscale);
00596 glVertex3f((k[0]+1)*gscale, (k[1] )*gscale, (k[2]+1)*gscale);
00597 glVertex3f((k[0]+1)*gscale, (k[1]+1)*gscale, (k[2] )*gscale);
00598 glVertex3f((k[0]+1)*gscale, (k[1]+1)*gscale, (k[2]+1)*gscale);
00599
00600 if (g->neighbors[0] == &emptyGrid)
00601 {
00602 glColor3f(1.0f,0.0f,0.0f);
00603 glVertex3f((k[0] )*gscale, (k[1]+0.3f)*gscale, (k[2]+0.3f)*gscale);
00604 glVertex3f((k[0] )*gscale, (k[1]+0.7f)*gscale, (k[2]+0.7f)*gscale);
00605 glVertex3f((k[0] )*gscale, (k[1]+0.3f)*gscale, (k[2]+0.7f)*gscale);
00606 glVertex3f((k[0] )*gscale, (k[1]+0.7f)*gscale, (k[2]+0.3f)*gscale);
00607 }
00608 if (g->neighbors[1] == &emptyGrid)
00609 {
00610 glColor3f(1.0f,0.5f,0.5f);
00611 glVertex3f((k[0]+1 )*gscale, (k[1]+0.3f)*gscale, (k[2]+0.3f)*gscale);
00612 glVertex3f((k[0]+1 )*gscale, (k[1]+0.7f)*gscale, (k[2]+0.7f)*gscale);
00613 glVertex3f((k[0]+1 )*gscale, (k[1]+0.3f)*gscale, (k[2]+0.7f)*gscale);
00614 glVertex3f((k[0]+1 )*gscale, (k[1]+0.7f)*gscale, (k[2]+0.3f)*gscale);
00615 }
00616 if (g->neighbors[2] == &emptyGrid)
00617 {
00618 glColor3f(0.0f,1.0f,0.0f);
00619 glVertex3f((k[0]+0.3f)*gscale, (k[1] )*gscale, (k[2]+0.3f)*gscale);
00620 glVertex3f((k[0]+0.7f)*gscale, (k[1] )*gscale, (k[2]+0.7f)*gscale);
00621 glVertex3f((k[0]+0.3f)*gscale, (k[1] )*gscale, (k[2]+0.7f)*gscale);
00622 glVertex3f((k[0]+0.7f)*gscale, (k[1] )*gscale, (k[2]+0.3f)*gscale);
00623 }
00624 if (g->neighbors[3] == &emptyGrid)
00625 {
00626 glColor3f(0.5f,1.0f,0.5f);
00627 glVertex3f((k[0]+0.3f)*gscale, (k[1]+1 )*gscale, (k[2]+0.3f)*gscale);
00628 glVertex3f((k[0]+0.7f)*gscale, (k[1]+1 )*gscale, (k[2]+0.7f)*gscale);
00629 glVertex3f((k[0]+0.3f)*gscale, (k[1]+1 )*gscale, (k[2]+0.7f)*gscale);
00630 glVertex3f((k[0]+0.7f)*gscale, (k[1]+1 )*gscale, (k[2]+0.3f)*gscale);
00631 }
00632 if (g->neighbors[4] == &emptyGrid)
00633 {
00634 glColor3f(0.0f,0.0f,1.0f);
00635 glVertex3f((k[0]+0.3f)*gscale, (k[1]+0.3f)*gscale, (k[2] )*gscale);
00636 glVertex3f((k[0]+0.7f)*gscale, (k[1]+0.7f)*gscale, (k[2] )*gscale);
00637 glVertex3f((k[0]+0.7f)*gscale, (k[1]+0.3f)*gscale, (k[2] )*gscale);
00638 glVertex3f((k[0]+0.3f)*gscale, (k[1]+0.7f)*gscale, (k[2] )*gscale);
00639 }
00640 if (g->neighbors[5] == &emptyGrid)
00641 {
00642 glColor3f(0.5f,0.5f,1.0f);
00643 glVertex3f((k[0]+0.3f)*gscale, (k[1]+0.3f)*gscale, (k[2]+1 )*gscale);
00644 glVertex3f((k[0]+0.7f)*gscale, (k[1]+0.7f)*gscale, (k[2]+1 )*gscale);
00645 glVertex3f((k[0]+0.7f)*gscale, (k[1]+0.3f)*gscale, (k[2]+1 )*gscale);
00646 glVertex3f((k[0]+0.3f)*gscale, (k[1]+0.7f)*gscale, (k[2]+1 )*gscale);
00647 }
00648 if (!g->empty)
00649 {
00650 glColor3f(0.5f,0.5f,0.5f);
00651 int x,y,z;
00652 for (z = 0; z<=GRIDDIM; z++)
00653 for (y = 0; y<=GRIDDIM; y++)
00654 {
00655 if ((y==0 || y==GRIDDIM) && (z==0 || z==GRIDDIM)) continue;
00656 glVertex3f((k[0]*GRIDDIM )*cscale, (k[1]*GRIDDIM + y )*cscale, (k[2]*GRIDDIM + z )*cscale);
00657 glVertex3f((k[0]*GRIDDIM + GRIDDIM)*cscale, (k[1]*GRIDDIM + y )*cscale, (k[2]*GRIDDIM + z )*cscale);
00658 }
00659 for (z = 0; z<=GRIDDIM; z++)
00660 for (x = 0; x<=GRIDDIM; x++)
00661 {
00662 if ((x==0 || x==GRIDDIM) && (z==0 || z==GRIDDIM)) continue;
00663 glVertex3f((k[0]*GRIDDIM + x )*cscale, (k[1]*GRIDDIM )*cscale, (k[2]*GRIDDIM + z )*cscale);
00664 glVertex3f((k[0]*GRIDDIM + x )*cscale, (k[1]*GRIDDIM + GRIDDIM)*cscale, (k[2]*GRIDDIM + z )*cscale);
00665 }
00666 for (y = 0; y<=GRIDDIM; y++)
00667 for (x = 0; x<=GRIDDIM; x++)
00668 {
00669 if ((x==0 || x==GRIDDIM) && (y==0 || y==GRIDDIM)) continue;
00670 glVertex3f((k[0]*GRIDDIM + x )*cscale, (k[1]*GRIDDIM + y )*cscale, (k[2]*GRIDDIM )*cscale);
00671 glVertex3f((k[0]*GRIDDIM + x )*cscale, (k[1]*GRIDDIM + y )*cscale, (k[2]*GRIDDIM + GRIDDIM)*cscale);
00672 }
00673 }
00674 }
00675 glEnd();
00676 }
00677
00678 template<class DataTypes>
00679 SpatialGridContainer<DataTypes>::SpatialGridContainer()
00680 : grid(NULL)
00681 , d_cellWidth(initData(&d_cellWidth, (Real)1.0, "cellWidth", "Width each cell in the grid. If it is used to compute neighboors, it should be greater that the max radius considered."))
00682 , d_showGrid(initData(&d_showGrid, false, "showGrid", "activate rendering of the grid"))
00683 , d_autoUpdate(initData(&d_autoUpdate, false, "autoUpdate", "Automatically update the grid at each iteration."))
00684 , d_sortPoints(initData(&d_sortPoints, false, "sortPoints", "Sort points depending on which cell they are in the grid. This is required for efficient collision detection."))
00685 , mstate(NULL)
00686 {
00687 this->f_listening.setValue(true);
00688 }
00689
00690 template<class DataTypes>
00691 SpatialGridContainer<DataTypes>::~SpatialGridContainer()
00692 {
00693 if (grid != NULL)
00694 delete grid;
00695 }
00696
00697 template<class DataTypes>
00698 void SpatialGridContainer<DataTypes>::init()
00699 {
00700 mstate = dynamic_cast<core::componentmodel::behavior::MechanicalState<DataTypes>*>(this->getContext()->getMechanicalState());
00701 grid = new Grid(d_cellWidth.getValue());
00702 }
00703
00704 template<class DataTypes>
00705 void SpatialGridContainer<DataTypes>::reinit()
00706 {
00707 if (grid == NULL || grid->getCellWidth() != d_cellWidth.getValue())
00708 {
00709 if (grid != NULL)
00710 delete grid;
00711 grid = new Grid(d_cellWidth.getValue());
00712 }
00713 }
00714
00715 template<class DataTypes>
00716 bool SpatialGridContainer<DataTypes>::sortPoints()
00717 {
00718 if (mstate)
00719 updateGrid(*mstate->getX());
00720 if (this->f_printLog.getValue())
00721 std::cout << "SpatialGridContainer::sortPoints(): sorting..."<<std::endl;
00722 helper::vector<unsigned int> old2new, new2old;
00723 grid->reorderIndices(&old2new, &new2old);
00724
00725 bool identity = true;
00726 for (unsigned int i=0;i<old2new.size();++i)
00727 if (old2new[i] != i)
00728 {
00729 identity = false;
00730 break;
00731 }
00732 if (identity)
00733 {
00734 if(this->f_printLog.getValue())
00735 std::cout << "SpatialGridContainer::sortPoints(): no changes."<<std::endl;
00736 return false;
00737 }
00738 if(this->f_printLog.getValue())
00739 {
00740 std::cout << "map:";
00741 for (unsigned int i=0;i<new2old.size();++i)
00742 std::cout << " "<<new2old[i]<<"->"<<i;
00743 std::cout << std::endl;
00744 std::cout << "invmap:";
00745 for (unsigned int i=0;i<old2new.size();++i)
00746 std::cout << " "<<i<<"->"<<old2new[i];
00747 std::cout << std::endl;
00748 }
00749
00750 sofa::component::topology::PointSetTopologyModifier* pointMod;
00751 this->getContext()->get(pointMod);
00752
00753 if (pointMod)
00754 {
00755 if(this->f_printLog.getValue())
00756 std::cout << "SpatialGridContainer::sortPoints(): renumber using PointSetTopologyModifier."<<std::endl;
00757
00758 pointMod->renumberPoints(new2old,old2new);
00759 }
00760 else
00761 {
00762 MechanicalObject<DataTypes>* object = dynamic_cast<MechanicalObject<DataTypes>*>(this->mstate);
00763 if (object != NULL)
00764 {
00765 if(this->f_printLog.getValue())
00766 std::cout << "SpatialGridContainer::sortPoints(): renumber using MechanicalObject."<<std::endl;
00767 object->renumberValues(new2old);
00768 }
00769 else
00770 {
00771 std::cout << "SpatialGridContainer::sortPoints(): no external object supporting renumbering!"<<std::endl;
00772 }
00773 }
00774 return true;
00775 }
00776 template<class DataTypes>
00777 void SpatialGridContainer<DataTypes>::handleEvent(sofa::core::objectmodel::Event* event)
00778 {
00779 if ( dynamic_cast<simulation::AnimateBeginEvent*>(event))
00780
00781 {
00782 if (d_sortPoints.getValue())
00783 {
00784 sortPoints();
00785 }
00786 else if (d_autoUpdate.getValue())
00787 {
00788 if (mstate)
00789 updateGrid(*mstate->getX());
00790 }
00791 }
00792 }
00793
00794 template<class DataTypes>
00795 void SpatialGridContainer<DataTypes>::draw()
00796 {
00797 if (!d_showGrid.getValue())
00798 return;
00799 if (grid != NULL)
00800 grid->draw();
00801 }
00802
00803 }
00804
00805 }
00806
00807 }
00808
00809 #endif