TriangleModel.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/TriangleModel.h>
00026 #include <sofa/component/collision/CubeModel.h>
00027 #include <sofa/component/collision/Triangle.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/gl/template.h>
00034 #include <iostream>
00035 
00036 #include <sofa/component/topology/PointSetTopologyChange.h>
00037 #include <sofa/component/topology/TriangleSetTopologyChange.h>
00038 
00039 
00040 using std::cerr;
00041 using std::endl;
00042 
00043 namespace sofa
00044 {
00045 
00046 namespace component
00047 {
00048 
00049 namespace collision
00050 {
00051 
00052 SOFA_DECL_CLASS(Triangle)
00053     
00054 int TriangleModelClass = core::RegisterObject("collision model using a triangular mesh, as described in BaseMeshTopology")
00055 .add< TriangleModel >()
00056 .addAlias("TriangleMeshModel")
00057 .addAlias("TriangleSetModel")
00058 .addAlias("TriangleMesh")
00059 .addAlias("TriangleSet")
00060 .addAlias("Triangle")
00061 ;
00062 
00063 TriangleModel::TriangleModel()
00064 : mstate(NULL)
00065 , computeNormals(initData(&computeNormals, true, "computeNormals", "set to false to disable computation of triangles normal"))
00066 , meshRevision(-1)
00067 {
00068     triangles = &mytriangles;
00069 }
00070     
00071 void TriangleModel::resize(int size)
00072 {
00073     this->core::CollisionModel::resize(size);
00074     elems.resize(size);
00075 }
00076 
00077 void TriangleModel::init()
00078 {
00079     _topology = this->getContext()->getMeshTopology();
00080 
00081     this->CollisionModel::init();
00082     mstate = dynamic_cast< core::componentmodel::behavior::MechanicalState<Vec3Types>* > (getContext()->getMechanicalState());
00083 
00084     if (mstate==NULL)
00085     {
00086         std::cerr << "ERROR: TriangleModel requires a Vec3 Mechanical Model.\n";
00087         return;
00088     }
00089 
00090      if (!_topology) {
00091         std::cerr << "ERROR: TriangleModel requires a BaseMeshTopology.\n";
00092         return;
00093     }
00094     
00095     //std::cout << "INFO_print : Col - init TRIANGLE " << std::endl;    
00096     triangles = &_topology->getTriangles();
00097     resize(_topology->getNbTriangles());
00098     
00099     updateFromTopology();
00100     updateNormals();
00101 }
00102 
00103 void TriangleModel::updateNormals()
00104 {
00105     for (int i=0;i<size;i++)
00106     {
00107         Triangle t(this,i);
00108         const Vector3& pt1 = t.p1();
00109         const Vector3& pt2 = t.p2();
00110         const Vector3& pt3 = t.p3();
00111 
00112         t.n() = cross(pt2-pt1,pt3-pt1);
00113         t.n().normalize();
00114     }
00115 }
00116 
00117 void TriangleModel::updateFromTopology()
00118 {
00119 //    needsUpdate = false;
00120     const unsigned npoints = mstate->getX()->size();
00121     const unsigned ntris = _topology->getNbTriangles();
00122     const unsigned nquads = _topology->getNbQuads();
00123     const unsigned newsize = ntris+2*nquads;
00124 
00125     int revision = _topology->getRevision();
00126     if (revision == meshRevision && newsize==(unsigned)size) {
00127         return;
00128     }
00129     needsUpdate=true;
00130 
00131     resize(newsize);
00132 
00133     if (newsize == ntris)
00134     { // no need to copy the triangle indices
00135         triangles = & _topology->getTriangles();
00136     }
00137     else
00138     {
00139         triangles = &mytriangles;
00140         mytriangles.resize(newsize);
00141         int index = 0;
00142         for (unsigned i=0; i<ntris; i++)
00143         {
00144             topology::BaseMeshTopology::Triangle idx = _topology->getTriangle(i);
00145             if (idx[0] >= npoints || idx[1] >= npoints || idx[2] >= npoints)
00146             {
00147                 std::cerr << "ERROR: Out of range index in triangle "<<i<<": "<<idx[0]<<" "<<idx[1]<<" "<<idx[2]<<" ( total points="<<npoints<<")\n";
00148                 if (idx[0] >= npoints) idx[0] = npoints-1;
00149                 if (idx[1] >= npoints) idx[1] = npoints-1;
00150                 if (idx[2] >= npoints) idx[2] = npoints-1;
00151             }
00152             mytriangles[index] = idx;
00153             ++index;
00154         }
00155         for (unsigned i=0; i<nquads; i++)
00156         {
00157             topology::BaseMeshTopology::Quad idx = _topology->getQuad(i);
00158             if (idx[0] >= npoints || idx[1] >= npoints || idx[2] >= npoints || idx[3] >= npoints)
00159             {
00160                 std::cerr << "ERROR: Out of range index in quad "<<i<<": "<<idx[0]<<" "<<idx[1]<<" "<<idx[2]<<" "<<idx[3]<<" ( total points="<<npoints<<")\n";
00161                 if (idx[0] >= npoints) idx[0] = npoints-1;
00162                 if (idx[1] >= npoints) idx[1] = npoints-1;
00163                 if (idx[2] >= npoints) idx[2] = npoints-1;
00164                 if (idx[3] >= npoints) idx[3] = npoints-1;
00165             }
00166             mytriangles[index][0] = idx[1];
00167             mytriangles[index][1] = idx[2];
00168             mytriangles[index][2] = idx[0];
00169             ++index;
00170             mytriangles[index][0] = idx[3];
00171             mytriangles[index][1] = idx[0];
00172             mytriangles[index][2] = idx[2];
00173             ++index;
00174         }
00175     }
00176     updateFlags();
00177     meshRevision = revision;
00178 }
00179 
00180 void TriangleModel::updateFlags(int ntri)
00181 {
00182     if (ntri < 0) ntri = triangles->size();
00183     //VecCoord& x = *mstate->getX();
00184     //VecDeriv& v = *mstate->getV();
00185     vector<bool> pflags(mstate->getSize());
00186     std::set<std::pair<int,int> > eflags;
00187     for (unsigned i=0; i<triangles->size(); i++)
00188     {
00189         int f = 0;
00190         topology::Triangle t = (*triangles)[i];
00191         if (!pflags[t[0]])
00192         {
00193             f |= FLAG_P1;
00194             pflags[t[0]] = true;
00195         }
00196         if (!pflags[t[1]])
00197         {
00198             f |= FLAG_P2;
00199             pflags[t[1]] = true;
00200         }
00201         if (!pflags[t[2]])
00202         {
00203             f |= FLAG_P3;
00204             pflags[t[2]] = true;
00205         }
00206         if (eflags.insert( (t[0]<t[1])?std::make_pair(t[0],t[1]):std::make_pair(t[1],t[0]) ).second)
00207         {
00208             f |= FLAG_E12;
00209         }
00210         if (i < (unsigned)ntri && eflags.insert( (t[1]<t[2])?std::make_pair(t[1],t[2]):std::make_pair(t[2],t[1]) ).second) // don't use the diagonal edge of quads
00211         {
00212             f |= FLAG_E23;
00213         }
00214         if (eflags.insert( (t[2]<t[0])?std::make_pair(t[2],t[0]):std::make_pair(t[0],t[2]) ).second)
00215         {
00216             f |= FLAG_E31;
00217         }
00218         elems[i].flags = f;
00219     }
00220 }
00221     
00222 void TriangleModel::handleTopologyChange()
00223 {
00224     bool debug_mode = false;
00225 
00226     if (triangles != &mytriangles)
00227     {
00228         // We use the same triangle array as the topology -> only resize and recompute flags
00229         resize(_topology->getNbTriangles());
00230         needsUpdate = true;
00231         updateFlags();
00232         updateNormals(); // not strictly necessary but useful if we display the model before the next collision iteration
00233         
00234         return;
00235     }
00236 
00237     sofa::core::componentmodel::topology::TopologyModifier* topoMod; 
00238     this->getContext()->get(topoMod);     
00239         
00240     if (topoMod) { // dynamic topology
00241 
00242         std::list<const sofa::core::componentmodel::topology::TopologyChange *>::const_iterator itBegin=_topology->firstChange();
00243         std::list<const sofa::core::componentmodel::topology::TopologyChange *>::const_iterator itEnd=_topology->lastChange();
00244 
00245 
00246         while( itBegin != itEnd )
00247         {
00248             core::componentmodel::topology::TopologyChangeType changeType = (*itBegin)->getChangeType();
00249             
00250             switch( changeType ) {
00251 
00252                 
00253                 case core::componentmodel::topology::ENDING_EVENT:
00254                 {
00255                     //std::cout << "INFO_print : Col - ENDING_EVENT" << std::endl;
00256                     needsUpdate=true;                   
00257                     break;
00258                 }
00259                 
00260 
00261                 case core::componentmodel::topology::TRIANGLESADDED:
00262                     {
00263                         //std::cout << "INFO_print : Col - TRIANGLESADDED" << std::endl;
00264                         TriangleInfo t;
00265                         const sofa::component::topology::TrianglesAdded *ta=static_cast< const sofa::component::topology::TrianglesAdded * >( *itBegin );
00266                         for (unsigned int i=0;i<ta->getNbAddedTriangles();++i) {                            
00267                             mytriangles.push_back(ta->triangleArray[i]);                                                     
00268                         }
00269                         resize( mytriangles.size());                                
00270                         needsUpdate=true;
00271                                                 
00272                         break;
00273                     }
00274 
00275                 case core::componentmodel::topology::TRIANGLESREMOVED:
00276                     {
00277                         //std::cout << "INFO_print : Col - TRIANGLESREMOVED" << std::endl;
00278                         unsigned int last;
00279                         unsigned int ind_last;                          
00280                                                 
00281                         last= _topology->getNbPoints() - 1;                                         
00282 
00283                         const sofa::helper::vector<unsigned int> &tab = ( static_cast< const sofa::component::topology::TrianglesRemoved *>( *itBegin ) )->getArray();
00284                         
00285                         TriangleInfo tmp;
00286                         topology::Triangle tmp2;                        
00287 
00288                         for (unsigned int i = 0; i <tab.size(); ++i)
00289                         {
00290 
00291                             unsigned int ind_k = tab[i];                                                        
00292 
00293                             tmp = elems[ind_k];
00294                             elems[ind_k] = elems[last];
00295                             elems[last] = tmp;
00296                                       
00297                             tmp2 = mytriangles[ind_k];
00298                             mytriangles[ind_k] = mytriangles[last];
00299                             mytriangles[last] = tmp2;
00300                                                                     
00301                             ind_last = elems.size() - 1;
00302 
00303                             if(last != ind_last){
00304 
00305                                 tmp = elems[last];
00306                                 elems[last] = elems[ind_last];
00307                                 elems[ind_last] = tmp;
00308                                   
00309                                   tmp2 = mytriangles[last];
00310                                   mytriangles[last] = mytriangles[ind_last];
00311                                   mytriangles[ind_last] = tmp2;                                                                                                             
00312                             }
00313 
00314                             mytriangles.resize( elems.size() - 1 );
00315                             resize( elems.size() - 1 );                         
00316 
00317                             --last;
00318                         }
00319 
00320                         needsUpdate=true;
00321                         
00322                         break;
00323                     }               
00324 
00325                 
00326                 case core::componentmodel::topology::POINTSREMOVED:
00327                     {
00328                             //std::cout << "INFO_print : Col - POINTSREMOVED" << std::endl;
00329                             if (_topology->getNbTriangles()>0) {
00330                                 
00331                                 unsigned int last = _topology->getNbPoints() -1;
00332 
00333                                 unsigned int i,j;
00334                                 const sofa::helper::vector<unsigned int> tab = ( static_cast< const sofa::component::topology::PointsRemoved * >( *itBegin ) )->getArray();
00335                                 
00336                                 sofa::helper::vector<unsigned int> lastIndexVec;
00337                                 for(unsigned int i_init = 0; i_init < tab.size(); ++i_init){
00338 
00339                                     lastIndexVec.push_back(last - i_init);
00340                                 }
00341                                 
00342                                 for ( i = 0; i < tab.size(); ++i)
00343                                 {
00344                                     unsigned int i_next = i;
00345                                     bool is_reached = false;
00346                                     while( (!is_reached) && (i_next < lastIndexVec.size() - 1)){
00347 
00348                                         i_next += 1 ;
00349                                         is_reached = is_reached || (lastIndexVec[i_next] == tab[i]);
00350                                     }
00351 
00352                                     if(is_reached){
00353 
00354                                         lastIndexVec[i_next] = lastIndexVec[i];
00355 
00356                                     }
00357 
00358                                     const sofa::helper::vector<unsigned int> &shell=_topology->getTriangleVertexShell(lastIndexVec[i]);
00359                                     for (j=0;j<shell.size();++j) {
00360                                         
00361                                         unsigned int ind_j =shell[j];
00362 
00363                                         if ((unsigned)mytriangles[ind_j][0]==last)
00364                                             mytriangles[ind_j][0]=tab[i];
00365                                         else if ((unsigned)mytriangles[ind_j][1]==last)
00366                                             mytriangles[ind_j][1]=tab[i];
00367                                         else if ((unsigned)mytriangles[ind_j][2]==last)
00368                                             mytriangles[ind_j][2]=tab[i];                                   
00369                                     }
00370 
00371                                     if (debug_mode) {
00372 
00373                                         for (unsigned int j_loc=0;j_loc<mytriangles.size();++j_loc) {
00374 
00375                                             bool is_forgotten = false;
00376                                             if ((unsigned)mytriangles[j_loc][0]==last){
00377                                                 mytriangles[j_loc][0]=tab[i];
00378                                                 is_forgotten=true;
00379 
00380                                             }else{
00381                                                 if ((unsigned)mytriangles[j_loc][1]==last){
00382                                                     mytriangles[j_loc][1]=tab[i];
00383                                                     is_forgotten=true;
00384 
00385                                                 }else{
00386                                                     if ((unsigned)mytriangles[j_loc][2]==last){
00387                                                         mytriangles[j_loc][2]=tab[i];
00388                                                         is_forgotten=true;
00389                                                     }
00390                                                 }
00391 
00392                                             }
00393 
00394                                             if(is_forgotten){
00395 
00396                                                 unsigned int ind_forgotten = j;                                             
00397 
00398                                                 bool is_in_shell = false;
00399                                                 for (unsigned int j_glob=0;j_glob<shell.size();++j_glob) {
00400                                                     is_in_shell = is_in_shell || (shell[j_glob] == ind_forgotten);
00401                                                 }
00402 
00403                                                 if(!is_in_shell) {
00404                                                     std::cout << "INFO_print : Col - triangle is forgotten in SHELL !!! global index = "  << ind_forgotten << std::endl;
00405                                                 }
00406 
00407                                             }
00408 
00409                                         }
00410                                     }
00411 
00412                                     --last;
00413                                 }
00414                                                         
00415                             }       
00416                         
00417                         needsUpdate=true;
00418                     
00419                         break;
00420                     }
00421 
00422                     // Case "POINTSRENUMBERING" added to propagate the treatment to the Visual Model
00423 
00424                     case core::componentmodel::topology::POINTSRENUMBERING:
00425                     {   
00426                             //std::cout << "INFO_print : Vis - POINTSRENUMBERING" << std::endl;
00427 
00428                             if (_topology->getNbTriangles()>0) {                                                                
00429 
00430                                 unsigned int i;
00431 
00432                                 const sofa::helper::vector<unsigned int> tab = ( static_cast< const sofa::component::topology::PointsRenumbering * >( *itBegin ) )->getinv_IndexArray();
00433 
00434                                 for ( i = 0; i < mytriangles.size(); ++i)
00435                                 {                                   
00436                                     mytriangles[i][0]  = tab[mytriangles[i][0]];
00437                                     mytriangles[i][1]  = tab[mytriangles[i][1]];
00438                                     mytriangles[i][2]  = tab[mytriangles[i][2]];                                        
00439                                 }                               
00440                                 
00441                             }
00442 
00443                         //}                     
00444                         
00445                         break;
00446                         
00447                     }
00448 
00449                 default:
00450                     // Ignore events that are not Triangle  related.
00451                     break;
00452             }; // switch( changeType )
00453 
00454             mytriangles.resize( elems.size() ); // not necessary
00455             resize( elems.size() ); // not necessary
00456 
00457             ++itBegin;
00458         } // while( changeIt != last; )
00459     }
00460     if (needsUpdate){
00461         updateFlags();
00462     }
00463 }
00464 
00465 void TriangleModel::draw(int index)
00466 {
00467     Triangle t(this,index);
00468     glBegin(GL_TRIANGLES);
00469     helper::gl::glNormalT(t.n());
00470     helper::gl::glVertexT(t.p1());
00471     helper::gl::glVertexT(t.p2());
00472     helper::gl::glVertexT(t.p3());
00473     glEnd();
00474 }
00475 
00476 void TriangleModel::draw()
00477 {
00478     if (getContext()->getShowCollisionModels())
00479     {
00480         if (getContext()->getShowWireFrame())
00481             glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
00482 
00483         glEnable(GL_LIGHTING);
00484         //Enable<GL_BLEND> blending;
00485         //glLightModeli(GL_LIGHT_MODEL_TWO_SIDE, GL_TRUE);
00486 
00487         glMaterialfv (GL_FRONT_AND_BACK, GL_AMBIENT_AND_DIFFUSE, getColor4f());
00488         static const float emissive[4] = { 0.0f, 0.0f, 0.0f, 0.0f};
00489         static const float specular[4] = { 1.0f, 1.0f, 1.0f, 1.0f};
00490         glMaterialfv (GL_FRONT_AND_BACK, GL_EMISSION, emissive);
00491         glMaterialfv (GL_FRONT_AND_BACK, GL_SPECULAR, specular);
00492         glMaterialf (GL_FRONT_AND_BACK, GL_SHININESS, 20);
00493 
00494         for (int i=0;i<size;i++)
00495         {
00496             draw(i);
00497         }
00498 
00499         glColor3f(1.0f, 1.0f, 1.0f);
00500         glDisable(GL_LIGHTING);
00501         if (getContext()->getShowWireFrame())
00502             glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
00503     }
00504     if (getPrevious()!=NULL && getContext()->getShowBoundingCollisionModels())
00505         getPrevious()->draw();
00506 }
00507 
00508 void TriangleModel::computeBoundingTree(int maxDepth)
00509 {
00510     CubeModel* cubeModel = createPrevious<CubeModel>();
00511         updateFromTopology();
00512     if (needsUpdate && !cubeModel->empty()) cubeModel->resize(0);
00513     if (!isMoving() && !cubeModel->empty() && !needsUpdate) return; // No need to recompute BBox if immobile
00514     
00515     needsUpdate=false;
00516     Vector3 minElem, maxElem;
00517     const VecCoord& x = *this->mstate->getX();
00518 
00519     const bool calcNormals = computeNormals.getValue();
00520 
00521     if (maxDepth == 0)
00522     { // no hierarchy
00523     if (empty())
00524         cubeModel->resize(0);
00525     else
00526     {
00527         cubeModel->resize(1);
00528         minElem = x[0];
00529         maxElem = x[0];
00530         for (unsigned i=1;i<x.size();i++)
00531         {
00532         const Vector3& pt1 = x[i];
00533         if (pt1[0] > maxElem[0]) maxElem[0] = pt1[0];
00534         else if (pt1[0] < minElem[0]) minElem[0] = pt1[0];
00535         if (pt1[1] > maxElem[1]) maxElem[1] = pt1[1];
00536         else if (pt1[1] < minElem[1]) minElem[1] = pt1[1];
00537         if (pt1[2] > maxElem[2]) maxElem[2] = pt1[2];
00538         else if (pt1[2] < minElem[2]) minElem[2] = pt1[2];
00539         }
00540         if (calcNormals)
00541         for (int i=0;i<size;i++)
00542         {
00543         Triangle t(this,i);
00544         const Vector3& pt1 = x[t.p1Index()];
00545         const Vector3& pt2 = x[t.p2Index()];
00546         const Vector3& pt3 = x[t.p3Index()];
00547         
00548         /*for (int c = 0; c < 3; c++)
00549         {
00550             if (i==0)
00551             {
00552             minElem[c] = pt1[c];
00553             maxElem[c] = pt1[c];
00554             }
00555             else
00556             {
00557             if (pt1[c] > maxElem[c]) maxElem[c] = pt1[c];
00558             else if (pt1[c] < minElem[c]) minElem[c] = pt1[c];
00559             }
00560             if (pt2[c] > maxElem[c]) maxElem[c] = pt2[c];
00561             else if (pt2[c] < minElem[c]) minElem[c] = pt2[c];
00562             if (pt3[c] > maxElem[c]) maxElem[c] = pt3[c];
00563             else if (pt3[c] < minElem[c]) minElem[c] = pt3[c];
00564         }*/
00565         
00566         // Also recompute normal vector
00567         t.n() = cross(pt2-pt1,pt3-pt1);
00568         t.n().normalize();
00569         
00570         }
00571         cubeModel->setLeafCube(0, std::make_pair(this->begin(),this->end()), minElem, maxElem); // define the bounding box of the current triangle
00572     }
00573     }
00574     else
00575     {
00576 
00577         cubeModel->resize(size);  // size = number of triangles
00578     if (!empty())
00579     {
00580         for (int i=0;i<size;i++)
00581         {
00582             Triangle t(this,i);
00583         const Vector3& pt1 = x[t.p1Index()];
00584         const Vector3& pt2 = x[t.p2Index()];
00585         const Vector3& pt3 = x[t.p3Index()];
00586         
00587             for (int c = 0; c < 3; c++)
00588             {
00589                                               minElem[c] = pt1[c];
00590                                               maxElem[c] = pt1[c];
00591                      if (pt2[c] > maxElem[c]) maxElem[c] = pt2[c];
00592                 else if (pt2[c] < minElem[c]) minElem[c] = pt2[c];
00593                      if (pt3[c] > maxElem[c]) maxElem[c] = pt3[c];
00594                 else if (pt3[c] < minElem[c]) minElem[c] = pt3[c];
00595             }
00596             if (calcNormals)
00597             {
00598             // Also recompute normal vector
00599             t.n() = cross(pt2-pt1,pt3-pt1);
00600             t.n().normalize();
00601             }
00602                         cubeModel->setParentOf(i, minElem, maxElem); // define the bounding box of the current triangle
00603         }
00604         cubeModel->computeBoundingTree(maxDepth);
00605     }
00606     }
00607 }
00608 
00609 void TriangleModel::computeContinuousBoundingTree(double dt, int maxDepth)
00610 {   CubeModel* cubeModel = createPrevious<CubeModel>();
00611     updateFromTopology();
00612     if (needsUpdate) cubeModel->resize(0);
00613     if (!isMoving() && !cubeModel->empty() && !needsUpdate) return; // No need to recompute BBox if immobile
00614     
00615     needsUpdate=false;
00616     Vector3 minElem, maxElem;
00617 
00618     cubeModel->resize(size);
00619     if (!empty())
00620     {
00621         for (int i=0;i<size;i++)
00622         {
00623             Triangle t(this,i);
00624             const Vector3& pt1 = t.p1();
00625             const Vector3& pt2 = t.p2();
00626             const Vector3& pt3 = t.p3();
00627             const Vector3 pt1v = pt1 + t.v1()*dt;
00628             const Vector3 pt2v = pt2 + t.v2()*dt;
00629             const Vector3 pt3v = pt3 + t.v3()*dt;
00630         
00631             for (int c = 0; c < 3; c++)
00632             {
00633                                               minElem[c] = pt1[c];
00634                                               maxElem[c] = pt1[c];
00635                      if (pt2[c] > maxElem[c]) maxElem[c] = pt2[c];
00636                 else if (pt2[c] < minElem[c]) minElem[c] = pt2[c];
00637                      if (pt3[c] > maxElem[c]) maxElem[c] = pt3[c];
00638                 else if (pt3[c] < minElem[c]) minElem[c] = pt3[c];
00639 
00640                      if (pt1v[c] > maxElem[c]) maxElem[c] = pt1v[c];
00641                 else if (pt1v[c] < minElem[c]) minElem[c] = pt1v[c];
00642                      if (pt2v[c] > maxElem[c]) maxElem[c] = pt2v[c];
00643                 else if (pt2v[c] < minElem[c]) minElem[c] = pt2v[c];
00644                      if (pt3v[c] > maxElem[c]) maxElem[c] = pt3v[c];
00645                 else if (pt3v[c] < minElem[c]) minElem[c] = pt3v[c];
00646             }
00647         
00648             // Also recompute normal vector
00649             t.n() = cross(pt2-pt1,pt3-pt1);
00650             t.n().normalize();
00651 
00652             cubeModel->setParentOf(i, minElem, maxElem);
00653         }
00654         cubeModel->computeBoundingTree(maxDepth);
00655     }
00656 }
00657 
00658                                       
00659 void TriangleModel::buildOctree(){
00660 /*
00661     cerr<<"TriangleModel::buildOctree(), coords = "<<*mstate->getX()<<endl;
00662     const int ntris = mesh->getNbTriangles();
00663     const int nquads = mesh->getNbQuads();
00664     for (int i=0; i<ntris; i++)
00665     {
00666         topology::MeshTopology::Triangle idx = mesh->getTriangle(i);
00667         cerr<<"  triangle "<< idx[0] <<", "<<idx[1]<<", "<<idx[2]<<endl;;
00668     }
00669     for (int i=0; i<nquads; i++)
00670     {
00671         topology::MeshTopology::Quad idx = mesh->getQuad(i);
00672         cerr<<"  triangle "<< idx[0] <<", "<<idx[1]<<", "<<idx[2]<<endl;;
00673         cerr<<"  triangle "<< idx[0] <<", "<<idx[2]<<", "<<idx[3]<<endl;;
00674     }
00675 */
00676 }
00677 
00678 } // namespace collision
00679 
00680 } // namespace component
00681 
00682 } // namespace sofa
00683 

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