TAPs 0.7.7.3
TAPsModelStrand.hpp
Go to the documentation of this file.
00001 /******************************************************************************
00002 TAPsModelStrand.hpp
00003 ******************************************************************************/
00016 /******************************************************************************
00017 SUKITTI PUNAK   (07/10/2005)
00018 UPDATE          (12/09/2010)
00019 ******************************************************************************/
00020 #ifndef TAPs_STRAND_MODEL_HPP
00021 #define TAPs_STRAND_MODEL_HPP
00022 
00023 //=============================================================================
00025 //-----------------------------------------------------------------------------
00026 //-----------------------------------------------------------------------------
00027 //=============================================================================
00028 
00029 //#define   TAPs_STRAND_DEBUG
00031 
00032 //#ifdef    TAPs_STRAND_DEBUG
00033 #if (defined TAPs_STRAND_DEBUG || defined TAPs_STRAND_SPECIAL_DEBUG )
00034     int special_debug_knotID = -1;
00035 #endif//TAPs_STRAND_DEBUG
00036 
00037 //=============================================================================
00058 //-----------------------------------------------------------------------------
00059 //#define TAPs_STRAND_LOCK_SEGMENTS
00060 #ifdef  TAPs_STRAND_LOCK_SEGMENTS
00061 #endif//TAPs_STRAND_LOCK_SEGMENTS
00062 //=============================================================================
00063 
00064 //=============================================================================
00070 //-----------------------------------------------------------------------------
00071 //#define TAPs_STRAND_KNOT_RECOGNITION_ADD_ONs
00072 //-----------------------------------------------------------------------------
00073 #ifdef  TAPs_STRAND_KNOT_RECOGNITION_ADD_ONs
00074     bool m_bIsClumpped = false;
00075 #endif//TAPs_STRAND_KNOT_RECOGNITION_ADD_ONs
00076 //-----------------------------------------------------------------------------
00077 //=============================================================================
00078 
00079 //=============================================================================
00087 //-----------------------------------------------------------------------------
00088 //#define TAPs_STRAND_KNOT_CONTROL
00089 //-----------------------------------------------------------------------------
00090 #ifdef  TAPs_STRAND_KNOT_CONTROL
00091 
00092 
00093     #ifdef  TAPs_STRAND_KNOT_RECOGNITION_BY_DOWKER_NOTATION
00094 
00095         //-----------------------------------------------------------
00101         //#define   TAPs_PROJECTION_ALLOWS_MULTIPLE_CONTACT_POINTS
00102         //-----------------------------------------------------------
00103 
00104         //-----------------------------------------------------------
00108         //#define   TAPs_ALLOW_SETTING_PROJECTION_DIRECTION
00109         //-----------------------------------------------------------
00110 
00111         //-----------------------------------------------------------
00115         //#define TAPs_STRAND_KNOT_CONTROL_USE_DOWKER_NOTATION_VERSION_01
00116         #ifdef  TAPs_STRAND_KNOT_CONTROL_USE_DOWKER_NOTATION_VERSION_01
00117 
00118             #define TAPs_PROJECTION_ALLOWS_MULTIPLE_CONTACT_POINTS
00119             #define TAPs_ALLOW_SETTING_PROJECTION_DIRECTION
00120 
00121             #include <ctime>
00122 
00123         #endif//TAPs_STRAND_KNOT_CONTROL_USE_DOWKER_NOTATION_VERSION_01
00124         //-----------------------------------------------------------
00125 
00126     #endif//TAPs_STRAND_KNOT_RECOGNITION_BY_DOWKER_NOTATION
00127 
00128 #endif//TAPs_STRAND_KNOT_CONTROL
00129 //-----------------------------------------------------------------------------
00130 //=============================================================================
00131 
00132 //=============================================================================
00142 //-----------------------------------------------------------------------------
00143 //#define TAPs_STRAND_KNOT_RECOGNITION_BY_DOWKER_NOTATION
00144 //-----------------------------------------------------------------------------
00145 #ifdef  TAPs_STRAND_KNOT_RECOGNITION_BY_DOWKER_NOTATION
00146     #include "../Data/TAPsDatabaseDowkerNotation.hpp"
00147 #endif//TAPs_STRAND_KNOT_RECOGNITION_BY_DOWKER_NOTATION
00148 //-----------------------------------------------------------------------------
00149 //=============================================================================
00150 
00151 #include "TAPsOpenGLModel.hpp"
00152 
00153 #include "../Physics/TAPsPhysics.hpp"
00154 #include "../Simulation/TAPsListOfODESolvers.hpp"
00155 #include <set>
00156 #include "../CD/TAPsBVHTree.hpp"
00157 #include "../CD/TAPsMultiBoundingVolume.hpp"    // for collision detection by bounding volumes
00158 
00160 //#define   TAPs_USE_EXTERNAL_ODE_SOLVER
00161 
00162 #ifdef  TAPs_USE_EXTERNAL_ODE_SOLVER
00163 #else //TAPs_USE_EXTERNAL_ODE_SOLVER
00164     #define TAPs_USE_INTERNAL_ODE_SOLVER_EULER
00165     #include "../Gadgets/TAPsCircularCounter.hpp"
00166 #endif//TAPs_USE_EXTERNAL_ODE_SOLVER
00167 
00168 // Add On Fns
00169 //#include "AddOn/TAPsAddOnForStrandModelCatmullRom.hpp"
00170 
00171 BEGIN_NAMESPACE_TAPs__OpenGL
00172 //=============================================================================
00173 template <typename T>
00174 class ModelStrand : public /*virtual*/ OpenGLModel<T> {
00175     //-------------------------------------------------------------------------
00176     // (Friend Fn) put it through ostream
00177     friend std::ostream & operator<< ( std::ostream &output, ModelStrand<T> const &o )
00178     {
00179         output  << "\n======================\n"
00180                 <<   "TAPs::ModelStrand<"
00181                 << typeid(T).name() << "> Class:\n"
00182                 <<   "======================\n";
00183         //----------------------------------------------------------------
00184         output  << "\n# of Links " << o.m_iNoLinks
00185                 << "\nEach link has length " << o.m_tLinkLength 
00186                 << " and weight " << o.m_tPointWeight << "\n";
00187         return output;
00188     }
00189 //-----------------------------------------------------------------------------
00190 // Member Functions ------------------------------------------------------------
00191 public:
00192     //-------------------------------------------------------------------------
00193     // Constructor(s)
00194     ModelStrand ();
00195     ModelStrand ( 
00196         int iNoLinks,   // # of links/segments
00197         T tLength,      // the strand length
00198         T tWeight,      // the strand weight
00199         Vector3<T> & posOfVertex0 = Vector3<T>(),   // position of the 1st node
00200         T tRadius = 0.05
00201     );
00202     /*
00203     ModelStrand ( 
00204         int iNoLinks,   // # of links/segments
00205         T tLength,      // the strand length
00206         T tWeight,      // the strand weight
00207         Vector3<T> & posOfVertex0,  // position of the 1st node
00208         T tRadius, 
00209         T tKRatioOfStretchingAllowed,
00210         T tKRatioOfCompressionAllowed,
00211         T tKStretching,
00212         T tKBending,
00213         T tKTwisting,
00214         T tKFriction,
00215         T tKContact,
00216         T tKGravity
00217     );
00218     //*/
00219     //-------------------------------------------------------------------------
00220     // Destructor
00221     virtual ~ModelStrand ();
00222     //-------------------------------------------------------------------------
00223     // Abstract Virtual Fn(s) from Model<T>
00224     virtual T GetMaxHalfLength () const { return m_iNoLinks * m_tLinkLength; }
00225     virtual void Initialize () {};  // Need it for OpenGL Model Hierarchy
00226     virtual void Reset ();
00227     //-------------------------------------------------------------------------
00228     // Abstract Virtual Fn(s) from ColDetSupport<T>
00229     // Collision Detection Fn(s)
00230     virtual void CalBoundingAABB ()         {};
00231     virtual void CalBoundingEllipsoid ()    {};
00232     virtual void CalBoundingSphere ()       {};
00233     //-------------------------------------------------------------------------
00234     // Get/Set Fn(s)
00235     inline virtual int  GetNumberOfLinks () { return m_iNoLinks; }
00236     inline int  GetNumberOfStrandLinksWithoutNeedle ()  { return m_iNoLinks; }
00237     inline T    GetLength ()        { return m_iNoLinks * m_tLinkLength; }
00238     inline T    GetLinkLength ()    { return m_tLinkLength; }
00239     inline T    GetWeight ()        { return (m_iNoLinks+1) * m_tPointWeight; }
00240     inline void SetWeight ( T w )   { m_tPointWeight = w / (m_iNoLinks+1); }
00241     inline T    GetPointWeight ()       { return m_tPointWeight; }
00242     inline void SetPointWeight ( T w )  { m_tPointWeight = w; }
00243     inline T    GetRadius ()        { return m_tRadius; }
00244     inline void SetRadius ( T val ) { m_tRadius = val; }
00245 
00247     T   GetCurrentLength ()
00248     {
00249         T currLen = 0;
00250         for ( int i = 0; i < m_iNoLinks; ++i ) {
00251             currLen += ( m_prVertex[i+1] - m_prVertex[i] ).Length();
00252         }
00253         return currLen;
00254     }
00255 
00256     // Fix Point Status
00257     inline bool GetFixStatusOfPtNo ( int i ) { return m_prIsFixed[i]; }
00258     inline void SetFixStatusOfPtNo ( int i, bool b );
00259     inline void ToggleFixStatusOfPtNo ( int i );
00260     inline unsigned int GetNumFixedPts ()
00261     { return static_cast<unsigned int>( m_setOfFixedPts.size() ) };
00262 
00264     void FixSegment     ( int start, int end ); 
00265 
00266     void UnfixSegment   ( int start, int end ); 
00267 
00268     inline virtual Vector3<T> const & RetPointPosition ( int i ) const;
00269     inline virtual Vector3<T> & RetPointPosition ( int i );
00270 
00271     inline virtual Vector3<T> GetPointPosition ( int i ) const;
00272     inline virtual void SetPointPosition ( 
00273         int i, const Vector3<T> & position, 
00274         //T tMoveDistanceLimit = 100, 
00275         MultiBoundingVolume<T> const * const mbvObj = NULL, 
00276         TransformationSupport<T> const * const pTransform = NULL 
00277     );
00278     inline virtual void ChangeOnlyPointPositionByAddedWithThisVector ( int i, const Vector3<T> & adjuster )
00279     {
00280         m_prVertex[i] += adjuster;
00281     }
00282     //----------------------------------------------------------------
00283     // Get/Set Fn(s) for Parameters
00284     inline T    GetPercentOfStretchingAllowed () const  { return m_tKRatioOfStretchingAllowed * 100.0; }
00285     inline T    GetPercentOfCompressionAllowed () const { return m_tKRatioOfCompressionAllowed * 100.0; }
00286     inline T    GetKStretching () const { return m_tKStretching; }
00287     inline T    GetKBending    () const { return m_tKBending; }
00288     inline T    GetKTwisting   () const { return m_tKTwisting; }
00289     inline T    GetKFriction   () const { return m_tKFriction; }
00290     inline T    GetKContact1   () const { return m_tKContact1; }
00291     inline T    GetKContact2   () const { return m_tKContact2; }
00292     inline T    GetKGravity    () const { return m_tKGravity; }
00293     //-------------------------------------------
00294     inline void SetPercentOfStretchingAllowed ( T val ) {  m_tKRatioOfStretchingAllowed = val / 100.0; }
00295     inline void SetPercentOfCompressionAllowed ( T val )    {  m_tKRatioOfCompressionAllowed = val / 100.0; }
00296     inline void SetKStretching ( T val )    {  m_tKStretching = val; }
00297     inline void SetKBending    ( T val )    {  m_tKBending = val; }
00298     inline void SetKTwisting   ( T val )    {  m_tKTwisting = val; }
00299     inline void SetKFriction   ( T val )    {  m_tKFriction = val; }
00300     inline void SetKContact1   ( T val )    {  m_tKContact1 = val; }
00301     inline void SetKContact2   ( T val )    {  m_tKContact2 = val; }
00302     inline void SetKGravity    ( T val )    {  m_tKGravity = val; }
00303     //-------------------------------------------
00304     inline T    GetMoveStepDistAllowed () const { return m_tMoveStepDistAllowed; }
00305     inline void SetMoveStepDistAllowed ( T v )  { m_tMoveStepDistAllowed = v; }
00306     //----------------------------------------------------------------
00307 
00312 //#define   TAPs_STRAND_ENABLE_DAMPING_LIMIT
00313 #ifdef  TAPs_STRAND_ENABLE_DAMPING_LIMIT
00314     inline void ResetCounterDamping ()  { uiCounterDamping = 0; }
00315     inline void SetCounterDamping ( unsigned int val )  { uiCounterDamping = val; }
00316     inline unsigned int GetLimitCounterDamping () const { return uiLimitCounterDamping; }
00317     inline void         SetLimitCounterDamping ( unsigned int i )   { uiLimitCounterDamping = i; }
00318     inline bool IsLimitCouterDampingReached () { return uiLimitCounterDamping <= uiCounterDamping; }
00319 #endif//TAPs_STRAND_ENABLE_DAMPING_LIMIT
00320 
00321     //----------------------------------------------------------------
00322     // Return size of too stretch strand parts
00323     int ReportTooStretchStrandSections ( 
00324         const int * leftPts, 
00325         const int * rightPts )
00326     {
00327         leftPts  = m_aiTooStretchLeftPts;
00328         rightPts = m_aiTooStretchRightPts;
00329         return m_iNumTooStretchSections;
00330     }
00331 //protected:
00332     int     m_iNumTooStretchSections;
00333     int     m_aiTooStretchLeftPts[20];
00334     int     m_aiTooStretchRightPts[20];
00335 public:
00336     //----------------------------------------------------------------
00337     // User adjustable parameters
00338 //  void SetKstiff ( T k )  { m_tKstiff = k; }
00339 //  T    GetKstiff () const { return m_tKstiff; }
00340 //  void SetKfollow ( T k ) { m_tKfollow = k; }
00341 //  T    GetKfollow () const    { return m_tKfollow; }
00342     //----------------------------------------------------------------
00343     // Collision Detection
00344     BVHTree<T> * GetBVHTree () // use sphere node for BVHTree
00345         { return m_BVHTree; }
00346     //----------------------------------------------------------------
00347     // SetDispLinks() --> use Chaikin (quardratic) subdivision to set display 
00348     //   links according to the original links.
00349     void SetDisplayLinks ();
00350 protected:
00351     //==========================================================================
00352     // Helper Fn(s)
00353     void AllocateLinkProps ( Vector3<T> &posOfVertex0 );    // for assisting ctor
00354     //================================================================
00355     // For Simulation
00356     //----------------------------------------------------------------
00357 public:
00358     //-------------------------------------------------------------------------
00359     // Collided Nodes
00360     virtual std::vector< BVHNode<T> * > & GetListOfCollidedNodes()      { return m_svCollidedNode; }
00361     virtual std::vector< BVHNode<T> * > & GetListOfCollidedNodesThat()  { return m_svCollidedNodeThat; }
00362 protected:
00363     std::vector< BVHNode<T> * > m_svCollidedNode;       
00364     std::vector< BVHNode<T> * > m_svCollidedNodeThat;   
00365     //----------------------------------------------------------------
00366 protected:
00367     /*
00368     //----------------------------------------------------------
00369     // pos is from 0 to #links
00370     inline Vector3<T> CalForceStretchingAndCompression ( int pos );
00371     inline Vector3<T> CalForceBending ( int pos );
00372     inline Vector3<T> CalForceTwisting ( int pos );
00373     inline Vector3<T> CalForceFriction ( int pos );
00374     inline Vector3<T> CalForceContact ( int pos );
00375     inline Vector3<T> CalForceGravity ( int pos );
00376     //-------------------------------------------
00377     // Link No is from 0 to #links - 1
00378     inline Vector3<T>   GetLinkUnitVector ( int linkNo );
00379     inline T            GetLinkCurrentLength ( int linkNo );
00380     //*/
00381     //----------------------------------------------------------
00382     void CalTorqueTorsion ();
00383     void CalTorqueBending ();
00384     //----------------------------------------------------------
00385     void SimGravity ( T tCurrent, T tNext );
00386     void SimByForce ( T tCurrent, T tNext );
00387     //---------------------------------------------------------------
00388     // Collision Detection and Response for Strand with An MBV Object
00389 protected:
00390     void CDAndRForStrandWithAnMBVObj ( 
00391         int iLeader, int iFollower, 
00392         MultiBoundingVolume<T> const * const pMBV, 
00393         TransformationSupport<T> const * const pTransform = NULL );
00394     //----------------------------------------------------------
00395     int FindClosestStrandPtToPt ( Vector3<T> const & point );
00396     //----------------------------------------------------------
00397     //----------------------------------------------------------
00398 public:
00399     //----------------------------------------------------------
00400     // Collision Detection
00401     void BuildBVHTree ();
00402     BVHTree<T> * BuildBVHTreeRecursively ( 
00403                     int startID, 
00404                     BVHNode<T> ** childNodeList, 
00405                     int numOfChildNodes );
00406 public:
00407     void UpdateBVHTree ();
00408     // Assume no intersections between immediate adjacent links
00409     void CheckSelfIntersections ();
00410 protected:
00411     void UpdateBVHNodeRecursively ( BVHNode<T> * node );
00412     void CheckSelfIntersectionsNextLevelRecursively (
00413             BVHNode<T> * node1, BVHNode<T> * node2 );
00414     T    CheckSelfIntersectionsRecursively ( 
00415             BVHNode<T> * node1, BVHNode<T> * node2 );
00416     //----------------------------------------------------------
00417 
00418 //=============================================================================
00419 #ifdef  TAPs_STRAND_KNOT_RECOGNITION_BY_DOWKER_NOTATION
00420 //-----------------------------------------------------------------------------
00421 // Knot Recognition by Dowker Notation
00443 public:
00444 
00445 #ifdef  TAPs_ALLOW_SETTING_PROJECTION_DIRECTION
00446 
00447 
00448     Vector3<T> GetProjectionDirection ( 
00449         Vector3<T> const & pt1, Vector3<T> const & pt2, Vector3<T> const & pt3 );
00450 
00452     int CheckSelfCrossingForKnotRecognition ( Vector3<T> const & projectionDirection );
00453 
00455     void CheckSelfCrossingsNextLevelRecursively (
00456             BVHNode<T> * node1, BVHNode<T> * node2, 
00457             Vector3<T> const & projectionDirection 
00458     );
00459     T    CheckSelfCrossingsRecursively ( 
00460             BVHNode<T> * node1, BVHNode<T> * node2, 
00461             Vector3<T> const & projectionDirection 
00462     );
00463     T    TestOverlapCircle ( 
00464             BVHNode<T> * node1, BVHNode<T> * node2, 
00465             Vector3<T> const & projectionDirection 
00466     );
00467     void CheckCrossings ( 
00468             BVHNode<T> * node1, BVHNode<T> * node2, 
00469             Vector3<T> const & projectionDirection 
00470     );
00471 #endif//TAPs_ALLOW_SETTING_PROJECTION_DIRECTION
00472 
00474     int CheckSelfCrossingForKnotRecognition ()
00475     {
00476         // In z-direction
00477         // Find the Dowker notation on the current strand
00478         CheckSelfCrossingForKnotRecognition_zDir();
00479         // Find the knot that match with the Dowker notation
00480         int knotID = DowkerNotationToKnotName();
00481         if ( knotID >= 0 ) {
00482             //std::cout << "zDir found Knot ID# " << knotID << "\n";
00483             return knotID;
00484         }
00485 
00486         //*
00487         // In y-direction
00488         // Find the Dowker notation on the current strand
00489         CheckSelfCrossingForKnotRecognition_yDir();
00490         // Find the knot that match with the Dowker notation
00491         knotID = DowkerNotationToKnotName();
00492         if ( knotID >= 0 ) {
00493             //std::cout << "yDir found Knot ID# " << knotID << "\n";
00494             return knotID;
00495         }
00496         // In x-direction
00497         // Find the Dowker notation on the current strand
00498         CheckSelfCrossingForKnotRecognition_xDir();
00499         // Find the knot that match with the Dowker notation
00500         knotID = DowkerNotationToKnotName();
00501         if ( knotID >= 0 ) {
00502             //std::cout << "xDir found Knot ID# " << knotID << "\n";
00503             return knotID;
00504         }
00505         //*/
00506 
00507         //-------------------------------------------------
00508         #ifdef  TAPs_STRAND_KNOT_RECOGNITION_ADD_ONs
00509         // Check Clumped
00510         if ( m_iNumCrossingPairs > 1 ) {
00511             if ( m_ucTrackingKnot != Data::DatabaseDowkerNotation::KNOT::UNDEFINED ) {
00512                 T sphereRadius = m_tLinkLength * 10.0;
00513                 CheckClumped( m_iKnotStartPt, m_iKnotEndPt, sphereRadius );
00514                 if ( IsClumped() ) {
00515                     #ifdef TAPs_STRAND_DEBUG
00516                     std::cout << "CLUMPED: true (" << m_iKnotStartPt << "," << m_iKnotEndPt << ")" << "\n";
00517                     #endif//TAPs_STRAND_DEBUG
00518 
00519                     m_uiCounterForFixingKnot = m_uiCounterThreshold+1;
00520 
00521                     #ifdef TAPs_STRAND_DEBUG
00522                     std::cout << "RET: " << m_ucTrackingKnot << "\n";
00523                     #endif//TAPs_STRAND_DEBUG
00524 
00525                     return m_ucTrackingKnot;
00526                 }
00527             }
00528             else {
00529                 //std::cout << "CLUMPED: false (" << m_iKnotStartPt << "," << m_iKnotEndPt << ")" << std::endl;
00530             }
00531         }
00532         #endif//TAPs_STRAND_KNOT_RECOGNITION_ADD_ONs
00533         //-------------------------------------------------
00534 
00535         // return -1 if not found, otherwise the knotID
00536         //std::cout << "Not found Knot ID# " << knotID << "\n";
00537         return knotID;
00538     }
00539     void CheckSelfCrossingForKnotRecognition_zDir ();
00540     void CheckSelfCrossingForKnotRecognition_yDir ();
00541     void CheckSelfCrossingForKnotRecognition_xDir ();
00542 
00546 #ifdef  TAPs_ALLOW_SETTING_PROJECTION_DIRECTION
00547     std::string GetKnotName ( Vector3<T> const & projectionDirection );
00548 #else //TAPs_ALLOW_SETTING_PROJECTION_DIRECTION
00549     std::string GetKnotName ();
00550 #endif//TAPs_ALLOW_SETTING_PROJECTION_DIRECTION
00551 
00562     int DowkerNotationToKnotName ( std::string * knotName = NULL );
00563     //unsigned char GetNumKnots () { return m_ucNumKnots; }
00564 
00566     void PrtDowkerNotation ()
00567     {
00568         std::cout << "Dowker Notation:";
00569         for ( int i = 0; i < m_iNumCrossingPairs; ++i ) {
00570             std::cout << " " << m_iaDowkerNotation[i];
00571         }
00572         std::cout << "\n";
00573     }
00574 
00576     int GetKnotStartPt ()   { return m_iKnotStartPt; };
00578     int GetKnotEndPt ()     { return m_iKnotEndPt; };
00579 
00580 protected:
00581     // Data Members -------------------------------------------------
00582     int     m_iMaxCrossingPairs, m_iNumCrossingPairs;   
00583     int *   m_iaDowkerNotation; 
00584     int     m_iKnotStartPt, m_iKnotEndPt;   
00585 #ifdef  TAPs_PROJECTION_ALLOWS_MULTIPLE_CONTACT_POINTS
00586 
00635     int *   m_iaCrossingCounters;
00636     class IC_Crossing { public:
00637         int number, id;
00638         IC_Crossing( int number, int id )   { this->number = number; this->id = id; }
00639     };
00640     std::list< IC_Crossing > m_crossings;   
00641     void InsertToList( int number, int id )
00642     {
00643         // Add at the start
00644         if ( m_crossings.size() == 0 ) {
00645             m_crossings.push_back( IC_Crossing( number, id ) );
00646             return;
00647         }
00648         // Insert in a middle
00649         std::list< IC_Crossing >::iterator it = m_crossings.begin();
00650         while ( it != m_crossings.end() ) {
00651             if ( (*it).id > id ) {
00652                 m_crossings.insert( it, IC_Crossing( number, id ) );
00653                 return;
00654             }
00655             ++it;
00656         }
00657         // Add at the end
00658         m_crossings.push_back( IC_Crossing( number, id ) );
00659     }
00660 
00661 //#define   DEBUG_TOO
00662     #ifdef  DEBUG_TOO
00663     std::list< IC_Crossing > m_crossings_TOO;   
00664     void InsertToList_TOO( int number, int id )
00665     {
00666         // Add at the start
00667         if ( m_crossings_TOO.size() == 0 ) {
00668             m_crossings_TOO.push_back( IC_Crossing( number, id ) );
00669             return;
00670         }
00671         // Insert in a middle
00672         std::list< IC_Crossing >::iterator it = m_crossings_TOO.begin();
00673         while ( it != m_crossings_TOO.end() ) {
00674             if ( (*it).id > id ) {
00675                 m_crossings_TOO.insert( it, IC_Crossing( number, id ) );
00676                 return;
00677             }
00678             ++it;
00679         }
00680         // Add at the end
00681         m_crossings_TOO.push_back( IC_Crossing( number, id ) );
00682     }
00683     #endif//DEBUG_TOO
00684 
00685 #else //TAPs_PROJECTION_ALLOWS_MULTIPLE_CONTACT_POINTS
00686     int *   m_iaCrossingsForDowkerNotation; 
00687 #endif//TAPs_PROJECTION_ALLOWS_MULTIPLE_CONTACT_POINTS
00688 
00689 //#ifdef    TAPs_STRAND_DEBUG
00690 #if (defined TAPs_STRAND_DEBUG || defined TAPs_STRAND_SPECIAL_DEBUG )
00691 public:
00692     void PrintLinkLengths ()
00693     {
00694         std::cout << "\n----------\n";
00695         std::cout <<   "LINK INFO:\n";
00696         std::cout <<   "----------\n";
00697         std::cout << "(Link Length: " << m_tLinkLength << ")\n";
00698         for ( int i = 0; i < m_iNoLinks; ++i ) {
00699             std::cout << "Link# " << i << ":\t";
00700             std::cout << (m_prVertex[i] - m_prVertex[i+1]).Length();
00701             std::cout << "\n";
00702         }
00703         std::cout <<   "----------\n\n";
00704     }
00705 
00706     std::vector<int> debug_crosses;
00707     std::vector<int> debug_crossesID;
00708 
00709     std::string Debug_Str ()
00710     {
00711         std::ostringstream ss;
00712         ss << "# of crossing pairs: " << m_iNumCrossingPairs << "\n";
00713         ss << "Cross#: ";
00714         for ( int i = 0; i < static_cast<int>(debug_crosses.size()); ++i ) {
00715             ss << "\t" << debug_crosses[i];
00716         }
00717         ss << "\n";
00718 
00719         ss << "ID#:    ";
00720         for ( int i = 0; i < static_cast<int>(debug_crossesID.size()); ++i ) {
00721             ss << "\t" << debug_crossesID[i];
00722         }
00723         ss << "\n";
00724 
00725         ss << "Dowker#:";
00726         for ( int i = 0; i < static_cast<int>(debug_crossesID.size()); ++i ) {
00727             ss << "\t" << m_iaDowkerNotation[i];
00728         }
00729         ss << "\n";
00730 
00731         ss << "Recognized Knot ID: " << special_debug_knotID << "\n";
00732 
00733         ss << "Tracking Knot: " << m_ucTrackingKnot
00734            << "  Accumulate: " << m_uiCounterForFixingKnot
00735            << "  Knot Len: " << GetKnotEndPt() << " - " << GetKnotStartPt() << " = " << GetKnotEndPt() - GetKnotStartPt()
00736            << "  Acc Length: " << m_uiLengthAccumulateTarget
00737            << "  m_uiMinLengthThreshold: " << m_uiMinLengthThreshold
00738            << "\n\n";
00739 
00740         return ss.str();
00741     }
00742 #endif//TAPs_STRAND_DEBUG
00743 
00744 
00745 #ifdef  TAPs_STRAND_KNOT_RECOGNITION_ADD_ONs
00746 
00756     bool CheckClumped ( int startPt, int endPt, T sphereRadius );
00757     bool IsClumped ()   { return m_bIsClumped; }
00758 
00759     bool m_bIsClumped;
00760 #endif//TAPs_STRAND_KNOT_RECOGNITION_ADD_ONs
00761 
00762     //unsigned char m_ucNumKnots;   //! Number of knots formed on the strand
00763     void CreateDataSpaceForKnotRecognitionByDowkerNotation ();
00764     void DeleteDataSpaceForKnotRecognitionByDowkerNotation ();
00765 
00766     // Member Functions ---------------------------------------------
00767     //---------------------------------------------------------------
00769     //---------------------------------------------------------------
00770     void CheckSelfCrossingsNextLevelRecursively_zDir (
00771             BVHNode<T> * node1, BVHNode<T> * node2 );
00772     T    CheckSelfCrossingsRecursively_zDir ( 
00773             BVHNode<T> * node1, BVHNode<T> * node2 );
00774     T    TestOverlapCircle_zDir ( BVHNode<T> * node1, BVHNode<T> * node2 );
00775     void CheckCrossings_zDir ( 
00776             BVHNode<T> * node1, BVHNode<T> * node2 );
00777     //---------------------------------------------------------------
00778 
00779     //---------------------------------------------------------------
00781     //---------------------------------------------------------------
00782     void CheckSelfCrossingsNextLevelRecursively_yDir (
00783             BVHNode<T> * node1, BVHNode<T> * node2 );
00784     T    CheckSelfCrossingsRecursively_yDir ( 
00785             BVHNode<T> * node1, BVHNode<T> * node2 );
00786     T    TestOverlapCircle_yDir ( BVHNode<T> * node1, BVHNode<T> * node2 );
00787     void CheckCrossings_yDir ( 
00788             BVHNode<T> * node1, BVHNode<T> * node2 );
00789     //---------------------------------------------------------------
00790 
00791     //---------------------------------------------------------------
00793     //---------------------------------------------------------------
00794     void CheckSelfCrossingsNextLevelRecursively_xDir (
00795             BVHNode<T> * node1, BVHNode<T> * node2);
00796     T    CheckSelfCrossingsRecursively_xDir ( 
00797             BVHNode<T> * node1, BVHNode<T> * node2 );
00798     T    TestOverlapCircle_xDir ( BVHNode<T> * node1, BVHNode<T> * node2 );
00799     void CheckCrossings_xDir ( 
00800             BVHNode<T> * node1, BVHNode<T> * node2 );
00801     //---------------------------------------------------------------
00802 
00803     //===============================================================
00804 
00805 //-----------------------------------------------------------------------------
00806 #endif//TAPs_STRAND_KNOT_RECOGNITION_BY_DOWKER_NOTATION
00807 //=============================================================================
00808 
00809     //----------------------------------------------------------
00810     // REMARK:  DxDt has to be static so that we can pass it to 
00811     // ODESolver Fn.
00812     // But we don't want StateToArray and ArrayToState be static.
00813     // Therefore, we need to pass userData, i.e. this pointer
00814     // as a void pointer.
00815     static bool DxDt (  
00816         T dt,                           // i/p: time step
00817         Simulation::VectorSet<T> &x,    // i/p: array  x = {pos, vel}
00818         Simulation::VectorSet<T> &xdot, // o/p: array xdot = {vel, accel}
00819         void *userData                  // o/p: array of user data
00820     );
00821     //----------------------------------------------------------
00822     void StateToArray ( T *dst );       // copy Strand states to dst array
00823     void ArrayToState ( T *src );       // copy src array to Strand states
00824     void DdtStateToArray ( T *xdot, T dt ); // copy d/dt Strand states to dst (xdot) array
00825     void ClearForces ();        // clear (all) forces
00826     void ClearVelocities ();    // clear (all) velocities
00827 public:
00828     virtual void AdvanceSimulation ( T tCurrent, T tNext );
00829     virtual void AdvanceSimulation ( Simulation::SimClock<T> & simClock );
00830 
00831     //----------------------------------------------------------------
00832     // Collision Detection
00833     virtual bool TestOverlapWith ( BVHTree<T> const * const that );
00834 
00835     //----------------------------------------------------------------
00836     /*
00837     // Move the vertex # i by vector u
00838     void MoveVertexNo ( int i, Vector3<T> & u );
00839     //----------------------------------------------------------------
00840     // Twist the vertex i for deg degrees
00841     void TwistVertexNo ( int i, Real deg );
00842     //----------------------------------------------------------------
00843     // Move and Twist the vertex # i by vector u and deg respectively
00844     void MoveAndTwistVertexNo ( int i, Vector3<T> & u, Real deg );
00845     */
00846     //----------------------------------------------------------------
00847 public:
00848     void BackToPreviousPosition ( int iVertexNo )
00849         {   m_prVertex[ iVertexNo ] = m_prVertexPrev[ iVertexNo ];  }
00850     void SavePreviousPositions ();
00851     void RestorePreviousPositions ();
00852     //---------------------------------------------------------------
00853 //=============================================================================
00854 // Data Members ----------------------------------------------------------------
00855 protected:
00856 
00857 //=============================================================================
00858 // CUDA
00859 //-----------------------------------------------------------------------------
00860     // CUDA ---------------------------------------------------------
00861 #ifdef  TAPs_USE_CUDA
00862 
00863     bool CUDA_Initialize_All ();
00864     bool CUDA_Initialize_VertexList ();
00865     bool CUDA_Initialize_PrevVertexList ();
00866     void CUDA_Cleanup_All ();
00867     void CUDA_Cleanup_VertexList ();
00868     void CUDA_Cleanup_PrevVertexList ();
00869     void CUDA_CopyVertexToMem ();
00870     void CUDA_CopyMemToVertex ();
00871     void CUDA_CopyPrevVertexToMem ();
00872     void CUDA_CopyMemToPrevVertex ();
00873 
00874     #ifdef  TAPs_ADVANCED_SIMULATION
00875         bool CUDA_Initialize_SimFlagsList ();
00876         void CUDA_Cleanup_SimFlagsList ();
00877         void CUDA_CopySimFlagsToMem ();
00878         void CUDA_CopyMemToSimFlags ();
00879 
00880         bool CUDA_Initialize_PosConstraintList ();
00881         void CUDA_Cleanup_PosConstraintList ();
00882         void CUDA_CopyPosConstraintToMem ();
00883         void CUDA_CopyMemToPosConstraint ();
00884     #endif//TAPs_ADVANCED_SIMULATION
00885 
00886     inline void CUDA_SwapBuffers ();
00887 #endif//TAPs_USE_CUDA
00888     // CUDA ---------------------------------------------------------
00889 
00890 #ifdef  TAPs_USE_CUDA
00891 
00892 
00893 
00894     unsigned int    m_cudaID;                   
00895     float *         m_cudaVertexList;           
00896     float *         m_cudaPrevVertexList;       
00897 
00898     #ifdef  TAPs_ADVANCED_SIMULATION
00899         unsigned int *  m_cudaSimFlagsList;         
00900         float *         m_cudaPosConstraintList;    
00901     #endif//TAPs_ADVANCED_SIMULATION
00902 
00903     // DEBUG
00904     void PrintDebug()
00905     {
00906         for ( int i = 0; i < 5; ++i ) {
00907             int idx = i*4;
00908             printf( "Host Vertex List #     %d: %g %g %g %g\n", i, m_cudaVertexList[idx], m_cudaVertexList[idx+1], m_cudaVertexList[idx+2], m_cudaVertexList[idx+3] );
00909             printf( "Host Prev Vertex List #%d: %g %g %g %g\n", i, m_cudaPrevVertexList[idx], m_cudaPrevVertexList[idx+1], m_cudaPrevVertexList[idx+2], m_cudaPrevVertexList[idx+3] );
00910         }
00911     }
00912 #endif//TAPs_USE_CUDA
00913 //-----------------------------------------------------------------------------
00914 // CUDA
00915 //=============================================================================
00916 
00917     //---------------------------------------------------------------
00918     int             m_iNoLinks;     
00919     T               m_tRadius;      
00920     T               m_tLinkLength;  
00921     T               m_tPointWeight; 
00922     Vector3<T> *    m_prVertex;     
00923     Vector3<T> *    m_prVertexPrevPos;  
00924     Vector3<T> *    m_prTempVertex1;    
00925     Vector3<T> *    m_prTempVertex2;    
00926     Vector3<T> *    m_prVelocity;   
00927     Vector3<T> *    m_prForce;      
00928     T *             m_prDegRot;     
00929 
00930 #ifdef  TAPs_ADVANCED_SIMULATION
00931 public:
00932 
00934     DS::SimulationFlags & RetSimulationFlagsOfVertexNo ( unsigned int i )
00935     { return m_SimFlags[i]; }
00936 
00938     DS::SimulationFlags const & RetSimulationFlagsOfVertexNo ( unsigned int i ) const
00939     { return m_SimFlags[i]; }
00940 
00941 //  t_TAPsAdvSimID          AdvSimID;       //!< advanced simulation ID
00942     static unsigned int     TotalModels;    
00943 
00944 protected:
00945     DS::SimulationFlags *   m_SimFlags; 
00946 #endif//TAPs_ADVANCED_SIMULATION
00947 
00948 protected:
00949     //===============================================================
00950     // For simulation
00951     //---------------------------------------------------------------
00952 #ifdef  TAPs_USE_EXTERNAL_ODE_SOLVER
00953 
00962     Simulation::ODESolver<T> *  m_prODESolver;  // ODE solver
00963     Simulation::VectorSet<T> x0;                // #m_iStateSize
00964     Simulation::VectorSet<T> xEnd;              // #m_iStateSize
00965     int m_iStateSize;   // (#Links + 1) * 6; where 6 = 3 positions + 3 velocities (for x,y,z)
00966 
00967 //#ifdef    TAPs_USE_EXTERNAL_ODE_SOLVER
00968 #else //TAPs_USE_EXTERNAL_ODE_SOLVER
00969 
00975     Vector3<T> **   m_prVertexPositionRecord;
00976     Vector3<T> **   m_prVertexVelocityRecord;
00977     Vector3<T> **   m_prVertexForceRecord;
00979     Vector3<T> *    m_prVertexPrev;
00980     Vector3<T> *    m_prVelocityPrev;
00981     Vector3<T> *    m_prForcePrev;
00982 
00983 private:
00984     CircularCounter<unsigned char>  m_PositionCounter;
00985     CircularCounter<unsigned char>  m_VelocityCounter;
00986     CircularCounter<unsigned char>  m_ForceCounter;
00987 protected:
00988     inline void CycleBuffer ()
00989     {
00990         m_prVertexPrev   = m_prVertex;
00991         m_prVelocityPrev = m_prVelocity;
00992         m_prForcePrev    = m_prForce;
00993 
00994         m_prVertex   = m_prVertexPositionRecord[ m_PositionCounter.CountUpAndReturnTheCountValue() ];
00995         m_prVelocity = m_prVertexVelocityRecord[ m_VelocityCounter.CountUpAndReturnTheCountValue() ];
00996         m_prForce    = m_prVertexForceRecord[    m_ForceCounter.CountUpAndReturnTheCountValue() ];
00997     }
00998     
00999 #endif//TAPs_USE_EXTERNAL_ODE_SOLVER
01000     //-----------------------------------------------------
01001     // Physical Forces
01002     struct StructForce {
01003         Vector3<T> gravity;     // gravity force
01004         //Vector3<T> antiBending;   // anti-bending force
01005     };
01006     StructForce *   m_StructForce;
01007     //-----------------------------------------------------
01008     // Collision Detection
01009     BVHTree<T> *    m_BVHTree;  // use sphere node for BVHTree
01010     struct CollisionNodePairID {
01011         int id1;
01012         int id2;
01013     };
01014     std::vector<CollisionNodePairID>    m_svCollisionNodePairID;
01015     //---------------------------------------------------------------
01016     //===============================================================
01017 
01018     //-------------------------------------------
01019     T       m_tMoveStepDistAllowed; // how much each step the thread can move
01020     //----------------------------------------------------------------
01021     // Temp Values
01022     Vector3<T> *    m_prLinkDirection;  // the link direction (from 0 to # of vertices-1)
01023     //----------------------------------------------------------------
01024 //  std::vector<int>    m_vListOfFixedPoints;   // list of fixed points
01025     //----------------------------------------------------------------
01026     // Material Properties
01027     //---------------------
01028     // Parameter Constants
01029     T       m_tKRatioOfStretchingAllowed;       // e.g. 0.10 of a link length
01030     T       m_tKRatioOfCompressionAllowed;      // e.g. 0.05 of a link length
01031     T               m_tKStretching; // stretching and compression
01032     T               m_tKBending;    // bending
01033     T               m_tKTwisting;   // twisting
01034     T               m_tKFriction;   // friction
01035     T               m_tGravity;     // gravity / time   (must not be set!)
01036     T               m_tKGravity;    // gravity constant
01037     T               m_tKContact1;   // contact1 (see SimByForce Fn on how this const is used)
01038     T               m_tKContact2;   // contact2 (see SimByForce Fn on how this const is used)
01039     //
01040 
01041 #ifdef  TAPs_STRAND_ENABLE_DAMPING_LIMIT
01042     unsigned int    uiCounterDamping;       // Counter for damping (for stopping vibration)
01043     unsigned int    uiLimitCounterDamping;  // stop advancing simulation when uiCounterDamping reaching this value
01044 #endif//TAPs_STRAND_ENABLE_DAMPING_LIMIT
01045 
01046     //----------------------------------------------------------------
01047     // Material Properties
01048 //  T               m_tKstretch;    // stretch allowed
01049 //  T               m_tKstiff;      // anti-bending
01050 //  T               m_tKfollow;     // how much follower follows leader
01051                                     // 0 means follow 100%
01052                                     // 1 means rigid follower
01053     void InitCurrentShape ();
01054     //----------------------------------------------------------------
01055 protected:
01056     //----------------------------------------------------------------
01057     // Shape Memory
01058 public:
01059     void SetupShape ( Vector3<T> startPosition );
01060 protected:
01061     Vector3<T> *    m_prOrigVertex; // pointer to original (shape memory) vertices
01062     //----------------------------------------------------------------
01063 
01064 //=============================================================================
01065 #ifdef  TAPs_STRAND_LOCK_SEGMENTS
01066 //-----------------------------------------------------------------------------
01067 public:
01077     int DivideAtPt ( unsigned int pt );
01078 
01080     void PrtSegments ()
01081     {
01082         int i = 0;
01083         std::cout << "\nTotal Number of Segments: " << GetNumSegments() << "\n";
01084         for ( std::vector<IC_Segment>::iterator it = m_Segments.begin(); it != m_Segments.end(); ++it, ++i ) {
01085             std::cout << "  Segment: ID(" << i
01086                 << ") start(" << GetStartPtOfSegment( i )
01087                 << ") end(" << GetEndPtOfSegment( i )
01088                 << ") isLocked(" << (*it).isLocked
01089                 << ") isVisible(" << (*it).isVisible
01090                 << ")\n";
01091         }
01092         std::cout << "\n";
01093     }
01094 
01096     unsigned int GetNumSegments ()  { return static_cast<unsigned int>( m_Segments.size() ); }
01097 
01099     int GetStartPtOfSegment ( unsigned int segment );
01100 
01102     int GetEndPtOfSegment ( unsigned int segment );
01103 
01105     bool GetSegmentLockStatus ( unsigned int segment );
01106 
01108     bool GetSegmentVisibleStatus ( unsigned int segment );
01109 
01111     void SetSegmentLockStatus ( unsigned int segment, bool status );
01112 
01114     void SetSegmentVisibleStatus ( unsigned int segment, bool status );
01115 
01116 protected:
01117     // Data Members ---------------------------------------
01118     class IC_Segment {
01119         // Data Members -------------------------
01120     public:
01121         unsigned int    start;      
01122         unsigned int    end;        
01123         bool            isLocked;   
01124         bool            isVisible;  
01125         // Member Fns ---------------------------
01126         IC_Segment( unsigned int s, unsigned int e, bool l, bool v )
01127             : start(s), end(e), isLocked(l), isVisible(v)
01128         {}
01129     };
01134     std::vector<IC_Segment> m_Segments;
01135 private:
01140     bool *          m_prIsLocked;       
01141 
01143     inline bool ValidateSegment ( unsigned int segment )
01144     {   return m_Segments.size() > segment; }
01145 
01147     void ClearSegments ()
01148     {
01149         m_Segments.clear();
01150         m_Segments.push_back( IC_Segment( 0, m_iNoLinks, false, true ) );
01151         for ( int i = 0; i <= m_iNoLinks; ++i ) {
01152             m_prIsLocked[i] = false;
01153         }
01154     }
01155 //-----------------------------------------------------------------------------
01156 #endif//TAPs_STRAND_LOCK_SEGMENTS
01157 //=============================================================================
01158 
01159 //=============================================================================
01160 #ifdef  TAPs_STRAND_KNOT_CONTROL
01161 //-----------------------------------------------------------------------------
01162 public:
01163     // Data Members -----------------------------------------------------------
01164     // Member Fns -------------------------------------------------------------
01165     void InitKnotControl ( unsigned char numKnotAllowed );
01166     void ResetKnotControl ();
01167     std::string CheckSurgeonsKnot ();
01168     std::string GetStrNameForKnotCombination ();
01169 
01170 #ifdef  TAPs_COLLECT_DATA
01171 
01172     std::string GetNameOfKnot   ( unsigned int i, bool withPosOrNegPostfix = false );
01173 
01175     int         GetIDOfKnot     ( unsigned int i );
01176 #endif//TAPs_COLLECT_DATA
01177 
01178 protected:
01179     // Data Members -----------------------------------------------------------
01180     // Member Fns -------------------------------------------------------------
01181 public:
01182     unsigned int    GetKnotCount () const   { return m_ucKnotCount; }
01183 private:
01184     // Data Members -----------------------------------------------------------
01185     unsigned char   m_ucMaxNumKnotsAllowed; 
01186     unsigned char   m_ucKnotCount;          
01187     int *           m_piKnotID;             
01188     // Member Fns -------------------------------------------------------------
01189     void CreateKnotControl ( unsigned char numKnotAllowed = 8 );
01190     void DeleteKnotControl ();
01191 
01192     //=========================================================================
01193     #ifdef TAPs_STRAND_KNOT_CONTROL_USE_DOWKER_NOTATION_VERSION_01
01194     //-------------------------------------------------------------------------
01195     public:
01196         // Data Members -------------------------------------------------------
01197         enum Threshold {
01198             THRESHOLD_FOR_FIXING_KNOT,  
01199             THRESHOLD_WAITING_TIME,     
01200             LENGTH_THRESHOLD_0,         
01201             LENGTH_THRESHOLD_1,         
01202             LENGTH_THRESHOLD_2,         
01203             LENGTH_THRESHOLD_3,         
01204             LENGTH_THRESHOLD_4,         
01205             LENGTH_THRESHOLD_5,         
01206             LENGTH_THRESHOLD_6,         
01207             LENGTH_THRESHOLD_7,         
01208         };
01209         // Member Fns ---------------------------------------------------------
01211         bool SetKnotControlThreshold ( Threshold th, T val );
01213         T GetKnotControlThreshold ( Threshold th ) const;
01215         int GetTrackingKnot () const    { return m_ucTrackingKnot; }
01216 
01217     protected:
01218         // Data Members -------------------------------------------------------
01219         // Member Fns ---------------------------------------------------------
01220     private:
01221         // Data Members -------------------------------------------------------
01224         unsigned int    m_uiCounterThreshold;       
01225         unsigned int    m_uiCounterForFixingKnot;
01226 
01233         // ???
01235         // ???
01236         //unsigned int  m_uiCounterSpecialThreshold;
01237         double          m_WaitingTime;              
01238         double          m_AccTime;
01239         time_t          m_StartTime;
01240         inline void ResetStartTime ()
01241         {
01242             time( &m_StartTime );   // reset time
01243         }
01244         inline void ResetElapsedTime ()
01245         {
01246             time( &m_StartTime );   // reset time
01247             m_AccTime = 0.0;
01248         }
01249         inline double AddElapsedTime ()
01250         {
01251             time_t prevTime = m_StartTime;
01252             time( &m_StartTime );   // new start time
01253             // difftime fn is from <ctime>
01254             m_AccTime += difftime( m_StartTime, prevTime );
01255 
01256             return m_AccTime;
01257         }
01258         inline bool IsTimeLimitReached ()
01259         {
01260             return m_AccTime >= m_WaitingTime;
01261         }
01262 
01265         unsigned int    m_uiMinLengthThreshold;     
01266         unsigned int    m_uiLengthThreshold[8];     
01267         unsigned int    m_uiLengthAccumulateTarget; 
01268 
01269         int             m_ucTrackingKnot;   
01270         // Member Fns ---------------------------------------------------------
01271     //-------------------------------------------------------------------------
01272     #endif//TAPs_STRAND_KNOT_CONTROL_USE_DOWKER_NOTATION_VERSION_01
01273     //=========================================================================
01274 //-----------------------------------------------------------------------------
01275 #endif//TAPs_STRAND_KNOT_CONTROL
01276 //=============================================================================
01277 
01278     //----------------------------------------------------------------
01283 private:
01284     bool *          m_prIsFixed;        
01285 protected:
01286     std::set<int>   m_setOfFixedPts;    
01287 
01288 protected:
01289     //----------------------------------------------------------------
01290     // For (Self) Intersection
01291     //char *            m_prWasIntersect;   // if previously intersect
01292             // manipulated by FTL and CheckSelfIntersections fns
01293             // 0 ==> no intersect
01294             // 1 ==> was intersect
01295             // 2 ==> is intersect
01296     //----------------------------------------------------------------
01298     Vector3<T> *    m_prDispVertex;
01299 //-----------------------------------------------------------------------------
01300 }; // CLASS END: ModelStrand  **************************************************
01301 //=============================================================================
01302 END_NAMESPACE_TAPs__OpenGL
01303 //-----------------------------------------------------------------------------
01304 // Include definition if TAPs_USE_EXPORT is not defined
01305 //#if !defined( TAPs_USE_EXPORT )
01306     #include "TAPsModelStrand.cpp"
01307 //#endif
01308 //-----------------------------------------------------------------------------
01309 #endif
01310 //345678901234567890123456789012345678901234567890123456789012345678901234567890
01311 //--+----1----+----2----+----3----+----4----+----5----+----6----+----7----+----8
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines