TetrahedronModel.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/TetrahedronModel.h>
00026 #include <sofa/component/collision/CubeModel.h>
00027 #include <sofa/helper/gl/template.h>
00028 #include <sofa/simulation/tree/GNode.h>
00029 #include <sofa/component/topology/RegularGridTopology.h>
00030 #include <sofa/core/CollisionElement.h>
00031 #include <sofa/core/ObjectFactory.h>
00032 #include <vector>
00033 #include <sofa/helper/system/gl.h>
00034 #include <iostream>
00035 using std::cerr;
00036 using std::endl;
00037 
00038 namespace sofa
00039 {
00040 
00041 namespace component
00042 {
00043 
00044 namespace collision
00045 {
00046 
00047 SOFA_DECL_CLASS(TetrahedronModel)
00048     
00049 int TetrahedronModelClass = core::RegisterObject("collision model using a tetrahedral mesh, as described in BaseMeshTopology")
00050 .add< TetrahedronModel >()
00051 .addAlias("Tetrahedron")
00052 ;
00053 
00054 TetrahedronModel::TetrahedronModel()
00055 : tetra(NULL), mstate(NULL)
00056 {
00057 }
00058     
00059 void TetrahedronModel::resize(int size)
00060 {
00061     this->core::CollisionModel::resize(size);
00062     elems.resize(size);
00063     if (getPrevious() != NULL) getPrevious()->resize(0); // force recomputation of bounding tree
00064 }
00065 
00066 void TetrahedronModel::init()
00067 {
00068     _topology = this->getContext()->getMeshTopology();
00069 
00070     this->CollisionModel::init();
00071     mstate = dynamic_cast< core::componentmodel::behavior::MechanicalState<Vec3Types>* > (getContext()->getMechanicalState());
00072 
00073     if (mstate==NULL)
00074     {
00075         std::cerr << "ERROR: TetrahedronModel requires a Vec3 Mechanical Model.\n";
00076         return;
00077     }
00078        
00079     if (!_topology) {
00080         std::cerr << "ERROR: TetrahedronModel requires a BaseMeshTopology.\n";
00081         return;
00082     }
00083     
00084     tetra = &_topology->getTetras();
00085     resize(tetra->size());
00086     
00087 }
00088     
00089 void TetrahedronModel::handleTopologyChange()
00090 {
00091     resize(_topology->getNbTetras());
00092 }
00093 
00094 void TetrahedronModel::draw(int index)
00095 {
00096     Tetrahedron t(this,index);
00097     glBegin(GL_TRIANGLES);
00098     Coord p1 = t.p1();
00099     Coord p2 = t.p2();
00100     Coord p3 = t.p3();
00101     Coord p4 = t.p4();
00102     Coord c = (p1+p2+p3+p4)*0.25f;
00103     p1 += (c-p1)*0.1f;
00104     p2 += (c-p2)*0.1f;
00105     p3 += (c-p3)*0.1f;
00106     p4 += (c-p4)*0.1f;
00107     Coord n1,n2,n3,n4;
00108     n1 = cross(p3-p1,p2-p1); n1.normalize();
00109     helper::gl::glNormalT(n1);
00110     helper::gl::glVertexT(p1);
00111     helper::gl::glVertexT(p3);
00112     helper::gl::glVertexT(p2);
00113     
00114     n2 = cross(p4-p1,p3-p1); n2.normalize();
00115     helper::gl::glNormalT(n2);
00116     helper::gl::glVertexT(p1);
00117     helper::gl::glVertexT(p4);
00118     helper::gl::glVertexT(p3);
00119     
00120     n3 = cross(p2-p1,p4-p1); n3.normalize();
00121     helper::gl::glNormalT(n3);
00122     helper::gl::glVertexT(p1);
00123     helper::gl::glVertexT(p2);
00124     helper::gl::glVertexT(p4);
00125     
00126     n4 = cross(p3-p2,p4-p2); n4.normalize();
00127     helper::gl::glNormalT(n4);
00128     helper::gl::glVertexT(p2);
00129     helper::gl::glVertexT(p3);
00130     helper::gl::glVertexT(p4);
00131     glEnd();
00132     if (getContext()->getShowNormals())
00133     {
00134     Coord p;
00135     glBegin(GL_LINES);
00136     p = (p1+p2+p3)*(1.0/3.0);
00137     helper::gl::glVertexT(p);
00138     helper::gl::glVertexT(p+n1*0.1);
00139     p = (p1+p3+p4)*(1.0/3.0);
00140     helper::gl::glVertexT(p);
00141     helper::gl::glVertexT(p+n2*0.1);
00142     p = (p1+p4+p2)*(1.0/3.0);
00143     helper::gl::glVertexT(p);
00144     helper::gl::glVertexT(p+n3*0.1);
00145     p = (p2+p3+p4)*(1.0/3.0);
00146     helper::gl::glVertexT(p);
00147     helper::gl::glVertexT(p+n4*0.1);
00148     glEnd();
00149     }
00150 }
00151 
00152 void TetrahedronModel::draw()
00153 {
00154     if (mstate && _topology && getContext()->getShowCollisionModels())
00155     {
00156         if (getContext()->getShowWireFrame())
00157             glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
00158 
00159         glEnable(GL_LIGHTING);
00160         //Enable<GL_BLEND> blending;
00161         //glLightModeli(GL_LIGHT_MODEL_TWO_SIDE, GL_TRUE);
00162 
00163         glMaterialfv (GL_FRONT_AND_BACK, GL_AMBIENT_AND_DIFFUSE, getColor4f());
00164         static const float emissive[4] = { 0.0f, 0.0f, 0.0f, 0.0f};
00165         static const float specular[4] = { 1.0f, 1.0f, 1.0f, 1.0f};
00166         glMaterialfv (GL_FRONT_AND_BACK, GL_EMISSION, emissive);
00167         glMaterialfv (GL_FRONT_AND_BACK, GL_SPECULAR, specular);
00168         glMaterialf (GL_FRONT_AND_BACK, GL_SHININESS, 20);
00169 
00170         for (int i=0;i<size;i++)
00171         {
00172             draw(i);
00173         }
00174 
00175         glColor3f(1.0f, 1.0f, 1.0f);
00176         glDisable(GL_LIGHTING);
00177         if (getContext()->getShowWireFrame())
00178             glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
00179     }
00180     if (getPrevious()!=NULL && getContext()->getShowBoundingCollisionModels())
00181         getPrevious()->draw();
00182 }
00183 
00184 void TetrahedronModel::computeBoundingTree(int maxDepth)
00185 {
00186     CubeModel* cubeModel = createPrevious<CubeModel>();
00187     if (!mstate || !_topology) return;
00188     if (!isMoving() && !cubeModel->empty()) return; // No need to recompute BBox if immobile
00189 
00190     Vector3 minElem, maxElem;
00191     const VecCoord& x = *this->mstate->getX();
00192 
00193     for (int i=0;i<size;i++)
00194     {
00195     Tetrahedron t(this,i);
00196     const Vector3& pt1 = x[t.p1Index()];
00197     const Vector3& pt2 = x[t.p2Index()];
00198     const Vector3& pt3 = x[t.p3Index()];
00199     const Vector3& pt4 = x[t.p4Index()];
00200     Matrix3 m, minv;
00201     m[0] = pt2-pt1;
00202     m[1] = pt3-pt1;
00203     m[2] = pt4-pt1;
00204     m.transpose();
00205     minv.invert(m);
00206     elems[i].coord0 = pt1;
00207     elems[i].bary2coord = m;
00208     elems[i].coord2bary = minv;
00209     }
00210     
00211     if (maxDepth == 0)
00212     { // no hierarchy
00213         if (empty())
00214             cubeModel->resize(0);
00215         else
00216         {
00217             cubeModel->resize(1);
00218             minElem = x[0];
00219             maxElem = x[0];
00220             for (unsigned i=1;i<x.size();i++)
00221             {
00222                 const Vector3& pt1 = x[i];
00223                 if (pt1[0] > maxElem[0]) maxElem[0] = pt1[0];
00224                 else if (pt1[0] < minElem[0]) minElem[0] = pt1[0];
00225                 if (pt1[1] > maxElem[1]) maxElem[1] = pt1[1];
00226                 else if (pt1[1] < minElem[1]) minElem[1] = pt1[1];
00227                 if (pt1[2] > maxElem[2]) maxElem[2] = pt1[2];
00228                 else if (pt1[2] < minElem[2]) minElem[2] = pt1[2];
00229             }
00230             cubeModel->setLeafCube(0, std::make_pair(this->begin(),this->end()), minElem, maxElem); // define the bounding box of the current Tetrahedron
00231         }
00232     }
00233     else
00234     {
00235         cubeModel->resize(size);  // size = number of Tetrahedrons
00236         if (!empty())
00237         {
00238             for (int i=0;i<size;i++)
00239             {
00240                 Tetrahedron t(this,i);
00241                 const Vector3& pt1 = x[t.p1Index()];
00242                 const Vector3& pt2 = x[t.p2Index()];
00243                 const Vector3& pt3 = x[t.p3Index()];
00244                 const Vector3& pt4 = x[t.p4Index()];
00245                 for (int c = 0; c < 3; c++)
00246                 {
00247                                                   minElem[c] = pt1[c];
00248                                                   maxElem[c] = pt1[c];
00249                          if (pt2[c] > maxElem[c]) maxElem[c] = pt2[c];
00250                     else if (pt2[c] < minElem[c]) minElem[c] = pt2[c];
00251                          if (pt3[c] > maxElem[c]) maxElem[c] = pt3[c];
00252                     else if (pt3[c] < minElem[c]) minElem[c] = pt3[c];
00253                          if (pt4[c] > maxElem[c]) maxElem[c] = pt4[c];
00254                     else if (pt4[c] < minElem[c]) minElem[c] = pt4[c];
00255                 }
00256                 cubeModel->setParentOf(i, minElem, maxElem); // define the bounding box of the current Tetrahedron
00257             }
00258             cubeModel->computeBoundingTree(maxDepth);
00259         }
00260     }
00261 }
00262 
00263 } // namespace collision
00264 
00265 } // namespace component
00266 
00267 } // namespace sofa

Generated on Sun Nov 23 02:36:13 2008 for Sofa by  doxygen 1.5.7.1