TAPs 0.7.7.3
TAPsModelSutureMath.cpp
Go to the documentation of this file.
00001 /*******************************************************************************
00002 TAPsModelSutureMath.cpp
00003 
00004 A two-headed needle suture
00005 
00006 SUKITTI PUNAK   (01/30/2006)
00007 UPDATE          (09/03/2010)
00008 *******************************************************************************/
00009 #include "TAPsModelSutureMath.hpp"
00010 // Using Inclusion Model (i.e. definitions are included in declarations)
00011 //                       (this name.cpp is included in name.hpp)
00012 // Each friend is defined directly inside its declaration.
00013 
00014 BEGIN_NAMESPACE_TAPs__OpenGL
00015 //==============================================================================
00016 //------------------------------------------------------------------------------
00017 // Default constructor
00018 template <typename T>
00019 ModelSutureMath<T>::ModelSutureMath ()
00020     : ModelStrandMath<T>( 128, 0.1, 0.1, Vector3<T>(), 0.05 ), 
00021       m_iLevel( 3 )
00022 {
00023     InitNeedles();
00024     //----------------------------------------------------------------
00025     #ifdef  TAPs_ENABLE_DEBUG
00026     std::cout   << "Default ModelSutureMath<" << typeid(T).name() << "> with:\n"
00027                 << "  " << m_iNoLinks << " links with each link of length "
00028                 << m_tLinkLength << " and weight " << m_tPointWeight << "\n";
00029     #endif//TAPs_DEBUG_MODE
00030 }
00031 //------------------------------------------------------------------------------
00032 // Constructor
00033 template <typename T>
00034 ModelSutureMath<T>::ModelSutureMath (   int iNoLinks, T tLength, T tWeight, 
00035                                 Vector3<T> & posOfVertex0, T tRadius )
00036 
00037     : ModelStrandMath<T>( iNoLinks, tLength, tWeight, posOfVertex0, tRadius ), 
00038       m_iLevel( 3 )
00039 {
00040     InitNeedles();
00041     //----------------------------------------------------------------
00042     #ifdef  TAPs_ENABLE_DEBUG
00043     std::cout   << "ModelSutureMath<" << typeid(T).name() << "> with:\n"
00044                 << "  " << m_iNoLinks << " links with each link of length "
00045                 << m_tLinkLength << " and weight " << m_tPointWeight << "\n";
00046     #endif//TAPs_DEBUG_MODE
00047 }
00048 //------------------------------------------------------------------------------
00049 // Constructor
00050 template <typename T>
00051 ModelSutureMath<T>::ModelSutureMath (   int iNoLinks, T tLength, T tWeight, 
00052                                 Vector3<T> & posOfVertex0, T tRadius, 
00053                                 const char * needle1 
00054                             )
00055 
00056     : ModelStrandMath<T>( iNoLinks, tLength, tWeight, posOfVertex0, tRadius ), 
00057       m_iLevel( 3 )
00058 {
00059     InitNeedles( needle1 );
00060     //----------------------------------------------------------------
00061     #ifdef  TAPs_ENABLE_DEBUG
00062     std::cout   << "ModelSutureMath<" << typeid(T).name() << "> with:\n"
00063                 << "  " << m_iNoLinks << " links with each link of length "
00064                 << m_tLinkLength << " and weight " << m_tPointWeight << "\n";
00065     #endif//TAPs_DEBUG_MODE
00066 }
00067 //------------------------------------------------------------------------------
00068 // Constructor
00069 template <typename T>
00070 ModelSutureMath<T>::ModelSutureMath (   int iNoLinks, T tLength, T tWeight, 
00071                                 Vector3<T> & posOfVertex0, T tRadius, 
00072                                 T tKRatioOfStretchingAllowed,
00073                                 T tKRatioOfCompressionAllowed,
00074                                 T tKStretching,
00075                                 T tKBending,
00076                                 T tKTwisting,
00077                                 T tKFriction,
00078                                 T tKContact,
00079                                 T tKGravity,
00080                                 const char * needle1 
00081                             )
00082 
00083     : ModelStrandMath<T>( iNoLinks, tLength, tWeight, posOfVertex0, tRadius, 
00084             tKRatioOfStretchingAllowed, tKRatioOfCompressionAllowed, 
00085             tKStretching, tKBending, tKTwisting, 
00086             tKFriction, tKContact, tKGravity ), 
00087       m_iLevel( 3 )
00088 {
00089     InitNeedles( needle1 );
00090     //----------------------------------------------------------------
00091     #ifdef  TAPs_ENABLE_DEBUG
00092     std::cout   << "ModelSutureMath<" << typeid(T).name() << "> with:\n"
00093                 << "  " << m_iNoLinks << " links with each link of length "
00094                 << m_tLinkLength << " and weight " << m_tPointWeight << "\n";
00095     #endif//TAPs_DEBUG_MODE
00096 }
00097 //------------------------------------------------------------------------------
00098 // Destructor
00099 template <typename T>
00100 ModelSutureMath<T>::~ModelSutureMath ()
00101 {
00102     //if ( m_pNeedleLeft )  delete m_pNeedleLeft;       // ERROR Deleting Object!  FIX IT!
00103     //if ( m_pNeedleRight ) delete m_pNeedleRight;
00104     //----------------------------------------------------------------
00105     if ( m_prPickPts )  delete [] m_prPickPts;
00106     if ( m_prbIsSharp ) delete [] m_prbIsSharp;
00107     //----------------------------------------------------------------
00108     #ifdef  TAPs_ENABLE_DEBUG
00109     std::cout << "ModelSutureMath<" << typeid(T).name() << "> Destructor\n";
00110     #endif//TAPs_DEBUG_MODE
00111 }
00112 //------------------------------------------------------------------------------
00113 // Initialize Needles
00114 template <typename T>
00115 void ModelSutureMath<T>::InitNeedles ()
00116 {
00117     //char fileName1[] = "Data/3dsMax/HeadNeedle.ASE";
00118     //char fileName1[] = "Data/3dsMax/HeadNeedle2.ASE";
00119     char needle1[] = "Data/3dsMax/HeadNeedle3.ASE";
00120     //char fileName2[] = "Data/3dsMax/HeadNeedle.ASE";
00121     InitNeedles( needle1 );
00122 }
00123 //------------------------------------------------------------------------------
00124 // Initialize Needles
00125 template <typename T>
00126 void ModelSutureMath<T>::InitNeedles ( const char * needle1 )
00127 {
00128     //m_pNeedleLeft  = NULL;
00129     //m_pNeedleRight = NULL;
00130     //----------------------------------------------------------------
00131     m_pNeedleLeft  = new OpenGLHalfEdgeModel<T>();
00132     //m_pNeedleRight = new OpenGLHalfEdgeModel<T>();
00133     //----------------------------------------------------------------
00134 
00135     #ifdef  TAPs_DEBUG_MODE
00136     std::cout << "Create Left Needle" << std::endl;
00137     #endif//TAPs_DEBUG_MODE
00138 
00139     if ( !ReadModels<Real>::readFile( needle1, m_pNeedleLeft ) ) {
00140         std::cout << "ERROR: In File Reading for creating the left needle!" << std::endl;
00141         exit ( EXIT_FAILURE );
00142     }
00143     else {
00144         #ifdef  TAPs_DEBUG_MODE
00145         std::cout << "Creating Left Needle" << std::endl;
00146         #endif//TAPs_DEBUG_MODE
00147 
00148         m_pNeedleLeft->SetMaterial( OpenGL::Enum::HEAD_NEEDLE );
00149         m_pNeedleLeft->BuildBVHTree( TAPs::Enum::BVH_TREE_BINARY_SPHERE );
00150     }
00151     //----------------------------------------------------------------
00152     /*
00153 
00154     #ifdef  TAPs_DEBUG_MODE
00155     std::cout << "Create Right Needle" << std::endl;
00156     #endif//TAPs_DEBUG_MODE
00157 
00158     if ( !ReadModels<Real>::readFile( needle2, m_pNeedleRight ) ) {
00159         std::cout << "ERROR: In File Reading for creating the right needle!" << std::endl;
00160         exit ( EXIT_FAILURE );
00161     }
00162     else {
00163         #ifdef  TAPs_DEBUG_MODE
00164         std::cout << "Creating Right Needle" << std::endl;
00165         #endif//TAPs_DEBUG_MODE
00166 
00167         m_pNeedleRight->SetMaterial( OpenGL::Enum::HEAD_NEEDLE );
00168         m_pNeedleRight->BuildBVHTree( TAPs::Enum::BVH_TREE_BINARY_SPHERE );
00169     }
00170     //*/
00171     //--------------------------------------------------------------------
00172     InitNeedlesPickPts();
00173     SetNeedlesPickPts();
00174     InitNeedlesSharpPts();
00175 }
00176 //------------------------------------------------------------------------------
00177 // Initialize Needles Pick Points
00178 template <typename T>
00179 void ModelSutureMath<T>::InitNeedlesPickPts ()
00180 {
00181     // SET Number of Pick Pts HERE! ==> 2^m_iLevel
00182     m_iLevel = 4;
00183     //----------------------------------------------------------------
00184     // Set number of pick able points for needles
00185     //m_iNoPickPts = static_cast<int>( pow( 2.0, m_iLevel ) ); // * 2;
00186     m_iNoPickPts = 1 << m_iLevel;
00187 
00188     #ifdef  TAPs_DEBUG_MODE
00189     std::cout << "Number of pickable points for the needle is set at" << m_iNoPickPts << ".\n";
00190     #endif//TAPs_DEBUG_MODE
00191 
00192     m_prPickPts = new Vector3<T>*[ m_iNoPickPts ];
00193     assert( m_prPickPts );
00194     //----------------------------------------------------------------
00195     // Use a recursive function
00196     BVHNode<T> ** L = new BVHNode<T>*[1];
00197     L[0] = m_pNeedleLeft->GetBVHTree()->Root();
00198     InitNeedlesPickPts( L, 0 );     // Node List and Level Number
00199     delete [] L;
00200 }
00201 //------------------------------------------------------------------------------
00202 // Initialize Needles Pick Points
00203 template <typename T>
00204 void ModelSutureMath<T>::InitNeedlesPickPts ( BVHNode<T> ** node, int level )
00205 {
00206     #ifdef  TAPs_DEBUG_MODE
00207     std::cout << "InitNeedlesPickPts with LEVEL of " << level << std::endl;
00208     #endif//TAPs_DEBUG_MODE
00209 
00210     if ( level > m_iLevel ) return;
00211     //----------------------------------------------------------------
00212     //int size = static_cast<int>( pow( 2.0, level ) );
00213     int size = 1 << level;
00214     BVHNode<T> ** L = new BVHNode<T>*[ size*2 ];
00215     for ( int i = 0, j = 0; i < size; ++i, j+=2 ) {
00216         L[j  ] = node[i]->Child(0);
00217         L[j+1] = node[i]->Child(1);
00218     }
00219     InitNeedlesPickPts( L, ++level );
00220     //----------------------------------------------------------------
00221     if ( level == m_iLevel ) {
00222         //----------------------------------------------------------------
00223         #ifdef  TAPs_DEBUG_MODE
00224         std::cout << "--------------------   NEEDLE PICK POINTS   --------------------\n";
00225         #endif//TAPs_DEBUG_MODE
00226 
00227         for ( int i = 0; i < m_iNoPickPts; ++i ) {
00228             m_prPickPts[i] = &(L[i]->GetCenter());
00229 
00230             #ifdef  TAPs_DEBUG_MODE
00231             std::cout << *(m_prPickPts[i]) << "\n";
00232             #endif//TAPs_DEBUG_MODE
00233         }
00234         #ifdef  TAPs_DEBUG_MODE
00235         std::cout << "-------------------- END NEEDLE PICK POINTS --------------------\n";
00236         #endif//TAPs_DEBUG_MODE
00237     }
00238     delete [] L;
00239 }
00240 //------------------------------------------------------------------------------
00241 // SetNeedlesPickPts
00242 //   Align needles with the movement of the strand
00243 template <typename T>
00244 void ModelSutureMath<T>::SetNeedlesPickPts ()
00245 {
00246     static int i;
00247     static T angle;
00248     static Vector3<T> dir, axis;
00249 
00250     //--------------------------------------------------------------------
00251     // Left Needle
00252     i = 0;
00253     dir = m_prVertex[i] - m_prVertex[i+1];
00254     axis = dir ^ (-CGMath<T>::VectorY);
00255     angle = acos( (dir * (-CGMath<T>::VectorY)) / dir.Length() ) 
00256           * Math<T>::RAD_TO_DEG;
00257     // Translation and Rotation
00258     //m_vTransForLeftNeedle  = m_prVertex[i];
00259     m_pNeedleLeft->GetTransform().SetTranslation( m_prVertex[i] );
00260     //m_mRotMatForLeftNeedle = CGMath<T>::CreateRotationMatrix3x3( axis, -angle );
00261     if ( !GetFixStatusOfPtNo( 0 ) )
00262         m_pNeedleLeft->GetTransform().SetMatrixRotation( CGMath<T>::CreateRotationMatrix3x3( axis, -angle ) );
00263     //std::cout << m_pNeedleLeft->GetTransform().GetMatrixRotation() << "\n";
00264     /*
00265     //--------------------------------------------------------------------
00266     // Get Rotation Matrix using OpenGL
00267     GLfloat m[16];
00268     glPushMatrix();
00269         glLoadIdentity();
00270         glRotatef( -angle, axis[0], axis[1], axis[2] );
00271         glGetFloatv( GL_MODELVIEW_MATRIX, m );
00272     glPopMatrix();
00273     m_vTransForLeftNeedle  = m_prVertex[i];
00274     m_mRotMatForLeftNeedle = Matrix3x3<T>(  m[ 0], m[ 4], m[ 8],
00275                                             m[ 1], m[ 5], m[ 9],
00276                                             m[ 2], m[ 6], m[10] );
00277     //*/
00278 
00279     //--------------------------------------------------------------------
00280     //--------------------------------------------------------------------
00281     //--------------------------------------------------------------------
00282     //--------------------------------------------------------------------
00283 }
00284 //------------------------------------------------------------------------------
00285 // InitNeedlesSharpPts
00286 template <typename T>
00287 void ModelSutureMath<T>::InitNeedlesSharpPts ()
00288 {
00289     //---------------------------------------------------------------
00290     // For Left Needle
00291     m_prbIsSharp = new bool[ m_iNoPickPts ];
00292     for ( int i = 0; i < m_iNoPickPts; ++i ) {
00293         m_prbIsSharp[i] = false;
00294     }
00295 
00296     /*
00297     //---------------------------------------------------------------
00298     // Sort Needle Points
00299     int * sortArray = new int[ m_iNoPickPts ];
00300     for ( int i = 0; i < m_iNoPickPts; ++i ) {
00301         sortArray[i] = i;
00302     }
00303     T minDistance = (*(m_prPickPts[0]) - m_prVertex[0]).Length();
00304     T distance;
00305     int minPt;
00306     //-----------------------------------------------------
00307     for ( int j = 0; j < m_iNoPickPts; ++j ) {
00308         distance = (*(m_prPickPts[j]) - m_prVertex[0]).Length();
00309         if ( distance < minDistance ) {
00310             minPt = j;
00311             minDistance = distance;
00312         }
00313     }
00314     sortArray[0]     = minPt;
00315     sortArray[minPt] = 0;
00316     /*
00317     //-----------------------------------------------------
00318     for ( int i = 1; i < m_iNoPickPts; ++i ) {
00319         minDistance = (*(m_prPickPts[sortArray[i]]) - *(m_prPickPts[sortArray[i-1]])).Length();
00320         for ( int j = i+1; j < m_iNoPickPts; ++j ) {
00321             distance = (*(m_prPickPts[sortArray[j]]) - *(m_prPickPts[sortArray[i-1]])).Length();
00322             if ( distance < minDistance ) {
00323                 minPt = j;
00324                 minDistance = distance;
00325             }
00326         }
00327         int tmp = sortArray[i];
00328         sortArray[i]     = sortArray[minPt];
00329         sortArray[minPt] = tmp;
00330     }
00331     //*/
00332     //-----------------------------------------------------
00333     //m_prbIsSharp[sortArray[m_iNoPickPts-1]] = true;
00334     //m_prbIsSharp[sortArray[0]] = true;
00335     //*/
00336 
00337     //---------------------------------------------------------------
00338     int needleSharpPt = 0;
00339     T maxDistance = (*(m_prPickPts[0]) - m_prVertex[0]).Length();
00340     T distance;
00341     for ( int i = 1; i < m_iNoPickPts; ++i ) {
00342         distance = (*(m_prPickPts[i]) - m_prVertex[0]).Length();
00343         if ( distance > maxDistance ) {
00344             needleSharpPt = i;
00345             maxDistance = distance;
00346         }
00347     }
00348     m_prbIsSharp[needleSharpPt] = true;
00349     m_iNeedleSharpPt = needleSharpPt;
00350 }
00351 //------------------------------------------------------------------------------
00352 template <typename T>
00353 inline Vector3<T> ModelSutureMath<T>::GetPointPosition ( int i ) const
00354 {
00355     if ( i <= m_iNoLinks )  return m_prVertex[i];
00356     else                    return GetNeedlesPosition( i-m_iNoLinks-1 );
00357 }
00358 //------------------------------------------------------------------------------
00359 template <typename T>
00360 inline Vector3<T> ModelSutureMath<T>::GetNeedlesPosition ( int i ) const
00361 {
00362     assert( 0 <= i && i < m_iNoPickPts );
00363     // Left Needle
00364     //return m_mRotMatForLeftNeedle * *(m_prPickPts[i]) + m_vTransForLeftNeedle;
00365     return m_pNeedleLeft->GetTransform().GetMatrixRotation() * 
00366                 *(m_prPickPts[i]) + m_pNeedleLeft->GetTransform().GetTranslation();
00367 }
00368 //------------------------------------------------------------------------------
00369 template <typename T>
00370 inline void ModelSutureMath<T>::SetPointPosition ( 
00371     int i, const Vector3<T> & position )
00372 {
00373     if ( i <= m_iNoLinks )  {
00374         ModelStrandMath<T>::SetPointPosition( i, position );
00375         SetNeedlesPickPts();
00376     }
00377     else {
00378         //SetNeedlesPosition( i-m_iNoLinks-1, position, m_mRotMatForLeftNeedle );
00379 
00380         SetNeedlesPosition( i-m_iNoLinks-1, position, m_pNeedleLeft->GetTransform().GetMatrixRotation() );
00381 
00382         //ModelStrandMath<T>::SetPointPosition( 0, m_vTransForLeftNeedle );
00383 
00384         //ModelStrandMath<T>::SetPointPosition( 1, position );
00385         ModelStrandMath<T>::SetPointPosition( 0, m_pNeedleLeft->GetTransform().GetTranslation() );
00386     }
00387 }
00388 //------------------------------------------------------------------------------
00389 template <typename T>
00390 inline void ModelSutureMath<T>::SetPointPosition ( 
00391     int i, const Vector3<T> & position, Matrix3x3<T> & rotation, 
00392     //T tMoveDistanceLimit, 
00393     MultiBoundingVolume<T> const * const pMBV, 
00394     TransformationSupport<T> const * const pTransform 
00395 )
00396 {
00397     if ( i <= m_iNoLinks )  {
00398         ModelStrandMath<T>::SetPointPosition( i, position, pMBV, pTransform );
00399         SetNeedlesPickPts();
00400     }
00401     else {
00402         SetNeedlesPosition( i-m_iNoLinks-1, position, rotation );
00403         //ModelStrandMath<T>::SetPointPosition( 0, m_vTransForLeftNeedle );
00404         ModelStrandMath<T>::SetPointPosition( 0, m_pNeedleLeft->GetTransform().GetTranslation() );
00405     }
00406 }
00407 //------------------------------------------------------------------------------
00408 template <typename T>
00409 inline void ModelSutureMath<T>::SetNeedlesPosition ( 
00410     int i, const Vector3<T> & position, Matrix3x3<T> & rotation )
00411 {
00412     assert( 0 <= i && i < m_iNoPickPts );
00413     //--------------------------------------------------------------------
00414     // Left Needle
00415     //m_mRotMatForLeftNeedle =  rotation;
00416 
00417     //rotation.MakeIdentity();
00418 
00419     // Rotate with the first link of the strand
00420     m_pNeedleLeft->GetTransform().SetMatrixRotation( rotation );
00421 
00422     Vector3<T> translation = position - GetNeedlesPosition( i );
00423     //m_vTransForLeftNeedle += translation;
00424     m_pNeedleLeft->GetTransform().SetTranslation( 
00425         m_pNeedleLeft->GetTransform().GetTranslation() + translation
00426     );
00427 }
00428 //------------------------------------------------------------------------------
00429 //==============================================================================
00430 // Get/Set Fn(s)
00431 //------------------------------------------------------------------------------
00432 //------------------------------------------------------------------------------
00433 //==============================================================================
00434 // Helper Fn(s)
00435 //------------------------------------------------------------------------------
00436 //------------------------------------------------------------------------------
00437 //==============================================================================
00438 // For Simulation
00439 //------------------------------------------------------------------------------
00440 // DxDt
00441 template <typename T>
00442 bool ModelSutureMath<T>::DxDt ( 
00443     T dt,                           // i/p: time step
00444     Simulation::VectorSet<T> &x,    // i/p: array  x = {pos, vel}
00445     Simulation::VectorSet<T> &xdot, // o/p: array xdot = {vel, accel}
00446     void *userData                  // o/p: array of user data
00447 )
00448 {
00449     return ModelStrandMath<T>::DxDt( dt, x, xdot, userData );
00450 }
00451 //------------------------------------------------------------------------------
00452 // StateToArray
00453 template <typename T>
00454 void ModelSutureMath<T>::StateToArray ( T *dst )
00455 {
00456     ModelStrandMath<T>::StateToArray( dst );
00457 }
00458 //------------------------------------------------------------------------------
00459 // ArrayToState
00460 template <typename T>
00461 void ModelSutureMath<T>::ArrayToState ( T *src )
00462 {
00463     ModelStrandMath<T>::ArrayToState( src );
00464 }
00465 //------------------------------------------------------------------------------
00466 // DdtStateToArray
00467 template <typename T>
00468 void ModelSutureMath<T>::DdtStateToArray ( T *xdot, T dt )
00469 {
00470     ModelStrandMath<T>::DdtStateToArray( xdot, dt );
00471 }
00472 //------------------------------------------------------------------------------
00473 // AdvanceSimulation
00474 template <typename T>
00475 void ModelSutureMath<T>::AdvanceSimulation ( T tCurrent, T tNext )
00476 {
00477     ModelStrandMath<T>::AdvanceSimulation( tCurrent, tNext );
00478     SetNeedlesPickPts();
00479 }
00480 //------------------------------------------------------------------------------
00481 // AdvanceSimulation
00482 template <typename T>
00483 void ModelSutureMath<T>::AdvanceSimulation ( Simulation::SimClock<T> & simClock )
00484 {
00485     ModelStrandMath<T>::AdvanceSimulation( simClock );
00486     SetNeedlesPickPts();
00487 }
00488 //------------------------------------------------------------------------------
00489 
00490 //------------------------------------------------------------------------------
00491 // SetupShape Fn
00492 template <typename T>
00493 void ModelSutureMath<T>::SetupShape ( Vector3<T> startPosition )
00494 {
00495     ModelStrandMath<T>::SetupShape( startPosition );
00496 }
00497 //------------------------------------------------------------------------------
00498 //==============================================================================
00499 END_NAMESPACE_TAPs__OpenGL
00500 //------------------------------------------------------------------------------
00501 //345678901234567890123456789012345678901234567890123456789012345678901234567890
00502 //--+----1----+----2----+----3----+----4----+----5----+----6----+----7----+----8
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines