TAPs 0.7.7.3
TAPsElasticRodKR.hpp
Go to the documentation of this file.
00001 /******************************************************************************
00002 TAPsElasticRodKR.hpp
00003 ******************************************************************************/
00011 /******************************************************************************
00012 SUKITTI PUNAK   (08/31/2009)
00013 UPDATE          (03/23/2011)
00014 ******************************************************************************/
00015 #ifndef TAPs_ELASTIC_ROD__KR_HPP
00016 #define TAPs_ELASTIC_ROD__KR_HPP
00017 
00018 #include "TAPsElasticRodParameters.hpp"
00019 #include "TAPsElasticRodNode.hpp"
00020 
00021 // Dowker Notation
00022 #include "../../Data/TAPsDatabaseDowkerNotation.hpp"
00023 #include "../../Data/TAPsKnotTrackingConstraint.hpp"
00024 
00025 // For collision detection
00026 #include "../../CD/TAPsBVHTree.hpp"
00027 
00028 // For drawing by OpenGL
00029 #if defined(__gl_h_) || defined(__GL_H__)
00030     #include "../../OpenGL/TAPsOpenGLUsefulObjs.hpp"
00031     #include "../../OpenGL/TAPsOpenGLObj.hpp"
00032 #endif
00033 
00034 BEGIN_NAMESPACE_TAPs
00035 //=============================================================================
00036 template <typename T>
00037 class ElasticRodKR {
00038 
00039     typedef std::vector< ElasticRodNode<T> >    SetOfElasticRodNodes;
00040 
00041     // Member Functions -------------------------------------------------------
00043     friend std::ostream & operator<< ( std::ostream &output, ElasticRodKR<T> const &obj )
00044     {
00045         output << obj.StrInfo();
00046         return output;
00047     }
00048 public:
00049 
00050     // Data Members -----------------------------------------------------------
00051     enum Threshold {
00052         THRESHOLD_FOR_FIXING_KNOT,  
00053         THRESHOLD_WAIT_TIME,        
00054         LENGTH_THRESHOLD_0,         
00055         LENGTH_THRESHOLD_1,         
00056         LENGTH_THRESHOLD_2,         
00057         LENGTH_THRESHOLD_3,         
00058         LENGTH_THRESHOLD_4,         
00059         LENGTH_THRESHOLD_5,         
00060         LENGTH_THRESHOLD_6,         
00061         LENGTH_THRESHOLD_7,         
00062     };
00063 
00064     //-------------------------------------------------------------------------
00066     ElasticRodKR ();
00067 
00069     //ElasticRodKR ( ElasticRodKR<T> const &obj );
00070 
00072     virtual ~ElasticRodKR ();
00073 
00075     void CreateKR (
00076         int *                       pIdxCurr,       
00077         int *                       pIdxNext,       
00078         ElasticRodParameters<T> *   pParameters,    
00079         SetOfElasticRodNodes *      pNodeList,      
00080         BVHTree<T> *    bvhTree,            
00081         unsigned char   numOfNotAllowed     
00082     );
00083 
00085     void DeleteKR ();
00086 
00088     //void CDRforSelfIntersections ();
00089 
00091     //void CheckIntersection ();
00092 
00093     //-------------------------------------------------------------------------
00095     virtual std::string StrInfo () const;
00096 
00097     //-------------------------------------------------------------------------
00098     // Operations
00099 
00101     void Init ( unsigned char numKnotAllowed );
00103     void Reset ();
00105     std::string CheckSurgeonsKnot ();
00106 
00108     int KnotRecognition ();
00109 
00124     void CombineTwoKnots (
00125         int startLockedKnotID,                          
00126         Data::DatabaseDowkerNotation::KNOT knotType,    
00127         Matrix4x4<T> const & orientation                
00128     );
00129 
00130     
00132     void ConstrainKnots ();
00133 
00135     std::string GetStrNameForKnotCombination ();
00137     std::string GetNameOfKnot   ( unsigned int i, bool withPosOrNegPostfix = false );
00138 
00142     int GetMinPtIdThatIsInRecordedKnots () const { return m_iMinPtIdThatIsInRecordedKnots; }
00146     int GetMaxPtIdThatIsInRecordedKnots () const { return m_iMaxPtIdThatIsInRecordedKnots; }
00147 
00148     //void SetMinPtIdThatIsInRecordedKnots ( int i ) { m_iMinPtIdThatIsInRecordedKnots = i; }
00149     //void SetMaxPtIdThatIsInRecordedKnots ( int i ) { m_iMaxPtIdThatIsInRecordedKnots = i; }
00150     
00151     //===============================================================
00152     // Animating Knot Tying
00153     //---------------------------------------------------------------
00154 #ifdef  TAPs_ADD_ANIMATED_KNOTS
00155 
00157     Matrix4x4<T> &          RefToOrientationForCombinedKnot ()          { return m_OrientationForCombinedKnot; }
00159     Matrix4x4<T> const &    RefToOrientationForCombinedKnot () const    { return m_OrientationForCombinedKnot; }
00160 
00162     void ProcessKnotAnimation ();
00163 
00169     int ConstrainAnimatedKnots (
00170         Data::DatabaseDowkerNotation::KNOT & knotTypeOfTheFinishTightenKnot,    
00171         int & knotIDStartOfTheFinishTightenKnot,    
00172         int & knotIDEndOfTheFinishTightenKnot,      
00173         int & numOfCrossingsOfTheFinishTightenKnot  
00174     );
00175 
00177     class AnimatedKnot {
00178     public:
00179         AnimatedKnot ( int animatedKnotID = 0 )
00180             : NumOfCrossings(0)
00181             , KnotIDStart(-1)
00182             , KnotIDStart_Limit(-1)
00183             , KnotIDEnd_Limit(-1)
00184             , KnotIDEnd(-1)
00185             , KnotSizeLimit( 1 )
00186             , KnotType( Data::DatabaseDowkerNotation::UNDEFINED )
00187             , StepsLeftForSettingKnot( 0 )
00188             , IsKnotTight( false )
00189             , IsOrientationFixed( false )
00190             , m_iID( animatedKnotID )
00191             , m_bCalKnotLocation( true )
00192         #ifdef  TAPs_SPECIFIC_FOR_SUTUREAPP_02
00193             , pKnotTightenStatus( NULL )        
00194         #endif//TAPs_SPECIFIC_FOR_SUTUREAPP_02
00195         {}
00196 
00197         ~AnimatedKnot () {}     // Nothing to delete here
00198 
00199         AnimatedKnot & operator= ( AnimatedKnot const& orig )
00200         {
00201             m_iID = orig.m_iID;
00202 
00203             KnotIDStart = orig.KnotIDStart;
00204             KnotIDStart_Limit = orig.KnotIDStart_Limit;
00205             KnotIDEnd_Limit = orig.KnotIDEnd_Limit;
00206             KnotIDEnd = orig.KnotIDEnd;
00207             KnotSizeLimit = orig.KnotSizeLimit;
00208             KnotType = orig.KnotType;
00209             NumOfCrossings = orig.NumOfCrossings;
00210             StepsLeftForSettingKnot = orig.StepsLeftForSettingKnot;
00211             Orientation = orig.Orientation;
00212             Center = orig.Center;
00213             m_bCalKnotLocation = orig.m_bCalKnotLocation;
00214             IsKnotTight = orig.IsKnotTight;
00215             IsOrientationFixed = orig.IsOrientationFixed;
00216         #ifdef  TAPs_SPECIFIC_FOR_SUTUREAPP_02
00217             pKnotTightenStatus = orig.pKnotTightenStatus;
00218         #endif//TAPs_SPECIFIC_FOR_SUTUREAPP_02
00219 
00220             return *this;
00221         }
00222 
00223         int KnotIDStart;        
00224         int KnotIDStart_Limit;  
00225         int KnotIDEnd_Limit;    
00226         int KnotIDEnd;          
00227         int KnotSizeLimit;      
00228         Data::DatabaseDowkerNotation::KNOT  KnotType;
00229         int NumOfCrossings;     
00230         int StepsLeftForSettingKnot;    
00231 
00232         Vector3<T>      Center;             
00233         Matrix4x4<T>    Orientation;        
00234         bool            IsOrientationFixed; 
00235 
00236         bool IsKnotTight;   
00237 
00238         int GetID ()    { return m_iID; }
00239 
00240         bool GetStatusCalKnotPosition () const  { return m_bCalKnotLocation; }
00241         void SetStatusCalKnotPosition ( bool b )    { m_bCalKnotLocation = b; }
00242 
00243     #ifdef  TAPs_SPECIFIC_FOR_SUTUREAPP_02
00244         bool * pKnotTightenStatus;  
00245     #endif//TAPs_SPECIFIC_FOR_SUTUREAPP_02
00246 
00247     protected:
00248         int     m_iID;              
00249         bool    m_bCalKnotLocation; 
00250     };
00251 
00252 protected:
00253     std::vector< AnimatedKnot > m_ListOfAnimatedKnot;   // list of animated knot
00254 public:
00255 
00257     bool GetStatusKnotAnimation ()  const { return m_ListOfAnimatedKnot.size() > 0; }
00259     unsigned int GetNumberOfAnimatedKnots () const { return m_ListOfAnimatedKnot.size(); }
00261     AnimatedKnot *  GetTheLastAnimatedKnot ()
00262     {
00263         if ( KnotAnimationStatus )  return *m_ListOfAnimatedKnot.back();
00264         else return NULL;
00265     }
00266 
00271     bool AddAnimatedKnot ( 
00272     #ifdef  TAPs_SPECIFIC_FOR_SUTUREAPP_02
00273         bool * pKnotTightenStatus,                  
00274     #endif//TAPs_SPECIFIC_FOR_SUTUREAPP_02
00275         int grabbedNodeID,                          
00276         Data::DatabaseDowkerNotation::KNOT knot,    
00277         int startNodeIDLimit = -1,                  
00278         int endNodeIDLimit = -1,                        
00279         bool bCalKnotPosition = true,               
00280         bool bEndIsGrabbed = true,                  
00281         int offset = 5,                             
00282         Matrix4x4<T> * pOrientation = NULL          
00283     );
00284 
00289     bool AddAnimatedKnot ( 
00290     #ifdef  TAPs_SPECIFIC_FOR_SUTUREAPP_02
00291         bool * pKnotTightenStatus,                  
00292     #endif//TAPs_SPECIFIC_FOR_SUTUREAPP_02
00293         Data::DatabaseDowkerNotation::KNOT knot,    
00294         int startNodeIDLimit = -1,                  
00295         int startLoopNodeIDLimit = -1,              
00296         int endLoopNodeIDLimit = -1,                    
00297         int endNodeIDLimit = -1,                        
00298         bool bCalKnotPosition = true,               
00299         bool bEndIsGrabbed = true,                  
00300         Matrix4x4<T> * pOrientation = NULL          
00301     );
00302 
00303 protected:
00304     AnimatedKnot    m_AnimatedKnot; 
00305     Matrix4x4<T>    m_OrientationForCombinedKnot;   
00306 
00307 #endif//TAPs_ADD_ANIMATED_KNOTS
00308     //---------------------------------------------------------------
00309     // Animating Knot Tying
00310     //===============================================================
00311 
00312 public:
00313 
00315     //virtual std::vector< BVHNode<T> * > & GetListOfCollidedNodes()        { return m_svCollidedNode; }
00317     //virtual std::vector< BVHNode<T> * > & GetListOfCollidedNodesThat()    { return m_svCollidedNodeThat; }
00318 
00320     bool SetKnotControlThreshold ( enum Threshold thdID, T val );
00322     T GetKnotControlThreshold ( enum Threshold thdID ) const;
00323 
00325     void GetCurrentTrackingKnot_StartAndEndLinkIDs (
00326         int & startLink,    
00327         int & endLink       
00328     );
00329 
00331     unsigned int    GetNumOfKnotsAllowed () const   { return static_cast<unsigned int>( m_ucMaxNumKnotsAllowed ); }
00332 
00334     unsigned int    GetKnotCount () const   { return static_cast<unsigned int>( m_ucKnotCount ); }
00335 
00337     void GetKnotStartAndEndLinkID ( unsigned int knotID, unsigned int & start, unsigned int & end ) const
00338     {
00339         if ( knotID < GetKnotCount() ) {
00340             start = m_pListOfLockedKnots[knotID].StartLinkID;
00341             end = m_pListOfLockedKnots[knotID].EndLinkID;
00342         }
00343     }
00344 
00346     void GetKnotStartLoopLinkAndEndLinkLoopLinkID ( unsigned int knotID, unsigned int & startLoopLink, unsigned int & endLoopLink ) const
00347     {
00348         if ( knotID < GetKnotCount() ) {
00349             startLoopLink = m_pListOfLockedKnots[knotID].StartLoopLinkID;
00350             endLoopLink = m_pListOfLockedKnots[knotID].EndLoopLinkID;
00351         }
00352     }
00353 
00355     bool IsKnotLocationLocked ( unsigned int knotID ) const
00356     {
00357         if ( knotID < GetKnotCount() )  return m_pListOfLockedKnots[knotID].DoLockLocation;
00358         else                            return false;
00359     }
00360 
00362     void SetStatusKnotLocationLocked ( unsigned int knotID, bool b )
00363     {
00364         if ( knotID < GetKnotCount() )  m_pListOfLockedKnots[knotID].DoLockLocation = b;
00365     }
00366 
00368     Vector3<T> GetKnotCenter ( unsigned int knotID ) const
00369     {
00370         if ( knotID < GetKnotCount() )  return m_pListOfLockedKnots[knotID].Center;
00371         else                            return Vector3<T>();
00372     }
00374     void SetKnotCenter ( unsigned int knotID, Vector3<T> & center )
00375     {
00376         if ( knotID < GetKnotCount() )  m_pListOfLockedKnots[knotID].Center = center;
00377     }
00378 
00380     Quaternion<T> GetKnotOrientation ( unsigned int knotID ) const
00381     {
00382         if ( knotID < GetKnotCount() )  return m_pListOfLockedKnots[knotID].Orientation;
00383         else                            return Quaternion<T>();
00384     }
00386     void SetKnotOrientation ( unsigned int knotID, Quaternion<T> & orientation )
00387     {
00388         if ( knotID < GetKnotCount() )  return m_pListOfLockedKnots[knotID].Orientation = orientation;
00389     }
00390 
00392     //void GetApproxKnotCenterAndOrientation ( unsigned int i, Vector3<T> &center, Quaternion<T> &orientation );
00393 
00394     // Data Members -----------------------------------------------------------
00395 //=============================================================================
00396 protected:
00397     // Member Functions -------------------------------------------------------
00398     // Data Members -----------------------------------------------------------
00399 //=============================================================================
00400 private:
00401     // Member Functions -------------------------------------------------------
00402 
00404     inline void SetTheShapeOfAnimatedKnot ( AnimatedKnot & knot );
00405 
00407     inline void FinalizeTheShapeOfAnimatedKnot ( AnimatedKnot & knot );
00408 
00410     void CreateData ( unsigned char numKnotAllowed = 8 );
00412     void DeleteData ();
00413 
00416     inline Vector3<T> GetProjDirection () const;
00417 
00419     int CheckSelfCrossingForKnotRecognition ( Vector3<T> const & projectionDirection );
00420 
00422     void CheckSelfCrossingsNextLevelRecursively (
00423             BVHNode<T> * node1, BVHNode<T> * node2, 
00424             Vector3<T> const & projectionDirection 
00425     );
00427     T    CheckSelfCrossingsRecursively ( 
00428             BVHNode<T> * node1, BVHNode<T> * node2, 
00429             Vector3<T> const & projectionDirection 
00430     );
00432     T    TestOverlapCircle ( 
00433             BVHNode<T> * node1, BVHNode<T> * node2, 
00434             Vector3<T> const & projectionDirection 
00435     );
00437     void CheckCrossings ( 
00438             BVHNode<T> * node1, BVHNode<T> * node2, 
00439             Vector3<T> const & projectionDirection 
00440     );
00441 
00443     int GetKnotStartPt () const { return m_iKnotStartPt; };
00445     int GetKnotEndPt () const   { return m_iKnotEndPt; };
00446 
00450     void RecordKnot ( int startLink, int endLink, int knotID );
00451 
00456     void RecordKnot ( int startLink, int startLoopLink, int endLoopLink, int endLink, int knotID );
00457 
00470     int ConverseDowkerNotationToKnotName ( std::string * knotName = NULL );
00471 
00472     // The links for accessing the properties of the elastic rod
00473     int *                       m_pIdxCurr;     
00474     int *                       m_pIdxNext;     
00475     ElasticRodParameters<T> *   m_pParameters;  
00476     SetOfElasticRodNodes *      m_pNodeList;    
00477     //std::vector< BVHNode<T> * > m_svCollidedNode;     //!< list of collided nodes for collision detection
00478     //std::vector< BVHNode<T> * > m_svCollidedNodeThat; //!< list of other object BVH tree's collided nodes for collision detection
00479     BVHTree<T> *    m_BVHTree;  
00480 
00481     unsigned char   m_ucMaxNumKnotsAllowed; 
00482     unsigned char   m_ucKnotCount;          
00483 
00484     class IC_LockedKnot {
00485     public:
00486         IC_LockedKnot () 
00487             : ID(-1)
00488             , StartLinkID(-1)
00489             , StartLoopLinkID(-1)
00490             , EndLoopLinkID(-1)
00491             , EndLinkID(-1)
00492             , DoLockLocation( false )
00493         {
00494             Center.SetXYZ( 0, 0.5, 0 );
00495         }
00496 
00497         ~IC_LockedKnot () {};
00498 
00499         IC_LockedKnot & operator= ( IC_LockedKnot const & orig )
00500         {
00501             ID = orig.ID;
00502             StartLinkID = orig.StartLinkID;
00503             StartLoopLinkID = orig.StartLoopLinkID;
00504             EndLoopLinkID = orig.EndLoopLinkID;
00505             EndLinkID = orig.EndLinkID;
00506             DoLockLocation = orig.DoLockLocation;
00507         }
00508 
00509         void Reset ()
00510         {
00511             ID = -1;
00512             StartLinkID = -1;
00513             StartLoopLinkID = -1;
00514             EndLoopLinkID = -1;
00515             EndLinkID = -1;
00516             DoLockLocation = false;
00517         }
00518 
00519         int ID;                 
00520         int StartLinkID;        
00521         int StartLoopLinkID;    
00522         int EndLoopLinkID;      
00523         int EndLinkID;          
00524 
00525         Vector3<T>      Center;         
00526         Quaternion<T>   Orientation;    
00527         bool            DoLockLocation; 
00528     };
00529 
00530     IC_LockedKnot * m_pListOfLockedKnots;
00531 
00532     int m_iMinPtIdThatIsInRecordedKnots;
00533     int m_iMaxPtIdThatIsInRecordedKnots;
00534 
00537     unsigned int    m_uiMinLengthThreshold;     
00538     unsigned int *  m_puiLengthThresholds;      
00539     unsigned int    m_uiLengthAccumulateTarget; 
00540 
00541     int     m_ucTrackingKnot;           
00542     int     m_KnotLinkStartTempRecord;  
00543     int     m_KnotLinkEndTempRecord;    
00544     //Data::KnotTrackingConstraint<T>   m_KnotTrackingConstraint;   //!< a knot tracking constraint
00545 
00548     unsigned int    m_uiCounterThreshold;       
00549     unsigned int    m_uiCounterForFixingKnot;
00550     T               m_tWaitTime;                
00551     T               m_tAccTime;                 
00552 
00553     ElasticRodNode<T> * m_NodesForProjPoints[3];    
00554 
00555     int     m_iMaxCrossingPairs, m_iNumCrossingPairs;   
00556     int *   m_iaDowkerNotation;                         
00557     int     m_iKnotStartPt, m_iKnotEndPt;               
00558 
00608     int *   m_iaCrossingCounters;
00609     class IC_Crossing {
00610     public:
00611         int number, id;
00612         IC_Crossing( int number, int id )   { this->number = number; this->id = id; }
00613     };
00614     std::list< IC_Crossing > m_crossings;   
00615     void InsertToList( int number, int id )
00616     {
00617         // Add at the start
00618         if ( m_crossings.size() == 0 ) {
00619             m_crossings.push_back( IC_Crossing( number, id ) );
00620             return;
00621         }
00622         // Insert in a middle
00623         std::list< IC_Crossing >::iterator it = m_crossings.begin();
00624         while ( it != m_crossings.end() ) {
00625             if ( (*it).id > id ) {
00626                 m_crossings.insert( it, IC_Crossing( number, id ) );
00627                 return;
00628             }
00629             ++it;
00630         }
00631         // Add at the end
00632         m_crossings.push_back( IC_Crossing( number, id ) );
00633     }
00634 
00635     // Manage time
00636     time_t          m_StartTime;
00637     inline void ResetStartTime ()
00638     {
00639         time( &m_StartTime );   // reset time
00640     }
00641     inline void ResetElapsedTime ()
00642     {
00643         time( &m_StartTime );   // reset time
00644         m_tAccTime = 0.0;
00645     }
00646     inline double AddElapsedTime ()
00647     {
00648         time_t prevTime = m_StartTime;
00649         time( &m_StartTime );   // new start time
00650         // difftime fn is from <ctime>
00651         m_tAccTime += difftime( m_StartTime, prevTime );
00652 
00653         return m_tAccTime;
00654     }
00655     inline bool IsTimeLimitReached ()
00656     {
00657         return m_tAccTime >= m_tWaitTime;
00658     }
00659 
00660 
00661     //*
00662     // DEBUG
00663     std::vector<int> debug_crosses;
00664     std::vector<int> debug_crossesID;
00665 
00666     std::string Debug_Str ()
00667     {
00668         std::ostringstream ss;
00669         ss << "# of crossing pairs: " << m_iNumCrossingPairs << "\n";
00670         ss << "Cross#: ";
00671         for ( int i = 0; i < static_cast<int>(debug_crosses.size()); ++i ) {
00672             ss << "\t" << debug_crosses[i];
00673         }
00674         ss << "\n";
00675 
00676         ss << "ID#:    ";
00677         for ( int i = 0; i < static_cast<int>(debug_crossesID.size()); ++i ) {
00678             ss << "\t" << debug_crossesID[i];
00679         }
00680         ss << "\n";
00681 
00682         ss << "Dowker#:";
00683         for ( int i = 0; i < static_cast<int>(debug_crossesID.size()); ++i ) {
00684             ss << "\t" << m_iaDowkerNotation[i];
00685         }
00686         ss << "\n";
00687 
00688         //ss << "Recognized Knot ID: " << special_debug_knotID << "\n";
00689 
00690         ss << "Tracking Knot: " << m_ucTrackingKnot
00691            << "  Accumulate: " << m_uiCounterForFixingKnot
00692            << "  Knot Len: " << GetKnotEndPt() << " - " << GetKnotStartPt() << " = " << GetKnotEndPt() - GetKnotStartPt()
00693            << "  Acc Length: " << m_uiLengthAccumulateTarget
00694            << "  m_uiMinLengthThreshold: " << m_uiMinLengthThreshold
00695            << "\n\n";
00696 
00697         return ss.str();
00698     }
00699     //*/
00700 
00701 //=============================================================================
00702 
00703 //OpenGL
00704 //-----------------------------------------------------------------------------
00705 //#define __GL_H__
00706 //#define   TAPs_USE_GLSL
00707 //-----------------------------------------------------------------------------
00708 #if defined(__gl_h_) || defined(__GL_H__)
00709 public:
00711     inline virtual void Draw () const;
00712     
00714     inline virtual void DrawForDebug () const;
00715 
00716     //OpenGL::OpenGLObj Rendering;  //!< OpenGL Object has material color properties
00717 protected:
00718     OpenGL::OpenGLUsefulObj<T>  * m_pOGLUsefulObj;  
00719 
00720 #endif//defined(__gl_h_) || defined(__GL_H__)
00721 //-----------------------------------------------------------------------------
00722 //=============================================================================
00723 }; // CLASS END: ElasticRodKR
00724 //=============================================================================
00725 END_NAMESPACE_TAPs
00726 //-----------------------------------------------------------------------------
00727 #include "TAPsElasticRodKR.cpp"
00728 //-----------------------------------------------------------------------------
00729 #endif
00730 //34567890123456789012345678901234567890123456789012345678901234567890123456789
00731 //--+----1----+----2----+----3----+----4----+----5----+----6----+----7----+----
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines