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 #ifndef SOFA_COMPONENT_COLLISION_DISTANCEGRIDCOLLISIONMODEL_H
00026 #define SOFA_COMPONENT_COLLISION_DISTANCEGRIDCOLLISIONMODEL_H
00027
00028 #include <sofa/core/CollisionModel.h>
00029 #include <sofa/component/MechanicalObject.h>
00030 #include <sofa/defaulttype/Vec3Types.h>
00031 #include <sofa/defaulttype/RigidTypes.h>
00032 #include <sofa/helper/io/Mesh.h>
00033 #include <sofa/component/topology/RegularGridTopology.h>
00034
00035
00036 namespace sofa
00037 {
00038
00039 namespace component
00040 {
00041
00042 namespace collision
00043 {
00044
00045 using namespace sofa::defaulttype;
00046 using namespace sofa::helper;
00047
00048 class DistanceGrid
00049 {
00050 public:
00051 static SReal maxDist() { return (SReal)1e10; }
00052 typedef Vector3 Coord;
00053 typedef defaulttype::ExtVector<SReal> VecSReal;
00054 typedef defaulttype::ExtVector<Coord> VecCoord;
00055
00056 DistanceGrid(int nx, int ny, int nz, Coord pmin, Coord pmax);
00057
00058 DistanceGrid(int nx, int ny, int nz, Coord pmin, Coord pmax, defaulttype::ExtVectorAllocator<SReal>* alloc);
00059
00060 protected:
00061 ~DistanceGrid();
00062
00063 public:
00065 static DistanceGrid* load(const std::string& filename, double scale=1.0, int nx=64, int ny=64, int nz=64, Coord pmin = Coord(), Coord pmax = Coord());
00066
00068 static DistanceGrid* loadShared(const std::string& filename, double scale=1.0, int nx=64, int ny=64, int nz=64, Coord pmin = Coord(), Coord pmax = Coord());
00069
00071 DistanceGrid* addRef();
00072
00074 bool release();
00075
00077 bool save(const std::string& filename);
00078
00080 void calcDistance(sofa::helper::io::Mesh* mesh, double scale=1.0);
00081
00084 void calcCubeDistance(SReal dim=1, int np=5);
00085
00087 void computeBBox();
00088
00089 int getNx() const { return nx; }
00090 int getNy() const { return ny; }
00091 int getNz() const { return nz; }
00092 const Coord& getCellWidth() const { return cellWidth; }
00093
00094 int size() const { return nxnynz; }
00095
00096 const Coord& getBBMin() const { return bbmin; }
00097 const Coord& getBBMax() const { return bbmax; }
00098 void setBBMin(const Coord& val) { bbmin = val; }
00099 void setBBMax(const Coord& val) { bbmax = val; }
00100 Coord getBBCorner(int i) const { return Coord((i&1)?bbmax[0]:bbmin[0],(i&2)?bbmax[1]:bbmin[1],(i&4)?bbmax[2]:bbmin[2]); }
00101 bool inBBox(const Coord& p, SReal margin=0.0f) const
00102 {
00103 for (int c=0;c<3;++c)
00104 if (p[c] < bbmin[c]-margin || p[c] > bbmax[c]+margin) return false;
00105 return true;
00106 }
00107
00108 const Coord& getPMin() const { return pmin; }
00109 const Coord& getPMax() const { return pmax; }
00110 Coord getCorner(int i) const { return Coord((i&1)?pmax[0]:pmin[0],(i&2)?pmax[1]:pmin[1],(i&4)?pmax[2]:pmin[2]); }
00111
00112 bool isCube() const { return cubeDim != 0; }
00113 SReal getCubeDim() const { return cubeDim; }
00114
00115 bool inGrid(const Coord& p) const
00116 {
00117 Coord epsilon = cellWidth*0.1;
00118 for (int c=0;c<3;++c)
00119 if (p[c] < pmin[c]+epsilon[c] || p[c] > pmax[c]-epsilon[c]) return false;
00120 return true;
00121 }
00122
00123 Coord clamp(Coord p) const
00124 {
00125 for (int c=0;c<3;++c)
00126 if (p[c] < pmin[c]) p[c] = pmin[c];
00127 else if (p[c] > pmax[c]) p[c] = pmax[c];
00128 return p;
00129 }
00130
00131 int ix(const Coord& p) const
00132 {
00133 return rfloor((p[0]-pmin[0])*invCellWidth[0]);
00134 }
00135
00136 int iy(const Coord& p) const
00137 {
00138 return rfloor((p[1]-pmin[1])*invCellWidth[1]);
00139 }
00140
00141 int iz(const Coord& p) const
00142 {
00143 return rfloor((p[2]-pmin[2])*invCellWidth[2]);
00144 }
00145
00146 int index(const Coord& p, Coord& coefs) const
00147 {
00148 coefs[0] = (p[0]-pmin[0])*invCellWidth[0];
00149 coefs[1] = (p[1]-pmin[1])*invCellWidth[1];
00150 coefs[2] = (p[2]-pmin[2])*invCellWidth[2];
00151 int x = rfloor(coefs[0]);
00152 if (x<0) x=0; else if (x>=nx-1) x=nx-2;
00153 coefs[0] -= x;
00154 int y = rfloor(coefs[1]);
00155 if (y<0) y=0; else if (y>=ny-1) y=ny-2;
00156 coefs[1] -= y;
00157 int z = rfloor(coefs[2]);
00158 if (z<0) z=0; else if (z>=nz-1) z=nz-2;
00159 coefs[2] -= z;
00160 return x+nx*(y+ny*(z));
00161 }
00162
00163 int index(const Coord& p) const
00164 {
00165 Coord coefs;
00166 return index(p, coefs);
00167 }
00168
00169 int index(int x, int y, int z)
00170 {
00171 return x+nx*(y+ny*(z));
00172 }
00173
00174 Coord coord(int x, int y, int z)
00175 {
00176 return pmin+Coord(x*cellWidth[0], y*cellWidth[1], z*cellWidth[2]);
00177 }
00178
00179 SReal operator[](int index) const { return dists[index]; }
00180 SReal& operator[](int index) { return dists[index]; }
00181
00182 static SReal interp(SReal coef, SReal a, SReal b)
00183 {
00184 return a+coef*(b-a);
00185 }
00186
00187 SReal interp(int index, const Coord& coefs) const
00188 {
00189 return interp(coefs[2],interp(coefs[1],interp(coefs[0],dists[index ],dists[index+1 ]),
00190 interp(coefs[0],dists[index +nx ],dists[index+1+nx ])),
00191 interp(coefs[1],interp(coefs[0],dists[index +nxny],dists[index+1 +nxny]),
00192 interp(coefs[0],dists[index +nx+nxny],dists[index+1+nx+nxny])));
00193 }
00194
00195 SReal interp(const Coord& p) const
00196 {
00197 Coord coefs;
00198 int i = index(p, coefs);
00199 return interp(i, coefs);
00200 }
00201
00202 Coord grad(int index, const Coord& coefs) const
00203 {
00204
00205
00206
00207
00208
00209
00210
00211
00212
00213
00214
00215
00216 const SReal dist000 = dists[index ];
00217 const SReal dist100 = dists[index+1 ];
00218 const SReal dist010 = dists[index +nx ];
00219 const SReal dist110 = dists[index+1+nx ];
00220 const SReal dist001 = dists[index +nxny];
00221 const SReal dist101 = dists[index+1 +nxny];
00222 const SReal dist011 = dists[index +nx+nxny];
00223 const SReal dist111 = dists[index+1+nx+nxny];
00224 return Coord(
00225 interp(coefs[2],interp(coefs[1],dist100-dist000,dist110-dist010),interp(coefs[1],dist101-dist001,dist111-dist011)),
00226 interp(coefs[2],interp(coefs[0],dist010-dist000,dist110-dist100),interp(coefs[0],dist011-dist001,dist111-dist101)),
00227 interp(coefs[1],interp(coefs[0],dist001-dist000,dist101-dist100),interp(coefs[0],dist011-dist010,dist111-dist110)));
00228 }
00229
00230 Coord grad(const Coord& p) const
00231 {
00232 Coord coefs;
00233 int i = index(p, coefs);
00234 return grad(i, coefs);
00235 }
00236
00237 SReal eval(const Coord& x) const
00238 {
00239 SReal d;
00240 if (inGrid(x))
00241 {
00242 d = interp(x);
00243 }
00244 else
00245 {
00246 Coord xclamp = clamp(x);
00247 d = interp(xclamp);
00248 d = rsqrt((x-xclamp).norm2() + d*d);
00249 }
00250 return d;
00251 }
00252
00253 SReal quickeval(const Coord& x) const
00254 {
00255 SReal d;
00256 if (inGrid(x))
00257 {
00258 d = dists[index(x)] - cellWidth[0];
00259 }
00260 else
00261 {
00262 Coord xclamp = clamp(x);
00263 d = dists[index(xclamp)] - cellWidth[0];
00264 d = rsqrt((x-xclamp).norm2() + d*d);
00265 }
00266 return d;
00267 }
00268
00269 SReal eval2(const Coord& x) const
00270 {
00271 SReal d2;
00272 if (inGrid(x))
00273 {
00274 SReal d = interp(x);
00275 d2 = d*d;
00276 }
00277 else
00278 {
00279 Coord xclamp = clamp(x);
00280 SReal d = interp(xclamp);
00281 d2 = ((x-xclamp).norm2() + d*d);
00282 }
00283 return d2;
00284 }
00285
00286 SReal quickeval2(const Coord& x) const
00287 {
00288 SReal d2;
00289 if (inGrid(x))
00290 {
00291 SReal d = dists[index(x)] - cellWidth[0];
00292 d2 = d*d;
00293 }
00294 else
00295 {
00296 Coord xclamp = clamp(x);
00297 SReal d = dists[index(xclamp)] - cellWidth[0];
00298 d2 = ((x-xclamp).norm2() + d*d);
00299 }
00300 return d2;
00301 }
00302
00303 VecCoord meshPts;
00304
00305 protected:
00306 int nbRef;
00307 VecSReal dists;
00308 const int nx,ny,nz, nxny, nxnynz;
00309 const Coord pmin, pmax;
00310 const Coord cellWidth, invCellWidth;
00311 Coord bbmin, bbmax;
00312
00313 SReal cubeDim;
00314
00315
00316 enum Status { FMM_FRONT0 = 0, FMM_FAR = -1, FMM_KNOWN_OUT = -2, FMM_KNOWN_IN = -3 };
00317 helper::vector<int> fmm_status;
00318 helper::vector<int> fmm_heap;
00319 int fmm_heap_size;
00320
00321 int fmm_pop();
00322 void fmm_push(int index);
00323 void fmm_swap(int entry1, int entry2);
00324
00325
00326
00327 struct DistanceGridParams
00328 {
00329 std::string filename;
00330 double scale;
00331 int nx,ny,nz;
00332 Coord pmin,pmax;
00333 bool operator==(const DistanceGridParams& v) const
00334 {
00335 if (!(filename == v.filename)) return false;
00336 if (!(scale == v.scale )) return false;
00337 if (!(nx == v.nx )) return false;
00338 if (!(ny == v.ny )) return false;
00339 if (!(nz == v.nz )) return false;
00340 if (!(pmin[0] == v.pmin[0] )) return false;
00341 if (!(pmin[1] == v.pmin[1] )) return false;
00342 if (!(pmin[2] == v.pmin[2] )) return false;
00343 if (!(pmax[0] == v.pmax[0] )) return false;
00344 if (!(pmax[1] == v.pmax[1] )) return false;
00345 if (!(pmax[2] == v.pmax[2] )) return false;
00346 return true;
00347 }
00348 bool operator<(const DistanceGridParams& v) const
00349 {
00350 if (filename < v.filename) return true;
00351 if (filename > v.filename) return false;
00352 if (scale < v.scale ) return true;
00353 if (scale > v.scale ) return false;
00354 if (nx < v.nx ) return false;
00355 if (nx > v.nx ) return true;
00356 if (ny < v.ny ) return false;
00357 if (ny > v.ny ) return true;
00358 if (nz < v.nz ) return false;
00359 if (nz > v.nz ) return true;
00360 if (pmin[0] < v.pmin[0] ) return false;
00361 if (pmin[0] > v.pmin[0] ) return true;
00362 if (pmin[1] < v.pmin[1] ) return false;
00363 if (pmin[1] > v.pmin[1] ) return true;
00364 if (pmin[2] < v.pmin[2] ) return false;
00365 if (pmin[2] > v.pmin[2] ) return true;
00366 if (pmax[0] < v.pmax[0] ) return false;
00367 if (pmax[0] > v.pmax[0] ) return true;
00368 if (pmax[1] < v.pmax[1] ) return false;
00369 if (pmax[1] > v.pmax[1] ) return true;
00370 if (pmax[2] < v.pmax[2] ) return false;
00371 if (pmax[2] > v.pmax[2] ) return true;
00372 return false;
00373 }
00374 bool operator>(const DistanceGridParams& v) const
00375 {
00376 if (filename > v.filename) return true;
00377 if (filename < v.filename) return false;
00378 if (scale > v.scale ) return true;
00379 if (scale < v.scale ) return false;
00380 if (nx > v.nx ) return false;
00381 if (nx < v.nx ) return true;
00382 if (ny > v.ny ) return false;
00383 if (ny < v.ny ) return true;
00384 if (nz > v.nz ) return false;
00385 if (nz < v.nz ) return true;
00386 if (pmin[0] > v.pmin[0] ) return false;
00387 if (pmin[0] < v.pmin[0] ) return true;
00388 if (pmin[1] > v.pmin[1] ) return false;
00389 if (pmin[1] < v.pmin[1] ) return true;
00390 if (pmin[2] > v.pmin[2] ) return false;
00391 if (pmin[2] < v.pmin[2] ) return true;
00392 if (pmax[0] > v.pmax[0] ) return false;
00393 if (pmax[0] < v.pmax[0] ) return true;
00394 if (pmax[1] > v.pmax[1] ) return false;
00395 if (pmax[1] < v.pmax[1] ) return true;
00396 if (pmax[2] > v.pmax[2] ) return false;
00397 if (pmax[2] < v.pmax[2] ) return true;
00398 return false;
00399 }
00400 };
00401 static std::map<DistanceGridParams, DistanceGrid*>& getShared();
00402
00403 };
00404
00408
00409 class RigidDistanceGridCollisionModel;
00410
00411 class RigidDistanceGridCollisionElement : public core::TCollisionElementIterator<RigidDistanceGridCollisionModel>
00412 {
00413 public:
00414
00415 RigidDistanceGridCollisionElement(RigidDistanceGridCollisionModel* model, int index);
00416
00417 explicit RigidDistanceGridCollisionElement(core::CollisionElementIterator& i);
00418
00419 DistanceGrid* getGrid();
00420
00421 bool isTransformed();
00422 const Matrix3& getRotation();
00423 const Vector3& getTranslation();
00424
00425 void setGrid(DistanceGrid* surf);
00426
00430 DistanceGrid* getPrevGrid();
00431 const Matrix3& getPrevRotation();
00432 const Vector3& getPrevTranslation();
00433 double getPrevDt();
00435
00437 void setNewState(double dt, DistanceGrid* grid, const Matrix3& rotation, const Vector3& translation);
00438 };
00439
00440 class RigidDistanceGridCollisionModel : public core::CollisionModel
00441 {
00442 protected:
00443
00444 class ElementData
00445 {
00446 public:
00447 Matrix3 rotation;
00448 Vector3 translation;
00449 DistanceGrid* grid;
00450
00454 DistanceGrid* prevGrid;
00455 Matrix3 prevRotation;
00456 Vector3 prevTranslation;
00457 double prevDt;
00458
00459
00460 bool isTransformed;
00461 ElementData() : grid(NULL), prevGrid(NULL), prevDt(0.0), isTransformed(false) { rotation.identity(); prevRotation.identity(); }
00462 };
00463
00464 sofa::helper::vector<ElementData> elems;
00465 bool modified;
00466
00467
00468 Data< std::string > filename;
00469 Data< double > scale;
00470 Data< helper::fixed_array<DistanceGrid::Coord,2> > box;
00471 Data< int > nx;
00472 Data< int > ny;
00473 Data< int > nz;
00474 Data< std::string > dumpfilename;
00475
00476 core::componentmodel::behavior::MechanicalState<RigidTypes>* rigid;
00477
00478 void updateGrid();
00479 public:
00480 typedef Rigid3Types InDataTypes;
00481 typedef Vec3Types DataTypes;
00482 typedef RigidDistanceGridCollisionElement Element;
00483
00484 Data< bool > usePoints;
00485
00486 RigidDistanceGridCollisionModel();
00487
00488 ~RigidDistanceGridCollisionModel();
00489
00490 core::componentmodel::behavior::MechanicalState<InDataTypes>* getRigidModel() { return rigid; }
00491 core::componentmodel::behavior::MechanicalState<InDataTypes>* getMechanicalState() { return rigid; }
00492
00493 void init();
00494
00495 DistanceGrid* getGrid(int index=0)
00496 {
00497 return elems[index].grid;
00498 }
00499 bool isTransformed(int index=0)
00500 {
00501 return elems[index].isTransformed;
00502 }
00503 const Matrix3& getRotation(int index=0)
00504 {
00505 return elems[index].rotation;
00506 }
00507 const Vector3& getTranslation(int index=0)
00508 {
00509 return elems[index].translation;
00510 }
00511
00512 void setGrid(DistanceGrid* surf, int index=0);
00513
00514 DistanceGrid* getPrevGrid(int index=0)
00515 {
00516 return elems[index].prevGrid;
00517 }
00518 const Matrix3& getPrevRotation(int index=0)
00519 {
00520 return elems[index].prevRotation;
00521 }
00522 const Vector3& getPrevTranslation(int index=0)
00523 {
00524 return elems[index].prevTranslation;
00525 }
00526 double getPrevDt(int index=0)
00527 {
00528 return elems[index].prevDt;
00529 }
00530
00532 void setNewState(int index, double dt, DistanceGrid* grid, const Matrix3& rotation, const Vector3& translation);
00533
00535
00537 void setNewState(double dt, DistanceGrid* grid, const Matrix3& rotation, const Vector3& translation);
00538
00539
00540
00541 void resize(int size);
00542
00544 void computeBoundingTree(int maxDepth=0);
00545
00546 void draw(int index);
00547
00548 void draw();
00549 };
00550
00551 inline RigidDistanceGridCollisionElement::RigidDistanceGridCollisionElement(RigidDistanceGridCollisionModel* model, int index)
00552 : core::TCollisionElementIterator<RigidDistanceGridCollisionModel>(model, index)
00553 {}
00554
00555 inline RigidDistanceGridCollisionElement::RigidDistanceGridCollisionElement(core::CollisionElementIterator& i)
00556 : core::TCollisionElementIterator<RigidDistanceGridCollisionModel>(static_cast<RigidDistanceGridCollisionModel*>(i.getCollisionModel()), i.getIndex())
00557 {
00558 }
00559
00560 inline DistanceGrid* RigidDistanceGridCollisionElement::getGrid() { return model->getGrid(index); }
00561 inline void RigidDistanceGridCollisionElement::setGrid(DistanceGrid* surf) { return model->setGrid(surf, index); }
00562
00563 inline bool RigidDistanceGridCollisionElement::isTransformed() { return model->isTransformed(index); }
00564 inline const Matrix3& RigidDistanceGridCollisionElement::getRotation() { return model->getRotation(index); }
00565 inline const Vector3& RigidDistanceGridCollisionElement::getTranslation() { return model->getTranslation(index); }
00566
00567 inline DistanceGrid* RigidDistanceGridCollisionElement::getPrevGrid() { return model->getPrevGrid(index); }
00568 inline const Matrix3& RigidDistanceGridCollisionElement::getPrevRotation() { return model->getPrevRotation(index); }
00569 inline const Vector3& RigidDistanceGridCollisionElement::getPrevTranslation() { return model->getPrevTranslation(index); }
00570 inline double RigidDistanceGridCollisionElement::getPrevDt() { return model->getPrevDt(index); }
00571
00572 inline void RigidDistanceGridCollisionElement::setNewState(double dt, DistanceGrid* grid, const Matrix3& rotation, const Vector3& translation)
00573 {
00574 return model->setNewState(dt, grid, rotation, translation);
00575 }
00576
00580
00581 class FFDDistanceGridCollisionModel;
00582
00583 class FFDDistanceGridCollisionElement : public core::TCollisionElementIterator<FFDDistanceGridCollisionModel>
00584 {
00585 public:
00586
00587 FFDDistanceGridCollisionElement(FFDDistanceGridCollisionModel* model, int index);
00588
00589 explicit FFDDistanceGridCollisionElement(core::CollisionElementIterator& i);
00590
00591 DistanceGrid* getGrid();
00592
00593 void setGrid(DistanceGrid* surf);
00594 };
00595
00596 class FFDDistanceGridCollisionModel : public core::CollisionModel
00597 {
00598 public:
00599 typedef SReal GSReal;
00600 typedef DistanceGrid::Coord GCoord;
00601 class DeformedCube
00602 {
00603 public:
00604 DistanceGrid* grid;
00605 DeformedCube() : grid(NULL) {}
00606 int elem;
00607 struct Point
00608 {
00609 GCoord bary;
00610 int index;
00611 };
00612 vector<Point> points;
00613 GCoord initP0,initDP,invDP;
00614 GCoord corners[8];
00615 enum {C000 = 0+0+0,
00616 C100 = 1+0+0,
00617 C010 = 0+2+0,
00618 C110 = 1+2+0,
00619 C001 = 0+0+4,
00620 C101 = 1+0+4,
00621 C011 = 0+2+4,
00622 C111 = 1+2+4};
00623 typedef Vec<4,GSReal> Plane;
00624 Plane faces[6];
00625 enum {FX0 = 0+0,
00626 FX1 = 0+1,
00627 FY0 = 2+0,
00628 FY1 = 2+1,
00629 FZ0 = 4+0,
00630 FZ1 = 4+1};
00637 GCoord Dx;
00638 GCoord Dy;
00639 GCoord Dz;
00640 GCoord Dxy;
00641 GCoord Dxz;
00642 GCoord Dyz;
00643 GCoord Dxyz;
00644
00645
00646 void updateDeform();
00647
00648 GCoord center;
00649 GSReal radius;
00650 vector<GCoord> deformedPoints;
00651 bool pointsUpdated;
00652 void updatePoints();
00653 bool facesUpdated;
00654 void updateFaces();
00655
00656 DistanceGrid::Coord baryCoords(const GCoord& c) const
00657 {
00658 return GCoord( (c[0]-initP0[0])*invDP[0],
00659 (c[1]-initP0[1])*invDP[1],
00660 (c[2]-initP0[2])*invDP[2]);
00661 }
00663 GCoord initpos(const GCoord& b) const
00664 {
00665 return GCoord( initP0[0]+initDP[0]*b[0],
00666 initP0[1]+initDP[1]*b[1],
00667 initP0[2]+initDP[2]*b[2]);
00668 }
00670 GCoord deform(const GCoord& b) const
00671 {
00672 return corners[C000] + Dx*b[0] + (Dy + Dxy*b[0])*b[1] + (Dz + Dxz*b[0] + (Dyz + Dxyz*b[0])*b[1])*b[2];
00673 }
00674
00675 static GSReal interp(GSReal coef, GSReal a, GSReal b)
00676 {
00677 return a+coef*(b-a);
00678 }
00679
00681 GCoord deformDir(const GCoord& b, const GCoord& dir) const
00682 {
00683 GCoord r;
00684
00685 r = (Dx + Dxy*b[1] + (Dxz + Dxyz*b[1])*b[2])*dir[0];
00686
00687 r += (Dy + Dxy*b[0] + (Dyz + Dxyz*b[0])*b[2])*dir[1];
00688
00689 r += (Dz + Dxz*b[0] + (Dyz + Dxyz*b[0])*b[1])*dir[2];
00690 return r;
00691 }
00692
00694 Mat<3,3,double> Jdeform(const GCoord& b) const
00695 {
00696 Mat<3,3,double> J;
00697 for (int i=0;i<3;i++)
00698 {
00699
00700 J[i][0] = (Dx[i] + Dxy[i]*b[1] + (Dxz[i] + Dxyz[i]*b[1])*b[2]);
00701
00702 J[i][1] = (Dy[i] + Dxy[i]*b[0] + (Dyz[i] + Dxyz[i]*b[0])*b[2]);
00703
00704 J[i][2] = (Dz[i] + Dxz[i]*b[0] + (Dyz[i] + Dxyz[i]*b[0])*b[1]);
00705 }
00706 return J;
00707 }
00708
00710 GCoord undeform0(const GCoord& p) const
00711 {
00712 GCoord b;
00713 for (int i=0;i<3;i++)
00714 {
00715 GSReal b0 = faces[2*i+0]*Plane(p,1);
00716 GSReal b1 = faces[2*i+1]*Plane(p,1);
00717 b[i] = b0 / (b0 + b1);
00718 }
00719 return b;
00720 }
00722 GCoord undeformDir(const GCoord& b, const GCoord& dir) const
00723 {
00724
00725
00726 Mat<3,3,double> m = Jdeform(b);
00727 Mat<3,3,double> minv;
00728 minv.invert(m);
00729 return minv*dir;
00730 }
00731
00733 Plane computePlane(int c00, int c10, int c01, int c11);
00734 };
00735
00736 protected:
00737
00738 sofa::helper::vector<DeformedCube> elems;
00739
00740
00741 Data< std::string > filename;
00742 Data< double > scale;
00743 Data< helper::fixed_array<DistanceGrid::Coord,2> > box;
00744 Data< int > nx;
00745 Data< int > ny;
00746 Data< int > nz;
00747 Data< std::string > dumpfilename;
00748
00749 core::componentmodel::behavior::MechanicalState<Vec3Types>* ffd;
00750 topology::RegularGridTopology* ffdGrid;
00751
00752 void updateGrid();
00753 public:
00754 typedef Vec3Types InDataTypes;
00755 typedef Vec3Types DataTypes;
00756 typedef topology::RegularGridTopology Topology;
00757 typedef FFDDistanceGridCollisionElement Element;
00758
00759 Data< bool > usePoints;
00760
00761 FFDDistanceGridCollisionModel();
00762
00763 ~FFDDistanceGridCollisionModel();
00764
00765 core::componentmodel::behavior::MechanicalState<DataTypes>* getDeformModel() { return ffd; }
00766 topology::RegularGridTopology* getDeformGrid() { return ffdGrid; }
00767
00768
00769
00770 core::componentmodel::behavior::MechanicalState<DataTypes>* getMechanicalState() { return ffd; }
00771 topology::RegularGridTopology* getMeshTopology() { return ffdGrid; }
00772
00773 void init();
00774
00775 DistanceGrid* getGrid(int index=0)
00776 {
00777 return elems[index].grid;
00778 }
00779
00780 DeformedCube& getDeformCube(int index=0)
00781 {
00782 return elems[index];
00783 }
00784
00785 void setGrid(DistanceGrid* surf, int index=0);
00786
00787
00788
00789 void resize(int size);
00790
00792 void computeBoundingTree(int maxDepth=0);
00793
00794 void draw(int index);
00795
00796 void draw();
00797 };
00798
00799 inline FFDDistanceGridCollisionElement::FFDDistanceGridCollisionElement(FFDDistanceGridCollisionModel* model, int index)
00800 : core::TCollisionElementIterator<FFDDistanceGridCollisionModel>(model, index)
00801 {}
00802
00803 inline FFDDistanceGridCollisionElement::FFDDistanceGridCollisionElement(core::CollisionElementIterator& i)
00804 : core::TCollisionElementIterator<FFDDistanceGridCollisionModel>(static_cast<FFDDistanceGridCollisionModel*>(i.getCollisionModel()), i.getIndex())
00805 {
00806 }
00807
00808 inline DistanceGrid* FFDDistanceGridCollisionElement::getGrid() { return model->getGrid(index); }
00809 inline void FFDDistanceGridCollisionElement::setGrid(DistanceGrid* surf) { return model->setGrid(surf, index); }
00810
00811 }
00812
00813 }
00814
00815 }
00816
00817 #endif