SPHFluidSurfaceMapping.inl

Go to the documentation of this file.
00001 /******************************************************************************
00002 *       SOFA, Simulation Open-Framework Architecture, version 1.0 beta 3      *
00003 *                (c) 2006-2008 MGH, INRIA, USTL, UJF, CNRS                    *
00004 *                                                                             *
00005 * This library is free software; you can redistribute it and/or modify it     *
00006 * under the terms of the GNU Lesser General Public License as published by    *
00007 * the Free Software Foundation; either version 2.1 of the License, or (at     *
00008 * your option) any later version.                                             *
00009 *                                                                             *
00010 * This library is distributed in the hope that it will be useful, but WITHOUT *
00011 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or       *
00012 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License *
00013 * for more details.                                                           *
00014 *                                                                             *
00015 * You should have received a copy of the GNU Lesser General Public License    *
00016 * along with this library; if not, write to the Free Software Foundation,     *
00017 * Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301 USA.          *
00018 *******************************************************************************
00019 *                               SOFA :: Modules                               *
00020 *                                                                             *
00021 * Authors: The SOFA Team and external contributors (see Authors.txt)          *
00022 *                                                                             *
00023 * Contact information: contact@sofa-framework.org                             *
00024 ******************************************************************************/
00025 #ifndef SOFA_COMPONENT_MAPPING_SPHFLUIDSURFACEMAPPING_INL
00026 #define SOFA_COMPONENT_MAPPING_SPHFLUIDSURFACEMAPPING_INL
00027 
00028 #include <sofa/component/mapping/SPHFluidSurfaceMapping.h>
00029 #include <sofa/component/container/SpatialGridContainer.inl>
00030 #include <sofa/core/Mapping.inl>
00031 #include <sofa/helper/rmath.h>
00032 #include <sofa/simulation/tree/GNode.h>
00033 #include <sofa/helper/gl/template.h>
00034 #include <map>
00035 #include <list>
00036 
00037 
00038 
00039 namespace sofa
00040 {
00041 
00042 namespace component
00043 {
00044 
00045 namespace mapping
00046 {
00047 
00048 using namespace sofa::defaulttype;
00049 
00050 
00051 template <class In, class Out>
00052 void SPHFluidSurfaceMapping<In,Out>::init()
00053 {
00054     this->Inherit::init();
00055     simulation::tree::GNode* node = dynamic_cast<simulation::tree::GNode*>(this->getFrom()->getContext());
00056     if (node)
00057     {
00058         //the following line produces a compilation error with GCC 3.3 :(
00059         //sph = node->getNodeObject<SPHForceField>();
00060       node->getNodeObject(sph);
00061     }
00062     if (sph)
00063     {
00064       //mRadius.getValue() = sph->getParticleRadius();
00065       if (mIsoValue.getValue() == 0.5)
00066         mIsoValue.setValue( mIsoValue.getValue()/ sph->getParticleFieldConstant((InReal)mRadius.getValue()));
00067     }
00068 
00069     grid = new Grid((InReal)mStep.getValue());
00070 }
00071 
00072 template <class In, class Out>
00073 void SPHFluidSurfaceMapping<In,Out>::createPoints(OutVecCoord& out, int x, int y, int z, Cell* c, const Cell* cx, const Cell* cy, const Cell* cz, const OutReal isoval)
00074 {
00075     if (c->data.val>isoval)
00076     {
00077         if (!(cx->data.val>isoval))
00078             c->data.p[0] = addPoint<0>(out, x,y,z,c->data.val,cx->data.val,isoval);
00079         if (!(cy->data.val>isoval))
00080             c->data.p[1] = addPoint<1>(out, x,y,z,c->data.val,cy->data.val,isoval);
00081         if (!(cz->data.val>isoval))
00082             c->data.p[2] = addPoint<2>(out, x,y,z,c->data.val,cz->data.val,isoval);
00083     }
00084     else
00085     {
00086         if (cx->data.val>isoval)
00087             c->data.p[0] = addPoint<0>(out, x,y,z,c->data.val,cx->data.val,isoval);
00088         if (cy->data.val>isoval)
00089             c->data.p[1] = addPoint<1>(out, x,y,z,c->data.val,cy->data.val,isoval);
00090         if (cz->data.val>isoval)
00091             c->data.p[2] = addPoint<2>(out, x,y,z,c->data.val,cz->data.val,isoval);
00092     }
00093 }
00094 
00095 
00096 template <class In, class Out>
00097 void SPHFluidSurfaceMapping<In,Out>::createFaces(OutVecCoord& out, const Cell** cells, const OutReal isoval)
00098 {
00099 
00100 /* Convention:
00101  *          Z
00102  *          ^
00103  *          |
00104  *          4----4----5
00105  *         /|        /|
00106  *        7 |       5 |
00107  *       /  8      /  9
00108  *      7---+6----6   |
00109  *      |   |     |   |
00110  *      |   0----0+---1--> X
00111  *     11  /     10  /
00112  *      | 3       | 1
00113  *      |/        |/
00114  *      3----2----2
00115  *     /
00116  *    /
00117  *  |_
00118  * Y
00119  */
00120 
00121     static const int edgecell[12] = { 0, 1, 2, 0, 4, 5, 6, 4, 0, 1, 3, 2 };
00122     static const int edgepts [12] = { 0, 1, 0, 1, 0, 1, 0, 1, 2, 2, 2, 2 };
00123     
00124     int mk;
00125     if (cells[0]->data.val > isoval) mk = 1; else mk=0;
00126     if (cells[1]->data.val > isoval) mk|= 2;
00127     if (cells[3]->data.val > isoval) mk|= 4;
00128     if (cells[2]->data.val > isoval) mk|= 8;
00129     if (cells[4]->data.val > isoval) mk|= 16;
00130     if (cells[5]->data.val > isoval) mk|= 32;
00131     if (cells[7]->data.val > isoval) mk|= 64;
00132     if (cells[6]->data.val > isoval) mk|= 128;
00133     
00134     const int* tri=helper::MarchingCubeTriTable[mk];
00135     while (*tri>=0)
00136     {
00137         if (addFace(cells[edgecell[tri[0]]]->data.p[edgepts[tri[0]]],
00138                     cells[edgecell[tri[1]]]->data.p[edgepts[tri[1]]],
00139                     cells[edgecell[tri[2]]]->data.p[edgepts[tri[2]]], out.size())<0)
00140         {
00141             std::cerr << "  mk=0x"<<std::hex<<mk<<std::dec<<" p1="<<tri[0]<<" p2="<<tri[1]<<" p3="<<tri[2]<<std::endl;
00142             for (int e=0;e<12;e++) std::cerr << "  e"<<e<<"="<<cells[edgecell[e]]->data.p[edgepts[e]];
00143             std::cerr<<std::endl;
00144         }
00145         tri+=3;
00146     }
00147 }
00148 
00149 template <class In, class Out>
00150 void SPHFluidSurfaceMapping<In,Out>::apply( OutVecCoord& out, const InVecCoord& in )
00151 {
00152     if (!sph) return;
00153     //const InReal invStep = (InReal)(1/mStep.getValue());
00154     out.resize(0);
00155     clear();
00156     if (in.size()==0) return;
00157     const InReal r = (InReal)(getRadius()); // / mStep.getValue());
00158     grid->begin();
00159     for (unsigned int ip=0; ip<in.size(); ip++)
00160     {
00161         grid->add(ip, in[ip], true);
00162     }
00163     grid->end();
00164 
00166     grid->computeField(sph, r);
00167 
00169     
00170     const OutReal isoval = (OutReal) getIsoValue();
00171     typename Grid::iterator end = grid->gridEnd();
00172     typename Grid::iterator it;
00173     
00174     // Create points
00175     for (it = grid->gridBegin();it!=end;++it)
00176     {
00177         typename Grid::Key p0 = it->first;
00178         const int x0 = p0[0]*GRIDDIM;
00179         const int y0 = p0[1]*GRIDDIM;
00180         const int z0 = p0[2]*GRIDDIM;
00181         typename Grid::Grid* g = it->second;
00182         const typename Grid::Grid* gx1 = g->neighbors[1];
00183         const typename Grid::Grid* gy1 = g->neighbors[3];
00184         const typename Grid::Grid* gz1 = g->neighbors[5];
00185         int x,y,z;
00186         Cell* c = g->cell;
00187         const Cell* cx1 = gx1->cell;
00188         const Cell* cy1 = gy1->cell;
00189         const Cell* cz1 = gz1->cell;
00190         for (z=0; z<GRIDDIM-1; z++)
00191         {
00192             for (y=0; y<GRIDDIM-1; y++)
00193             {
00194                 for (x=0; x<GRIDDIM-1; x++)
00195                 {
00196                     createPoints(out, x0+x, y0+y, z0+z, c, c+DX, c+DY, c+DZ, isoval);
00197                     c+=DX;
00198                 }
00199                 // X border
00200                 createPoints(out, x0+x, y0+y, z0+z, c, cx1, c+DY, c+DZ, isoval);
00201                 c+=DX;
00202                 cx1+=DY;
00203             }
00204             // Y BORDER
00205             {
00206                 for (x=0; x<GRIDDIM-1; x++)
00207                 {
00208                     createPoints(out, x0+x, y0+y, z0+z, c, c+DX, cy1, c+DZ, isoval);
00209                     c+=DX;
00210                     cy1+=DX;
00211                 }
00212                 // X border
00213                 createPoints(out, x0+x, y0+y, z0+z, c, cx1, cy1, c+DZ, isoval);
00214                 c+=DX;
00215                 cx1+=DY;
00216                 cy1+=DZ+DX-DY;
00217             }
00218         }
00219         // Z BORDER
00220         for (y=0; y<GRIDDIM-1; y++)
00221         {
00222             for (x=0; x<GRIDDIM-1; x++)
00223             {
00224                 createPoints(out, x0+x, y0+y, z0+z, c, c+DX, c+DY, cz1, isoval);
00225                 c+=DX;
00226                 cz1+=DX;
00227             }
00228             // X border
00229             createPoints(out, x0+x, y0+y, z0+z, c, cx1, c+DY, cz1, isoval);
00230             c+=DX;
00231             cx1+=DY;
00232             cz1+=DX;
00233         }
00234         // Y BORDER
00235         {
00236             for (x=0; x<GRIDDIM-1; x++)
00237             {
00238                 createPoints(out, x0+x, y0+y, z0+z, c, c+DX, cy1, cz1, isoval);
00239                 c+=DX;
00240                 cy1+=DX;
00241                 cz1+=DX;
00242             }
00243             // X border
00244             createPoints(out, x0+x, y0+y, z0+z, c, cx1, cy1, cz1, isoval);
00245         }
00246     }
00247     
00248     // Create faces
00249     for (it = grid->gridBegin();it!=end;++it)
00250     {
00251         typename Grid::Grid* g = it->second;
00252         const typename Grid::Grid* gx1 = g->neighbors[1];
00253         const typename Grid::Grid* gy1 = g->neighbors[3];
00254         const typename Grid::Grid* gz1 = g->neighbors[5];
00255         int x,y,z;
00256         const Cell* cells[8];
00257         const Cell* c = g->cell;
00258         const Cell* cx1 = gx1->cell;
00259         const Cell* cy1 = gy1->cell;
00260         const Cell* cz1 = gz1->cell;
00261         const Cell* cx1y1 = g->neighbors[1]->neighbors[3]->cell;
00262         const Cell* cx1z1 = g->neighbors[1]->neighbors[5]->cell;
00263         const Cell* cy1z1 = g->neighbors[3]->neighbors[5]->cell;
00264         const Cell* cx1y1z1 = g->neighbors[1]->neighbors[3]->neighbors[5]->cell;
00265         for (z=0; z<GRIDDIM-1; z++)
00266         {
00267             for (y=0; y<GRIDDIM-1; y++)
00268             {
00269                 for (x=0; x<GRIDDIM-1; x++)
00270                 {
00271                     cells[0] = c;               cells[1] = c+DX;            cells[2] = c+DY;            cells[3] = c+DX+DY;
00272                     cells[4] = cells[0]+DZ;     cells[5] = cells[1]+DZ;     cells[6] = cells[2]+DZ;     cells[7] = cells[3]+DZ;
00273                     createFaces(out, cells, isoval);
00274                     c+=DX;
00275                 }
00276                 // X border
00277                 cells[0] = c;               cells[1] = cx1;             cells[2] = c+DY;            cells[3] = cx1+DY;
00278                 cells[4] = cells[0]+DZ;     cells[5] = cells[1]+DZ;     cells[6] = cells[2]+DZ;     cells[7] = cells[3]+DZ;
00279                 createFaces(out, cells, isoval);
00280                 c+=DX;
00281                 cx1+=DY;
00282             }
00283             // Y BORDER
00284             {
00285                 for (x=0; x<GRIDDIM-1; x++)
00286                 {
00287                     cells[0] = c;               cells[1] = c+DX;            cells[2] = cy1;             cells[3] = cy1+DX;
00288                     cells[4] = cells[0]+DZ;     cells[5] = cells[1]+DZ;     cells[6] = cells[2]+DZ;     cells[7] = cells[3]+DZ;
00289                     createFaces(out, cells, isoval);
00290                     c+=DX;
00291                     cy1+=DX;
00292                 }
00293                 // X border
00294                 cells[0] = c;               cells[1] = cx1;            cells[2] = cy1;              cells[3] = cx1y1;
00295                 cells[4] = cells[0]+DZ;     cells[5] = cells[1]+DZ;     cells[6] = cells[2]+DZ;     cells[7] = cells[3]+DZ;
00296                 createFaces(out, cells, isoval);
00297                 c+=DX;
00298                 cx1+=DY;
00299                 cy1+=DZ+DX-DY;
00300                 cx1y1+=DZ;
00301             }
00302         }
00303         // Z BORDER
00304         for (y=0; y<GRIDDIM-1; y++)
00305         {
00306             for (x=0; x<GRIDDIM-1; x++)
00307             {
00308                 cells[0] = c;               cells[1] = c+DX;            cells[2] = c+DY;            cells[3] = c+DX+DY;
00309                 cells[4] = cz1;             cells[5] = cz1+DX;          cells[6] = cz1+DY;          cells[7] = cz1+DX+DY;
00310                 createFaces(out, cells, isoval);
00311                 c+=DX;
00312                 cz1+=DX;
00313             }
00314             // X border
00315             cells[0] = c;               cells[1] = cx1;            cells[2] = c+DY;            cells[3] = cx1+DY;
00316             cells[4] = cz1;             cells[5] = cx1z1;          cells[6] = cz1+DY;          cells[7] = cx1z1+DY;
00317             createFaces(out, cells, isoval);
00318             c+=DX;
00319             cx1+=DY;
00320             cz1+=DX;
00321             cx1z1+=DY;
00322         }
00323         // Y BORDER
00324         {
00325             for (x=0; x<GRIDDIM-1; x++)
00326             {
00327                 cells[0] = c;               cells[1] = c+DX;            cells[2] = cy1;            cells[3] = cy1+DX;
00328                 cells[4] = cz1;             cells[5] = cz1+DX;          cells[6] = cy1z1;          cells[7] = cy1z1+DX;
00329                 createFaces(out, cells, isoval);
00330                 c+=DX;
00331                 cy1+=DX;
00332                 cz1+=DX;
00333                 cy1z1+=DX;
00334             }
00335             // X border
00336             cells[0] = c;               cells[1] = cx1;            cells[2] = cy1;            cells[3] = cx1y1;
00337             cells[4] = cz1;             cells[5] = cx1z1;          cells[6] = cy1z1;          cells[7] = cx1y1z1;
00338             createFaces(out, cells, isoval);
00339         }
00340     }
00341 
00342     //std::cout << out.size() << " points, "<<seqTriangles.size()<<" faces."<<std::endl;
00343 }
00344 
00345 template <class In, class Out>
00346 void SPHFluidSurfaceMapping<In,Out>::applyJ( OutVecDeriv& /*out*/, const InVecDeriv& /*in*/ )
00347 {
00348 }
00349 
00350 template <class In, class Out>
00351 void SPHFluidSurfaceMapping<In,Out>::draw()
00352 {
00353     if (!getContext()->getShowMappings()) return;
00354     if (!grid) return;
00355         grid->draw();
00356     
00357     float scale = (float)mStep.getValue();
00358     typename Grid::iterator end = grid->gridEnd();
00359     typename Grid::iterator it;
00360     
00361     glPointSize(3);
00362     glColor4f(1,1,1,1);
00363     glBegin(GL_POINTS);
00364     for (it = grid->gridBegin();it!=end;++it)
00365     {
00366         typename Grid::Key p0 = it->first;
00367         const int x0 = p0[0]*GRIDDIM;
00368         const int y0 = p0[1]*GRIDDIM;
00369         const int z0 = p0[2]*GRIDDIM;
00370         typename Grid::Grid* g = it->second;
00371         int x,y,z;
00372         Cell* c = g->cell;
00373         for (z=0; z<GRIDDIM; z++)
00374         {
00375             for (y=0; y<GRIDDIM; y++)
00376             {
00377                 for (x=0; x<GRIDDIM; x++)
00378                 {
00379                     if (c->data.val > mIsoValue.getValue())
00380                         glVertex3f((x0+x)*scale,(y0+y)*scale,(z0+z)*scale);
00381                     c+=DX;
00382                 }
00383             }
00384         }
00385     }
00386     glEnd();
00387     glPointSize(1);
00388     
00389     glPointSize(5);
00390     glColor4f(0.5f,1,0.5f,1);
00391     glBegin(GL_POINTS);
00392     const OutVecCoord& out = *this->toModel->getX();
00393     for (unsigned int i=0; i<out.size(); ++i)
00394     {
00395         helper::gl::glVertexT(out[i]);
00396     }
00397     glEnd();
00398     glPointSize(1);
00399     
00400     //glLineSize(3);
00401     glColor4f(0,1,0,1);
00402     glBegin(GL_LINES);
00403     for (it = grid->gridBegin();it!=end;++it)
00404     {
00405         typename Grid::Key p0 = it->first;
00406         const int x0 = p0[0]*GRIDDIM;
00407         const int y0 = p0[1]*GRIDDIM;
00408         const int z0 = p0[2]*GRIDDIM;
00409         typename Grid::Grid* g = it->second;
00410         int x,y,z;
00411         Cell* c = g->cell;
00412         for (z=0; z<GRIDDIM; z++)
00413         {
00414             for (y=0; y<GRIDDIM; y++)
00415             {
00416                 for (x=0; x<GRIDDIM; x++)
00417                 {
00418                     if (c->data.p[0]>0)
00419                     {
00420                         glVertex3f((x0+x)*scale,(y0+y)*scale,(z0+z)*scale);
00421                         glVertex3f((x0+x+1)*scale,(y0+y)*scale,(z0+z)*scale);
00422                     }
00423                     if (c->data.p[1]>0)
00424                     {
00425                         glVertex3f((x0+x)*scale,(y0+y)*scale,(z0+z)*scale);
00426                         glVertex3f((x0+x)*scale,(y0+y+1)*scale,(z0+z)*scale);
00427                     }
00428                     if (c->data.p[2]>0)
00429                     {
00430                         glVertex3f((x0+x)*scale,(y0+y)*scale,(z0+z)*scale);
00431                         glVertex3f((x0+x)*scale,(y0+y)*scale,(z0+z+1)*scale);
00432                     }
00433                     c+=DX;
00434                 }
00435             }
00436         }
00437     }
00438     glEnd();
00439     //glLineSize(1);
00440 }
00441 
00442 } // namespace mapping
00443 
00444 } // namespace component
00445 
00446 } // namespace sofa
00447 
00448 #endif

Generated on Sun Nov 23 03:34:38 2008 for Sofa by  doxygen 1.5.7.1