TAPs 0.7.7.3
TAPsModelElasticRod.hpp
Go to the documentation of this file.
00001 /******************************************************************************
00002 TAPsModelEasticRod.hpp
00003 ******************************************************************************/
00058 /******************************************************************************
00059 SUKITTI PUNAK   (07/07/2009)
00060 UPDATE          (01/27/2010)
00061 ******************************************************************************/
00062 #ifndef TAPs_MODEL_ELASTIC_ROD_HPP
00063 #define TAPs_MODEL_ELASTIC_ROD_HPP
00064 
00065 
00066 //#define USE_CORDE_SIM
00067 
00068 
00069 // FOR TIMING
00070 #define ER_TIMING_ADV_SIM   0
00071 #define ER_TIMING_ADV_SIM_STOP      10000.0
00072 #define ER_TIMING_RENDERING 0
00073 #define ER_TIMING_RENDERING_STOP    10000.0
00074 
00075 #if ER_TIMING_ADV_SIM != 0
00076 #define ER_TIMING_ADV_SIM_DETAILS 1     // ER_TIMING_ADV_SIM has to be 1 in order for this to be effective
00077 #endif
00078 
00079 // For knot recognition
00081 //#define   TAPs_ADD_KNOT_RECOGNITION
00083 #ifdef  TAPs_ADD_KNOT_RECOGNITION
00084 
00085 
00086 
00087 
00088     #ifndef TAPs_ADVANCED_SIMULATION
00089         #define TAPs_ADVANCED_SIMULATION
00090     #endif
00091     #ifdef  TAPs_ADVANCED_SIMULATION
00092         //#include "../Support/TAPsAdvSimSupport_DS.hpp"
00093         #include "ElasticRodSupport/TAPsElasticRodKR.hpp"
00094     #endif//TAPs_ADVANCED_SIMULATION
00095 #endif//TAPs_ADD_KNOT_RECOGNITION
00096 
00098 //#define   TAPs_ADD_INTERACTIONS
00100 #ifdef  TAPs_ADD_INTERACTIONS
00101     #ifndef TAPs_ADVANCED_SIMULATION
00102         #define TAPs_ADVANCED_SIMULATION
00103     #endif//TAPs_ADVANCED_SIMULATION
00104     //#include "../Physics/TAPsForces.hpp"
00105     //#include "../Support/TAPsAdvSimCtrl.hpp"
00106 #endif//TAPs_ADD_INTERACTIONS
00107 
00109 //#define   TAPs_ADVANCED_SELF_COLLISION_DETECTION
00111 #ifdef  TAPs_ADVANCED_SELF_COLLISION_DETECTION
00112 #endif//TAPs_ADVANCED_SELF_COLLISION_DETECTION
00113 
00114 
00115 #include "ElasticRodSupport/TAPsElasticRodParameters.hpp"
00116 #include "ElasticRodSupport/TAPsElasticRodNode.hpp"
00117 
00118 // For collision detection
00119 #include "ElasticRodSupport/TAPsElasticRodCD.hpp"
00120 
00121 // For drawing by OpenGL
00122 #if defined(__gl_h_) || defined(__GL_H__)
00123     #include "../OpenGL/TAPsOpenGLObj.hpp"
00124 #endif
00125 
00127 #define TAPs_ER_DRAW_WITH_SUBDIVISION
00128 
00129 #ifdef  TAPs_ER_DRAW_WITH_SUBDIVISION
00130 #endif//TAPs_ER_DRAW_WITH_SUBDIVISION
00131 
00132 #ifdef  TAPs_USE_CUDA
00133     #include "ElasticRodSupport/TAPsElasticRod_CompByCUDA.hpp"
00134 #endif//TAPs_USE_CUDA
00135 
00136 // For GUIs by wxWidgets
00137 #ifdef  TAPs_USE_WXWIDGETS
00138     #include "../wxWidgets/Dialogs/TAPsWXElasticRodParameters.hpp"
00139 #endif//TAPs_USE_WXWIDGETS
00140 
00141 
00142 BEGIN_NAMESPACE_TAPs
00143 //=============================================================================
00144 template <typename T>
00145 class ModelElasticRod {
00146 
00147     // Member Functions -------------------------------------------------------
00149     friend std::ostream & operator<< ( std::ostream &output, ModelElasticRod<T> const &obj )
00150     {
00151         output << obj.StrInfo();
00152         return output;
00153     }
00154 
00155 public:
00156     //enum Shape {
00157     //  STRAIGHT_SHAPE,
00158     //  HELIX_SHAPE,
00159     //};    //!< List of initial shapes
00160 
00161     // For initializing the start shape
00162     class ShapeInitializationParameters {
00163     public:
00164         enum Shape {
00165             STRAIGHT_SHAPE,
00166             HELIX_SHAPE,
00167         };  
00168 
00169         ShapeInitializationParameters () : Helix_Radius( 0.5 ), Helix_Pitch( 0.2 ), StartShape( STRAIGHT_SHAPE ) {}
00170         T Helix_Radius;
00171         T Helix_Pitch;
00172         Shape StartShape;
00173     };
00174     ShapeInitializationParameters   InitShapeParameters;    
00175 
00176     typedef std::vector< ElasticRodNode<T> >    SetOfElasticRodNodes;
00177     //-------------------------------------------------------------------------
00179     ModelElasticRod (
00180         int iNoLinks,       
00181         T tRadius,          
00182         T tTotalLength,     
00183         T tTotalMass,       
00184         Vector3<T> & posOfVertex0 = Vector3<T>(),   
00185         ShapeInitializationParameters ShapeParameters = ShapeInitializationParameters() 
00186     #ifdef  TAPs_USE_CUDA
00187         ,
00188         bool    bUseCUDAsPLHM = true 
00189     #endif//TAPs_USE_CUDA
00190     );
00191 
00193     //ModelElasticRod ( ModelElasticRod<T> const &obj );
00194 
00196     ModelElasticRod<T> * CopySegment ( int startLink, int endLink );
00197 
00199     virtual ~ModelElasticRod ();
00200 
00201     //-------------------------------------------------------------------------
00203     virtual std::string StrInfo () const;
00204 
00205     //-------------------------------------------------------------------------
00207     //inline ModelElasticRod<T> & operator= ( ModelElasticRod<T> const &v );
00208 
00209     //-------------------------------------------------------------------------
00210     // Get/Set Fn(s)
00211     // Self Collision Detection -----------------
00213     inline void EnableSelfCollision ( bool b = true )   { m_Parameters.EnableSelfCDR = b; }
00215     inline void DisableSelfCollision ( bool b = true )  { m_Parameters.EnableSelfCDR = !b; }
00217     inline T    GetConstantSelfCollisionResponse () const   { return m_Parameters.KselfCDR; }
00219     inline void SetConstantSelfCollisionResponse ( T k )    { m_Parameters.KselfCDR = k; }
00221     inline T    GetDistanceScaleForConstantSelfCollisionResponse () const   { return m_Parameters.KselfCDR_ScaleDistance; }
00223     inline void SetDistanceScaleForConstantSelfCollisionResponse ( T s )    { m_Parameters.KselfCDR_ScaleDistance = s; }
00225     inline ElasticRodCD<T> &        CDUnit ()       { return m_CD; }
00227     inline ElasticRodCD<T> const &  CDUnit () const { return m_CD; }
00228 
00230     inline T    GetConstantCollisionResponseWithCylinderBV () const { return m_Parameters.K_CDRwBV_Cylinder; }
00232     inline void SetConstantCollisionResponseWithCylinderBV ( T k )  { m_Parameters.K_CDRwBV_Cylinder = k; }
00234     inline T    GetConstantCollisionResponseWithSphereBV () const   { return m_Parameters.K_CDRwBV_Sphere; }
00236     inline void SetConstantCollisionResponseWithSphereBV ( T k )    { m_Parameters.K_CDRwBV_Sphere = k; }
00238     inline T    GetConstantCollisionResponseWithTriangle () const   { return m_Parameters.K_CDRwTriangle; }
00240     inline void SetConstantCollisionResponseWithTriangle ( T k )    { m_Parameters.K_CDRwTriangle = k; }
00241 
00242 #ifdef  TAPs_ADD_RESTING_LEVEL_Y
00243 
00244     inline virtual void SetRestingLevel ( T y ) { m_Parameters.RestingLevel = y; }
00245 #endif//TAPs_ADD_RESTING_LEVEL_Y
00246 
00247 #ifdef  TAPs_ADD_KNOT_RECOGNITION
00248     // Knot Recognition -------------------------
00250     inline void EnableKnotRecognition ( bool b = true )     { m_Parameters.EnableKR = b; }
00252     inline void DisableKnotRecognition ( bool b = true )    { m_Parameters.EnableKR = !b; }
00254     inline void EnableLockKnots ( bool b = true )   { m_Parameters.EnableKR_LockKnots = b; }
00256     inline void DisableLockKnots ( bool b = true )  { m_Parameters.EnableKR_LockKnots = !b; }
00257 
00259     inline T    GetConstantStickPair () const   { return m_Parameters.KstickPair; }
00261     inline void SetConstantStickPair ( T k )    { m_Parameters.KstickPair = k; }
00262 
00264     unsigned int    GetNumOfKnots () const      { return m_KR.GetKnotCount(); }
00266     unsigned int    GetNumberOfKnots () const   { return m_KR.GetKnotCount(); }
00267 
00268 #endif//TAPs_ADD_KNOT_RECOGNITION
00269 
00270 
00272     static inline int   GetNumberOfElasticRods () { return g_NumOfElasticRods; }
00274     static inline int   GetNumOfElasticRods () { return g_NumOfElasticRods; }
00275 
00277     inline int  GetID () const  { return m_ID; }
00278 
00280     inline ElasticRodParameters<T> const & RefToParameters () const { return m_Parameters; }
00281 
00283     inline virtual int  GetNumOfPoints () const     { return m_Parameters.NumOfNodes; }
00285     inline virtual int  GetNumberOfPoints () const  { return m_Parameters.NumOfNodes; }
00287     inline virtual int  GetNumOfLinks () const      { return m_Parameters.NumOfNodes-1; }
00289     inline virtual int  GetNumberOfLinks () const   { return m_Parameters.NumOfNodes-1; }
00291     inline T    GetTotalLength () const { return m_Parameters.TotalLength; }
00293     inline T    GetLinkLength () const  { return m_Parameters.LinkLength; }
00295     inline T    GetTotalMass () const   { return m_Parameters.TotalMass; }
00297     inline T    GetRadius () const  { return m_Parameters.Radius; }
00298 
00300     inline T    GetSimTimeStep () const { return m_Parameters.TimeStep; }
00302     inline void SetSimTimeStep ( T h )  { m_Parameters.TimeStep = h; }
00303 
00305     inline unsigned int GetSimIterationTimes () const   { return m_Parameters.SimIterationTimes; }
00307     inline void SetSimIterationTimes ( unsigned int times ) { m_Parameters.SimIterationTimes = times; }
00308 
00310     inline T    GetConstantPotentialStretch () const    { return m_Parameters.Ps; }
00312     inline void SetConstantPotentialStretch ( T k )     { m_Parameters.Ps = k; }
00313 
00315     inline void GetConstantPotentialBend ( T k[3] ) const   { k[0]=m_Parameters.Pb[0]; k[1]=m_Parameters.Pb[1]; k[2]=m_Parameters.Pb[2]; }
00317     inline void GetConstantPotentialBend ( T &k0, T &k1, T &k2 ) const  { k0=m_Parameters.Pb[0]; k1=m_Parameters.Pb[1]; k2=m_Parameters.Pb[2]; }
00319     inline void SetConstantPotentialBend ( T k[3] ) { m_Parameters.Pb[0]=k[0]; m_Parameters.Pb[1]=k[1]; m_Parameters.Pb[2]=k[2]; }
00321     inline void SetConstantPotentialBend ( T k0, T k1, T k2 )   { m_Parameters.Pb[0]=k0; m_Parameters.Pb[1]=k1; m_Parameters.Pb[2]=k2; }
00322 
00324     inline T    GetConstantKineticTranslational () const    { return m_Parameters.Kt; }
00326     inline void SetConstantKineticTranslational ( T k )     { m_Parameters.Kt = k; }
00327 
00329     inline void GetConstantKineticRotational ( T k[3] ) const   { k[0]=m_Parameters.Kr[0]; k[1]=m_Parameters.Kr[1]; k[2]=m_Parameters.Kr[2]; }
00331     inline void GetConstantKineticRotational ( T &k0, T &k1, T &k2 ) const  { k0=m_Parameters.Kr[0]; k1=m_Parameters.Kr[1]; k2=m_Parameters.Kr[2]; }
00333     inline void SetConstantKineticRotational ( T k[3] ) { m_Parameters.Kr[0]=k[0]; m_Parameters.Kr[1]=k[1]; m_Parameters.Kr[2]=k[2]; }
00335     inline void SetConstantKineticRotational ( T k0, T k1, T k2 )   { m_Parameters.Kr[0]=k0; m_Parameters.Kr[1]=k1; m_Parameters.Kr[2]=k2; }
00336 
00338     inline T    GetConstantDissipationTranslational () const    { return m_Parameters.Dt; }
00340     inline void SetConstantDissipationTranslational ( T k )     { m_Parameters.Dt = k; }
00341 
00343     inline void GetConstantDissipationRotational ( T k[3] ) const   { k[0]=m_Parameters.Dr[0]; k[1]=m_Parameters.Dr[1]; k[2]=m_Parameters.Dr[2]; }
00345     inline void GetConstantDissipationRotational ( T &k0, T &k1, T &k2 ) const  { k0=m_Parameters.Dr[0]; k1=m_Parameters.Dr[1]; k2=m_Parameters.Dr[2]; }
00347     inline void SetConstantDissipationRotational ( T k[3] ) { m_Parameters.Dr[0]=k[0]; m_Parameters.Dr[1]=k[1]; m_Parameters.Dr[2]=k[2]; }
00349     inline void SetConstantDissipationRotational ( T k0, T k1, T k2 )   { m_Parameters.Dr[0]=k0; m_Parameters.Dr[1]=k1; m_Parameters.Dr[2]=k2; }
00350 
00352     inline T    GetConstantConstraint_3rdDirAlignTangent () const   { return m_Parameters.Kconstraint_3rdDirAlignTangent; }
00354     inline void SetConstantConstraint_3rdDirAlignTangent ( T k )    { m_Parameters.Kconstraint_3rdDirAlignTangent = k; }
00355 
00357     inline T    GetConstantConstraint_ScaleIntrinsicStrainRate () const { return m_Parameters.Kconstraint_ScaleIntrinsicStrainRate; }
00359     inline void SetConstantConstraint_ScaleIntrinsicStrainRate ( T k )  { m_Parameters.Kconstraint_ScaleIntrinsicStrainRate = k; }
00360 
00362     inline T    GetConstantDampingVelocity () const { return 1-m_Parameters.Kvdamping; }
00364     inline void SetConstantDampingVelocity ( T k )  { m_Parameters.Kvdamping = 1-k; }
00365 
00367     inline T    GetGravitationalConstant () const   { return m_Parameters.Kgravity; }
00369     inline void SetGravitationalConstant ( T k )    { m_Parameters.Kgravity = -k; }
00370 
00372     inline T    GetStretchModulus () const;
00374     inline void SetStretchModulus ( T k );
00375 
00377     inline T    GetBendModulus () const;
00379     inline void SetBendModulus ( T k );
00380 
00382     inline T    GetShearModulus () const;
00384     inline void SetShearModulus ( T k );
00385 
00387     inline T    GetMaterialDensity () const;
00389     inline void SetMaterialDensity ( T material_density );
00390 
00392     inline void SetMaterialProperties ( T stretch_modulus, T bend_modulus, T shear_modulus, T material_density );
00393 
00395     inline SetOfElasticRodNodes &       GetListOfNodes ()       { return m_Nodes; }
00397     inline SetOfElasticRodNodes const & GetListOfNodes () const { return m_Nodes; }
00398 
00400     inline Vector3<T> const & RefToCurrentVertexPositionOfNodeNumber ( unsigned int id ) const  { return m_Nodes[id].Centerline[IdxCurr].GetPosition(); }
00402     inline Vector3<T> const & RefToPreviousVertexPositionOfNodeNumber ( unsigned int id ) const { return m_Nodes[id].Centerline[IdxPrev].GetPosition(); }
00404     inline Vector3<T> & RefToCurrentVertexPositionOfNodeNumber ( unsigned int id )  { return m_Nodes[id].Centerline[IdxCurr].GetPosition(); }
00406     inline Vector3<T> & RefToPreviousVertexPositionOfNodeNumber ( unsigned int id ) { return m_Nodes[id].Centerline[IdxPrev].GetPosition(); }
00407 
00409     inline Quaternion<T> const & RefToCurrentOrientationOfLinkNumber ( unsigned int id ) const  { return m_Nodes[id].Orientation[IdxCurr]; }
00411     inline Quaternion<T> const & RefToPreviousOrientationOfLinkNumber ( unsigned int id ) const { return m_Nodes[id].Orientation[IdxPrev]; }
00413     inline Quaternion<T> & RefToCurrentOrientationOfLinkNumber ( unsigned int id )  { return m_Nodes[id].Orientation[IdxCurr]; }
00415     inline Quaternion<T> & RefToPreviousOrientationOfLinkNumber ( unsigned int id ) { return m_Nodes[id].Orientation[IdxPrev]; }
00416 
00418     inline Vector3<T> const & RefToCurrentVertexForceOfNodeNumber ( unsigned int id ) const     { return m_Nodes[id].Centerline[IdxCurr].GetForce(); }
00420     inline Vector3<T> const & RefToPreviousVertexForceOfNodeNumber ( unsigned int id ) const    { return m_Nodes[id].Centerline[IdxPrev].GetForce(); }
00422     inline Vector3<T> & RefToCurrentVertexForceOfNodeNumber ( unsigned int id )     { return m_Nodes[id].Centerline[IdxCurr].GetForce(); }
00424     inline Vector3<T> & RefToPreviousVertexForceOfNodeNumber ( unsigned int id )    { return m_Nodes[id].Centerline[IdxPrev].GetForce(); }
00425 
00427     inline int  GetCurrentIndex ()  { return IdxCurr; }
00429     inline int  GetPreviousIndex () { return IdxPrev; }
00430 
00431     //-------------------------------------------------------------------------
00432     // Operations
00433 
00435     virtual void    Reset ();
00436 
00438     inline Vector3<T>   GetPosOfStartPt ();
00440     inline Vector3<T>   GetPosOfEndPt ();
00442     inline void SetPosOfStartPt ( Vector3<T> const & pos, Quaternion<T> const & ori = Quaternion<T>() );
00444     inline void SetPosOfEndPt ( Vector3<T> const & pos, Quaternion<T> const & ori = Quaternion<T>() );
00446     inline void MovePosOfStartPt ( Vector3<T> const & pos, Quaternion<T> const & ori = Quaternion<T>() );
00448     inline void MovePosOfEndPt ( Vector3<T> const & pos, Quaternion<T> const & ori = Quaternion<T>() );
00449 
00451     inline virtual void ClearExternalForces ();
00452 
00454     //
00461     inline virtual void ClearExternalForces_Reserved ();
00462 
00464     inline virtual bool CDRwith (
00465         MultiBoundingVolume<T> * const pMBVObj,     
00466         TransformationSupport<T> * const pTransform 
00467     );
00468 
00470     inline virtual bool CDRwith (
00471         TAPs::OpenGL::HETriMeshOneModelMultiParts<T> * pObj,    
00472         TransformationSupport<T> * const pTransform             
00473     );
00474 
00487     virtual void    AdvanceSimulation ();
00488 
00496     virtual int FindTheClosestPointToPoint ( 
00497         Vector3<T> const & closeToPoint,    
00498         T distance_limit                    
00499     ) const;
00500 
00509     inline virtual bool PickAt (
00510         Vector3<T> const & closeToPoint,    
00511         T distance_limit,                   
00512         int & pickedID                      
00513     );
00514 
00518     inline virtual void PickPoint (
00519         int pickedID            
00520     );
00521 
00525     inline virtual void MovePickedPoint (
00526         int pickedID,           
00527         Vector3<T> & position   
00528     );
00529 
00533     inline virtual void UnpickPoint (
00534         int pickedID            
00535     );
00536 
00537     // Data Members -----------------------------------------------------------
00538 //=============================================================================
00539 protected:
00540     // Member Functions -------------------------------------------------------
00541 
00543     inline virtual void ClearInternalForces ();
00544 
00545 public:
00547     inline virtual void StoreInternalForces ();
00548 
00550     inline virtual void RestoreInternalForces ();
00551 protected:
00552 
00554     inline void AdvSimLoop ();
00555 
00557     void    Initialize ( enum ShapeInitializationParameters::Shape shape ) throw(...);
00558 
00561     void    InitializeElasticRodNodes ( enum ShapeInitializationParameters::Shape shape );
00562 
00564     inline void SwitchDataAccessing ();
00565 
00567     void    ComputeAndStoreCenterlineRestLengths ();
00568 
00570     void    ComputeAndStoreOrientationRestLengths ();
00571 
00572     // Computations
00573 
00575     inline T    ComputeLengthOfCenterlineSegment ( 
00576         PointMass<T> const & c1, 
00577         PointMass<T> const & c2 
00578     );
00579 
00581     inline T    ComputeLengthOfOrientationSegment ( 
00582         PointMass<T> const & c1, 
00583         PointMass<T> const & c2, 
00584         PointMass<T> const & c3 
00585     );
00586 
00587     // Data Members -----------------------------------------------------------
00588     SetOfElasticRodNodes    m_Nodes;    
00589 
00590         
00591     ElasticRodParameters<T> m_Parameters;
00592 
00593     // Elastic rod global properties
00594     //int   m_iNoNodes;     //!< number of nodes
00595     //T m_tRadius;          //!< radius
00596     //T m_tTotalMass;       //!< total mass
00597     //T m_tTotalLength;     //!< total length
00598     //T m_tLinkLength;      //!< link length
00599     Vector3<T> m_vStartPos; 
00600 
00601     // Simulation Constants
00602     //T Kstretch_modulus;   //!< stretch Young's modulus (Es)
00603     //T Kbend_modulus;      //!< bend Young's modulus (Eb)
00604     //T Kshear_modulus;     //!< shear modulus (G)
00605     //T MaterialDensity;    //!< material density
00606 
00607     //T Ps;         //!< potential stretch constant (Ps = Es*Area, where area is \pi*r^2)
00608     //T Pb[3];      //!< potential bend constant (Pb[0] = Pb[1] = Eb*pi*r^2*0.25; Pb[2] = G*pi*r^2*0.5)
00609     //T Kt;         //!< kinetic translational constant
00610     //T Kr[3];      //!< kinetic rotational constant
00611     //T Dt;         //!< translational dissipation constant
00612     //T Dr[3];      //!< rotational dissipation constant
00613     //T Kconstraint_3rdDirAlignTangent; //!< a constant for computing constraint force.  This value should be in the same order as Ps.
00614     //T Kvdamping;  //!< damping constant for velocity (in the range of [0,1])
00615     Matrix3x3<T> Jinv;      
00616 
00617     // Related to rotation by quaternion
00618     Vector3<T>  U_strain_rates; // strain rates in the local frame
00619 
00620 
00621     // REMARK:
00622     // Ps is the stretch stiffness constant ($K_s$) that is computed from the 
00623     // stretch Young's modulus ($E_s$) and the radius of the elastic rod.
00624     // $K_s = E_s \pi r^2$
00625 
00626     // Kr[3] is the diagonal of the stiffness tensor (K), since an elastic rod 
00627     // is assumed to have a uniform cross-section, the off-diagonal terms in 
00628     // K can be neglected.
00629     // Where $K_{11} = K{22} = E_b \frac{\pi r^2}{4}$, and $K_{33} = G \frac{\pi r^2}{2}$,
00630     // $E_b$ is the bend Young's modulus governing the bend resistance,
00631     // $G$ is the shear modulus governing the torsional resistance,
00632     // and r is the radius of the elastic rod's cross-section.
00633 
00634 
00639 
00640     // r'_i = \frac{r_{i+1}-r_{i}}{\|r_{i+1}-r_{i}\|} or
00641     // r'_i \approx \frac{r_{i+1}-r_{i}}{l^0_i}
00642     // where l_i = \|r^0_{i+1}-r^0_{i}\| is the resting length of the center-
00643     // line element i.  Where r^0 are the initial positions of the point masses.
00644     // This is based on assuming a high stretch stiffness.
00645 
00647     // q'_j \approx \frac{q_{j+1}-q_{j}}{l_j}
00648     // where l_j = \frac{1}{2}(\|r^0_{j+2}-r^0_{j+1}\| + \|r^0_{j+1}-r^0_{j}\|) 
00649     // is the resting length of the orientation element j.
00650 
00652     // Therefore, the total energy of the rod does not have to be computed.
00653     // It is enough just to compute the energies of each element.
00654     // The energies for centerline and orientation element is computed by 
00655     // integrating the energies over the length of the respective element.
00656     // These energies are the potential, kinetic and dissipation energies.
00657 
00659         // the nodes.  Therefore, the displacements are interpolated within 
00660         // the elements.  Here, a constant shape function \bar{r} and \bar{q} 
00661         // is used where \bar{r}_i = \frac{1}{2}(r_{i}+r_{i+1}) and 
00662         //               \bar{q}_j = \frac{1}{2}(q_{j}+q_{j+1}).
00663 
00665         // the stretch energy
00666         // V_s[i] = \frac{1}{2} l_i K_s ( \frac{1}{l_i}\sqrt{(r_{i+1}-r_{i})\cdot(r_{i+1}-r_{i})} - 1 )^2
00667         // the bend energy
00668         // V_b[j] = \frac{l_j}{2} \sum_{k=1}^{3} K_{kk} ( B_k (q_{j}+q_{j+1}) \cdot \frac{1}{l_j}(q_{j+1}-q_{j} ) - \hat{u}_k )^2
00669 
00671         // the translational kinetic energy
00672         // T_t[i] = \frac{1}{8} \rho\pi r^2 l_i (\dot{r}_{i}+\dot{r}_{i+1})\cdot(\dot{r}_{i}+\dot{r}_{i+1})
00673         // the rotational kinetic energy
00674         // T_r[j] = \frac{l_j}{8} \sum_{k=1}^3 I_{kk} ( B_k (q_{j}+q_{j+1}) \cdot (\dot{q}_{j}+\dot{q}_{j+1}) )^2
00675 
00677         // the translational dissipation energy
00678         // D_t[i] = \frac{l_i}{2} \gamma_t v_i^(rel) \cdot v_i^(rel)
00679         // where v_i^(rel) = \frac{1}{\|r'_i\|^2} r'_i ( \dot{r}'_i \cdot r'_i )
00680         // assume that \|r'_i\| \approx 1, which is valid for a large stretch 
00681         // stiffness, then 
00682         // v_i^(rel) = \frac{1}{{l_i}^3} (r_{i+1}-r{i}) ( (\dot{r}_{i+1}-\dot{r}_{i}) \cdot (r_{i+1}-r_{i}) )
00683         // the rotational dissipation energy
00684         // D_r[j] = \frac{2}{l_j} \gamma_r \sum_{k=1}^3 ( B^0_k q_{j+1} \dot{q}_{j+1} - B^0_k q_{j} \dot{q}_{j} )^2
00685         // where \|q_j\| \approx 1 is assumed for all j.
00686 
00688         // A penalty constraint to force d_3 to align with r_i can be treated 
00689         // as an addtional potential energy term in the Lagrangian equation 
00690         // of motion of the rod.
00691         // E_p[i] = \frac{l_i}{2} \kappa ( \frac{r_{i+1}-r_{i}}{\|r_{i+1}-r_{i}\|} - d_3(q_i) ) \cdot ( \frac{r_{i+1}-r_{i}}{\|r_{i+1}-r_{i}\|} - d_3(q_i) )
00692         // To enforce the quaternion unit length constraint, 
00693         // a coordinate projection is used
00694         // q_i \leftarrow \frac{\hat{q}_i}{\|\hat{q}_i\|}
00695 
00697         // The evolution of the point masses
00698         // v^{t+h}_i = v^t_i + \frac{h}{m_i} F^t
00699         // r^{t+h}_i = r^t_i + (h v^{t+h}_i)
00700         // The evolution of the orientations
00701         // \omega^{t+h}_j = I^{-1} ( \tilde{\tau}^t_j - \omega^t_j \times (I\omega^t_j) )h + \omega^t_j
00702         // where \tilde{\tau}_j is the vector part of \frac{1}{2} Q^T_j \tau_j
00703         // \hat{q}^{t+h}_j = \frac{1}{2} Q^t_j ( 0, \omega^{t+h}_j )^T h + q^t_j
00704         // q^{t+h}_j = \frac{\hat{q}^{t+h}_j}{\|\hat{q}^{t+h}_j\|}
00705 
00706     // Member Functions -------------------------------------------------------
00707 
00708     //---------------------------------------------------------------
00709     // START: Related to Centerline
00710 
00712     inline void ComputeStretchForceOfCenterline ( typename SetOfElasticRodNodes::iterator & iterNode );
00713 
00714 #ifdef  USE_CORDE_SIM
00715 
00716     inline void ComputeTranslationalDissipationForceOfCenterline ( typename SetOfElasticRodNodes::iterator & iterNode );
00718     inline void ComputeKineticForceOfCenterline ( typename SetOfElasticRodNodes::iterator & iterNode );
00719 #endif//USE_CORDE_SIM
00720 
00722     inline void ComputeDampingVelocityOfCenterline ( typename SetOfElasticRodNodes::iterator & iterNode );
00723 
00725     inline void ComputeGravitationalForceOfCenterline ( typename SetOfElasticRodNodes::iterator & iterNode );
00726     //inline void   ComputeGravitationalVelocityOfCenterline ( T timestep, typename SetOfElasticRodNodes::iterator & iterNode );
00727 
00728     // END: Related to Centerline
00729     //---------------------------------------------------------------
00730     
00731     //---------------------------------------------------------------
00732     // START: Related to Quaternion
00733 
00735     inline void ComputeBendTorqueOfQuaternion ( typename SetOfElasticRodNodes::iterator & iterNode );
00736 
00737 #ifdef  USE_CORDE_SIM
00738 
00739     inline void ComputeRotationalDissipationTorqueOfQuaternion ( typename SetOfElasticRodNodes::iterator & iterNode );
00741     inline void ComputeKineticTorqueOfQuaternion ( typename SetOfElasticRodNodes::iterator & iterNode );
00742 #endif//USE_CORDE_SIM
00743 
00745     void ComputeIntrinsicStrainRate ( typename SetOfElasticRodNodes::iterator & iterNode );
00746 
00748     //inline Quaternion<T>  DiffOrientation ( typename SetOfElasticRodNodes::iterator & iterNode );
00750     
00751     // END: Related to Quaternion
00752     //---------------------------------------------------------------
00753 
00755     inline void ComputeConstraintForceOfCenterlineAndOrientation ( typename SetOfElasticRodNodes::iterator & iterNode );
00756 
00757     
00758 //=============================================================================
00759 private:
00760     // Member Functions -------------------------------------------------------
00761 
00762     // Compute the factorization of the rotation matrix using constant 
00763     // skew-symmetric matrices (see appendix in the CoRdE papers)
00764 
00766     inline Quaternion<T>    B_1 ( Quaternion<T> const & q ) const;
00768     inline Quaternion<T>    B_2 ( Quaternion<T> const & q ) const;
00770     inline Quaternion<T>    B_3 ( Quaternion<T> const & q ) const;
00772     inline Quaternion<T>    B0_1 ( Quaternion<T> const & q ) const;
00774     inline Quaternion<T>    B0_2 ( Quaternion<T> const & q ) const;
00776     inline Quaternion<T>    B0_3 ( Quaternion<T> const & q ) const;
00777 
00781 
00783     inline Vector3<T>   Get1stDirector ( Quaternion<T> const & q ) const;
00785     inline Vector3<T>   Get2ndDirector ( Quaternion<T> const & q ) const;
00787     inline Vector3<T>   Get3rdDirector ( Quaternion<T> const & q ) const;
00788 
00790     inline Quaternion<T>    u_1_LocFrame ( 
00791         Quaternion<T> const & q,        // the current quaternion
00792         Quaternion<T> const & q_ds,     // the spatial derivative of the current quaternion
00793         T scale                         // the scale should be 2/||quaternion||^2
00794     );
00796     inline Quaternion<T>    u_2_LocFrame ( 
00797         Quaternion<T> const & q,        // the current quaternion
00798         Quaternion<T> const & q_ds,     // the spatial derivative of the current quaternion
00799         T scale                         // the scale should be 2/||quaternion||^2
00800     );
00802     inline Quaternion<T>    u_3_LocFrame ( 
00803         Quaternion<T> const & q,        // the current quaternion
00804         Quaternion<T> const & q_ds,     // the spatial derivative of the current quaternion
00805         T scale                         // the scale should be 2/||quaternion||^2
00806     );
00807 
00809     inline Quaternion<T>    omega_1_LocFrame ( 
00810         Quaternion<T> const & q,        // the current quaternion
00811         Quaternion<T> const & q_dt,     // the time derivative of the current quaternion
00812         T scale                         // the scale should be 2/||quaternion||^2
00813     );
00815     inline Quaternion<T>    omega_2_LocFrame ( 
00816         Quaternion<T> const & q,        // the current quaternion
00817         Quaternion<T> const & q_dt,     // the time derivative of the current quaternion
00818         T scale                         // the scale should be 2/||quaternion||^2
00819     );
00821     inline Quaternion<T>    omega_3_LocFrame ( 
00822         Quaternion<T> const & q,        // the current quaternion
00823         Quaternion<T> const & q_dt,     // the time derivative of the current quaternion
00824         T scale                         // the scale should be 2/||quaternion||^2
00825     );
00826 
00828     inline Quaternion<T>    omega0_1_RefFrame ( 
00829         Quaternion<T> const & q,        // the current quaternion
00830         Quaternion<T> const & q_dt,     // the time derivative of the current quaternion
00831         T scale                         // the scale should be 2/||quaternion||^2
00832     );
00834     inline Quaternion<T>    omega0_2_RefFrame ( 
00835         Quaternion<T> const & q,        // the current quaternion
00836         Quaternion<T> const & q_dt,     // the time derivative of the current quaternion
00837         T scale                         // the scale should be 2/||quaternion||^2
00838     );
00840     inline Quaternion<T>    omega0_3_RefFrame ( 
00841         Quaternion<T> const & q,        // the current quaternion
00842         Quaternion<T> const & q_dt,     // the time derivative of the current quaternion
00843         T scale                         // the scale should be 2/||quaternion||^2
00844     );
00845 
00846     // Data Members -----------------------------------------------------------
00847 
00849     int IdxCurr;//      = 0;        //!< an index to current data
00850     int IdxPrev;//      = 1;        //!< an index to previous data
00851     int &IdxNext;//     = IdxPrev;  //!< an alias for the index to previous data
00852 
00853     //static bool   g_IsGLSLInit;       //!< true if the GLSL is already initialized
00854     static int  g_NumOfElasticRods; 
00855     int         m_ID;               
00856 //=============================================================================
00857 
00858 
00859 // START: FOR COLLISION DETECTION
00860 //=============================================================================
00861 public:
00862     // MEMBER FUNCTIONS -------------------------------------------------------
00864     BVHTree<T> *        GetBVHTree ()       { return m_CD.GetBVHTree(); }
00865     BVHTree<T> const *  GetBVHTree () const { return m_CD.GetBVHTree(); }
00866 
00868     virtual std::vector< BVHNode<T> * > & GetListOfCollidedNodes()      { return m_svCollidedNode; }
00870     virtual std::vector< BVHNode<T> * > & GetListOfCollidedNodesThat()  { return m_svCollidedNodeThat; }
00871 
00872 protected:
00873     // MEMBER FUNCTIONS -------------------------------------------------------
00874 
00876     void UpdateBVHTree ()   { m_CD.UpdateBVHTree(); }
00877 
00879     void UpdateBVHTree_PBD ()   { m_CD.UpdateBVHTree_PBD(); }
00880 
00882     void UpdateVelocities_PBD ( T timestep )
00883     {
00884         SetOfElasticRodNodes::iterator  currNode  = m_Nodes.begin();
00885         while ( currNode != m_Nodes.end() ) {
00886             currNode->Centerline[IdxNext].SetVelocity( (currNode->Centerline[IdxNext].GetPosition() - currNode->Centerline[IdxCurr].GetPosition() ) / timestep );
00887             ++currNode;
00888         }
00889     }
00890 
00892     void CDRforSelfIntersections ()
00893     {
00894         if ( m_Parameters.EnableSelfCDR ) {
00895 
00896             //#ifdef    TAPs_ADVANCED_SELF_COLLISION_DETECTION
00897             //  #ifdef  TAPs_ADD_KNOT_RECOGNITION
00898             //      m_KR.GetCurrentTrackingKnot_StartAndEndLinkIDs ( m_CD.StartLinkIDofCurrentTrackedKnot, m_CD.EndLinkIDofCurrentTrackedKnot );
00899             //  #endif//TAPs_ADD_KNOT_RECOGNITION
00900             //#endif//TAPs_ADVANCED_SELF_COLLISION_DETECTION
00901 
00902             m_CD.CDRforSelfIntersections();
00903         }
00904     }
00905 
00907     void CDRforSelfIntersections_PBD () { if ( m_Parameters.EnableSelfCDR ) m_CD.CDRforSelfIntersections_PBD(); }
00908 
00909     // DATA MEMBERS -----------------------------------------------------------
00910     std::vector< BVHNode<T> * > m_svCollidedNode;       
00911     std::vector< BVHNode<T> * > m_svCollidedNodeThat;   
00912     ElasticRodCD<T> m_CD;           
00913 //=============================================================================
00914 // END: FOR COLLISION DETECTION
00915 
00916 
00917 // START: FOR KNOT RECOGNITION
00918 //=============================================================================
00919 #ifdef  TAPs_ADD_KNOT_RECOGNITION
00920 
00921 public:
00922     // MEMBER FUNCTIONS -------------------------------------------------------
00923     std::string CheckSurgeonsKnot ()
00924     {
00925         if ( m_Parameters.EnableKR ) {
00926         #ifdef  TAPs_ADD_ANIMATED_KNOTS
00927             if ( m_KR.GetStatusKnotAnimation() ) {
00928                 return "Knot is being animated!";
00929             }
00930             else {
00931                 return m_KR.CheckSurgeonsKnot();
00932             }
00933         #else //TAPs_ADD_ANIMATED_KNOTS
00934             return m_KR.CheckSurgeonsKnot();
00935         #endif//TAPs_ADD_ANIMATED_KNOTS
00936         }
00937         else {
00938             return "";
00939         }
00940 
00941     }
00942 
00944     inline ElasticRodKR<T> &        KRUnit ()       { return m_KR; }
00946     inline ElasticRodKR<T> const &  KRUnit () const { return m_KR; }
00947 
00948 protected:
00949     // MEMBER FUNCTIONS -------------------------------------------------------
00950 
00951     // DATA MEMBERS -----------------------------------------------------------
00952     ElasticRodKR<T> m_KR;   
00953 
00954 #endif//TAPs_ADD_KNOT_RECOGNITION
00955 //=============================================================================
00956 // END: FOR KNOT RECOGNITION
00957 
00958     
00959 // START: FOR COMPUTATION BY CUDA
00960 //=============================================================================
00961 #ifdef  TAPs_USE_CUDA
00962 
00963 public:
00964     // MEMBER FUNCTIONS -------------------------------------------------------
00965 
00966     // Is the simulation computed by CUDA?
00967     bool IsCompByCUDA () const          {   return m_Parameters.EnableCUDA; }
00968     // Enable/disable the simulation computed by CUDA
00969     void EnableCompByCUDA ( bool b )    {   m_Parameters.EnableCUDA = b; }
00970 
00971     #if defined(__gl_h_) || defined(__GL_H__)
00972     // Is the rendering computed by CUDA with OpenGL?
00973     bool IsRenderByCUDA_GL () const         {   return m_Parameters.EnableCUDA_GenDrawData; }
00974     // Enable/disable the rendering computed by CUDA with OpenGL
00975     void EnableRenderByCUDA_GL ( bool b )   {   m_Parameters.EnableCUDA_GenDrawData = b; }
00976     #endif//#if defined(__gl_h_) || defined(__GL_H__)
00977 
00978 protected:
00979     // MEMBER FUNCTIONS -------------------------------------------------------
00980 
00981     // DATA MEMBERS -----------------------------------------------------------
00982     ElasticRod_CompByCUDA<T>    m_CUDA;     
00983 
00984 #endif//TAPs_USE_CUDA
00985 //=============================================================================
00986 // END: FOR COMPUTATION BY CUDA
00987 
00988     
00989 //OpenGL
00990 //-----------------------------------------------------------------------------
00991 //#define __GL_H__
00992 //#define   TAPs_USE_GLSL
00993 //-----------------------------------------------------------------------------
00994 #if defined(__gl_h_) || defined(__GL_H__)
00995 public:
00996 
00997 
00998     #ifndef TAPs_USE_GLSL
00999         //#define ELASTIC_MODEL_SIMPLEST_DRAW
01000         #define ELASTIC_MODEL_GENERALIZED_CYLINDERS_DRAW
01001     #endif//TAPs_USE_GLSL
01002 
01004     unsigned int GetRenderingForNumberOfVerticesPerCrossSection () const    { return m_drawNV; }
01006     void SetRenderingForNumberOfVerticesPerCrossSection ( unsigned int i );
01008 //  static void SFn_SetRenderingForNumberOfVerticesPerCrossSection ( void * pObj, unsigned int i )
01009 //  {
01010 //      ModelElasticRod<T> * pER = dynamic_cast<ModelElasticRod *>( pObj );
01011 //      if ( pER ) {
01012 //          pER->SetRenderingForNumberOfVerticesPerCrossSection( i );
01013 //      }
01014 //  }
01015 
01017     virtual void Draw ();
01019     virtual void DrawForDebugging ()
01020     {
01021         #ifdef  TAPs_ADD_KNOT_RECOGNITION
01022         //m_KR.DrawForDebug();
01023         m_KR.Draw();
01024         #endif//TAPs_ADD_KNOT_RECOGNITION
01025 
01026         m_CD.DrawExtraSelfCDData();
01027 
01028         Draw();
01029 
01030         glPushAttrib( GL_ALL_ATTRIB_BITS );
01031         glDisable( GL_LIGHTING );
01032         glDisable( GL_DEPTH_TEST );
01033         glPointSize( 5 );
01034         glColor3f( 0, 1, 0 );
01035         glBegin( GL_POINTS );
01036         for ( int i = 0; i < GetNumOfPoints(); ++i ) {
01037             glVertex3fv( RefToCurrentVertexPositionOfNodeNumber(i).GetDataFloat() );
01038         }
01039         glEnd();
01040         glColor3f( 1, 1, 0 );
01041         glBegin( GL_LINE_STRIP );
01042         for ( int i = 0; i < GetNumOfPoints(); ++i ) {
01043             glVertex3fv( RefToCurrentVertexPositionOfNodeNumber(i).GetDataFloat() );
01044         }
01045         glEnd();
01046         glPopAttrib();
01047     }
01048 
01049     // FOR DEBUGGING
01050     // Draw orientations
01051     void DrawOrientations () const;
01052 
01053     OpenGL::OpenGLObj   Rendering;  
01054 
01055 private:
01057     Vector3<T> Matrix4x4MultVector3 ( Matrix4x4<T> const &M, Vector3<T> const &V ) const;
01058 
01060     void ComputeVerticesAndNormalsOfCircleCrossSection ();
01061 
01063     void GenAndDrawCylinderVertexData ();
01064 
01066     #ifdef  TAPs_ER_DRAW_WITH_SUBDIVISION
01067     void GenAndDrawCylinderVertexData_SUBDIVISION ();
01069     void GenAndDrawCylinderVertexData_SUBDIVISION_Gen (
01070         unsigned int level,             
01071         Vector3<T> posKept[],           
01072         Matrix4x4<T> rotMatKept[],      
01073         Vector3<T> posPts[],            
01074         Matrix4x4<T> rotMatPts[]        
01075     );
01077     void GenAndDrawCylinderVertexData_SUBDIVISION_Draw (
01078         Vector3<T> const & P,           
01079         Matrix4x4<T> const & RotMatP,   
01080         Vector3<T> const & Q,           
01081         Matrix4x4<T> const & RotMatQ,   
01082         T   texXstart = 0.0,            
01083         T   texXend   = 1.0             
01084     );
01086     inline void GenAndDrawCylinderVertexData_SUBDIVISION_Chaikin_Pts (
01087         Vector3<T> const & Pi,          
01088         Matrix4x4<T> const & RotMatPi,  
01089         Vector3<T> const & Pj,          
01090         Matrix4x4<T> const & RotMatPj,  
01091         Vector3<T> & Q,         
01092         Matrix4x4<T> & RotMatQ, 
01093         Vector3<T> & R,         
01094         Matrix4x4<T> & RotMatR  
01095     );
01096     #endif//TAPs_ER_DRAW_WITH_SUBDIVISION
01097 
01099     void InitGL ();
01100 
01102     void ClearGL ();
01103 
01104     #ifdef  TAPs_USE_GLSL
01105 
01106         bool InitGLSL ();
01107     #endif//TAPs_USE_GLSL
01108 
01110     //void ComputeVertexData ();
01111         
01112     //static const unsigned int m_drawNV = 8;   //!< number of vertices per cross section
01113     //Vector3<T>    m_drawCrossSectionVertices[m_drawNV];   //!< cross section's vertices
01114     //Vector3<T>    m_drawCrossSectionNormals[m_drawNV];    //!< cross section's normals
01115     //T         m_drawCrossSectionTexCoords[m_drawNV];  //!< cross section's texture coordinates
01116     unsigned int    m_drawNV;                       
01117     Vector3<T> *    m_drawCrossSectionVertices;     
01118     Vector3<T> *    m_drawCrossSectionNormals;      
01119     T *             m_drawCrossSectionTexCoords;    
01120     Vector3<T> **   vertices;       
01121     Vector3<T> **   normals;        
01122     Vector3<T> **   texCoords;      
01123     Vector3<T> *    sVertices;      
01124 
01125     GLuint      m_GLVertexArray;    
01126     GLfloat *   m_pVertexData;      
01127     GLuint      m_numOfVertices;    
01128     GLuint      m_NumOfBytesOfVertexData;   
01129 
01130 #endif//defined(__gl_h_) || defined(__GL_H__)
01131 //-----------------------------------------------------------------------------
01132 
01133 
01134 //wxWidgets
01135 //-----------------------------------------------------------------------------
01136 #ifdef  TAPs_USE_WXWIDGETS
01137 public:
01139     void ShowPropertyDialog ( wxWindow * parent = NULL );
01140 private:
01141     WX::WXElasticRodParameters  Dialogs;    
01142 #endif//TAPs_USE_WXWIDGETS
01143 //-----------------------------------------------------------------------------
01144 //=============================================================================
01145 }; // CLASS END: ModelElasticRod
01146 //=============================================================================
01147 END_NAMESPACE_TAPs
01148 //-----------------------------------------------------------------------------
01149 #include "TAPsModelElasticRod.cpp"
01150 //-----------------------------------------------------------------------------
01151 #endif
01152 //34567890123456789012345678901234567890123456789012345678901234567890123456789
01153 //--+----1----+----2----+----3----+----4----+----5----+----6----+----7----+----
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines