SphereTreeModel.cpp

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 #include <sofa/component/collision/SphereTreeModel.h>
00026 #include <sofa/helper/io/SphereLoader.h>
00027 #include <sofa/component/collision/CubeModel.h>
00028 #include <sofa/core/ObjectFactory.h>
00029 #include <iostream>
00030 #include <sofa/helper/system/gl.h>
00031 #include <sofa/helper/system/glut.h>
00032 #include <sofa/helper/system/FileRepository.h>
00033 
00034 using std::cerr;
00035 using std::endl;
00036 
00037 
00038 namespace sofa
00039 {
00040 
00041 namespace component
00042 {
00043 
00044 namespace collision
00045 {
00046 
00047 // Required for compilation purposes
00048 SOFA_DECL_CLASS(SphereTreeModel) 
00049 
00050 using namespace sofa::defaulttype;
00051 using namespace std;
00052 
00053 int SphereTreeModelClass = core::RegisterObject("CollisionModel based on a hierarchy of bounding spheres")
00054 .add< SphereTreeModel >()
00055 .addAlias("SphereTree")
00056 ;
00057 
00058 SphereTreeModel::SphereTreeModel(double radius)
00059 : defaultRadius(initData(&defaultRadius, radius, "radius","TODO"))
00060 {
00061 }
00062 
00063 
00064 void SphereTreeModel::resize(int size)
00065 {   // Correcting sizes
00066     this->component::MechanicalObject<Vec3Types>::resize(size);
00067     this->core::CollisionModel::resize(size);
00068     //this->elems.resize(size);
00069     
00070     if ((int)radius.size() < size)
00071     {
00072         radius.reserve(size);
00073         while ((int)radius.size() < size)
00074             radius.push_back(defaultRadius.getValue());
00075     }
00076     else
00077     {
00078         radius.resize(size);
00079     }
00080 }
00081 
00082 int SphereTreeModel::addSphere(const Vector3& pos, SReal radius)
00083 {
00084     int i = size;
00085     resize(i+1);
00086     setSphere(i, pos, radius);
00087     return i;
00088 }
00089 
00090 void SphereTreeModel::setSphere(int i, const Vector3& pos, SReal r)
00091 {
00092     if ((unsigned)i >= (unsigned) size) return;
00093     (*this->getX())[i] = pos;
00094     radius[i] = r;
00095 }
00096 
00097 bool SphereTreeModel::load(const char* filename)
00098 {
00099     this->resize(0);
00100     return loadSphereTree(filename);
00101 }
00102 
00103 bool SphereTreeModel::loadSphereTree( const char *fileName )
00104 {   
00105   std::ifstream inFile;
00106   
00107   std::string fileInRepository(fileName);
00108   if ( !sofa::helper::system::DataRepository.findFile ( fileInRepository ) )
00109     return false;
00110 
00111   fileInRepository = sofa::helper::system::DataRepository.getFile ( fileInRepository);  
00112   
00113   inFile.open(fileInRepository.c_str());
00114   if (inFile.fail()) 
00115   {
00116     std::cerr << "Fail to open file sph" << std::endl;
00117     return false;
00118   }
00119   levels = 0; degree = 0;
00120   inFile >> levels >> degree;
00121   
00122   if (!levels || !degree)
00123     return false;
00124 
00125   int numnodes = 1;
00126   int numSpheres=0;
00127  
00128   double x, y, z, r, errDec;
00129   for (int level = 0; level < levels; level++ ) 
00130   { 
00131 //     bool isLeaf = (level==levels-1);
00132     for (int i = 0; i < numnodes; i++) 
00133     {  
00134       inFile >> x >> y >> z >> r >> errDec;
00135 
00136       if (inFile.fail()) 
00137       {
00138         std::cerr << "Error: incorrect file format sph " << std::endl;
00139         return false;
00140       }
00141         
00142         resize( numSpheres+1 ); //need to resize the "x" vector of DOF's of the sphereTree
00143 
00144        // Collision element iterator
00145         SingleSphere s(this, numSpheres);
00146         s.setCenter(x,y,z);
00147         radius[numSpheres] = r; 
00148                 
00149 #if 0
00150         SphereData sphData;
00151         //sphData.isLeaf = isLeaf;
00152 
00153         if (isLeaf) 
00154         {
00155             sphData.leaf = core::CollisionElementIterator(this,numSpheres);
00156         }
00157         else
00158         {
00159             sphData.leaf = core::CollisionElementIterator();
00160         }
00161 
00162         sphData.node = s;
00163     
00164         this->elems.push_back( sphData );
00165 #endif
00166         numSpheres=numSpheres+1;        
00167           
00168     } // end numnodes
00169     numnodes *= degree;
00170   } // end for
00171 #if 0
00172    //Create relationships
00173   numnodes = 1;
00174   int node = 0;
00175   int nodeinit = 0;
00176   int firstchild;
00177   for (int level = 0; level < levels-1; level++ ) 
00178   { 
00179      for (int i = 0; i < numnodes; i++) 
00180      {  
00181         while ( node < nodeinit ) // <=
00182         {
00183             firstchild = node * degree + 1;
00184             for ( int deg = 0; deg <= degree; deg++) 
00185             {  
00186                 //core::CollisionElementIterator *s = this->nodes[firstchild + deg];
00187                 SphereData s = this->elems[ firstchild + deg ];
00188                 core::CollisionElementIterator begin(this, (firstchild+deg) );  
00189                 core::CollisionElementIterator end(this, (firstchild+degree) );
00190                 //Setting first child.
00191                 if ( deg == 0 ) this->elems[node].subcells.first = begin;
00192 
00193                 //Setting end for children 
00194                 if ( deg == degree ) this->elems[node].subcells.second = end;
00195 
00196             } // endfor degree.
00197         node++; 
00198         } // endwhile   
00199     } // end for numnodes
00200     numnodes *= degree;
00201     nodeinit = node+numnodes;
00202   } //end for levels
00203 #endif
00204   inFile.close();
00205   return true; 
00206 }
00207 
00208 void SphereTreeModel::applyScale(const double s)
00209 {
00210     Inherit::applyScale(s);
00211     std::cout << "Applying scale " << s << " to " << size << " spheres" << std::endl;
00212     for (int i=0;i<size;i++)
00213         radius[i] *= s;
00214 }
00215 
00216 
00217 void SphereTreeModel::draw(int index)
00218 {
00219     Vector3 p = (*getX())[index];
00220     glPushMatrix();
00221     glTranslated(p[0], p[1], p[2]);
00222     glutWireSphere(radius[index], 16, 8);
00223     glPopMatrix();
00224 }
00225 
00226 void SphereTreeModel::draw()
00227 {  
00228     float color = 1.0f;
00229     if ( getContext()->getShowCollisionModels())
00230     {
00231         glDisable(GL_LIGHTING);
00232         if (!isSimulated())
00233             glColor4f(1.0f, 1.0f, 1.0f, color);
00234         else
00235             glColor4f(1.0f, 1.0f, 0.0f, color);
00236     
00237             //if (color < 1.0f)
00238             //{
00239             //  glEnable(GL_BLEND);
00240             //  glDepthMask(0);
00241             //}
00242 
00243         int numnodes = 1;
00244         int node = 0;
00245         for (int level = 0; level < levels; level++ ) 
00246         {   
00247             if ( level < levels-1 ) {
00248                 glColor4f(1.0f, color, color*color, (1.0 - color) );
00249                 color *= 0.5f;
00250             }
00251             else glColor4f(0.0f, 0.0f, 1.0f, 1.0); 
00252 
00253             for (int i = 0; i < numnodes; i++) 
00254             {   
00255                 draw( node );
00256                 node++; 
00257             } 
00258             numnodes *= degree;
00259             
00260 
00261         } //end for levels
00262 
00263             //if (color < 1.0f)
00264             //{
00265             //  glDisable(GL_BLEND);
00266             //  glDepthMask(1);
00267             //}
00268 
00269     }
00270     if (isActive() && getPrevious()!=NULL && getContext()->getShowBoundingCollisionModels())
00271         getPrevious()->draw();
00272 }
00273 
00274 void SphereTreeModel::computeBoundingTree(int /*maxDepth*/)
00275 {
00276     // To do:
00277     // The tree is obtained from an off line proccess. T
00278     // This function should be used to update the tree in case of deformable bodies.
00279 }
00280 
00281 void SphereTreeModel::computeContinuousBoundingTree(double /*dt*/, int /*maxDepth*/)
00282 {   // To do
00283     cout << "SphereTreeModel::computeContinuousBoundingTree - not implemented" << endl;
00284 }
00285 
00286 std::pair<core::CollisionElementIterator,core::CollisionElementIterator> SphereTreeModel::getInternalChildren(int index) const
00287 {
00288     //return elems[index].subcells;
00289     int firstchild = index*degree+1;
00290     if (firstchild >= size)
00291         return std::make_pair(core::CollisionElementIterator(),core::CollisionElementIterator());
00292     int lastchild = firstchild+degree-1;
00293     if (lastchild >= size) lastchild = size-1; // note that this cannot happen if the last level of the tree is full
00294     return std::make_pair(core::CollisionElementIterator(const_cast<SphereTreeModel*>(this),firstchild),core::CollisionElementIterator(const_cast<SphereTreeModel*>(this),lastchild+1));
00295 }
00296 
00297 bool SphereTreeModel::isLeaf( int index ) const
00298 {
00299     int firstchild = index*degree+1;
00300     return (firstchild >= size);
00301     //return !elems[index].subcells.first.valid();
00302     //core::CollisionElementIterator i1 = elems[index].leaf;
00303     //if ( i1.valid() ) return true;
00304     //else return false;
00305 }
00306 
00307 
00308 } // namespace collision
00309 
00310 } // namespace component
00311 
00312 } // namespace sofa
00313 

Generated on Sun Nov 23 02:35:26 2008 for Sofa by  doxygen 1.5.7.1