Documentation


ConstrainedVertex.cpp

Go to the documentation of this file.
00001 /***************************************************************************
00002                           ConstrainedVertex.cpp  -  description
00003                              -------------------
00004     begin                : Wed Jan 14 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 #include "ConstrainedVertex.h"
00019 #include "octree_instanciation.h"
00020 
00021 #include <set>
00022 #include "SFVec3fCellConstrained.h"
00023 #include <iostream>
00024 using std::cerr;
00025 using std::endl;
00026 
00027 #include "Octree.h"
00028 
00029 
00030 namespace animal
00031 {
00032 namespace octree
00033 {
00037 ConstrainedVertex::ConstrainedVertex(   Vec3d position, CVertex *cv1, CVertex *cv2, CVertex *cv3, CVertex *cv4,
00038                                       CVertex *cv5, CVertex *cv6, CVertex *cv7, CVertex *cv8,
00039                                       Cell *connectedCell ) :
00040         _position(position),
00041         _velocity(0,0,0),
00042         _mass(0),
00043         _fatherCell(connectedCell), _mainCell(NULL), _geoLink(NULL)
00044     , _lastConstrainedDepth(0)
00045 {
00046 
00047     std::vector<ConstrainedVertex*> parents(8);
00048     std::vector<unsigned short> empty(0);
00049     parents[0] = cv1;
00050     parents[1] = cv2;
00051     parents[2] = cv3;
00052     parents[3] = cv4;
00053     parents[4] = cv5;
00054     parents[5] = cv6;
00055     parents[6] = cv7;
00056     parents[7] = cv8;
00057 
00058     _geoLink = new GeoLink( parents, empty, true, this );
00059     //updateFrame();
00060     
00061     Ensure( isFree() );
00062 }
00063 
00064 // ROOT
00065 ConstrainedVertex::ConstrainedVertex( Vec3d position,  Cell *connectedCell ) :
00066         _position(position),
00067         _velocity(0,0,0),
00068         _mass(0),
00069         _fatherCell(connectedCell), _mainCell(NULL), _geoLink(NULL)
00070     ,_lastConstrainedDepth(0)
00071 {
00072 
00073     Ensure( (isFree()) && (this->get_Vec3d() == position) );
00074     Ensure( nChildren() == 0 );
00075     
00076     //updateFrame();
00077 }
00078 
00079 
00080 ConstrainedVertex::ConstrainedVertex( FloatingPointType x, FloatingPointType y, FloatingPointType z, Cell *connectedCell ) :
00081         _position(Vec3d(x,y,z)),
00082         _velocity(0,0,0),
00083         _mass(0),
00084         _fatherCell(connectedCell), _mainCell(NULL), _geoLink(NULL)
00085     ,_lastConstrainedDepth(0)
00086 {
00087     //updateFrame();
00088     Ensure( (isFree()) && (this->get_Vec3d() == Vec3d(x,y,z)) );
00089     Ensure( nChildren() == 0 );
00090 }
00091 
00092 
00093 ConstrainedVertex::ConstrainedVertex( const ConstrainedVertex & cmsv )
00094 {
00095     copyAllData( cmsv );
00096 }
00097 
00098 
00099 ConstrainedVertex & ConstrainedVertex ::operator=( const ConstrainedVertex & cmsv )
00100 {
00101     copyAllData( cmsv );
00102     return *this;
00103 }
00104 
00105 
00106 
00107 
00108 
00109 ConstrainedVertex::~ConstrainedVertex()
00110 {
00111     Require( nChildren() == 0 );
00112     if( nChildren() != 0 )
00113     {
00114         std::cerr << "This is " << this << " of depth " << this->getDepth() << "\n";
00115         std::cerr << *(getMainCell()) << "\n";
00116         std::cerr << "My children are :\n";
00117         for( unsigned int i=0 ; i<nChildren(); ++i )
00118         {
00119             std::cerr << "\tchild["<<i<<"] = " << child(i) << " of depth " << child(i)->getDepth() << "\n";
00120             std::cerr << "\t\tIt's main cell is " << child(i)->getMainCell() << " of depth " << child(i)->getMainCell()->getData()._depth << "and vId is " << child(i)->getMainCellVertexId() << "\n";
00121             std::cerr << "\t\t" << *(child(i)->getMainCell()) << "\n";
00122         }
00123         exit(0);
00124     }
00125 
00126     if( _geoLink != NULL )
00127     {
00128         delete _geoLink;
00129         _geoLink = NULL;
00130     }
00131 
00132     // Unregister the cells
00133     Require( nConnectedCells() ==0 );
00134     while( nConnectedCells() !=0 )
00135     {
00136         this->unregisterCell(this->connectedCell(0));
00137     }
00138 
00139     // Unregister this vertex from our parents childs
00140     // This is done in the destructor of GeoLink
00141     /*
00142     for( unsigned short i=0 ; i<this->_geoLink->getNGeoParents() ; ++i )
00143     {
00144         std::cerr << "For our parent " << i << "\n";
00145         if( this->_geoLink->getGeoParent(i)->isChild(this) )
00146         {
00147             std::cerr << "Removing us from our parent's children list\n";
00148             this->_geoLink->getGeoParent(i)->removeChild(this);
00149         }
00150         std::cerr << "For our parent " << i << " End\n";
00151     }
00152     */
00153 
00154 
00155 }
00156 
00157 
00158 void ConstrainedVertex::copyAllData( const ConstrainedVertex & cmsv )
00159 {
00160 
00161     for( unsigned short i = 0 ; i<3 ; ++i )
00162         _positionROPointer[i] = cmsv._positionROPointer[i];
00163 
00164     _connectedCells = cmsv._connectedCells;
00165 
00166     _position = cmsv._position;
00167     _childs = cmsv._childs;
00168     _data = cmsv._data;
00169     _geoLink = new GeoLink( *cmsv._geoLink );
00170     _fatherCell = cmsv._fatherCell;
00171     _frame = cmsv._frame;
00172     _vertexId = cmsv._vertexId;
00173     _mainCell = cmsv._mainCell;
00174 
00175     std::cerr << "WARNING : copy All Data :\n";
00176     if( _mainCell != NULL )
00177         std::cerr << "\tmaincell is " << *_mainCell << "\n";
00178     getchar();
00179 }
00180 
00181 
00182 /*****************
00183  * End of constructors / desctructor
00184  */
00185 
00188 bool ConstrainedVertex::isFree() const
00189 {
00190     if( _geoLink == NULL )
00191         // ROOT VERTEX
00192         return true;
00193     else
00194         return _geoLink->isFree();
00195 }
00196 
00198 Vec3d ConstrainedVertex::get_Vec3d() const
00199 {
00200     return _position;
00201 }
00202 
00203 
00207 ConstrainedVertex::operator const FloatingPointType*()
00208 {
00209     Vec3d vec3d = this->get_Vec3d();
00210 
00211     _positionROPointer[0] = vec3d[0];
00212     _positionROPointer[1] = vec3d[1];
00213     _positionROPointer[2] = vec3d[2];
00214 
00215     return _positionROPointer;
00216 }
00217 
00218 FloatingPointType ConstrainedVertex::operator[]( int id ) const
00219 {
00220     return this->get_Vec3d()[id];
00221 }
00222 
00223 FloatingPointType* ConstrainedVertex::get_FloatingPointTypePointerCopy() const
00224 {
00225     Vec3d vec3d = this->get_Vec3d();
00226 
00227     FloatingPointType *toReturn = (FloatingPointType*) malloc( sizeof(FloatingPointType)*3 );
00228     toReturn[0] = vec3d[0];
00229     toReturn[1] = vec3d[1];
00230     toReturn[2] = vec3d[2];
00231 
00232     return toReturn;
00233 }
00234 
00235 
00236 
00237 
00238 
00244 // void ConstrainedVertex::set( FloatingPointType x, FloatingPointType y, FloatingPointType z, unsigned int depth ){
00245 //  this->set( Vec3d(x,y,z), depth );
00246 // }
00247 // void ConstrainedVertex::set( Vec3d newPos, unsigned int depth )
00248 // {
00249 //  if( isFree() )
00250 //  {
00251 //      //updateChildrensPosition( newPos - _position, depth );
00252 //      updateChildrensPositionOptimized( newPos - _position, depth );
00253 //      clearDelta();
00254 //      addDelta( newPos-_position );
00255 //      _position = newPos;
00256 //  }
00257 //
00258 //  else
00259 //  {
00260 //      updateChildrensPositionOptimizedNotFree( newPos - _position );
00261 //  }
00262 //
00263 // }
00264 
00265 
00266 typedef struct
00267 {
00268     ConstrainedVertex *_vertex;
00269     Vec3d _vecToAdd;
00270 }
00271 UpdateChildrensPositionOptimizedData;
00272 
00273 struct UpdateChildrensPositionOptimizedDataLess
00274 {
00275     bool operator()( const UpdateChildrensPositionOptimizedData & d1,
00276                      const UpdateChildrensPositionOptimizedData &d2 ) const
00277     {
00278         return d1._vertex < d2._vertex;
00279     }
00280 };
00281 
00282 bool operator<( const UpdateChildrensPositionOptimizedData & d1,
00283                 const UpdateChildrensPositionOptimizedData &d2 )
00284 {
00285     return d1._vertex < d2._vertex;
00286 }
00287 bool operator!=( const UpdateChildrensPositionOptimizedData & d1,
00288                  const UpdateChildrensPositionOptimizedData &d2 )
00289 {
00290     return d1._vertex != d2._vertex;
00291 }
00292 
00293 
00294 void ConstrainedVertex::updateChildrensPositionOptimized( Vec3d v, unsigned int depth )
00295 {
00296     /*
00297      * Invariant : un element (unique par son pointeur) n'est qu'une seule fois dans le set
00298      */
00299 
00300     typedef std::map<ConstrainedVertex*,Vec3d> map;
00301     typedef std::deque<ConstrainedVertex*> list;
00302 
00303     map toAddMap;
00304     list vertexList;
00305 
00306     for( unsigned int i=0 ; i<_childs.size() ; i++ )
00307     {
00308         // Note : Could perhaps avoid some of this
00309         if( (_childs[i]->getDepth() > depth) || !_childs[i]->isFree() )
00310         {
00311             if( _childs[i]->getGeoLink()->isGeoLinkParent(this) )
00312             {
00313                 _childs[i]->setDelta( Vec3d(0,0,0) );
00314                 toAddMap[_childs[i]] = v / _childs[i]->getGeoLink()->getNGeoParents();
00315                 vertexList.push_back( _childs[i] );
00316             }
00317         }
00318     }
00319 
00320     for( list::iterator it = vertexList.begin() ; it != vertexList.end() ; ++it )
00321     {
00322         (*it)->setDelta( Vec3d(0,0,0) );
00323     }
00324 
00325     while( !vertexList.empty() )
00326     {
00327         ConstrainedVertex* d = vertexList.front();
00328         vertexList.pop_front();
00329 
00330         for( unsigned i=0 ; i<d->_childs.size() ; ++i )
00331         {
00332             if( d->_childs[i]->getGeoLink()->isGeoLinkParent(d) )
00333             {
00334                 // We need to add some Vec to this child
00335                 Vec3d vecToAdd = toAddMap[d] / d->_childs[i]->getGeoLink()->getNGeoParents();
00336 
00337                 // Now find it in the other list to see if we need to add it
00338 
00339                 if( toAddMap.find(d->_childs[i]) == toAddMap.end() )
00340                 {
00341                     // The child was not in the list before, so add it
00342                     //std::cerr << "Adding\n";
00343                     d->_childs[i]->setDelta( Vec3d(0,0,0) );
00344                     toAddMap[d->_childs[i]] = vecToAdd;
00345                     vertexList.push_back(d->_childs[i]);
00346                 }
00347                 else
00348                 {
00349                     // Just add it
00350                     toAddMap[d->_childs[i]] += vecToAdd;
00351                 }
00352             }
00353             else
00354             {
00355                 // Perphaps no else !!!
00356             }
00357         }
00358 
00359         d->setPosition( d->_position + toAddMap[d] );
00360 
00361         d->setDelta( d->getDelta() + toAddMap[d] );
00362     }
00363 
00364 }
00365 
00366 
00367 // void ConstrainedVertex::addDelta( Vec3d d )
00368 // {
00369 //  _delta += d;
00370 // }
00371 //
00372 // void ConstrainedVertex::clearDelta()
00373 // {
00374 //  _delta = Vec3d(0,0,0);
00375 // }
00376 //
00377 // Vec3d ConstrainedVertex::getDelta() const
00378 // {
00379 //  return _delta;
00380 // }
00381 
00382 void ConstrainedVertex::updateChildrensPositionOptimizedNotFree( Vec3d v )
00383 {
00384     /*
00385      * Invariant : un element (unique par son pointeur) n'est qu'une seule fois dans le set
00386      */
00387 
00388     Require( !isFree() );
00389 
00390     typedef std::map<ConstrainedVertex*,Vec3d> map;
00391     typedef std::deque<ConstrainedVertex*> list;
00392 
00393     map toAddMap;
00394     list vertexList;
00395 
00396 
00397     // Find the list of free parents
00398     list tmpParents;
00399     tmpParents.push_front( this );
00400     while( !tmpParents.empty() )
00401     {
00402         ConstrainedVertex* cour = tmpParents.front();
00403         Require( !cour->isFree() );
00404 
00405         tmpParents.pop_front();
00406 
00407         for( unsigned int i=0 ; i<cour->getGeoLink()->getNGeoParents() ; ++i )
00408         {
00409             ConstrainedVertex* parent = cour->getGeoLink()->getGeoParent(cour->getGeoLink()->getGeoParentId(i));
00410             if( !parent->isFree() )
00411             {
00412                 tmpParents.push_back( parent );
00413             }
00414             else
00415             {
00416                 // Ok, we can add it to the vertexList and map;
00417                 // Only if it's not already in the map
00418                 if( toAddMap.find(parent) == toAddMap.end() )
00419                 {
00420                     toAddMap[ parent ] = v;
00421                     vertexList.push_back( parent );
00422                 }
00423             }
00424         }
00425     }
00426 
00427     for( list::iterator it = vertexList.begin() ; it != vertexList.end() ; ++it )
00428     {
00429         (*it)->setDelta( Vec3d(0,0,0) );
00430     }
00431     /*
00432     for( unsigned int i=0 ; i<_childs.size() ; i++ )
00433     {
00434         // Note : Could perhaps avoid some of this
00435         if( (_childs[i]->getDepth() > depth) || !_childs[i]->isFree() )
00436         {
00437             if( _childs[i]->getGeoLink()->isGeoLinkParent(this) )
00438             {
00439                 toAddMap[_childs[i]] = v / _childs[i]->getGeoLink()->getNGeoParents();
00440                 vertexList.push_back( _childs[i] );
00441             }
00442         }
00443     }
00444     */
00445 
00446     while( !vertexList.empty() )
00447     {
00448         ConstrainedVertex* d = vertexList.front();
00449         vertexList.pop_front();
00450 
00451         for( unsigned i=0 ; i<d->_childs.size() ; ++i )
00452         {
00453             if( d->_childs[i]->getGeoLink()->isGeoLinkParent(d) )
00454             {
00455                 // We need to add some Vec to this child
00456                 Vec3d vecToAdd = toAddMap[d] / d->_childs[i]->getGeoLink()->getNGeoParents();
00457 
00458                 // Now find it in the other list to see if we need to add it
00459 
00460                 if( toAddMap.find(d->_childs[i]) == toAddMap.end() )
00461                 {
00462                     // The child was not in the list before, so add it
00463                     //std::cerr << "Adding\n";
00464                     d->_childs[i]->setDelta( Vec3d(0,0,0) );
00465                     toAddMap[d->_childs[i]] = vecToAdd;
00466                     vertexList.push_back(d->_childs[i]);
00467                 }
00468                 else
00469                 {
00470                     // Just add it
00471                     toAddMap[d->_childs[i]] += vecToAdd;
00472                 }
00473             }
00474             else
00475             {
00476                 // Perphaps no else !!!
00477             }
00478         }
00479 
00480         d->_position += toAddMap[d];
00481         d->setDelta( d->getDelta() + toAddMap[d] );
00482     }
00483 
00484 }
00485 
00486 
00487 
00488 
00489 
00490 /*
00491 *
00492  * Update the position of our children
00493  * This is called for example when we are moving the vertex
00494  * We will then have to tell our children that we have moved
00495  */
00496 void ConstrainedVertex::updateChildrensPosition( Vec3d v, unsigned int depth )
00497 {
00498     for( unsigned int i=0 ; i<_childs.size() ; i++ )
00499     {
00500         if( _childs[i]->getDepth() > depth )
00501         {
00502             _childs[i]->updatePosition( this, v );
00503         }
00504         else if( !_childs[i]->isFree() )
00505         {
00506             // TODO !!
00507             _childs[i]->updateConstrainedChildrensPosition( v, depth );
00508         }
00509     }
00510 }
00511 
00512 void ConstrainedVertex::updateConstrainedChildrensPosition( Vec3d v, unsigned int depth )
00513 {
00514     depth = 0;
00515     exit(0);
00516     Require( !isFree() );
00517 
00518     Vec3d newPos = _position + v / this->getGeoLink()->getNGeoParents();
00519     for( unsigned int i=0 ; i<_childs.size() ; i++ )
00520     {
00521         if( !_childs[i]->isFree() )
00522             // depth 0 because this vertex can never have children of depth superior
00523             updateConstrainedChildrensPosition( newPos - _position, 0 );
00524 
00525     }
00526     _position = newPos;
00527 }
00528 
00529 
00530 
00531 
00532 void ConstrainedVertex::updatePosition( ConstrainedVertex *parent, Vec3d v )
00533 {
00534     Require( _geoLink != NULL );
00535     if( this->getGeoLink()->isGeoLinkParent(parent) )
00536     {
00537         Vec3d newPos = _position + v / this->getGeoLink()->getNGeoParents();
00538         // depth 0 because this vertex can never have children of depth superior
00539         updateChildrensPosition( newPos - _position, 0 );
00540         _position = newPos;
00541     }
00542 
00543 }
00544 
00545 
00546 
00547 
00548 ConstrainedVertex::operator const Vec3d() const
00549 {
00550     return get_Vec3d();
00551 }
00552 
00556 void ConstrainedVertex::freeIt()
00557 {
00558     Require( !isFree() );
00559     Require( _geoLink != NULL );
00560 
00561     this->getGeoLink()->freeIt();
00562 
00563     Ensure( isFree() );
00564     //updateFrame();
00565 }
00566 
00567 
00568 /*
00569  * Only a geo link for MR edition
00570  */
00571 void ConstrainedVertex::softLinkIt( ConstrainedVertex* cv1, ConstrainedVertex* cv2 )
00572 {
00573     Require( _geoLink != NULL );
00574 
00575     this->getGeoLink()->softLinkIt( cv1, cv2 );
00576     //  std::cerr << "\tLink position is : " << this->getGeoLink()->getPosition() << "\n";
00577     setValue( POS, getPosition() );
00578     //cerr<<"ConstrainedVertex::softLinkIt, init POS to: "<< value(POS) << endl;
00579     computeValueFromRelatives( VEL );
00580 
00581 }
00582 void ConstrainedVertex::softLinkIt( ConstrainedVertex* cv1, ConstrainedVertex* cv2, ConstrainedVertex* cv3, ConstrainedVertex* cv4 )
00583 {
00584     Require( _geoLink != NULL );
00585 
00586     this->getGeoLink()->softLinkIt( cv1, cv2, cv3, cv4 );
00587     //updateFrame();
00588     setValue( POS, getPosition() );
00589     //cerr<<"ConstrainedVertex::softLinkIt, init POS to: "<< value(POS) << endl;
00590     computeValueFromRelatives( VEL );
00591 }
00592 
00593 void ConstrainedVertex::softLinkIt( ConstrainedVertex* cv1, ConstrainedVertex* cv2, ConstrainedVertex* cv3, ConstrainedVertex* cv4, ConstrainedVertex* cv5, ConstrainedVertex* cv6, ConstrainedVertex* cv7, ConstrainedVertex* cv8 )
00594 {
00595     Require( _geoLink != NULL );
00596 
00597     this->getGeoLink()->softLinkIt( cv1, cv2, cv3, cv4, cv5, cv6, cv7, cv8 );
00598     //updateFrame();
00599     setValue( POS, getPosition() );
00600     //cerr<<"ConstrainedVertex::softLinkIt, init POS to: "<< value(POS) << endl;
00601     computeValueFromRelatives( VEL );
00602 }
00603 
00604 
00605 void ConstrainedVertex::hardLinkIt( ConstrainedVertex* cv1, ConstrainedVertex* cv2, ConstrainedVertex* cv3, ConstrainedVertex* cv4 )
00606 {
00607     Require( isFree() );
00608     Require( _geoLink != NULL );
00609 
00610     this->getGeoLink()->hardLinkIt( cv1, cv2, cv3, cv4 );
00611 
00612     //set( this->getGeoLink()->getPosition() );
00613 
00614     Ensure( !isFree() );
00615     
00616     // on pourrait se limiter à la vitesse et la masse ?
00617     setValue( POS, getPosition() );
00618     computeValueFromParents( VEL );
00619     //cerr<<"ConstrainedVertex::hardLinkIt, init POS to: "<< value(POS) << endl;
00620 //     for( int i=0; i<NB_AUXILIARY_VECTORS; ++i ){
00621 //         cerr<<"ConstrainedVertex::hardLinkIt, value "<<i<<" = "<<value(i)<<endl;
00622 //     }
00623 
00624 
00625 }
00629 void ConstrainedVertex::hardLinkIt( ConstrainedVertex* cv1, ConstrainedVertex* cv2 )
00630 {
00631     Require( isFree() );
00632     Require( _geoLink != NULL );
00633 
00634     this->getGeoLink()->hardLinkIt( cv1, cv2 );
00635 
00636     //set( this->getGeoLink()->getPosition() );
00637 
00638     //updateFrame();
00639 
00640     Ensure( !isFree() );
00641     
00642     // on pourrait se limiter à la vitesse et la masse ?
00643     setValue( POS, getPosition() );
00644     //cerr<<"ConstrainedVertex::hardLinkIt, init POS to: "<< value(POS) << endl;
00645     computeValueFromParents( VEL );
00646 /*    for( int i=0; i<NB_AUXILIARY_VECTORS; ++i ){
00647         cerr<<"ConstrainedVertex::hardLinkIt, value "<<i<<" = "<<value(i)<<endl;
00648     }*/
00649 }
00650 
00651 
00652 
00657 /*
00658 void ConstrainedVertex::linkIt( ConstrainedVertex* cv1, ConstrainedVertex* cv2 ){
00659     Require( isFree() );
00660     Require( _geoLink != NULL );
00661     
00662     this->getGeoLink()->hardLinkIt( cv1, cv2 );
00663     set( this->getGeoLink()->getPosition() );
00664     
00665     Ensure( !isFree() );
00666 }
00667 */
00671 /*
00672 void ConstrainedVertex::linkIt( ConstrainedVertex* cv1, ConstrainedVertex* cv2, ConstrainedVertex* cv3, ConstrainedVertex* cv4 ){
00673     Require( isFree() );
00674     Require( _geoLink != NULL );
00675     
00676     this->getGeoLink()->hardLinkIt( cv1, cv2, cv3, cv4 );
00677     set( this->getGeoLink()->getPosition() );
00678     
00679     Ensure( !isFree() );
00680 }
00681 */
00682 
00686 bool ConstrainedVertex::isChild( const ConstrainedVertex *cv ) const
00687 {
00688     for( unsigned int i=0 ; i<_childs.size() ; i++ )
00689         if( _childs[i] == cv )
00690             return true; // Found
00691 
00692     return false;
00693 }
00694 
00699 void ConstrainedVertex::addChild( ConstrainedVertex *cv )
00700 {
00701     Require( !isChild(cv) );
00702     //std::cerr << "addChild : cv is " << cv << " and this is " << this << "\n";
00703     //Require( cv->isParent(this) );
00704 
00705     _childs.push_back(cv);
00706 
00707     Ensure( isChild(cv) );
00708 }
00713 void ConstrainedVertex::removeChild( ConstrainedVertex *cv )
00714 {
00715     Require( isChild(cv) );
00716     _childs.erase( _childs.begin() + getChildPos(cv) );
00717     Ensure( !isChild(cv) );
00718 }
00719 
00723 unsigned int ConstrainedVertex::getChildPos( ConstrainedVertex *cv ) const
00724 {
00725     Require( isChild(cv) );
00726     unsigned int i;
00727     for( i=0 ; i<_childs.size() ; i++ )
00728         if( _childs[i] == cv )
00729             break;
00730 
00731     return i;
00732 }
00733 
00734 
00738 ConstrainedVertex * ConstrainedVertex::child( const unsigned int pos ) const
00739 {
00740     Require( pos < nChildren() );
00741     return _childs[pos];
00742 }
00743 
00744 unsigned int ConstrainedVertex::nChildren() const
00745 {
00746     return _childs.size();
00747 }
00748 
00749 
00750 
00751 bool ConstrainedVertex::isParent( const ConstrainedVertex *cv ) const
00752 {
00753     std::cerr << "isParent() : cv is " << cv << " and this is " << this << "\n";
00754     return getGeoLink()->isParent(cv);
00755 }
00756 
00757 
00758 
00759 
00760 
00767 void ConstrainedVertex::registerCell( Cell *connectedCell )
00768 {
00769     Require( !isConnected( connectedCell ) );
00770     //  Require( nConnectedCells() != 8 );
00771 
00772     //  _connectedCells[ nConnectedCells() ] = connectedCell;
00773     _connectedCells.push_back( connectedCell );
00774 
00775     Ensure( isConnected( connectedCell ) );
00776     //  Ensure( nConnectedCells() <= 8 );
00777 }
00778 
00782 void ConstrainedVertex::unregisterCell( const Cell* unconnectedCell )
00783 {
00784     Require( isConnected( unconnectedCell ) );
00785 
00786     deque<Cell*>::iterator it;
00787     for( it = _connectedCells.begin() ; (it != _connectedCells.end()) && (*it != unconnectedCell) ; ++it )
00788         ;
00789 
00790     Require( it != _connectedCells.end() );
00791     _connectedCells.erase( it );
00792 
00793     /*
00794     unsigned short c;
00795     for( c=0 ; c<nConnectedCells() ; ++c )
00796         if( connectedCell( c ) == unconnectedCell )
00797             break;
00798 
00799     // Replace it by the last connectedCell
00800     _connectedCells[ c ] = connectedCell(nConnectedCells()-1);
00801     */
00802 
00803     Ensure( !isConnected( unconnectedCell ) );
00804 }
00807 unsigned short ConstrainedVertex::nConnectedCells() const
00808 {
00809     //  Ensure( _connectedCells.size() <= 8 );
00810     /*
00811     if( _connectedCells.size() > 8 )
00812     {
00813         std::cerr << "Size is : " << _connectedCells.size() << "\n";
00814         for( unsigned int i=0 ; i<_connectedCells.size() ; ++i)
00815             std::cerr << "Cell : " << _connectedCells[i] << " ";
00816         std::cerr << "\n";
00817     }
00818     */
00819     return _connectedCells.size();
00820 }
00824 Cell* ConstrainedVertex::connectedCell( unsigned short id ) const
00825 {
00826     Require( id < nConnectedCells() );
00827 
00828     return _connectedCells[id];
00829 }
00831 bool ConstrainedVertex::isConnected( const Cell* cell ) const
00832 {
00833     unsigned short c;
00834     for( c=0 ; c<nConnectedCells() ; ++c )
00835         if( connectedCell( c ) == cell )
00836             break;
00837     if( c == nConnectedCells() )
00838         return false;
00839     else
00840         return true;
00841 }
00842 
00843 
00844 Cell* ConstrainedVertex::fatherCell() const
00845 {
00846     return _fatherCell;
00847 }
00848 
00849 unsigned int ConstrainedVertex::getDepth() const
00850 {
00851     /*
00852         if( fatherCell() == NULL )
00853             return 0;
00854         else
00855             return fatherCell()->getData()._depth+1;
00856         */
00857     return getMainCell()->getData()._depth;
00858 }
00859 
00860 
00861 void ConstrainedVertex::setData( const ConstrainedVertexData& d )
00862 {
00863     _data = d;
00864 }
00865 ConstrainedVertexData ConstrainedVertex::getData( ) const
00866 {
00867     return _data;
00868 }
00869 
00870 
00871 Vec3d ConstrainedVertex::getPosition() const
00872 {
00873     return get_Vec3d();
00874 }
00875 
00876 GeoLink* ConstrainedVertex::getGeoLink() const
00877 {
00878     Require( _geoLink != NULL );
00879     return _geoLink;
00880 }
00881 
00882 
00883 ConstrainedVertex*   ConstrainedVertex::getSmallestCellsFreeVertexSharingFaceForVertex( Cell *neighbour, unsigned int face, unsigned int vertex )
00884 {
00885     //  Require( !neighbour->isLeaf() );
00886 
00887     unsigned int direction;
00888     if( face <= 1 )
00889         direction = 0; //x
00890     else if( face >= 4 )
00891         direction = 2; //z
00892     else
00893         direction = 1; //y
00894 
00895     Cell* res = neighbour;
00896     //  unsigned int childPos = Cell::connectedVertices[vertex][direction];
00897 
00898     if( !res->vertex(vertex)->isFree() )
00899     {
00900         do
00901         {
00902             res = res->father();
00903         }
00904         while( !res->vertex(vertex)->isFree() );
00905         Ensure( res->vertex(vertex)->isFree() );
00906         return res->vertex(vertex);
00907     }
00908 
00909     Cell *prec = NULL;
00910 
00911     while( !res->isLeaf() && res->vertex(vertex)->isFree() )
00912     {
00913         prec = res;
00914         res = res->child(vertex);
00915     }
00916 
00917     if( !res->vertex(vertex)->isFree() )
00918     {
00919         Require( prec != NULL );
00920         Ensure( prec->vertex(vertex)->isFree() );
00921         return prec->vertex(vertex);
00922     }
00923     else
00924     {
00925         Ensure( res->vertex(vertex)->isFree() );
00926         return res->vertex(vertex);
00927     }
00928 }
00929 
00930 
00931 /*
00932  * Not really free...
00933  * We will not get a free vertex if !res->vertex(connectedVertexId)->isFree()
00934  */
00935 Cell*    ConstrainedVertex::getCellWithFreeVertexConnectedToVertex( Cell *cell, unsigned int direction, unsigned int vertexId ) const
00936 {
00937     Require( direction < 3 );
00938     Require( vertexId < 8 );
00939     Require( cell != NULL );
00940 
00941     Cell* res = cell;
00942     unsigned int connectedVertexId = TempOctree::Cell::connectedVertices[vertexId][direction];
00943 
00944     if( !res->vertex(connectedVertexId)->isFree() )
00945     {
00946         return res;
00947         /*
00948         // Then go up in the hierarchy
00949         do
00950         {
00951             res = res->father();
00952         }
00953         while( !res->vertex(connectedVertexId)->isFree() );
00954         Ensure( res->vertex(connectedVertexId)->isFree() );
00955         return res;
00956         */
00957     }
00958 
00959     Cell *prec = NULL;
00960 
00961     while( !res->isLeaf() && res->vertex(connectedVertexId)->isFree() )
00962     {
00963         prec = res;
00964         res = res->child(vertexId);
00965     }
00966 
00967     if( !res->vertex(connectedVertexId)->isFree() )
00968     {
00969         Require( prec != NULL );
00970         Ensure( prec->vertex(connectedVertexId)->isFree() );
00971         return prec;
00972     }
00973     else
00974     {
00975         Ensure( res->vertex(connectedVertexId)->isFree() );
00976         return res;
00977     }
00978 }
00979 
00980 
00984 void ConstrainedVertex::updateFrame()
00985 {
00986     _frame = computeFrame();
00987 }
00988 
00989 
00990 Frame ConstrainedVertex::computeFrame()
00991 {
00992 /*  ConstrainedVertex *_connectedVertices[2];
00993     FloatingPointType _connectedVerticesFactors[2];*/
00994     
00995     Require( hasMainCell() );
00996     
00997     Cell *neighbours[3];
00998     
00999     for( unsigned int i=0 ; i<3 ; ++i )
01000     {
01001         neighbours[i] = _mainCell->uncleSharingFace(TempOctree::verticesConnectedFaces[_vertexId][i]);
01002     }
01003     
01004     Vec3d vecs[3];
01005 
01006     Cell *cell = _mainCell ;
01007     
01008     while( !cell->isLeaf() )
01009     {
01010         cell = cell->child( this->getMainCellVertexId() );
01011     }
01012     
01013     cell = getVertexFreeCell(cell,this);
01014     
01015     
01016     for( unsigned short i=0 ; i<3 ; ++i )
01017     {
01018         neighbours[i] = cell->uncleSharingFace(TempOctree::verticesConnectedFaces[_vertexId][i]);
01019     
01020         Cell *connectedCell = getCellWithFreeVertexConnectedToVertex( cell, i, _vertexId );
01021     
01022         vecs[i] = connectedCell->vertex(Cell::connectedVertices[_vertexId][i])->getPosition() - this->getPosition();
01023         
01024         _connectedVertices[i][0] = connectedCell->vertex(Cell::connectedVertices[_vertexId][i]);
01025         _connectedVertices[i][1] = NULL;
01026         
01027         _connectedVerticesFactors[i][0] = 1.0;
01028         _connectedVerticesFactors[i][1] = 0.0;
01029         
01030         
01031     
01032         if( neighbours[i] == NULL )
01033         {
01034         // That's ok we've got it
01035         }
01036         else
01037         {
01038             vecs[i] = Vec3d(0,0,0);
01039             unsigned int dim = 0;
01040             
01041             vecs[i] += this->getPosition() - neighbours[i]->vertex(_vertexId)->getPosition();
01042             dim++;
01043         
01044             
01045             Cell *cFather = connectedCell;
01046         
01047             while( cFather->getData()._depth > neighbours[i]->getData()._depth )
01048             {
01049                 cFather = cFather->father();
01050             }
01051         
01052             vecs[i] += cFather->vertex(Cell::connectedVertices[_vertexId][i])->getPosition() - this->getPosition();
01053             dim++;
01054         
01055             
01056             vecs[i] /= dim;
01057             
01058             _connectedVertices[i][0] = cFather->vertex(Cell::connectedVertices[_vertexId][i]);
01059             _connectedVertices[i][1] = neighbours[i]->vertex(_vertexId);
01060         
01061             _connectedVerticesFactors[i][0] = 0.5;
01062             _connectedVerticesFactors[i][1] = -0.5;
01063         }
01064     
01065     }
01066     
01067     
01068     if( TempOctree::hasBrotherAlongFace[_vertexId][0] )
01069     {
01070         vecs[0] *= -1;
01071         _connectedVerticesFactors[0][0] *= -1.0;
01072         _connectedVerticesFactors[0][1] *= -1.0;
01073     }
01074     if( TempOctree::hasBrotherAlongFace[_vertexId][2] )
01075     {
01076         vecs[1] *= -1;
01077         _connectedVerticesFactors[1][0] *= -1.0;
01078         _connectedVerticesFactors[1][1] *= -1.0;
01079     }
01080     if( TempOctree::hasBrotherAlongFace[_vertexId][4] )
01081     {
01082         vecs[2] *= -1;
01083         _connectedVerticesFactors[2][0] *= -1.0;
01084         _connectedVerticesFactors[2][1] *= -1.0;
01085     }
01086     
01087 
01088     return Frame(this->getPosition(),vecs[0],vecs[1],vecs[2]);
01089 }
01090 
01091 //
01092 // return the smallest depth not constrained
01093 //
01094 unsigned int ConstrainedVertex::getConstrainedDepth() const
01095 {
01096     int maxNCells = 0;
01097     
01098     Cell *neighbours[3];
01099     neighbours[0] = this->getMainCell()->getNeighbour( TempOctree::verticesConnectedFaces[_vertexId][0] );
01100     neighbours[1] = this->getMainCell()->getNeighbour( TempOctree::verticesConnectedFaces[_vertexId][1] );
01101     neighbours[2] = this->getMainCell()->getNeighbour( TempOctree::verticesConnectedFaces[_vertexId][2] );
01102     
01103     if( neighbours[0] )
01104         maxNCells++;
01105     if( neighbours[1] )
01106         maxNCells++;
01107     if( neighbours[2] )
01108         maxNCells++;
01109     
01110     if( maxNCells == 0 )
01111     {
01112         maxNCells = 1;
01113     }
01114     else
01115     {
01116         maxNCells = 1 << maxNCells;
01117     }
01118     
01119     // 1, 2, 4 or 8 cells of the same depth must meet !
01120     // => maxNCells
01121     
01122 //  std::cerr << "Need to find " << maxNCells << " cells for " << *this->getMainCell() << " and ID is " << _vertexId << "\n";
01123     
01124     // on depth, give the number of cells
01125     std::map< int, int> nCellsOfDepth;
01126     for( unsigned int i=0 ; i<this->nConnectedCells() ; ++i )
01127     {
01128         nCellsOfDepth[this->connectedCell(i)->getData()._depth] += 1;
01129     }
01130     
01131     int deepest = -1;
01132     for( std::map< int, int>::iterator it=nCellsOfDepth.begin() ;
01133         it != nCellsOfDepth.end() ; ++it )
01134     {
01135 //      std::cerr << "\tFor depth " << it->first << " Got " << it->second << " cells\n";
01136 //      std::cerr << "Deepest is " << deepest << " and res " << (it->first > deepest) << "\n";
01137 //      std::cerr << "maxNCells : " << maxNCells << " and res " << (it->second == maxNCells) << "\n";
01138         if( (it->second == maxNCells) && (it->first > deepest) )
01139         {
01140 //          std::cerr << "\t\tGot deeper depth\n";
01141             deepest = it->first;
01142         }
01143     }
01144     
01145     Require( deepest != -1 );
01146     if( deepest == -1 )
01147     {
01148         std::cerr << "Weup deepest !\n";
01149     }
01150     
01151     return deepest;
01152 }
01153 
01154 // Frame ConstrainedVertex::computeFrame() const
01155 // {
01156 //  Require( isFree() );
01157 //  
01158 //  Vec3d pos = this->getPosition();
01159 //  
01160 //  Vec3d vecs[3];
01161 //  
01162 //  Cell *cell = getMainCell();
01163 //  while( !cell->isLeaf() )
01164 //  {
01165 //      cell = cell->child( this->getMainCellVertexId() );
01166 //  }
01167 //  
01168 //  for( unsigned int dir=0 ; dir<3 ; ++dir )
01169 //  {
01170 //      unsigned int nVecs = 0;
01171 //      
01172 //      Vec3d localVec;     unsigned int localDepth=INFINITY;   bool localOk = false;
01173 //      Vec3d neighbourVec; unsigned int neighbourDepth=INFINITY;   bool neighbourOk = false;
01174 //      FloatingPointType localFactor = 1.0;
01175 //      FloatingPointType neighbourFactor = 1.0;
01176 //      
01177 //      unsigned int connectedId = Cell::connectedVertices[_vertexId][dir];
01178 //      unsigned int face = Octree::verticesConnectedFaces[_vertexId][dir];
01179 //      
01180 //      // First find the vertex connected and free in cell or a parent cell
01181 //      Cell *parentCell = cell;
01182 //      
01183 //      while( !parentCell->vertex(connectedId)->isFree() && (parentCell->vertex(connectedId)->getDepth()>this->getDepth()) )
01184 //      {
01185 //          parentCell = parentCell->father();
01186 //      }
01187 //      
01188 //      localVec = parentCell->vertex( connectedId )->getPosition() - pos;
01189 //      localDepth = parentCell->getData()._depth;
01190 //      localOk = true;
01191 //      
01192 //      Cell *neighbour = cell->getNeighbour(face);
01193 //      
01194 //      // Can be something else
01195 //      if( neighbour )
01196 //      {
01197 //          int diffDepth = 0;
01198 //          while( !neighbour->isLeaf() )
01199 //          {
01200 //              neighbour = neighbour->child( connectedId );
01201 //              diffDepth++;
01202 //          }
01203 //          
01204 //          Cell *nParentCell = neighbour;
01205 //          // First find the vertex connected and free in cell or a parent cell
01206 //          while( !nParentCell->vertex(_vertexId)->isFree() && (nParentCell->vertex(_vertexId)->getDepth()>this->getDepth()) )
01207 //          {
01208 //              nParentCell = nParentCell->father();
01209 //              diffDepth--;
01210 //          }
01211 //          
01212 //          Require( diffDepth >= 0 );
01213 //          
01214 //          neighbourVec = nParentCell->vertex( _vertexId )->getPosition() - pos;
01215 //          neighbourDepth = nParentCell->getData()._depth;
01216 //          neighbourOk = true;
01217 //          
01218 //      }
01219 //      
01220 //      unsigned int smallestDepth = fmin(localDepth,neighbourDepth);
01221 //      
01222 //      if( localOk )
01223 //      {
01224 //          if( localDepth > smallestDepth )
01225 //          {
01226 //              localFactor = pow(2.0,localDepth-smallestDepth);
01227 //          }
01228 //          vecs[dir] += localFactor*localVec;
01229 //      }
01230 //      if( neighbourOk )
01231 //      {
01232 //          if( neighbourFactor > smallestDepth )
01233 //          {
01234 //              neighbourFactor = pow(2.0,neighbourFactor-smallestDepth);
01235 //          }
01236 //          vecs[dir] -= neighbourFactor*neighbourVec;
01237 //      }
01238 //      if( localOk && neighbourOk )
01239 //      {
01240 //          vecs[dir] /= 2;
01241 //      }
01242 //  }
01243 //  
01244 //  if( TempOctree::hasBrotherAlongFace[_vertexId][0] )
01245 //             vecs[0] *= -1;
01246 //         if( TempOctree::hasBrotherAlongFace[_vertexId][2] )
01247 //             vecs[1] *= -1;
01248 //         if( TempOctree::hasBrotherAlongFace[_vertexId][4] )
01249 //             vecs[2] *= -1;
01250 //      
01251 //  return Frame( this->getPosition(), vecs[0], vecs[1], vecs[2] );
01252 // }
01253 
01254 
01255 
01256 // Frame ConstrainedVertex::computeFrame() const
01257 // {
01258 //  
01259 //     Require( hasMainCell() );
01260 // 
01261 //     Cell *neighbours[3];
01262 // 
01263 //     for( unsigned int i=0 ; i<3 ; ++i )
01264 //     {
01265 //         neighbours[i] = _mainCell->uncleSharingFace(TempOctree::verticesConnectedFaces[_vertexId][i]);
01266 //     }
01267 // 
01268 //     FloatingPointType constrained = !this->isFree();
01269 //     Vec3d vecs[3];
01270 // 
01271 // 
01272 // 
01273 //     //else
01274 //     if( !constrained )
01275 //     {
01276 //         //std::cerr << "computeFrame : " << *_mainCell << " Id is " << _vertexId << "\n";
01277 //         //Require( _mainCell == getVertexFreeCell(_mainCell,this) );
01278 // 
01279 //         Cell *cell = _mainCell ;
01280 // 
01281 //         while( !cell->isLeaf() )
01282 //         {
01283 //             cell = cell->child( this->getMainCellVertexId() );
01284 //         }
01285 // 
01286 //         cell = getVertexFreeCell(cell,this);
01287 // 
01288 // 
01289 //         for( unsigned short i=0 ; i<3 ; ++i )
01290 //         {
01291 //             neighbours[i] = cell->uncleSharingFace(TempOctree::verticesConnectedFaces[_vertexId][i]);
01292 // 
01293 //             Cell *connectedCell = getCellWithFreeVertexConnectedToVertex( cell, i, _vertexId );
01294 // 
01295 //             vecs[i] = connectedCell->vertex(Cell::connectedVertices[_vertexId][i])->getPosition() - this->getPosition();
01296 // 
01297 //             if( neighbours[i] == NULL )
01298 //             {
01299 //                 // That's ok we've got it
01300 //             }
01301 //             else
01302 //             {
01303 //          vecs[i] = Vec3d(0,0,0);
01304 //      unsigned int dim = 0;
01305 //      
01306 // //       if( this->getMainCell()->getData()._points.size() != 0 )
01307 // //       {
01308 //                  vecs[i] += this->getPosition() - neighbours[i]->vertex(_vertexId)->getPosition();
01309 //          dim++;
01310 // //       }
01311 //      
01312 //                 Cell *cFather = connectedCell;
01313 // 
01314 //                 while( cFather->getData()._depth > neighbours[i]->getData()._depth )
01315 //                 {
01316 //                     cFather = cFather->father();
01317 //                 }
01318 //      
01319 // //       if( neighbours[i]->getData()._points.size() != 0 )
01320 // //       {
01321 //                  vecs[i] += cFather->vertex(Cell::connectedVertices[_vertexId][i])->getPosition() - this->getPosition();
01322 //          dim++;
01323 // //       }
01324 //      
01325 // //       Require( dim );
01326 //      vecs[i] /= dim;
01327 //             }
01328 // 
01329 // 
01330 //             // WARNING
01331 //             // Perhaps we should find the smallest unconstrained vertex here too
01332 //             //Vec3d v1 = getSmallestCellsFreeVertexSharingFaceForVertex( getMainCell(), TempOctree::verticesConnectedFaces[_vertexId][i], _vertexId );
01333 //             //           vecs[i] = _mainCell->vertex(Cell::connectedVertices[_vertexId][i])->getPosition() - this->getPosition();
01334 // 
01335 // 
01336 // 
01337 //         }
01338 // 
01339 // 
01340 //         if( TempOctree::hasBrotherAlongFace[_vertexId][0] )
01341 //             vecs[0] *= -1;
01342 //         if( TempOctree::hasBrotherAlongFace[_vertexId][2] )
01343 //             vecs[1] *= -1;
01344 //         if( TempOctree::hasBrotherAlongFace[_vertexId][4] )
01345 //             vecs[2] *= -1;
01346 // 
01347 // 
01348 //     }
01349 // 
01350 //     //std::cerr << "Finaly le retour " << vecs[2] << "\n";
01351 // 
01352 // 
01353 // //     if( vecs[0] != Vec3d(0.0,0.0,0.0) )
01354 // //         vecs[0] /= vecs[0].norm();
01355 // //     if( vecs[1] != Vec3d(0.0,0.0,0.0) )
01356 // //         vecs[1] /= vecs[1].norm();
01357 // //     if( vecs[2] != Vec3d(0.0,0.0,0.0) )
01358 // //         vecs[2] /= vecs[2].norm();
01359 // 
01360 // 
01361 //     //return Frame(vecs[0],vecs[1],vecs[2],true);
01362 // 
01363 // 
01364 // // vecs[0] *= _mainCell->getData()._initialSize[0];
01365 // // vecs[1] *= _mainCell->getData()._initialSize[1];
01366 // // vecs[2] *= _mainCell->getData()._initialSize[2];
01367 // 
01368 // 
01369 //     return Frame(this->getPosition(),vecs[0],vecs[1],vecs[2]);
01370 // }
01371 
01372 
01373 Frame & ConstrainedVertex::getFrame()
01374 {
01375     return _frame;
01376 }
01377 
01378 bool ConstrainedVertex::hasMainCell( ) const
01379 {
01380     return _mainCell != NULL;
01381 }
01382 void ConstrainedVertex::setMainCell( Cell* mainCell, unsigned int vId )
01383 {
01384     //Require( !hasMainCell() );
01385 
01386     //std::cerr << "setMainCell\n";
01387     // Now update the geoLink stuff !!!
01388     if( (_geoLink != NULL) && (_mainCell != NULL) && (mainCell->father() != _mainCell->father()) )
01389     {
01390         //std::cerr << "\tChangeMainCell\n";
01391         _geoLink->changeCell( mainCell );
01392     }
01393 
01394     _mainCell = mainCell;
01395     _vertexId = vId;
01396 
01397 }
01398 
01399 
01400 
01406 Vec3d ConstrainedVertex::getParameters( Cell *cStart, unsigned short vId )
01407 {
01408     Cell *curCell = cStart;
01409     ConstrainedVertex *curCV = curCell->vertex(vId);
01410 
01411     Vec3d params;
01412     unsigned int diffDepth = 0;
01413     while( !curCV->isFree() )
01414     {
01415         if( (curCell->fatherPos()%2) != 0 )
01416             params[0] += 1.0;
01417         if( (curCell->fatherPos()%4) >= 2 )
01418             params[1] += 1.0;
01419         if( curCell->fatherPos() >= 4 )
01420             params[2] += 1.0;
01421 
01422         params /= 2.0;
01423 
01424         curCell = curCell->father();
01425         curCV = curCell->vertex(vId);
01426         diffDepth++;
01427     }
01428 
01429     FloatingPointType pos = 1.0;
01430     if( diffDepth != 0 )
01431     {
01432         pos /= (FloatingPointType)(2<<(diffDepth-1));
01433     }
01434 
01435     if( (vId%2) != 0 )
01436         params[0] += pos;
01437     if( (vId%4) >= 2 )
01438         params[1] += pos;
01439     if( vId >= 4 )
01440         params[2] += pos;
01441 
01442     return params;
01443 }
01444 
01450 ConstrainedVertex* ConstrainedVertex::getFathersFreeVertex( Cell *cStart, unsigned short vId )
01451 {
01452     Cell *curCell = cStart;
01453     ConstrainedVertex *curCV = curCell->vertex(vId);
01454 
01455     while( !curCV->isFree() )
01456     {
01457         curCell = curCell->father();
01458         curCV = curCell->vertex(vId);
01459     }
01460 
01461     Ensure( curCV->isFree() )   ;
01462 
01463     return curCV;
01464 }
01465 
01466 Cell* ConstrainedVertex::getFathersFreeVertexCell( Cell *cStart, unsigned short vId )
01467 {
01468     /*
01469     Cell *curCell = cStart;
01470     ConstrainedVertex *curCV = curCell->vertex(vId);
01471 
01472     while( !curCV->isFree() )
01473     {
01474         curCell = curCell->father();
01475         curCV = curCell->vertex(vId);
01476     }
01477 
01478     Ensure( curCV->isFree() )   ;
01479 
01480     return curCell;
01481     */
01482     return getFathersFreeVertex( cStart, vId )->getMainCell();
01483 }
01484 
01485 
01486 
01492 Vec3d ConstrainedVertex::getParameters( Cell *cStart, unsigned int depth, unsigned short vId )
01493 {
01494     unsigned int curDepth = depth;
01495 
01496     Cell *curCell = cStart;
01497     ConstrainedVertex *curCV = curCell->vertex(vId);
01498 
01499     Vec3d params;
01500     unsigned int diffDepth = 0;
01501     while( curDepth-- > 0 )
01502     {
01503         if( (curCell->fatherPos()%2) != 0 )
01504             params[0] += 1.0;
01505         if( (curCell->fatherPos()%4) >= 2 )
01506             params[1] += 1.0;
01507         if( curCell->fatherPos() >= 4 )
01508             params[2] += 1.0;
01509 
01510         params /= 2.0;
01511 
01512         curCell = curCell->father();
01513         curCV = curCell->vertex(vId);
01514         diffDepth++;
01515     }
01516 
01517     FloatingPointType pos = 1.0;
01518     if( diffDepth != 0 )
01519     {
01520         pos /= (FloatingPointType)(2<<(diffDepth-1));
01521     }
01522 
01523     if( (vId%2) != 0 )
01524         params[0] += pos;
01525     if( (vId%4) >= 2 )
01526         params[1] += pos;
01527     if( vId >= 4 )
01528         params[2] += pos;
01529 
01530     return params;
01531 }
01532 
01533 
01534 
01535 
01536 /*
01537  * Needed to get the alpha, beta and gamma coefficients for a CVertex
01538  */
01539 
01540 
01541 FloatingPointType ConstrainedVertex::getAlpha( Cell *cell, unsigned int faceId, unsigned int vId, unsigned int diffDepth )
01542 {
01543     FloatingPointType alpha = 0.0;
01544 
01545     std::deque<unsigned int> alphaFactors = getAlphaFactors( cell, faceId, diffDepth );
01546     Require( !alphaFactors.empty() );
01547 
01548     unsigned int denom = 2<<(alphaFactors.size()-1);
01549     unsigned int num = 0;
01550 
01551     // Calculate alpha
01552     for( unsigned int i=0 ; i<alphaFactors.size() ; ++i )
01553     {
01554         num += alphaFactors[i] * (denom>>(i+1));
01555     }
01556     alpha = (FloatingPointType)num / (FloatingPointType)denom;
01557 
01558     // Now add some 1/2^i if the vertex is at the top of the cell
01559     if( (vId%2) == 1 )
01560     {
01561         alpha += 1.0 / (FloatingPointType)denom;
01562     }
01563 
01564     return alpha;
01565 }
01566 
01567 FloatingPointType ConstrainedVertex::getBeta( Cell *cell, unsigned int faceId, unsigned int vId, unsigned int diffDepth )
01568 {
01569     FloatingPointType beta = 0.0;
01570 
01571     std::deque<unsigned int> betaFactors = getBetaFactors( cell, faceId, diffDepth );
01572     Require( !betaFactors.empty() );
01573 
01574     unsigned int denom = 2<<(betaFactors.size()-1);
01575     unsigned int num = 0;
01576 
01577     // Calculate beta
01578     for( unsigned int i=0 ; i<betaFactors.size() ; ++i )
01579     {
01580         num += betaFactors[i] * (denom>>(i+1));
01581     }
01582     beta = (FloatingPointType)num / (FloatingPointType)denom;
01583 
01584     // Now add some 1/2^i if the vertex is at the top of the cell
01585     if( !((vId%4) <= 1) )
01586     {
01587         beta += 1.0 / (FloatingPointType)denom;
01588     }
01589 
01590     return beta;
01591 }
01592 
01593 FloatingPointType ConstrainedVertex::getGamma( Cell *cell, unsigned int faceId, unsigned int vId, unsigned int diffDepth )
01594 {
01595     FloatingPointType gamma = 0.0;
01596 
01597     std::deque<unsigned int> gammaFactors = getGammaFactors( cell, faceId, diffDepth );
01598     Require( !gammaFactors.empty() );
01599 
01600     unsigned int denom = 2<<(gammaFactors.size()-1);
01601     unsigned int num = 0;
01602 
01603     // Calculate beta
01604     for( unsigned int i=0 ; i<gammaFactors.size() ; ++i )
01605     {
01606         num += gammaFactors[i] * (denom>>(i+1));
01607     }
01608     gamma = (FloatingPointType)num / (FloatingPointType)denom;
01609 
01610     // Now add some 1/2^i if the vertex is at the top of the cell
01611     if( vId >= 4 )
01612     {
01613         gamma += 1.0 / (FloatingPointType)denom;
01614     }
01615 
01616     return gamma;
01617 }
01618 
01619 std::deque<unsigned int> ConstrainedVertex::getAlphaFactors( Cell *cell, unsigned int faceId, unsigned int depthLeft )
01620 {
01621     //std::cerr << "Faceid is " << faceId << " and fatherpos is " << cell->fatherPos() << "\n";
01622     Require( !cell->isRoot() );
01623 
01624     if( depthLeft == 0 )
01625     {
01626         return std::deque<unsigned int>(0);
01627     }
01628     else
01629     {
01630         std::deque<unsigned int> parents = getAlphaFactors( cell->father(), faceId, depthLeft-1 );
01631 
01632         unsigned int myId = cell->fatherPos();
01633         if( (myId%2) == 0 )
01634             // This is a bottom cell, return 0
01635             parents.push_back(0);
01636         else
01637             parents.push_back(1);
01638 
01639         return parents;
01640     }
01641 }
01642 
01643 std::deque<unsigned int> ConstrainedVertex::getBetaFactors( Cell *cell, unsigned int faceId, unsigned int depthLeft )
01644 {
01645     //std::cerr << "Faceid is " << faceId << " and fatherpos is " << cell->fatherPos() << "\n";
01646     Require( !cell->isRoot() );
01647 
01648     if( depthLeft == 0 )
01649     {
01650         return std::deque<unsigned int>(0);
01651     }
01652     else
01653     {
01654         std::deque<unsigned int> parents = getBetaFactors( cell->father(), faceId, depthLeft-1 );
01655 
01656         unsigned int myId = cell->fatherPos();
01657         if( (myId%4) <= 1 )
01658             // This is a bottom cell, return 0
01659             parents.push_back(0);
01660         else
01661             parents.push_back(1);
01662 
01663         return parents;
01664     }
01665 }
01666 
01667 std::deque<unsigned int> ConstrainedVertex::getGammaFactors( Cell *cell, unsigned int faceId, unsigned int depthLeft )
01668 {
01669     if( depthLeft == 0 )
01670     {
01671         return std::deque<unsigned int>(0);
01672     }
01673     else
01674     {
01675         std::deque<unsigned int> parents = getGammaFactors( cell->father(), faceId, depthLeft-1 );
01676 
01677         unsigned int myId = cell->fatherPos();
01678         if( myId <= 3 )
01679             // This is a bottom cell, return 0
01680             parents.push_back(0);
01681         else
01682             parents.push_back(1);
01683 
01684         return parents;
01685     }
01686 }
01687 
01688 
01694 Cell* ConstrainedVertex::getMainCell() const
01695 {
01696     return _mainCell;
01697 }
01698 
01699 
01700 
01701 
01702 std::set
01703     <ConstrainedVertex*> ConstrainedVertex::getFreeParentVertices( Cell *cell )
01704 {
01705     std::list<ConstrainedVertex*> queueVertices;
01706     std::set
01707         <ConstrainedVertex*> freeVertices, seenVertices;
01708 
01709     for( unsigned short vId=0 ; vId<8 ; ++vId )
01710     {
01711         queueVertices.push_back( cell->vertex(vId) );
01712         //std::cerr << "In this cell : " << cell->vertex(vId) << "\n";
01713     }
01714 
01715     // Add to the set all the freeVertices parents of the vertices
01716     // in queueVertices (if any)
01717     while( !queueVertices.empty() )
01718     {
01719         ConstrainedVertex *cv = queueVertices.front();
01720         queueVertices.pop_front();
01721 
01722         //std::cerr << "Removing " << cv << "\n";
01723 
01724         seenVertices.insert( cv );
01725 
01726         if( cv->isFree() )
01727         {
01728             freeVertices.insert(cv);
01729         }
01730         else
01731         {
01732             for( unsigned short i=0 ; i<cv->getGeoLink()->getNGeoParents() ; ++i )
01733             {
01734                 ConstrainedVertex *parent = cv->getGeoLink()->getGeoParent( cv->getGeoLink()->getGeoParentId(i) );
01735                 if( seenVertices.find(parent) == seenVertices.end() )
01736                 {
01737                     queueVertices.push_back(parent);
01738                 }
01739             }
01740         }
01741     }
01742 
01743     return freeVertices;
01744 }
01745 
01746 
01747 
01748 
01749 // void ConstrainedVertex::moveIndependent( FloatingPointType x, FloatingPointType y, FloatingPointType z )
01750 // {
01751 //  moveIndependent( Vec3d(x,y,z) );
01752 // }
01753 //
01754 // void ConstrainedVertex::moveIndependent( Vec3d newPos )
01755 // {
01756 //  Require( isFree() );
01757 //
01758 //  this->_position = newPos;
01759 //
01760 //  std::list<ConstrainedVertex*> queue;
01761 //
01762 //  for( unsigned int i=0 ; i<this->nChildren() ; ++i )
01763 //  {
01764 //      if( ! this->child(i)->isFree() )
01765 //      {
01766 //          queue.push_back( this->child(i) );
01767 //      }
01768 //  }
01769 //
01770 //  for( std::list<ConstrainedVertex*>::iterator it = queue.begin() ;
01771 //      it != queue.end(); ++it )
01772 //  {
01773 //      Require( !(*it)->isFree() );
01774 //
01775 //      (*it)->_position = (*it)->computeConstrainedPosition();
01776 //
01777 //      for( unsigned int i=0 ; i<(*it)->nChildren() ; ++i )
01778 //      {
01779 //          if( ! (*it)->child(i)->isFree() )
01780 //          {
01781 //              queue.push_back( (*it)->child(i) );
01782 //          }
01783 //      }
01784 //
01785 //  }
01786 //
01787 // }
01788 
01794 Vec3d ConstrainedVertex::computePosition() const
01795 {
01796     Require( !isFree() );
01797 
01798     Vec3d res;
01799 
01800     for( unsigned short i=0 ; i<getGeoLink()->getNGeoParents() ; ++i )
01801     {
01802         res += getGeoLink()->getGeoParent( getGeoLink()->getGeoParentId(i) )->getPosition();
01803     }
01804 
01805     res /= getGeoLink()->getNGeoParents();
01806 
01807     return res;
01808 }
01809 
01810 
01814 void ConstrainedVertex::setPosition( Vec3d newPos )
01815 {
01816     _position = newPos;
01817     this->getFrame().setOrigin( _position );
01818 }
01819 
01824 void ConstrainedVertex::setPositionAndPropagate( Vec3d newPos )
01825 {
01826     Require( isFree() );
01827 
01828 //     this->_position = newPos;
01829     this->setPosition( newPos );
01830 
01831     std::list<ConstrainedVertex*> queue;
01832 
01833     for( unsigned int i=0 ; i<this->nChildren() ; ++i )
01834     {
01835         if( ! this->child(i)->isFree() )
01836         {
01837             queue.push_back( this->child(i) );
01838         }
01839     }
01840 
01841     for( std::list<ConstrainedVertex*>::iterator it = queue.begin() ;
01842             it != queue.end(); ++it )
01843     {
01844         Require( !(*it)->isFree() );
01845 
01846         (*it)->setPosition( (*it)->computePosition() );
01847 
01848         for( unsigned int i=0 ; i<(*it)->nChildren() ; ++i )
01849         {
01850             if( ! (*it)->child(i)->isFree() )
01851             {
01852                 queue.push_back( (*it)->child(i) );
01853             }
01854         }
01855 
01856     }
01857 }
01858 
01864 void ConstrainedVertex::setPositionAndPropagateAll( Vec3d newPos, unsigned int depth )
01865 {
01866     if( isFree() )
01867     {
01868         //updateChildrensPosition( newPos - _position, depth );
01869         updateChildrensPositionOptimized( newPos - _position, depth );
01870         setDelta( Vec3d(0,0,0) );
01871         setDelta( getDelta() + newPos-_position );
01872         setPosition( newPos );
01873     }
01874 
01875     else
01876     {
01877         updateChildrensPositionOptimizedNotFree( newPos - _position );
01878     }
01879 }
01880 
01881 
01882 
01883 
01886 Vec3d ConstrainedVertex::getDelta() const
01887 {
01888     return _delta;
01889 }
01890 void ConstrainedVertex::setDelta( Vec3d d )
01891 {
01892     _delta = d;
01893 }
01894 Vec3d ConstrainedVertex::computeDelta() const
01895 {
01896     Require( !isFree() );
01897 
01898     Vec3d res;
01899     unsigned short nParents = getGeoLink()->getNGeoParents();
01900 
01901     for( unsigned short i=0 ; i<nParents ; ++i )
01902     {
01903         res += getGeoLink()->getGeoParent( getGeoLink()->getGeoParentId(i) )->getDelta();
01904     }
01905 
01906     res /= nParents;
01907 
01908     return res;
01909 }
01910 
01911 
01912 
01913 // Same thing for auxiliary vectors
01914 
01915 Vec3d ConstrainedVertex::computeValue(int value_id ) const
01916 {
01917     Require( !isFree() );
01918 
01919     Vec3d res;
01920 
01921     for( unsigned short i=0 ; i<getGeoLink()->getNGeoParents() ; ++i )
01922     {
01923         res += getGeoLink()->getGeoParent( getGeoLink()->getGeoParentId(i) )->value( value_id );
01924     }
01925 
01926     res /= getGeoLink()->getNGeoParents();
01927 
01928     return res;
01929 }
01930 
01931 void ConstrainedVertex::computeValueFromParents(int value_id )
01932 {
01933     Require( !isFree() );
01934 
01935     Vec3d res;
01936 
01937     for( unsigned short i=0 ; i<getGeoLink()->getNGeoParents() ; ++i )
01938     {
01939         res += getGeoLink()->getGeoParent( getGeoLink()->getGeoParentId(i) )->value( value_id );
01940     }
01941 
01942     res /= getGeoLink()->getNGeoParents();
01943 
01944     setValue(value_id, res);
01945 }
01946 
01947 void ConstrainedVertex::computeValueFromRelatives(int value_id )
01948 {
01949     Require( isFree() );
01950 
01951     Vec3d res;
01952 
01953     for( unsigned short i=0 ; i<getGeoLink()->getNGeoParents() ; ++i )
01954     {
01955         res += getGeoLink()->getGeoParent( getGeoLink()->getGeoParentId(i) )->value( value_id );
01956     }
01957 
01958     res /= getGeoLink()->getNGeoParents();
01959 
01960     setValue(value_id, res);
01961 }
01962 
01963 void ConstrainedVertex::setValue( int value_id, Vec3d newPos )
01964 {
01965     _aux[value_id] = newPos;
01966 }
01967 
01968 Vec3d& ConstrainedVertex::value( int value_id )
01969 {
01970     return _aux[value_id];
01971 }
01972 
01973 const Vec3d& ConstrainedVertex::value( int value_id ) const
01974 {
01975     return _aux[value_id];
01976 }
01977 
01978 void ConstrainedVertex::setValueAndPropagate( int value_id, Vec3d newPos )
01979 {
01980     Require( isFree() );
01981 
01982     this->_aux[value_id] = newPos;
01983 
01984     std::list<ConstrainedVertex*> queue;
01985 
01986     for( unsigned int i=0 ; i<this->nChildren() ; ++i )
01987     {
01988         if( ! this->child(i)->isFree() )
01989         {
01990             queue.push_back( this->child(i) );
01991         }
01992     }
01993 
01994     for( std::list<ConstrainedVertex*>::iterator it = queue.begin() ;
01995             it != queue.end(); ++it )
01996     {
01997         Require( !(*it)->isFree() );
01998 
01999         (*it)->setValue( value_id, (*it)->computeValue(value_id) );
02000 
02001         for( unsigned int i=0 ; i<(*it)->nChildren() ; ++i )
02002         {
02003             if( ! (*it)->child(i)->isFree() )
02004             {
02005                 queue.push_back( (*it)->child(i) );
02006             }
02007         }
02008 
02009     }
02010 }
02011 
02012 
02013 
02014 
02015 
02016 
02017 
02018 
02019 
02020 
02021 
02022 
02023 Cell::vertex_connected_iterator::vertex_connected_iterator( ConstrainedVertex* vertex, Cell *cell, unsigned int vPos )
02024 {
02025     //  std::cerr << "Cell is " << *cell << "\n";
02026 
02027     for( unsigned short dir=0 ; dir<3 ; ++dir )
02028     {
02029         _vList.push_back( cell->vertex(connectedVertices[vPos][dir]) );
02030 
02031         Cell *neighbour = cell->uncleSharingFace(TempOctree::verticesConnectedFaces[vPos][dir]);
02032         if( (neighbour != NULL) && vertex->isConnected(neighbour) )
02033         {
02034             Cell *otherCell = vertex->getCellWithFreeVertexConnectedToVertex( neighbour, dir, vPos );
02035             //          std::cerr << "Adding vertex " << vPos << " from cell " << *otherCell << "\n";
02036             _vList.push_back( otherCell->vertex(vPos) );
02037         }
02038     }
02039 
02040     /*
02041     for( unsigned short i=0 ; i < vertex->nConnectedCells() ; ++i )
02042     {
02043         Cell *connectedCell = vertex->connectedCell( i );
02044         if( connectedCell->getData()._depth <= depth )
02045         {
02046             // Find the corresponding vertex in this new cell
02047             unsigned short child;
02048             for( child=0 ; child<8 ; ++child )
02049             {
02050                 if( connectedCell->vertex(child) == vertex )
02051                 {
02052                     for( unsigned short dir=0 ; dir<3 ; ++dir )
02053                     {
02054                         _vSet.insert( connectedCell->vertex( Cell::connectedVertices[child][dir] ) );
02055                     }
02056                     break;
02057                 }
02058             }
02059             Require( child != 8 );
02060         }
02061     }
02062     */
02063 
02064 }
02065 
02066 Cell::vertex_connected_iterator::~vertex_connected_iterator()
02067 {}
02068 
02069 TempOctree::Vertex* Cell::vertex_connected_iterator::operator++()
02070 {
02071     Require( !empty() );
02072 
02073     /*
02074     Vertex* res = *_vSet.begin();
02075     _vSet.erase( _vSet.begin() );
02076     */
02077     Vertex* res = _vList.front();
02078     _vList.pop_front();
02079 
02080     return res;
02081 }
02082 bool Cell::vertex_connected_iterator::empty()
02083 {
02084     return _vList.empty();
02085     //return _vSet.empty();
02086 }
02087 
02088 
02089 }
02090 }
02091 
02092 
02093 

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