Documentation


Octree.cpp

Go to the documentation of this file.
00001 /***************************************************************************
00002                           x3d_octree.cpp  -  description
00003                              -------------------
00004     begin                : Tue Mar 23 2004
00005     copyright            : (C) 2004 by Mathieu Coquerelle
00006     email                : mathieu.coquerelle@imag.fr
00007  ***************************************************************************/
00008 
00009 /***************************************************************************
00010  *                                                                         *
00011  *   This program is free software; you can redistribute it and/or modify  *
00012  *   it under the terms of the GNU General Public License as published by  *
00013  *   the Free Software Foundation; either version 2 of the License, or     *
00014  *   (at your option) any later version.                                   *
00015  *                                                                         *
00016  ***************************************************************************/
00017 
00018 
00019 #include "Octree.h"
00020 #include "ConstrainedVertex.h"
00021 #include "SFVec3fCellConstrained.h"
00022 //#include "ParametersCalculus.h"
00023 // #include "Vec3.h"
00024 // #include "ConstrainedVertex.h"
00025 // #include "fastoctreedeformableconstrained.cpp"
00026 
00027 #include <set>
00028 using std::set
00029     ;
00030 
00031 
00032 #include "DirectManipulation.h"
00033 
00034 
00035 namespace animal
00036 {
00037 namespace octree
00038 {
00039 // //template class FastOc
00040 // template class FastOctree<OctreeVertex,OctreeData,Vec3d>
00041 // ;
00042 
00043 static int _globalPositionMethod;
00044 
00045 
00050 Vec3d getFirstVertexParametersInCell( Cell *cStart, Cell *cEnd )
00051 {
00052     Cell *curCell = cStart;
00053     Vec3d params;
00054 
00055     while( curCell != cEnd )
00056     {
00057         if( (curCell->fatherPos()%2) != 0 )
00058             params[0] += 1.0;
00059         if( (curCell->fatherPos()%4) >= 2 )
00060             params[1] += 1.0;
00061         if( curCell->fatherPos() >= 4 )
00062             params[2] += 1.0;
00063 
00064         params /= 2.0;
00065 
00066         curCell = curCell->father();
00067     }
00068 
00069     return params;
00070 }
00071 
00072 
00073 
00074 
00075 
00079 unsigned short getVertexPositionInCell( ConstrainedVertex *cv, Cell *cell )
00080 {
00081     unsigned short vId;
00082     for( vId=0 ; vId<8 ; ++vId )
00083     {
00084         if( cell->vertex(vId) == cv )
00085         {
00086             break;
00087         }
00088     }
00089     Require( vId != 8 );
00090 
00091     return vId;
00092 }
00093 
00094 
00095 
00100 Cell* getVertexFreeCell( Cell* cStart, const ConstrainedVertex* cv )
00101 {
00102     Require( cStart->isLeaf() );
00103     Require( cv->isFree() );
00104 
00105     //std::cerr << "getVert exFreeCell : searching for " << cv->getMainCellVertexId() << " in cell " << *cStart << "\n";
00106 
00107     bool stop = false;
00108 
00109     Cell * cell = cStart;
00110 
00111     while( !stop )
00112     {
00113         //std::cerr << "\tCell = " << *cell << "\n";
00114         Require( cell != NULL );
00115 
00116         //std::cerr << "\tCell is   " << *cell << "\n";
00117 
00118         unsigned short vId;
00119         for( vId=0 ; vId<8 ; ++vId )
00120         {
00121             //std::cerr << "\tvId = " << vId << " and vertex is : " << cell->vertex(vId) << "\n";
00122             if( cell->vertex(vId) == cv )
00123             {
00124                 break;
00125             }
00126         }
00127 
00128         if( vId == 8 )
00129         {
00130             //continue to father's cell
00131             cell = cell->father();
00132         }
00133         else
00134         {
00135             Cell *neighbours[3];
00136             std::vector<unsigned short> nonNullNeighbourDir;
00137 
00138             // Ok we've find it, but look if's it's a "free cell"
00139             unsigned short dir;
00140             for( dir=0 ; dir<3 ; ++dir )
00141             {
00142                 neighbours[dir] = cell->uncleSharingFace( TempOctree::verticesConnectedFaces[vId][dir] );
00143                 if( neighbours[dir] != NULL )
00144                 {
00145                     nonNullNeighbourDir.push_back( dir );
00146                     if( neighbours[dir]->getData()._depth < cell->getData()._depth )
00147                     {
00148                         // It's constrained
00149                         break;
00150                     }
00151                 }
00152             }
00153 
00154             if( dir == 3 )
00155             {
00156                 // Ok, wee got every non NULL neighbours at the same depth
00157                 if( nonNullNeighbourDir.size() <= 1 )
00158                 {
00159                     // Ok it's a free cell
00160                     stop = true;
00161                 }
00162                 else if( nonNullNeighbourDir.size() == 2 )
00163                 {
00164                     // Get the diagonal neighbour
00165                     Cell *dNeighbour = neighbours[ nonNullNeighbourDir[0] ]->uncleSharingFace( TempOctree::verticesConnectedFaces[ Cell::connectedVertices[vId][nonNullNeighbourDir[0]] ][nonNullNeighbourDir[1]] );
00166                     if( dNeighbour->getData()._depth == cell->getData()._depth )
00167                     {
00168                         stop = true;
00169                     }
00170                     else
00171                     {
00172                         cell = cell->father();
00173                     }
00174                 }
00175                 else
00176                 {
00177                     // we have 3 diagonal cells, test each of them
00178                     Cell *dNeighbours[3];
00179                     dNeighbours[0] = neighbours[ 0 ]->uncleSharingFace( TempOctree::verticesConnectedFaces[ Cell::connectedVertices[vId][0] ][1] );
00180                     dNeighbours[1] = neighbours[ 0 ]->uncleSharingFace( TempOctree::verticesConnectedFaces[ Cell::connectedVertices[vId][0] ][2] );
00181                     dNeighbours[2] = neighbours[ 1 ]->uncleSharingFace( TempOctree::verticesConnectedFaces[ Cell::connectedVertices[vId][1] ][2] );
00182                     if( dNeighbours[0]->getData()._depth == cell->getData()._depth &&
00183                             dNeighbours[1]->getData()._depth == cell->getData()._depth &&
00184                             dNeighbours[2]->getData()._depth == cell->getData()._depth
00185                       )
00186                     {
00187                         stop = true;
00188                     }
00189                     else
00190                     {
00191                         cell = cell->father();
00192                     }
00193                 }
00194             }
00195             else
00196             {
00197                 cell = cell->father();
00198             }
00199         }
00200         //std::cerr << "Next iteration\n";
00201     }
00202 
00203     Ensure( cell != NULL );
00204     return cell;
00205 }
00206 
00207 
00208 
00209 
00210 
00211 std::map<ConstrainedVertex*,Vec3d> getWeightsHash( Cell *cell, ConstrainedVertex *vertex, unsigned short vId )
00212 {
00213     //std::cerr << "Cell is " << *cell << " and vId is " << vId << "\n";
00214 
00215     std::map<ConstrainedVertex*,Vec3d> resMap;
00216 
00217     // Make the local cell parameters coordinates
00218     resMap[vertex] = Vec3d(0,0,0);
00219     for( unsigned short dir=0 ; dir<3 ; ++dir )
00220     {
00221         Vec3d val(0,0,0);
00222         val[dir] = 1;
00223         resMap[cell->vertex(TempOctree::Cell::connectedVertices[vId][dir])] = val;
00224     }
00225     resMap[cell->vertex(7-vId)] = Vec3d(1,1,1);
00226     for( unsigned short dir=0 ; dir<3 ; ++dir )
00227     {
00228         Vec3d val(1,1,1);
00229         val[dir] = 0;
00230         resMap[cell->vertex(TempOctree::Cell::connectedVertices[7-vId][dir])] = val;
00231     }
00232 
00233     if( cell->isLeaf() )
00234     {
00235         return resMap;
00236     }
00237 
00238 
00239     /*
00240      * vertexChildPos[v][0] gives our associated father's child position for the vertex v
00241      * vertexChildPos[v][1] gives the ID of the vertex in vertexChildPos[v][0] father's child
00242      */
00243 
00244     static const unsigned short vertexChildPos[27][2] =
00245         {
00246             {
00247                 0,0
00248             }
00249             , {0,1}, {1,1}, {0,2}, {0,3}, {1,3}, {2,2}, {2,3}, {3,3},
00250             {0,4}, {0,5}, {1,5}, {0,6}, {0,7}, {1,7}, {2,6}, {2,7}, {3,7},
00251             {4,4}, {4,5}, {5,5}, {4,6}, {4,7}, {5,7}, {6,6}, {6,7}, {7,7}
00252         };
00253 
00254 
00255 
00256     /*
00257      * vertexOnEdge[e][4] gives :
00258      *     [0] : the Id of the point in 0..26
00259      *     [1] : the direction of the edge (0,1 or 2)
00260      *     [2] : the Id of its father1
00261      *     [3] : the Id of its father2
00262      */
00263     static const unsigned short vertexOnEdge[12][4] =
00264         {
00265             {
00266                 1,0,0,2
00267             }
00268             , {7,0,6,8},    {19,0,18,20},   {25,0,24,26},
00269             {3,1,0,6}, {5,1,2,8},   {21,1,18,24},   {23,1,20,26},
00270             {9,2,0,18}, {11,2,2,20}, {15,2,6,24},{17,2,8,26}
00271         };
00272 
00279     static const unsigned short vertexOnFace[6][6] =
00280         {
00281             {
00282                 4,2,1,3,5,7
00283             }
00284             , {22,2,19,21,23,25},
00285             {12,0,3,21,9,15}, {14,0,5,23,11,17},
00286             {10,1,1,19,9,11}, {16,1,7,25,15,17}
00287         };
00288 
00289 
00290 
00291     //std::cerr << "Cell is " << *cell << " vId is " << vId << " and vertex : " << vertex << "\n";
00292 
00293 
00294 
00295 
00296     //std::cerr << "Cell is " << *cell << " vId is " << vId << " and vertex : " << vertex << "\n";
00297     /*
00298     for( unsigned short i=0 ; i<8 ; ++i )
00299     {
00300         std::cerr << "\tfor vertex " << i << " val is " << resMap[cell->vertex(i)] << "\n";
00301     }
00302     */
00303 
00304     std::list<Cell*> cellQueue;
00305     cellQueue.push_back(cell);
00306 
00307     {
00308         ConstrainedVertex *vertices[27];
00309 
00310         for( unsigned short i=0 ; i<27 ; ++i )
00311         {
00312             vertices[i] = cell->child( vertexChildPos[i][0] )->vertex( vertexChildPos[i][1] );
00313         }
00314 
00315         Cell *it = cellQueue.front();
00316         cellQueue.pop_front();
00317 
00318         Require( !it->isLeaf() );
00319         // Compute the parameters for the children's vertices
00320 
00321         // First the edges
00322         for( unsigned short e=0 ; e<12 ; ++e )
00323         {
00324             //std::cerr << "\tOn edge " << e << " vertex is " << vertexOnEdge[e][0] << "\n";
00325             unsigned short vEId = vertexOnEdge[e][0];
00326             ConstrainedVertex *cv = vertices[vEId];
00327 
00328             ConstrainedVertex *father1 = vertices[ vertexOnEdge[e][2] ];
00329             ConstrainedVertex *father2 = vertices[ vertexOnEdge[e][3] ];
00330 
00331             //std::cerr << "\t\tFathers are : " << vertexOnEdge[e][2] << " and " << vertexOnEdge[e][3] << "\n";
00332             //std::cerr << "\t\t for values : " << resMap[father1] << " and " << resMap[father2] << "\n";
00333 
00334             resMap[cv] = 0.5*(resMap[father1]+resMap[father2]);
00335 
00336             if( cv->isFree() )
00337             {
00338                 resMap[cv][vertexOnEdge[e][1]] = 1;
00339             }
00340             else
00341             {
00342             }
00343 
00344             //std::cerr << "\t\tRes : " << resMap[cv] << "\n";
00345         }
00346 
00347         // Then the faces
00348         for( unsigned short f=0 ; f<6 ; ++f )
00349         {
00350             unsigned short vFId = vertexOnFace[f][0];
00351             ConstrainedVertex *cv = vertices[vFId];
00352 
00353             //std::cerr << "\tOn face " << f << " vertex is " << vertexOnFace[f][0] << "\n";
00354             if( cv->isFree() )
00355             {
00356                 resMap[cv] = Vec3d(1,1,1);
00357             }
00358             else
00359             {
00360                 ConstrainedVertex *fathers[4];
00361 
00362                 for( unsigned short i=0 ; i<4 ; ++i )
00363                 {
00364                     fathers[i] = vertices[ vertexOnFace[f][2+i] ];
00365                 }
00366 
00367                 resMap[cv] = 0.25 * (resMap[fathers[0]]+resMap[fathers[1]]+resMap[fathers[2]]+resMap[fathers[3]]);
00368             }
00369             //std::cerr << "\t\tRes : " << resMap[cv] << "\n";
00370         }
00371 
00372         // Always free !
00373         resMap[ it->child(0)->vertex(7) ] = Vec3d(1,1,1);
00374 
00375         for( unsigned short c=0 ; c<8 ; ++c )
00376         {
00377             if( !it->child(c)->isLeaf() )
00378             {
00379                 cellQueue.push_back(it->child(c));
00380             }
00381         }
00382     }
00383 
00384 
00385     //std::cerr << "Cell is " << *cell << "\n";
00386     while( !cellQueue.empty() )
00387     {
00388         Cell *it = cellQueue.front();
00389         cellQueue.pop_front();
00390         Require( !it->isLeaf() );
00391 
00392         //std::cerr << "\tnew cell : " << *it << "\n";
00393 
00394         ConstrainedVertex *vertices[27];
00395 
00396         for( unsigned short i=0 ; i<27 ; ++i )
00397         {
00398             vertices[i] = it->child( vertexChildPos[i][0] )->vertex( vertexChildPos[i][1] );
00399         }
00400 
00401         //std::cerr << "\tcomputing for cell " << *it << "\n";
00402 
00403         // Compute the parameters for the children's vertices
00404 
00405         // First the edges
00406         for( unsigned short e=0 ; e<12 ; ++e )
00407         {
00408 
00409             unsigned short vEId = vertexOnEdge[e][0];
00410             ConstrainedVertex *cv = vertices[vEId];
00411 
00412             //std::cerr << "\tOn edge " << e << " vertex is " << vertexOnEdge[e][0] << " (ptr " << cv << ")\n";
00413             ConstrainedVertex *father1 = vertices[ vertexOnEdge[e][2] ];
00414             ConstrainedVertex *father2 = vertices[ vertexOnEdge[e][3] ];
00415 
00416             resMap[cv] = 0.5*(resMap[father1]+resMap[father2]);
00417 
00418             if( cv->isFree() )
00419             {
00420                 resMap[cv][vertexOnEdge[e][1]] = 1;
00421             }
00422 
00423         }
00424 
00425         // Then the faces
00426         // First the edges
00427         for( unsigned short f=0 ; f<6 ; ++f )
00428         {
00429             unsigned short vFId = vertexOnFace[f][0];
00430             ConstrainedVertex *cv = vertices[vFId];
00431 
00432             if( cv->isFree() )
00433             {
00434                 resMap[cv] = Vec3d(1,1,1);
00435             }
00436             else
00437             {
00438                 ConstrainedVertex *fathers[4];
00439 
00440                 for( unsigned short i=0 ; i<4 ; ++i )
00441                 {
00442                     fathers[i] = vertices[ vertexOnFace[f][2+i] ];
00443                 }
00444 
00445                 resMap[cv] = 0.25 * (resMap[fathers[0]]+resMap[fathers[1]]+resMap[fathers[2]]+resMap[fathers[3]]);
00446             }
00447         }
00448 
00449         // Always free !
00450         resMap[ it->child(0)->vertex(7) ] = Vec3d(1,1,1);
00451 
00452         for( unsigned short c=0 ; c<8 ; ++c )
00453         {
00454             if( !it->child(c)->isLeaf() )
00455             {
00456                 cellQueue.push_back(it->child(c));
00457             }
00458         }
00459 
00460     }
00461 
00462     //std::cerr << "Cell is " << *cell << " and vId is " << vId << "End\n\n";
00463 
00464     return resMap;
00465 }
00466 
00467 
00468 
00469 
00470 
00471 
00472 void printOctree( Cell *cell, unsigned int depth )
00473 {
00474     char pref[depth+1];
00475     for( unsigned int i=0 ; i<depth ; ++i )
00476     {
00477         pref[i] = '\t';
00478     }
00479     pref[depth] = '\0';
00480 
00481     std::cerr << pref << "Cell=" << *cell << "\n";
00482     for( unsigned int i=0;i<8 ; ++i )
00483     {
00484         std::cerr << pref << "\tvertex[" << i << "] is ";
00485         if( !cell->vertex(i)->isFree() )
00486             std::cerr << "not ";
00487         std::cerr << "free\n";
00488     }
00489 
00490     if( !cell->isLeaf() )
00491     {
00492         for( unsigned int i=0 ; i<8 ; ++i )
00493             printOctree( cell->child(i), depth+1 );
00494     }
00495 }
00496 
00497 
00498 
00499 
00500 
00501 
00502 
00503 
00504 
00505 
00506 
00507 
00508 
00509 
00510 
00511 
00512 
00513 
00514 
00515 
00516 
00517 
00518 
00519 
00520 
00521 
00522 
00523 
00524 
00525 
00526 
00527 
00528 
00529 
00530 
00531 
00532 Octree::Octree( Vec3d bboxMin, Vec3d bboxMax, MFVec3f *points, MFVec3f normals, unsigned int nMaxPointsPerCell ) :
00533         TempOctree( bboxMin, bboxMax.x-bboxMin.x, bboxMax.y-bboxMin.y, bboxMax.z-bboxMin.z),
00534         _nMaxPointsPerCell(nMaxPointsPerCell),
00535         _optionPositionMethod( LINEAR ),
00536     _freeFrames(false),
00537     _DMMethod(OCTREE_DM_NOTHING)
00538 {
00539     Require( getNMaxPointsPerCell() != 0 );
00540 
00541     std::cerr << "There are " << points->size() << " points to put in the octree\n";
00542 
00543     std::deque<SFVec3f*> pointsPointers;
00544     for( MFVec3f::iterator it = points->begin() ; it != points->end() ; ++it )
00545     {
00546         pointsPointers.push_back( &(*it) );
00547     }
00548 
00549 
00550 
00551     root()->getData()._depth = 0; // depth 0
00552     root()->getData()._initialSize = bboxMax - bboxMin;
00553 
00554     //      updateFrames(root());
00555 
00556     //
00557     // Now add the vertices in the cell
00558     //
00559     int vertexID = 0;
00560 
00561     MFVec3f::iterator itN = normals.begin();
00562     for(    std::deque<SFVec3f*>::iterator it = pointsPointers.begin() ;
00563             it != pointsPointers.end() ;
00564             ++it, ++itN
00565        )
00566     {
00567         root()->getData()._points.push_back( new SFVec3fCellConstrained(*it,root(),vertexID,*itN) );
00568 
00569         for( unsigned short i=0 ; i<8 ; ++i )
00570         {
00571             root()->getData()._points.back()->setRelativeWeight( root()->vertex(i), SFVec3fCellConstrained::computeWeight( root()->getData()._points.back()->getParameters(i), LOCAL_SKINNING ) );
00572             root()->getData()._points.back()->setInitNormalRelativeWeight( root()->vertex(i), SFVec3fCellConstrained::computeWeight( root()->getData()._points.back()->getInitNormalParameters(i), LOCAL_SKINNING ) );
00573         }
00574 
00575         vertexID++;
00576     }
00577 
00578     /*
00579     //
00580     // Now subdivide the octree if necessary
00581     //
00582     */
00583 
00584     int nCells;
00585     nCells = createOctree( root() );
00586     std::cerr << "There are " << nCells << " cells in the octree\n";
00587 
00588     structureChangedRecLeaves( root() );
00589     updateVertexInformations( root() );
00590 
00591 
00592 }
00593 
00594 Octree::~Octree( )
00595 {
00596     std::cerr << "~Octree()\n";
00597 }
00598 
00599 
00600 
00601 void Octree::setDMMethod( int method )
00602 {
00603     std::cerr << "Octree::setDMMethod( " << method << " )\n";
00604     Require( (method == OCTREE_DM_NOTHING) || (method == OCTREE_DM_VERTICES) || (method == OCTREE_DM_FRAMES) || (method == (OCTREE_DM_FRAMES|OCTREE_DM_VERTICES)) );
00605     _DMMethod = method;
00606 }
00607 
00608 void Octree::setFreeFrames( bool b )
00609 {
00610     _freeFrames = b;
00611 }
00612 
00613 
00614 
00615 
00616 
00617 
00618 /*
00619  * The depth information is allready filled for cell
00620  */
00621 int Octree::createOctree( Cell *cell )
00622 {
00623 
00624     if( cell->getData()._points.size() <= getNMaxPointsPerCell() )
00625     {
00626         return 1;
00627     }
00628     else
00629     {
00630         subdivideDeformed( cell );
00631 
00632         int acc = 0;
00633         for( unsigned int i=0 ; i<8 ; ++i )
00634         {
00635             acc += createOctree( cell->child(i) );
00636         }
00637 
00638         return acc;
00639     }
00640 }
00641 
00642 
00643 
00644 
00645 unsigned int Octree::getNMaxPointsPerCell()
00646 {
00647     return _nMaxPointsPerCell;
00648 }
00649 
00650 void Octree::setNMaxPointsPerCell(unsigned int n)
00651 {
00652     Require( n != 0 );
00653     _nMaxPointsPerCell = n;
00654     this->updateHierarchy( root() );
00655 }
00656 
00657 
00658 
00659 
00660 void Octree::updateHierarchy( Cell *cell )
00661 {
00662 
00663     unsigned nPoints = cell->getData()._points.size();
00664 
00665     if( cell->isLeaf() && (nPoints > getNMaxPointsPerCell()) )
00666     {
00667         this->subdivideDeformed( cell );
00668 
00669         for( unsigned int i=0 ; i<8 ; ++i )
00670         {
00671             updateHierarchy( cell->child(i) );
00672         }
00673 
00674     }
00675     else if( !cell->isLeaf() && (nPoints <= getNMaxPointsPerCell()) )
00676     {
00677         //          std::cerr << "Simplyfing : " << nPoints << " for max " << getNMaxPointsPerCell() << "\n";
00678         cell->simplify();
00679     }
00680     else if( !cell->isLeaf() )
00681     {
00682         for( unsigned int i=0 ; i<8 ; ++i )
00683         {
00684             updateHierarchy( cell->child(i) );
00685         }
00686     }
00687 }
00688 
00689 
00690 
00691 void Octree::setPositionMethod( int m )
00692 {
00693     _optionPositionMethod = m;
00694 
00695     // Clear some informations due to some techniques
00696     for( Cell::vertex_width_iterator it(root()) ; !it.empty() ; )
00697     {
00698         ConstrainedVertex *cv = ++it;
00699         cv->setDelta( Vec3d(0,0,0) );
00700     }
00701 }
00702 int Octree::getPositionMethod() const
00703 {
00704     return _optionPositionMethod;
00705 }
00706 
00707 
00708 
00709 
00710 
00711 
00712 
00713 
00714 
00715 
00716 void Octree::subdivideDeformed( Cell *cell )
00717 {
00718     Require( cell->isLeaf() );
00719 
00720     cell->subdivide();
00721     Ensure( !cell->isLeaf() );
00722     
00723  // Now make the depth data
00724     for( unsigned int i=0 ; i<8 ; ++i )
00725     {
00726         // Update the depth data
00727         cell->child(i)->getData()._depth = cell->getData()._depth + 1;
00728         cell->child(i)->getData()._initialSize = cell->getData()._initialSize / 2.0;
00729     }
00730         
00731     {
00732         static const float childNodesParams[19][3] =
00733     {
00734         // z-
00735         { 0.5, 0.0, 0.0 },
00736         { 0.0, 0.5, 0.0 },
00737         { 0.5, 0.5, 0.0 },
00738         { 1.0, 0.5, 0.0 },
00739         { 0.5, 1.0, 0.0 },
00740         
00741         // z = 0
00742         { 0.0, 0.0, 0.5 },
00743         { 0.5, 0.0, 0.5 },
00744         { 1.0, 0.0, 0.5 },
00745         { 0.0, 0.5, 0.5 },
00746         { 0.5, 0.5, 0.5 },
00747         { 1.0, 0.5, 0.5 },
00748         { 0.0, 1.0, 0.5 },
00749         { 0.5, 1.0, 0.5 },
00750         { 1.0, 1.0, 0.5 },
00751         
00752         // z+
00753         { 0.5, 0.0, 1.0 },
00754         { 0.0, 0.5, 1.0 },
00755         { 0.5, 0.5, 1.0 },
00756         { 1.0, 0.5, 1.0 },
00757         { 0.5, 1.0, 1.0 }
00758     };
00759     
00760     static const unsigned short cellsChildrenVertices[19][2] =
00761         {
00762         {0,1}, {0,2}, {0,3}, {1,3}, {2,3},
00763                 {0,4}, {0,5}, {1,5}, {0,6}, {0,7}, {1,7}, {2,6}, {2,7}, {3,7},
00764                 {4,5}, {4,6}, {4,7}, {5,7}, {6,7}
00765             };
00766     
00767     SFVec3fCellConstrained vec = **(cell->getData()._points.begin());
00768     for( unsigned int i=0 ; i<19 ; ++i )
00769     {
00770         unsigned short childId = cellsChildrenVertices[i][0];
00771         unsigned short vertId = cellsChildrenVertices[i][1];
00772 
00773         cell->child(childId)->vertex(vertId)->_lastConstrainedDepth = cell->child(childId)->vertex(vertId)->getMainCell()->getData()._depth-1;
00774         
00775         if( haveFreeFrames() && cell->child(childId)->vertex(vertId)->isFree() )
00776         {
00777             Vec3d v;
00778             
00779             vec.setParams( Vec3d( childNodesParams[i][0], childNodesParams[i][1], childNodesParams[i][2]) );
00780             vec.updateSkinningInformations( cell->getData()._influence );
00781             v = vec.computePosition( LOCAL_SKINNING );
00782             
00783             
00784             cell->child(childId)->vertex(vertId)->setPosition( v );
00785             v = cell->child(childId)->vertex(vertId)->getPosition();
00786             
00787             std::vector<Vec3d> frameVecs = vec.computeDerivative();
00788             
00789 //          std::cerr << "For point " << i << " and params " << vec.getLocalParams() << " frames are :\n";
00790 //          std::cerr << "\t" << frameVecs[0] << "\n";
00791 //          std::cerr << "\t" << frameVecs[1] << "\n";
00792 //          std::cerr << "\t" << frameVecs[2] << "\n";
00793             float factor = 1.0;
00794             cell->child(childId)->vertex(vertId)->getFrame() = Frame( v, frameVecs[0]/factor, frameVecs[1]/factor, frameVecs[2]/factor );
00795             
00796             
00797             
00798 //          std::cerr << "For point " << i << " got depth " << cell->child(childId)->vertex(vertId)->_lastConstrainedDepth << "\n";
00799         }
00800     }
00801     
00802     }
00803     
00804     
00805 
00806    
00807 
00808     // Now put each point in an OctreeDataPoints structur for children
00809     for( OctreeDataPoints::iterator it = cell->getData()._points.begin() ; it != cell->getData()._points.end() ; ++it )
00810     {
00811         Vec3d initParams = (*it)->getLocalParams();
00812 
00813         /*
00814          * Put it in the good child
00815          */
00816         unsigned int childPos = 0;
00817         if( initParams[0] > 0.5 )
00818         {
00819             childPos += 1;
00820             initParams[0] = (initParams[0] - 0.5)*2.0;
00821         }
00822         else
00823             initParams[0] *= 2.0;
00824 
00825         if( initParams[1] > 0.5 )
00826         {
00827             childPos += 2;
00828             initParams[1] = (initParams[1] - 0.5)*2.0;
00829         }
00830         else
00831             initParams[1] *= 2.0;
00832 
00833         if( initParams[2] > 0.5 )
00834         {
00835             childPos += 4;
00836             initParams[2] = (initParams[2] - 0.5)*2.0;
00837         }
00838         else
00839         {
00840             initParams[2] *= 2.0;
00841         }
00842 
00843         cell->child(childPos)->getData()._points.push_back( new SFVec3fCellConstrained( (*it)->getSFVec3f() , cell->child(childPos), initParams, (*it)->getVertexID(), (*it)->getInitNormal() ) );
00844     }
00845     
00846 }
00847 
00848 
00849 void Octree::subdivideRecDeformed( Cell *cell )
00850 {
00851     for( dfs_leaf_iterator it( cell ) ; !it.empty() ; )
00852     {
00853         Cell *tmpCell = ++it;
00854 
00855         if( tmpCell->isLeaf() && tmpCell->getData()._points.size() != 0 )
00856         {
00857             subdivideDeformed( tmpCell );
00858         }
00859     }
00860 
00861     structureChangedRecLeaves(root());
00862     movedRecLeaves(root());
00863     
00864 
00865 }
00866 
00867 
00868 
00869 
00870 
00871 
00872 
00873 void Octree::movedRecLeaves( Cell *cell )
00874 {
00875     if( !haveFreeFrames() )
00876     {
00877         updateFrames(cell);
00878     }
00879     if( this->getPositionMethod() == GLOBAL_LINEAR )
00880     {
00881         SFVec3fCellConstrained::globalLinearUpdatePositions( cell );
00882     }
00883     else
00884     {
00885         _globalPositionMethod = this->getPositionMethod();
00886         for( dfs_leaf_iterator it( cell, moved ) ; !it.empty() ; ++it )
00887             ;
00888     }
00889 }
00890 void Octree::moved( Cell *cell )
00891 {
00892     OctreeDataPoints *points = &(cell->getData()._points);
00893     for( OctreeDataPoints::iterator it = points->begin() ; it != points->end() ; ++it )
00894     {
00895         (*it)->updatePosition( _globalPositionMethod );
00896     }
00897 }
00898 
00899 
00900 
00901 
00902 
00903 void Octree::structureChangedRecLeaves( Cell *cell )
00904 {
00905 /*    updateFrames(cell);*/
00906     if( !haveFreeFrames() )
00907     {
00908         updateFrames(cell);
00909         
00910         Cell::vertex_width_iterator it( cell );
00911         
00912         while( !it.empty() )
00913         {
00914             Vertex* v= ++it;
00915             if( v->isFree() )
00916             {
00917                 v->_lastConstrainedDepth = v->getConstrainedDepth();
00918             }
00919         }
00920     }
00921     else
00922     {
00923         Cell::vertex_width_iterator it( cell );
00924         
00925         while( !it.empty() )
00926         {
00927             Vertex* v= ++it;
00928             if( v->isFree() )
00929             {
00930                 float factor = 1.0;
00931                 float depthFactor = 2.0;
00932                 
00933                 Frame &f = v->getFrame();
00934                 
00935                 unsigned int cDepth = v->getConstrainedDepth();
00936 //              std::cerr << "For vertex " << *(v->getMainCell()) << " Id " << v->getMainCellVertexId() <<
00937 //                  " depth was " << v->_lastConstrainedDepth << " got : " << cDepth << "\n";
00938                 if( cDepth < v->_lastConstrainedDepth )
00939                 {
00940                     factor = pow( depthFactor, (v->_lastConstrainedDepth-cDepth) );
00941                 }
00942                 else if( cDepth > v->_lastConstrainedDepth )
00943                 {
00944                     factor = 1.0 / pow( depthFactor, (cDepth-v->_lastConstrainedDepth) );
00945                 }
00946                  v->_lastConstrainedDepth = cDepth;
00947                 
00948                 f.setOrigin( v->getPosition() );
00949                 f.setVector( 0, f.getVector(0)*factor);
00950                 f.setVector( 1, f.getVector(1)*factor );
00951                 f.setVector( 2, f.getVector(2)*factor );
00952             }
00953         }   
00954     }
00955     
00956     for( dfs_leaf_iterator it( cell, structureChanged ) ; !it.empty() ; ++it )
00957         ;
00958 }
00959 void Octree::structureChanged( Cell *cell )
00960 {
00961     //updateFrame(cell);
00962     updateInfluenceMaps( cell );
00963     updateVertexInformations( cell );
00964 }
00965 
00966 
00967 
00968 
00969 
00970 
00971 
00972 
00973 
00974 
00975 void Octree::updateVertexInformationsRec( Cell *cell )
00976 {
00977     for( dfs_iterator it( cell, NULL, updateVertexInformations, NULL ) ; !it.empty() ; ++it )
00978         ;
00979 }
00980 
00981 void Octree::updateVertexInformationsRecLeaves( Cell *cell )
00982 {
00983     for( dfs_leaf_iterator it( cell, updateVertexInformations ) ; !it.empty() ; ++it )
00984         ;
00985 }
00986 
00987 
00988 void Octree::updateVertexInformations( Cell *cell )
00989 {
00990     for( OctreeDataPoints::iterator it=cell->getData()._points.begin() ; it!=cell->getData()._points.end() ; ++it )
00991     {
00992         (*it)->updateSkinningInformations( cell->getData()._influence );
00993     }
00994 }
00995 
00996 
00997 
00998 
00999 
01000 void Octree::simplify( Cell *cell )
01001 {
01002     if( !cell->isLeaf() )
01003     {
01004         cell->simplify();
01005 
01006         structureChangedRecLeaves( root() );
01007 
01008 //         updateFrame( root() );
01009 //  if( !haveFreeFrames() )
01010 //  {
01011 //      updateFrame( root() );
01012 //  }
01013 
01014         updateInfluenceMapsRecLeaves( root() );
01015         updateVertexInformationsRecLeaves( root() );
01016         movedRecLeaves( root() );
01017     }
01018 }
01019 
01020 
01021 
01022 
01023 
01024 
01025 
01026 void Octree::updateFrame( Cell *cell )
01027 {
01028     for( unsigned short i=0 ; i<8 ; ++i )
01029     {
01030         cell->vertex(i)->updateFrame();
01031     }
01032 }
01033 
01034 
01035 
01036 void Octree::updateFrames( Cell *cell )
01037 {
01038     Cell::vertex_width_iterator it( cell );
01039 
01040     while( !it.empty() )
01041     {
01042         Vertex* v= ++it;
01043         if( v->isFree() )
01044         {
01045             v->updateFrame();
01046         }
01047     }
01048 }
01049 
01050 
01051 
01052 
01053 
01054 void Octree::updateFrames( ConstrainedVertex* vertex, Cell *cell, unsigned int vPos  )
01055 {
01056     Cell::vertex_width_neighbours_iterator it( vertex, cell, vPos );
01057 
01058     // Do remove this
01059     set <Cell*> cellList;
01060 
01061     while( !it.empty() )
01062     {
01063         Vertex* v= ++it;
01064         v->updateFrame();
01065 
01066         for( unsigned int i=0 ; i<v->nConnectedCells() ; ++i )
01067         {
01068             if( v->connectedCell(i)->getData()._depth == v->getDepth() )
01069             {
01070                 cellList.insert(v->connectedCell(i));
01071             }
01072         }
01073     }
01074     /*
01075     for( set<Cell*>::iterator it=cellList.begin() ; it != cellList.end() ; ++it )
01076     {
01077         this->updateCellsData( *it );
01078     }
01079     */
01080 }
01081 
01082 
01083 
01084 
01085 
01086 void Octree::updateCellsData( Cell *cell )
01087 {
01088     std::cerr << "Don't iuse this\n";
01089     exit(0);
01090     if( cell->isLeaf() )
01091     {
01092         //std::cerr << "Ok leaf\n";
01093         OctreeDataPoints *points = &(cell->getData()._points);
01094         unsigned int nPoints=0;
01095         for( OctreeDataPoints::iterator it = points->begin() ; it != points->end() ; ++it )
01096         {
01097             (*it)->updatePosition( this->getPositionMethod() );
01098             nPoints++;
01099         }
01100         //std::cerr << "Have updated " << nPoints << " points\n";
01101     }
01102     else
01103     {
01104         for( unsigned int i=0 ; i < 8 ; ++i )
01105             updateCellsData( cell->child(i) );
01106     }
01107 }
01108 
01109 
01110 
01111 
01112 
01113 
01114 
01115 
01116 
01117 
01118 
01119 
01120 void Octree::updateInfluenceMapsRecLeaves( Cell *cell )
01121 {
01122     for( dfs_leaf_iterator it( cell, updateInfluenceMaps ) ; !it.empty() ; ++it )
01123         ;
01124 }
01125 
01126 
01127 
01128 void Octree::updateInfluenceMaps( Cell *cell )
01129 {
01130     // First get the list of freeVertices
01131     //
01132     std::set
01133         <ConstrainedVertex*> freeVertices = ConstrainedVertex::getFreeParentVertices( cell );
01134 
01135     //
01136     // Now fill the influencemaps
01137     //
01138     CellInfluenceData cid;
01139     unsigned int nfreeVertices = freeVertices.size();
01140 
01141     cid.influenceMaps.resize(nfreeVertices);
01142     cid.vertices.resize(nfreeVertices);
01143     cid.verticesId.resize(nfreeVertices);
01144     cid.parents.resize(nfreeVertices);
01145     cid.firstCellVertexParameters.resize(nfreeVertices);
01146 
01147     //std::cerr << "\n\nUPDATECELL : " << *cell << "\n";
01148 
01149     unsigned int i=0;
01150     // Now freeVertices contains the list of intereting vertices
01151     // Find the _cell's parent cell that is of same depth of each free vertex
01152     // And compute the parameters in this cell
01153     for( std::set
01154                 <ConstrainedVertex*>::iterator it=freeVertices.begin() ; it!=freeVertices.end() ; ++it )
01155         {
01156             //std::cerr << "\tI is " << i << " and vertex is " << *it << "\n";
01157             cid.vertices[i] = *it;
01158             cid.parents[i] = (void*)getVertexFreeCell( cell, (*it) );
01159 
01160             /*
01161             std::cerr << "Gloppy\n";
01162             cid.parents[i] = (void*)getVertexFreeCell( (*it)->getMainCell(), (*it) );
01163             std::cerr << "the cell is " << *(Cell*) cid.parents[i] << "\n";
01164             std::cerr << "the cell would be " << *getVertexFreeCell( cell, (*it) ) << "\n";
01165             */
01166 
01167             cid.verticesId[i] = getVertexPositionInCell(*it,(Cell*)cid.parents[i]);
01168 
01169             //std::cerr << "\tVertex id is " << cid.verticesId[i] << " and cell : " << *((Cell*)cid.parents[i])<< "\n";
01170 
01171             // Now get the parameter of "cell's" vertex(0) in the parent cell
01172             cid.firstCellVertexParameters[i] = getFirstVertexParametersInCell( cell, (Cell*)cid.parents[i] );
01173 
01174             cid.influenceMaps[i] = getWeightsHash( (Cell*)cid.parents[i], *it, cid.verticesId[i] );
01175 
01176             i++;
01177         }
01178 
01179     cell->getData()._influence = cid;
01180 }
01181 
01182 
01183 
01184 
01185 
01186 void Octree::directManipulation( SFVec3fCellConstrained* vertex, Vec3d newPosition )
01187 {
01188     Cell *cell = vertex->getCell();
01189     std::vector<FloatingPointType> weights;
01190     
01191     X3DTK::SFVec3f *sf = vertex->getSFVec3f();
01192     Vec3d deltaQ = newPosition - Vec3d( sf->x, sf->y, sf->z );
01193     
01194     std::vector<Vec3d> deltaP;
01195     
01196 //  std::cerr << "Moving vertex " << Vec3d( sf->x, sf->y, sf->z ) << " at position " << newPosition << "\n";
01197 //  std::cerr << "Delta Q is " << deltaQ << "\n";
01198 
01199     switch( this->getPositionMethod() )
01200     {
01201         case LINEAR:
01202         {
01203             Vec3d localParams = vertex->getLocalParams();
01204             
01205             for( unsigned int i=0 ; i<8 ; ++i )
01206             {
01207                 weights.push_back( vertex->computeWeight( vertex->getParameters(i), LINEAR ) );
01208             }
01209             
01210             deltaP = computeDirectManipulationResultPseudoInverse( weights, deltaQ );
01211             
01212             for( unsigned int i=0 ; i<8 ; ++i )
01213             {
01214                 cell->vertex(i)->setPositionAndPropagate( cell->vertex(i)->getPosition()+deltaP[i] );
01215             }
01216         }
01217         break;
01218         
01219         case LOCAL_SKINNING:
01220         {
01221             std::vector<ConstrainedVertex*> framesVertices;
01222             std::vector<Vec3d> relPos;
01223             
01224             CellInfluenceData cid = cell->getData()._influence;
01225             
01226             for( unsigned int i=0 ; i<cid.vertices.size() ; ++i )
01227                     {
01228                 weights.push_back( vertex->getRelativeWeight( cid.vertices[i] ) );
01229                 relPos.push_back( vertex->getRelativePosition(cid.vertices[i]) );
01230                 framesVertices.push_back( cid.vertices[i] );
01231             }
01232             
01233             if( _DMMethod == OCTREE_DM_VERTICES )
01234             {
01235                 if( !haveFreeFrames() )
01236                 {
01237                     
01238                     // results stored here
01239                     vector<ConstrainedVertex*> verticesToMove;
01240         
01241                     computeDirectManipulationSkinning(
01242                         deltaQ, weights, relPos, framesVertices, // in data
01243                         verticesToMove, deltaP ); // results here
01244                 
01245                     unsigned int i=0;
01246                     for( vector<ConstrainedVertex*>::iterator it=verticesToMove.begin() ;
01247                         it!=verticesToMove.end() ;
01248                         ++it )
01249                     {
01250                         (*it)->setPositionAndPropagate( (*it)->getPosition() + deltaP[i] );
01251                         ++i;
01252                     }
01253                 }
01254                 else
01255                 {
01256                     // results stored here
01257                     // Will have <dPi>
01258                     std::vector< Vec3d > deltas;
01259         
01260                     computeDirectManipulationSkinningVertices(
01261                         deltaQ, weights, relPos, framesVertices, // in data
01262                         deltas ); // results here
01263                     
01264                     unsigned int i=0;
01265                     for( vector<ConstrainedVertex*>::iterator it=framesVertices.begin() ;
01266                         it!=framesVertices.end() ;
01267                         ++it )
01268                     {
01269                         Frame &f = (*it)->getFrame();
01270                         f.setOrigin( f.getOrigin()+ deltas[i++] );
01271                         (*it)->setPositionAndPropagate( f.getOrigin() );
01272                     }
01273                 }
01274             }
01275             else if( _DMMethod == OCTREE_DM_FRAMES )
01276             {
01277                 Require( haveFreeFrames() );
01278                 
01279                 // results stored here
01280                 // <Ui' Vi' Wi'>
01281                 // for each frames of the "framesVertices" vector
01282                 std::vector< std::vector<Vec3d> > deltaFrames;
01283     
01284                 computeDirectManipulationSkinningFrames(
01285                     deltaQ, weights, relPos, framesVertices, // in data
01286                     deltaFrames ); // results here
01287             
01288                 unsigned int i=0;
01289                 for( vector<ConstrainedVertex*>::iterator it=framesVertices.begin() ;
01290                     it!=framesVertices.end() ;
01291                     ++it )
01292                 {
01293                     Frame &f = (*it)->getFrame();
01294                     f.setVector( 0, f.getVector(0) + deltaFrames[i][0] );
01295                     f.setVector( 1, f.getVector(1) + deltaFrames[i][1] );
01296                     f.setVector( 2, f.getVector(2) + deltaFrames[i][2] );
01297                     ++i;
01298                 }
01299                 
01300             }
01301             else if( (_DMMethod&OCTREE_DM_FRAMES)&&(_DMMethod&OCTREE_DM_VERTICES) )
01302             {   
01303                 Require( haveFreeFrames() );
01304                 
01305                 // results stored here
01306                 // Will have <dPi' dUi' dVi' dWi'>
01307                 // for each frames of the "framesVertices" vector
01308                 std::vector< Vec3d > deltas;
01309     
01310                 computeDirectManipulationSkinningVerticesAndFrames(
01311                     deltaQ, weights, relPos, framesVertices, // in data
01312                     deltas ); // results here
01313                 
01314                 unsigned int i=0;
01315                 for( vector<ConstrainedVertex*>::iterator it=framesVertices.begin() ;
01316                     it!=framesVertices.end() ;
01317                     ++it )
01318                 {
01319                     Frame &f = (*it)->getFrame();
01320                     f.setOrigin( f.getOrigin()+ deltas[i++] );
01321                     (*it)->setPositionAndPropagate( f.getOrigin() );
01322                     f.setVector( 0, f.getVector(0) + deltas[i++] );
01323                     f.setVector( 1, f.getVector(1) + deltas[i++] );
01324                     f.setVector( 2, f.getVector(2) + deltas[i++] );
01325                 }
01326                 
01327             }
01328             
01329             movedRecLeaves( root() );
01330             
01331 //          std::vector<ConstrainedVertex*> framesVertices;
01332 //          std::vector<Vec3d> relPos;
01333 //          
01334 //          CellInfluenceData cid = cell->getData()._influence;
01335 //          
01336 //          for( unsigned int i=0 ; i<cid.vertices.size() ; ++i )
01337 //                  {
01338 //              weights.push_back( vertex->getRelativeWeight( cid.vertices[i] ) );
01339 //              relPos.push_back( vertex->getRelativePosition(cid.vertices[i]) );
01340 //              framesVertices.push_back( cid.vertices[i] );
01341 //          }
01342 //          
01343 //          vector<ConstrainedVertex*> verticesToMove;
01344 //          
01345 //          //
01346 //          // iterative scheme
01347 //          //
01348 //          const double eps = 10e-8;
01349 //          const double maxErr = 10e-4;
01350 //          double err = INFINITY;
01351 //          double precErr = INFINITY;
01352 //          
01353 //          std::vector<Vec3d> oldPositions;
01354 //          
01355 //          unsigned int nIt = 0;
01356 //          do
01357 //          {
01358 //              precErr = err;
01359 //              
01360 //              computeDirectManipulationSkinning(
01361 //                  deltaQ, weights, relPos, framesVertices, // in data
01362 //                  verticesToMove, deltaP ); // results here
01363 //          
01364 //              oldPositions.clear();
01365 //              unsigned int i=0;
01366 //              for( vector<ConstrainedVertex*>::iterator it=verticesToMove.begin() ;
01367 //                  it!=verticesToMove.end() ;
01368 //                  ++it )
01369 //              {
01370 //                  oldPositions.push_back( (*it)->getPosition() );
01371 //                  (*it)->setPositionAndPropagate( (*it)->getPosition() + deltaP[i] );
01372 //                  ++i;
01373 //              }
01374 //              
01375 //              movedRecLeaves( root() );
01376 //              SFVec3f sfPos = *(vertex->getSFVec3f());
01377 //              Vec3d curPos(sfPos.x,sfPos.y,sfPos.z);
01378 //              
01379 //              err = (newPosition - curPos) * (newPosition - curPos);
01380 // //               std::cerr << "DM: for iteration " << nIt << " got err " << err << "\n";
01381 //              
01382 //              nIt++;
01383 //          }
01384 //          while( (err > eps) && (err<precErr) && (err<maxErr) );
01385 //          
01386 //          if( (err > precErr) || (err>maxErr) )
01387 //          {
01388 //              std::cerr << "\tStopping because diverging\n";
01389 //              unsigned int i=0;
01390 //              for( vector<ConstrainedVertex*>::iterator it=verticesToMove.begin() ;
01391 //                  it!=verticesToMove.end() ;
01392 //                  ++it )
01393 //              {
01394 //                  (*it)->setPositionAndPropagate( oldPositions[i] );
01395 //                  ++i;
01396 //              }   
01397 //              
01398 //          }
01399         }
01400         break;
01401     }
01402 }
01403 
01404 
01405 
01406 
01407 
01408 
01409 std::vector<Vec3d> Octree::getNormals() const
01410 {
01411     Cell *cell = root();
01412 
01413     std::vector<Vec3d> result( cell->getData()._points.size() );
01414 
01415     unsigned int i=0;
01416     for( OctreeDataPoints::iterator it = cell->getData()._points.begin() ; it != cell->getData()._points.end() ; ++it )
01417     {
01418         result[i] = (*it)->getInitNormal();
01419         ++i;
01420     }
01421 
01422     return result;
01423 }
01424 
01425 OctreeDataPoints& Octree::getMeshVertices()
01426 {
01427     return root()->getData()._points;
01428 }
01429 
01430 } // X3D
01431 
01432 } // X3DTK
01433 
01434 
01435 
01436 

Generated on Thu Dec 23 13:52:26 2004 by doxygen 1.3.6