TAPs 0.7.7.3
TAPsModelSurgicalSutureWithHeadNeedle.cpp
Go to the documentation of this file.
00001 /******************************************************************************
00002 TAPsModelSurgicalSutureWithHeadNeedle.cpp
00003 ******************************************************************************/
00007 /******************************************************************************
00008 SUKITTI PUNAK   (07/22/2010)
00009 UPDATE          (12/30/2010)
00010 ******************************************************************************/
00011 #include "TAPsModelSurgicalSutureWithHeadNeedle.hpp"
00012 // Using Inclusion Model (i.e. definitions are included in declarations)
00013 //                       (this name.cpp is included in name.hpp)
00014 // Each friend is defined directly inside its declaration.
00015 
00016 BEGIN_NAMESPACE_TAPs
00017 //=============================================================================
00018 // Constructors
00019 //-----------------------------------------------------------------------------
00020 template <typename T>
00021 ModelSurgicalSutureWithHeadNeedle<T>::ModelSurgicalSutureWithHeadNeedle (
00022     int iNoLinks,               
00023     T tRadius,                  
00024     T tTotalLength,             
00025     T tTotalMass,               
00026     Vector3<T> & posOfVertex0,  
00027     ShapeInitializationParameters ShapeParameters,  
00028     std::string * pHeadNeedleFile,  
00029     int iNoInteractionPts,          
00030     T   tScaleForExtendedSharpPoint 
00031 )   
00032     : ModelSurgicalSutureThread<T>( iNoLinks, tRadius, tTotalLength, tTotalMass, posOfVertex0, ShapeParameters )
00033     , m_pHeadNeedle( NULL)
00034     , m_pHeadNeedle_asHalfEdgeModel( NULL )
00035     , m_pNeedleSharpPt( NULL )
00036     , m_pNeedleSutureConnectingPt( NULL )
00037     , m_iHeadNeedleIPtSimFlagSetCount( 0 )
00038 
00039     #ifdef  TAPs_ADD_MODEL_DISABLE_OPTIONS
00040     , m_bDisableHeadNeedle( false )
00041     #endif//TAPs_ADD_MODEL_DISABLE_OPTIONS
00042 {
00043     m_pHeadNeedle = new RigidBodyDynamics<T>();
00044     if ( !m_pHeadNeedle ) {
00045         CleanUp();
00046         std::cout << "The needle of surgicalSutureWithHeadNeedle was not created successfully!" << std::endl;
00047         return;
00048     }
00049 
00050     // Create the head needle from file and create the BVH tree (for CD) for the head needle
00051     if ( m_pHeadNeedle->SetModelFromFile( *pHeadNeedleFile, Enum::MODEL_TYPE_HALFEDGE ) ) {
00052 
00053         int level = 0;
00054         int totalPoints = 1;
00055         while ( totalPoints < iNoInteractionPts ) {
00056             ++level;
00057             totalPoints += totalPoints; // since the BVH tree is assumed to be based on a binary tree
00058         }
00059 
00060         // a. Create a set of interaction points based on the BVH tree of the head needle
00061         m_pHeadNeedle->CreateInteractionPointGroupBasedOnBVHTree( level );
00062 
00063         // NOW THE RUNTIME ERROR IS GONE. WHY?
00064         // So doing b. then a. is more efficient.
00065     }
00066     else {
00067         CleanUp();
00068         std::cout << "pHeadNeedleFile: " << *pHeadNeedleFile << "\n";
00069         std::cout << "The needle, created from filename \"" << *pHeadNeedleFile << "\", of surgicalSutureWithHeadNeedle was not created successfully!" << std::endl;
00070         return;
00071     }
00072 
00073     // Find the needle's sharp point and its connecting point to suture
00074     FindAndAddNeedleSharpPtAndSutureConnectionPt();
00075 
00076     // Set the radii of head needle's interaction points
00077     SetHeadNeedleInteractionPointsRadii();
00078 
00079     // Set extended sharp point of the head needle for CD on needle puncturing an object
00080     SetExtendedHeadNeedleSharpPt( tScaleForExtendedSharpPoint );
00081 
00082     // Set the head needle's postion and orientation to connect with the first point of suture thread
00083     CoupleHeadNeedleOrienAndPosWithSutureThreadOrienAndPos();
00084 
00085     // Total points
00086     m_iTotalPoints = iNoLinks + 1 + m_pHeadNeedle->RefToInteractionPointGroup().GetTheSetOfInteractionPoints().size();
00087     //std::cout << "m_iTotalPoints: " << m_iTotalPoints << "\n";
00088 
00089     // Create CDUnit for head needle
00090     m_CDUnit_HeadNeedle.CreateCD( m_pHeadNeedle, m_pNeedleSharpPt, m_pNeedleSutureConnectingPt );
00091 
00092     // Set the list of constraint statuses of interaction points
00093     m_vbIsConstrained.resize( m_pHeadNeedle->RefToInteractionPointGroup().GetTheSetOfInteractionPoints().size(), false );
00094 
00095     InitHeadNeedleCirclePath();
00096 }
00097 //-----------------------------------------------------------------------------
00098 template <typename T>
00099 ModelSurgicalSutureWithHeadNeedle<T>::~ModelSurgicalSutureWithHeadNeedle ()
00100 {
00101     CleanUp();
00102 }
00103 //-----------------------------------------------------------------------------
00104 template <typename T>
00105 void ModelSurgicalSutureWithHeadNeedle<T>::CleanUp ()
00106 {
00107     if ( m_pHeadNeedle )    delete m_pHeadNeedle;
00108 }
00109 //-----------------------------------------------------------------------------
00110 template <typename T>
00111 std::string ModelSurgicalSutureWithHeadNeedle<T>::StrInfo () const
00112 {
00113     std::ostringstream ss;
00114     ss << "ModelSurgicalSutureWithHeadNeedle<" << typeid(T).name() << ">";
00115     ss << "with suture: " << ModelSurgicalSutureThread<T>::StrInfo();
00116     return ss.str();
00117 }
00118 //-----------------------------------------------------------------------------
00119 template <typename T>
00120 void ModelSurgicalSutureWithHeadNeedle<T>::Reset ()
00121 {
00122     ModelSurgicalSutureThread<T>::Reset();
00123 
00124     m_iHeadNeedleIPtSimFlagSetCount = 0;
00125     GetHeadNeedle().UnlockPosition();
00126 
00127     m_HeadNeedleCirclePath.Clear();
00128 
00129     UnpickAllPoints();
00130 
00131     #ifdef  TAPs_ADD_MODEL_DISABLE_OPTIONS
00132     EnableHeadNeedle();
00133     #endif//TAPs_ADD_MODEL_DISABLE_OPTIONS
00134 }
00135 //-----------------------------------------------------------------------------
00136 template <typename T>
00137 void ModelSurgicalSutureWithHeadNeedle<T>::FindAndAddNeedleSharpPtAndSutureConnectionPt ()
00138 {
00139     #ifdef  TAPs_ADD_MODEL_DISABLE_OPTIONS
00140     if ( IsHeadNeedleDisabled() )   return;
00141     #endif//TAPs_ADD_MODEL_DISABLE_OPTIONS
00142 
00143     // The head model is an instance of RigidBodyDynamics class.
00144 
00145     // Add the head needle's connecting point to suture to the head needle model 
00146     m_pHeadNeedle->RefToInteractionPointGroup().AddInteractionPoint( Vector3<T>(0,0,0) );
00147 
00148     // Add the head needle's sharp point to the head needle model
00149     // Assume that the furtest mesh vertex of the head model is the sharp point
00150     m_pHeadNeedle_asHalfEdgeModel = dynamic_cast< OpenGL::HalfEdgeModel<T> * >( m_pHeadNeedle->GetPtrToModel() );
00151     if ( !m_pHeadNeedle_asHalfEdgeModel ) {
00152         std::cout << "Cannot convert the pointer of head needle model to HalfEdge model pointer!" << std::endl;
00153         return;
00154     }
00155     // Find the furtest mesh vertex from the origin
00156     HEVertex<T> * pHEVertex = m_pHeadNeedle_asHalfEdgeModel->GetVertexList()->Head();
00157     Vector3<T> pos(0,0,0); // the origin
00158     T length, distance = 0;
00159     while ( pHEVertex != NULL ) {
00160         length = pHEVertex->GetPosition().Length();
00161         if ( length > distance ) {
00162             distance = length;
00163             pos = pHEVertex->GetPosition();
00164         }
00165         pHEVertex = pHEVertex->Next();
00166     }
00167     // Add the furtest mesh vertex from the origin to the interaction point group
00168     m_pHeadNeedle->RefToInteractionPointGroup().AddInteractionPoint( pos );
00169 
00170     // Sort all interaction points based on the distance from the origin position
00171     m_pHeadNeedle->RefToInteractionPointGroup().SortInteractionPointsBasedOnDistanceFromTheOriginPos_GreaterThan();
00172 
00173     // After the sorting the first interaction point is the connection point between the suture and the head needle
00174     // and the last interaction point is the sharp point of the head needle
00175     m_pNeedleSutureConnectingPt = &m_pHeadNeedle->RefToInteractionPointGroup().GetTheSetOfInteractionPoints().back();
00176     m_pNeedleSharpPt = &m_pHeadNeedle->RefToInteractionPointGroup().GetTheSetOfInteractionPoints().front();
00177 
00178     //std::cout << "size of IPs: " << m_pHeadNeedle->RefInteractionPointGroup().GetTheSetOfInteractionPoints().size() << "\n";
00179 }
00180 //-----------------------------------------------------------------------------
00181 template <typename T>
00182 void ModelSurgicalSutureWithHeadNeedle<T>::SetHeadNeedleInteractionPointsRadii ()
00183 {
00184     for ( unsigned int i = 0; i < m_pHeadNeedle->RefToInteractionPointGroup().GetTheSetOfInteractionPoints().size(); ++i ) {
00185         m_pHeadNeedle->RefToInteractionPointGroup().GetInteractionPointAtIndex(i).SetSize( GetRadius()*T(2.5) );
00186     }
00187 }
00188 //-----------------------------------------------------------------------------
00189 template <typename T>
00190 void ModelSurgicalSutureWithHeadNeedle<T>::SetExtendedHeadNeedleSharpPt ( T scaleForExtendedSharpPoint )
00191 {
00192     // From the second interaction point
00193     // Where the first interaction point is the head needle's sharp point
00194     m_ExtendedHeadNeedleSharpPtPos = GetHeadNeedle().RefToInteractionPointGroup().GetInteractionPointAtIndex(1).GetPosition();
00195 
00196     // Reflect in x, y, and z directions, originated at the sharp point
00197     // and reduce the y value by a scale value, i.e. change the angle
00198     m_ExtendedHeadNeedleSharpPtPos[2] = m_pNeedleSharpPt->GetPosition()[2] + m_pNeedleSharpPt->GetPosition()[2] - m_ExtendedHeadNeedleSharpPtPos[2];
00199     m_ExtendedHeadNeedleSharpPtPos[0] = m_pNeedleSharpPt->GetPosition()[0] + m_pNeedleSharpPt->GetPosition()[0] - m_ExtendedHeadNeedleSharpPtPos[0];    
00200     m_ExtendedHeadNeedleSharpPtPos[1] = m_pNeedleSharpPt->GetPosition()[1] + scaleForExtendedSharpPoint*(m_pNeedleSharpPt->GetPosition()[1] - m_ExtendedHeadNeedleSharpPtPos[1]);
00201 
00202     // Make it extend more by a scale
00203     T scale = 0.5;
00204     m_ExtendedHeadNeedleSharpPtPos = scale*( m_ExtendedHeadNeedleSharpPtPos - m_pNeedleSharpPt->GetPosition() ) + m_pNeedleSharpPt->GetPosition();
00205 }
00206 //-----------------------------------------------------------------------------
00207 template <typename T>
00208 void ModelSurgicalSutureWithHeadNeedle<T>::AdvanceSimulation ()
00209 {
00210     // Collision Detection of suture thread with head needle
00211     this->ClearExternalForces_Reserved();
00212     CDRofThreadwithNeedle();
00213 
00214     // Suture thread simulation
00215     ModelSurgicalSutureThread<T>::AdvanceSimulation();
00216 
00217     // Head needle simulation
00218     GetHeadNeedle().AdvanceSimulation( GetSimTimeStep() );
00219 
00220 
00221     #ifdef  TAPs_ADD_MODEL_DISABLE_OPTIONS
00222     if ( IsHeadNeedleDisabled() ) {
00223         CoupleHeadNeedleOrienAndPosWithSutureThreadOrienAndPos();
00224         return;
00225     }
00226     #endif//TAPs_ADD_MODEL_DISABLE_OPTIONS
00227 
00228 
00229     if ( m_iHeadNeedleIPtSimFlagSetCount || IsHeadNeedlePositionLocked() ) {
00230         // Set the suture thread's 1st point to follow the needle
00231         SetSutureThreadOrienAndPosToFollowHeadNeedle();
00232 
00233         // The suture thread is set to follow the head needle by enforcing a constraint on it
00234         // The constraint is set by PickPoint and PickAt functions and is clear by UnpickPoint function.
00235     }
00236     else {
00237         // Couple the head needle movement with the suture thread
00238         CoupleHeadNeedleOrienAndPosWithSutureThreadOrienAndPos();
00239     }
00240 }
00241 //-----------------------------------------------------------------------------
00242 template <typename T>
00243 void ModelSurgicalSutureWithHeadNeedle<T>::CoupleHeadNeedleOrienAndPosWithSutureThreadOrienAndPos ()
00244 {
00245     //static Matrix4x4<T> rotX(
00246     //   1,  0,  0,  0,
00247     //   0,  0,  1,  0,
00248     //   0,  1,  0,  0,
00249     //   0,  0,  0,  1
00250     //);
00251     //static Matrix4x4<T> rotY(
00252     //   0,  0, -1,  0,
00253     //   0,  1,  0,  0,
00254     //  -1,  0,  0,  0,
00255     //   0,  0,  0,  1
00256     //);
00257     //static Matrix4x4<T> Rot = rotX * rotY;
00258 
00259     // Set rotation center of the head needle
00260     GetHeadNeedle().SetOrientationCenter( CGMath<T>::ZeroVector );
00261 
00262     // Set orientation at the origin
00263     // An ad-hoc method to find an average of the orientations
00264     Quaternion<T> ori( ( GetHeadNeedle().GetOrientation() + this->RefToCurrentOrientationOfLinkNumber( 0 ) ) * T(0.5) );
00265     ori.Normalized();
00266     GetHeadNeedle().SetOrientation( ori );
00267     this->RefToCurrentOrientationOfLinkNumber( 0 ) = ori;
00268 
00269     // Set translation
00270     // The translation is the average of the positions -- suture thread's 1st point position and head needle's end point position
00271     Vector3<T> pos = ( GetHeadNeedle().GetOriginPoint() + this->RefToCurrentVertexPositionOfNodeNumber( 0 ) ) * T(0.5);
00272     GetHeadNeedle().SetOriginPoint( pos );
00273     this->RefToCurrentVertexPositionOfNodeNumber( 0 ) = pos;
00274 }
00275 //-----------------------------------------------------------------------------
00276 template <typename T>
00277 void ModelSurgicalSutureWithHeadNeedle<T>::SetSutureThreadOrienAndPosToFollowHeadNeedle ()
00278 {
00279     this->RefToCurrentOrientationOfLinkNumber( 0 ) = GetHeadNeedle().GetOrientation();
00280     this->RefToCurrentVertexPositionOfNodeNumber( 0 ) = GetHeadNeedle().GetOriginPoint();
00281 }
00282 //-----------------------------------------------------------------------------
00283 template <typename T>
00284 bool ModelSurgicalSutureWithHeadNeedle<T>::CDRofThreadwithNeedle ()
00285 {
00286     #ifdef  TAPs_ADD_MODEL_DISABLE_OPTIONS
00287     if ( IsHeadNeedleDisabled() )   return false;
00288     #endif//TAPs_ADD_MODEL_DISABLE_OPTIONS
00289 
00290     // The algorithm is based on the BVH trees of the suture thread and of the head needles
00291 
00292     //if ( GetBVHTree_HeadNeedle() == NULL )    return false;
00293 
00294     bool bResult = false;
00295 
00296     // Collision Detection
00297     Matrix4x4<T> & TrxMat = GetBVHTree_HeadNeedle()->GetTransform().RefToMatrixTransform() = GetHeadNeedle().CalMatrixTransform();
00298     bResult = CDUnit().GetBVHTree()->TestOverlapWithTillLeafNodes( GetBVHTree_HeadNeedle() );
00299     if ( !bResult ) return bResult;
00300 
00301     // Collision Response
00302     bResult = false;
00303     T scale = RefToParameters().KselfCDR / ( RefToParameters().TimeStep * RefToParameters().TimeStep );
00304 
00305     // The list of collided BV leaf nodes
00306     std::vector< BVHNode<T> * > & Thread_BVNodes  = CDUnit().GetBVHTree()->GetListOfCollidedNodes();
00307     std::vector< BVHNode<T> * > & HeadNeedle_BVNodes = CDUnit().GetBVHTree()->GetListOfCollidedNodesThat();
00308 
00309     for ( int i = 0; i < static_cast<int>( Thread_BVNodes.size() ); ++i ) {
00310         BVHNodeLeafElasticRodNode<T> * NodeThread = dynamic_cast< BVHNodeLeafElasticRodNode<T> * >( Thread_BVNodes[i] );
00311         BVHNodeLeafALinkFormedByTwoPointMasses<T> * NodeHeadNeedle = dynamic_cast< BVHNodeLeafALinkFormedByTwoPointMasses<T> * >( HeadNeedle_BVNodes[i] );
00312 
00313         // Skip the first link
00314         if ( NodeThread->GetPtrToPrimitive_1()->ID != 0 
00315             //|| NodeThread->GetPtrToPrimitive_2()->ID 
00316         ) {
00317             Vector3<T> cyl_1A( NodeThread->GetPtrToPrimitive_1()->Centerline[GetCurrentIndex()].GetPosition() );
00318             Vector3<T> cyl_1B( NodeThread->GetPtrToPrimitive_2()->Centerline[GetCurrentIndex()].GetPosition() );
00319             Vector3<T> cyl_2A( TrxMat * NodeHeadNeedle->GetPtrToPrimitive_1()->GetPosition() );
00320             Vector3<T> cyl_2B( TrxMat * NodeHeadNeedle->GetPtrToPrimitive_2()->GetPosition() );
00321             Vector3<T> direction;
00322             T distance;
00323             T headNeedle_radius = ( NodeHeadNeedle->GetPtrToPrimitive_1()->GetSize() + NodeHeadNeedle->GetPtrToPrimitive_2()->GetSize() ) * T(0.5);
00324 
00325             TAPs::CGMath<T>::FindClosestDistanceBetweenTwoLineSegments( 
00326                 cyl_1A, cyl_1B,
00327                 cyl_2A, cyl_2B,
00328                 distance,
00329                 direction
00330             );
00331             if ( distance < ( GetRadius() + headNeedle_radius ) ) { // suture's thread radius + head needle's radius
00332                 direction *= distance * scale / 2.0;
00333                 NodeThread->GetPtrToPrimitive_1()->ExternalForce_Reserved -= direction * NodeThread->GetPtrToPrimitive_1()->Centerline[GetCurrentIndex()].GetMass();
00334                 NodeThread->GetPtrToPrimitive_2()->ExternalForce_Reserved -= direction * NodeThread->GetPtrToPrimitive_2()->Centerline[GetCurrentIndex()].GetMass();
00335             }
00336         }
00337     }
00338 
00339     return bResult;
00340 }
00341 //-----------------------------------------------------------------------------
00342 template <typename T>
00343 int ModelSurgicalSutureWithHeadNeedle<T>::FindTheClosestPointToPoint (
00344     Vector3<T> const & closeToPoint,    
00345     T distance_limit                    
00346 ) const
00347 {
00348     int iClosestPointNumber = -1;
00349     T tClosestDistance = distance_limit;
00350     T tDistance;
00351 
00352     // Check with suture thread's points
00353     for ( int i = 0; i < GetNumberOfSutureThreadPoints() - 1; ++i ) {   // minus 1 to prevent boundary errors
00354         tDistance = ( closeToPoint - RefToCurrentVertexPositionOfNodeNumber( i ) ).Length();
00355         if ( tClosestDistance > tDistance ) {
00356             tClosestDistance = tDistance;
00357             iClosestPointNumber = i;
00358         }
00359     }
00360 
00361     #ifdef  TAPs_ADD_MODEL_DISABLE_OPTIONS
00362     if ( IsHeadNeedleDisabled() ) {
00363         return iClosestPointNumber;
00364     }
00365     #endif//TAPs_ADD_MODEL_DISABLE_OPTIONS
00366 
00367     // Check with head needle's points
00368     TransformationSupport<T> transform;
00369     Vector3<T> translation = GetHeadNeedle().GetOriginPoint();
00370     Matrix4x4<T> Trx( 1, 0, 0, translation[0], 0, 1, 0, translation[1], 0, 0, 1, translation[2], 0, 0, 0, 1 );
00371     Trx *= GetHeadNeedle().GetOrientation().GetRotationMatrix4x4();
00372     Trx *= m_pHeadNeedle_asHalfEdgeModel->GetTransform().RefToMatrixTransform();
00373     Trx.Inversed();     // transformation of closeToPoint in world coordinates to IPs's local coordinates.
00374     std::vector< InteractionPoint<T> > & IPs = m_pHeadNeedle->RefToInteractionPointGroup().GetTheSetOfInteractionPoints();
00375     Vector3<T> closePt = (Trx * Vector4<T>( closeToPoint )).GetVector3();
00376     for ( int i = 0; i < GetTotalPoints() - GetNumberOfSutureThreadPoints(); ++i ) {
00377         tDistance = ( closePt - IPs[ i ].GetPosition() ).Length();
00378         if ( tClosestDistance > tDistance ) {
00379             tClosestDistance = tDistance;
00380             iClosestPointNumber = i + GetNumberOfSutureThreadPoints();
00381         }
00382     }
00383 
00384     // Returns -1 if could not find a closest point
00385     // The return values is in the range of [0,GetNumberOfSutureThreadPoints()) if the closest point is on the suture thread.
00386     // The return values is in the range of [GetNumberOfSutureThreadPoints(),GetTotalPoints()) if the closest point is on the head needle.
00387     return iClosestPointNumber;
00388 }
00389 //-----------------------------------------------------------------------------
00390 template <typename T>
00391 Vector3<T> ModelSurgicalSutureWithHeadNeedle<T>::GetPositionOfHeadNeedleSharpPoint () const
00392 {
00393     TransformationSupport<T> transform;
00394     Vector3<T> translation = GetHeadNeedle().GetOriginPoint();
00395     Matrix4x4<T> Trx( 1, 0, 0, translation[0], 0, 1, 0, translation[1], 0, 0, 1, translation[2], 0, 0, 0, 1 );
00396     Trx *= GetHeadNeedle().GetOrientation().GetRotationMatrix4x4();
00397     Trx *= m_pHeadNeedle_asHalfEdgeModel->GetTransform().RefToMatrixTransform();
00398 
00399     return Trx * m_pNeedleSharpPt->GetPosition();
00400 }
00401 //-----------------------------------------------------------------------------
00402 template <typename T>
00403 Vector3<T> ModelSurgicalSutureWithHeadNeedle<T>::GetPositionOfPointNumberIonHeadNeedle ( unsigned int i ) const
00404 {
00405     TransformationSupport<T> transform;
00406     Vector3<T> translation = GetHeadNeedle().GetOriginPoint();
00407     Matrix4x4<T> Trx( 1, 0, 0, translation[0], 0, 1, 0, translation[1], 0, 0, 1, translation[2], 0, 0, 0, 1 );
00408     Trx *= GetHeadNeedle().GetOrientation().GetRotationMatrix4x4();
00409     Trx *= m_pHeadNeedle_asHalfEdgeModel->GetTransform().RefToMatrixTransform();
00410 
00411     return (i < GetHeadNeedle().RefToInteractionPointGroup().GetNumOfInteractionPoints() ? Trx * GetHeadNeedle().RefToInteractionPointGroup().GetInteractionPointAtIndex(i).GetPosition() : CGMath<T>::ZeroVector);
00412 }
00413 //-----------------------------------------------------------------------------
00414 template <typename T>
00415 void ModelSurgicalSutureWithHeadNeedle<T>::GetTwoPointsInWorldSpaceFormingLineExtendedFromHeadNeedleSharpPoint ( Vector3<T> & sharpPt, Vector3<T> & extendedPt ) const
00416 {
00417     TransformationSupport<T> transform;
00418     Vector3<T> translation = GetHeadNeedle().GetOriginPoint();
00419     Matrix4x4<T> Trx( 1, 0, 0, translation[0], 0, 1, 0, translation[1], 0, 0, 1, translation[2], 0, 0, 0, 1 );
00420     Trx *= GetHeadNeedle().GetOrientation().GetRotationMatrix4x4();
00421     Trx *= m_pHeadNeedle_asHalfEdgeModel->GetTransform().RefToMatrixTransform();
00422 
00423     sharpPt = Trx * m_pNeedleSharpPt->GetPosition();
00424     extendedPt = Trx * m_ExtendedHeadNeedleSharpPtPos;
00425 }
00426 //-----------------------------------------------------------------------------
00427 template <typename T>
00428 void ModelSurgicalSutureWithHeadNeedle<T>::GetTwoInteractionPointPositionsInWorldSpace ( unsigned int i, unsigned int j, Vector3<T> & iPoint, Vector3<T> & jPoint ) const
00429 {
00430     assert( i < m_pHeadNeedle->RefToInteractionPointGroup().GetNumOfInteractionPoints() );
00431     assert( j < m_pHeadNeedle->RefToInteractionPointGroup().GetNumOfInteractionPoints() );
00432 
00433     TransformationSupport<T> transform;
00434     Vector3<T> translation = GetHeadNeedle().GetOriginPoint();
00435     Matrix4x4<T> Trx( 1, 0, 0, translation[0], 0, 1, 0, translation[1], 0, 0, 1, translation[2], 0, 0, 0, 1 );
00436     Trx *= GetHeadNeedle().GetOrientation().GetRotationMatrix4x4();
00437     Trx *= m_pHeadNeedle_asHalfEdgeModel->GetTransform().RefToMatrixTransform();
00438 
00439     iPoint = Trx * m_pNeedleSharpPt->RefToInteractionPointGroup().GetInteractionPointAtIndex( i ).GetPosition();
00440     jPoint = Trx * m_pNeedleSharpPt->RefToInteractionPointGroup().GetInteractionPointAtIndex( j ).GetPosition();
00441 }
00442 //-----------------------------------------------------------------------------
00443 template <typename T>
00444 std::vector< Vector3<T> > ModelSurgicalSutureWithHeadNeedle<T>::GetAllInteractionPointPositionsInWorldSpace () const
00445 {
00446     TransformationSupport<T> transform;
00447     Vector3<T> translation = GetHeadNeedle().GetOriginPoint();
00448     Matrix4x4<T> Trx( 1, 0, 0, translation[0], 0, 1, 0, translation[1], 0, 0, 1, translation[2], 0, 0, 0, 1 );
00449     Trx *= GetHeadNeedle().GetOrientation().GetRotationMatrix4x4();
00450     Trx *= m_pHeadNeedle_asHalfEdgeModel->GetTransform().RefToMatrixTransform();
00451 
00452     std::vector< Vector3<T> > positions;
00453     for ( unsigned int i = 0; i < m_pHeadNeedle->RefToInteractionPointGroup().GetNumOfInteractionPoints(); ++i ) {
00454         positions.push_back( Trx * m_pHeadNeedle->RefToInteractionPointGroup().GetInteractionPointAtIndex(i).GetPosition() );
00455     }
00456 
00457     return positions;
00458 }
00459 //-----------------------------------------------------------------------------
00460 template <typename T>
00461 bool ModelSurgicalSutureWithHeadNeedle<T>::PickAt (
00462     Vector3<T> const & closeToPoint,    
00463     T distance_limit,                   
00464     int & pickedID                      
00465 )
00466 {
00467     pickedID = FindTheClosestPointToPoint( closeToPoint, distance_limit );
00468 
00469     //std::cout << "pickedID: " << pickedID << "\n";
00470 
00471     if ( pickedID < 0 ) return false;
00472 
00473     // DEBUG
00474     //pickedID = GetTotalPoints()-1;
00475 
00476     // Suture thread
00477     if ( pickedID < GetNumberOfSutureThreadPoints() ) {
00478         if ( m_Nodes[ pickedID ].UseEnforcedPosition )  return false;   // skip if the point is currently picked
00479         m_Nodes[ pickedID ].UseEnforcedPosition = true;
00480     }
00481     else /*if ( pickedID < GetTotalPoints() )*/ {
00482         if ( GetListOfNodes()[0].UseEnforcedPosition )  return false;   // skip if the point is currently picked
00483         GetHeadNeedle().RefToInteractionPointGroup().GetInteractionPointAtIndex( pickedID - GetNumberOfSutureThreadPoints() ).GetSimFlags().SetSimulationConstraints( Enum::AddOn::ATTACHED );
00484         ++m_iHeadNeedleIPtSimFlagSetCount;
00485         GetHeadNeedle().SetPhyPropGravitationalConstant( 0 );
00486 
00487         // Set the constraint that the first point of suture thread must follow the head needle
00488         GetListOfNodes()[0].UseEnforcedPosition = true;
00489         GetListOfNodes()[0].EnforcedPosition = GetHeadNeedle().GetOriginPoint();
00490         GetListOfNodes()[0].UseEnforcedOrientation = true;
00491         GetListOfNodes()[0].EnforcedOrientation = GetHeadNeedle().GetOrientation();
00492     }
00493     return true;
00494 }
00495 //-----------------------------------------------------------------------------
00496 template <typename T>
00497 void ModelSurgicalSutureWithHeadNeedle<T>::PickPoint (
00498     int pickedID            
00499 )
00500 {
00501     assert( 0 <= pickedID && pickedID < GetNumberOfSutureThreadPoints() );
00502 
00503     
00504 
00505     // Suture thread
00506     if ( /*0 <= pickedID &&*/ pickedID < GetNumberOfSutureThreadPoints() ) {
00507         if ( m_Nodes[ pickedID ].UseEnforcedPosition )  return; // skip if the point is currently picked
00508         m_Nodes[ pickedID ].UseEnforcedPosition = true;
00509     }
00510     // Head needle
00511     else /*if ( pickedID < GetTotalPoints() )*/ {
00512         if ( GetListOfNodes()[0].UseEnforcedPosition )  return; // skip if the point is currently picked
00513         GetHeadNeedle().RefToInteractionPointGroup().GetInteractionPointAtIndex( pickedID - GetNumberOfSutureThreadPoints() ).GetSimFlags().SetSimulationConstraints( Enum::AddOn::ATTACHED );
00514         ++m_iHeadNeedleIPtSimFlagSetCount;
00515         GetHeadNeedle().SetPhyPropGravitationalConstant( 0 );
00516 
00517         // Set the constraint that the first point of suture thread must follow the head needle
00518         GetListOfNodes()[0].UseEnforcedPosition = true;
00519         GetListOfNodes()[0].EnforcedPosition = GetHeadNeedle().GetOriginPoint();
00520         GetListOfNodes()[0].UseEnforcedOrientation = true;
00521         GetListOfNodes()[0].EnforcedOrientation = GetHeadNeedle().GetOrientation();
00522     }
00523 }
00524 //-----------------------------------------------------------------------------
00525 template <typename T>
00526 void ModelSurgicalSutureWithHeadNeedle<T>::MovePickedPoint (
00527     int pickedID,           
00528     Vector3<T> & position   
00529 )
00530 {
00531     assert( 0 <= pickedID && pickedID < GetNumberOfSutureThreadPoints() );
00532     // Suture thread
00533     if ( /*0 <= pickedID &&*/ pickedID < GetNumberOfSutureThreadPoints() ) {
00534         //if ( m_Nodes[ pickedID ].UseEnforcedPosition ) {
00535             m_Nodes[ pickedID ].EnforcedPosition  = position;
00536         //}
00537     }
00538     // Head needle
00539     else /*if ( pickedID < GetTotalPoints() )*/ {
00540         int IPtID = pickedID - GetNumberOfSutureThreadPoints();     // interaction point's id
00541         GetHeadNeedle().SetOriginPoint(
00542             position - GetHeadNeedle().GetOrientation().GetRotationMatrix4x4() * 
00543             ( m_pHeadNeedle->RefToInteractionPointGroup().GetInteractionPointAtIndex( IPtID ).GetPosition() 
00544             - m_pNeedleSutureConnectingPt->GetPosition() )
00545         );
00546         // Move the first point of suture thread to the origin of the head needle
00547         GetListOfNodes()[0].EnforcedPosition = GetHeadNeedle().GetOriginPoint();
00548         GetListOfNodes()[0].EnforcedOrientation = GetHeadNeedle().GetOrientation();
00549     }
00550 }
00551 //-----------------------------------------------------------------------------
00552 template <typename T>
00553 void ModelSurgicalSutureWithHeadNeedle<T>::UnpickPoint (
00554     int pickedID    
00555 )
00556 {
00557     assert( 0 <= pickedID && pickedID < GetNumberOfSutureThreadPoints() );
00558     // Suture thread
00559     if ( /*0 <= pickedID &&*/ pickedID < GetNumberOfSutureThreadPoints() ) {
00560         m_Nodes[ pickedID ].UseEnforcedPosition = false;
00561     }
00562     // Head needle
00563     else /*if ( pickedID < GetTotalPoints() )*/ {
00564         GetHeadNeedle().RefToInteractionPointGroup().GetInteractionPointAtIndex( pickedID - GetNumberOfSutureThreadPoints() ).GetSimFlags().ClearSimulationConstraints( Enum::AddOn::ATTACHED );
00565         if ( m_iHeadNeedleIPtSimFlagSetCount > 0 ) {
00566             --m_iHeadNeedleIPtSimFlagSetCount;
00567         }
00568 
00569         // Remove the constraint that the first point of suture thread must follow the head needle
00570         if ( m_iHeadNeedleIPtSimFlagSetCount == 0 ) {
00571             GetListOfNodes()[0].UseEnforcedPosition = false;
00572             GetListOfNodes()[0].UseEnforcedOrientation = false;
00573             GetHeadNeedle().SetPhyPropGravitationalConstant( -GetGravitationalConstant() );
00574         }
00575     }
00576 }
00577 //-----------------------------------------------------------------------------
00578 template <typename T>
00579 void ModelSurgicalSutureWithHeadNeedle<T>::UnpickAllPoints ()
00580 {
00581     std::cout << "UnpickAllPoints\n";
00582 
00583     // Suture thread
00584     int i = 0;
00585     for ( ; i < GetNumberOfSutureThreadPoints(); ++i ) {
00586         m_Nodes[ i ].UseEnforcedPosition = false;
00587     }
00588     // Head needle
00589     int p = 0;
00590     for ( ; i < GetTotalPoints(); ++i, ++p ) {
00591         GetHeadNeedle().RefToInteractionPointGroup().GetInteractionPointAtIndex( p ).GetSimFlags().ClearSimulationConstraints( Enum::AddOn::ATTACHED );
00592     }
00593 
00594     // Remove the constraint that the first point of suture thread must follow the head needle
00595     m_iHeadNeedleIPtSimFlagSetCount = 0;
00596     GetListOfNodes()[0].UseEnforcedPosition = false;
00597     GetListOfNodes()[0].UseEnforcedOrientation = false;
00598     GetHeadNeedle().SetPhyPropGravitationalConstant( -GetGravitationalConstant() );
00599 }
00600 //-----------------------------------------------------------------------------
00601 template <typename T>
00602 bool ModelSurgicalSutureWithHeadNeedle<T>::IsPointID_SutureThread ( int id ) const
00603 {
00604     if ( 0 <= id && id <= GetNumberOfSutureThreadLinks() )  return true;
00605     return false;
00606 }
00607 //-----------------------------------------------------------------------------
00608 template <typename T>
00609 bool ModelSurgicalSutureWithHeadNeedle<T>::IsPointID_HeadNeedle ( int id ) const
00610 {
00611     if ( GetNumberOfSutureThreadLinks() < id && id < m_iTotalPoints )   return true;
00612     return false;
00613 }
00614 //-----------------------------------------------------------------------------
00615 template <typename T>
00616 void ModelSurgicalSutureWithHeadNeedle<T>::ClearAllExternalForcesAndTorques ()
00617 {
00618     // Clear suture thread's external forces
00619     ModelSurgicalSutureThread<T>::ClearExternalForces();
00620     // Clear head needle external forces and torques
00621     GetHeadNeedle().ClearAllForcesAndTorques();
00622 }
00623 //-----------------------------------------------------------------------------
00624 template <typename T>
00625 void ModelSurgicalSutureWithHeadNeedle<T>::SetHeadNeedlePosition ( Vector3<T> const & position )
00626 {
00627     GetHeadNeedle().SetOriginPoint( position );
00628     SetSutureThreadOrienAndPosToFollowHeadNeedle();
00629 }
00630 //-----------------------------------------------------------------------------
00631 template <typename T>
00632 void ModelSurgicalSutureWithHeadNeedle<T>::SetHeadNeedleOrientation ( Quaternion<T> const & orientation )
00633 {
00634     // Set rotation center of the head needle
00635     GetHeadNeedle().SetOrientationCenter( CGMath<T>::ZeroVector );
00636     //Quaternion<T> ori( orientation );
00637     //ori.Normalized();
00638     GetHeadNeedle().SetOrientation( orientation );
00639     SetSutureThreadOrienAndPosToFollowHeadNeedle();
00640 }
00641 //-----------------------------------------------------------------------------
00642 template <typename T>
00643 void ModelSurgicalSutureWithHeadNeedle<T>::InitHeadNeedleCirclePath ()
00644 {
00645     //Matrix4x4<T> Trx;
00646     //Trx *= GetHeadNeedle().GetOrientation().GetRotationMatrix4x4();
00647     //Trx *= GetHeadNeedle().GetPtrToModel()->GetTransform().RefToMatrixTransform();
00648 
00649     int numOfIPs = GetHeadNeedle().RefToInteractionPointGroup().GetNumOfInteractionPoints();
00650     m_HeadNeedleCirclePath.SharpPt = GetHeadNeedle().RefToInteractionPointGroup().GetInteractionPointAtIndex( 0 ).GetPosition();
00651     m_HeadNeedleCirclePath.EndPt = GetHeadNeedle().RefToInteractionPointGroup().GetInteractionPointAtIndex( numOfIPs-1 ).GetPosition();
00652     m_HeadNeedleCirclePath.SharpPt.SetX( 0 );   // assume the head needle lies in a plane parallel to the local coordinate system where x-coordinate is zero
00653 
00654     //
00655     // Initialize the path circle
00656     //
00657     // Assume:
00658     //   The end point is at <0,0,0>.
00659     //   The head needle's shape traces a circle path.
00660     //   The head needle lies flat on the yz-plane.
00661     //   The normal plane of the head needle's path circle is <1,0,0>.
00662     // [after an algebra calculation]
00663     T k = m_HeadNeedleCirclePath.SharpPt.SquaredLength() / m_HeadNeedleCirclePath.SharpPt[1] * T(0.5);
00664     m_HeadNeedleCirclePath.Center.SetXYZ( 0, k, 0 );
00665     m_HeadNeedleCirclePath.Radius = k;  // Remark: k is negative
00666     m_HeadNeedleCirclePath.NormalPlane.SetXYZ( 1, 0, 0 );
00667 
00668     //
00669     // Find the cover angle
00670     m_HeadNeedleCirclePath.CoverAngle = Math<T>::ASin( ( m_HeadNeedleCirclePath.SharpPt.Length() / m_HeadNeedleCirclePath.Radius )*T(0.5) ) * T(2);
00671     std::cout << "m_HeadNeedleCirclePath.CoverAngle (radians): " << m_HeadNeedleCirclePath.CoverAngle << "\n";
00672     std::cout << "m_HeadNeedleCirclePath.CoverAngle (degrees): " << m_HeadNeedleCirclePath.CoverAngle * Math<T>::RAD_TO_DEG << "\n";
00673 
00674     // Suture thread' link length conversion to angle
00675     m_HeadNeedleCirclePath.LinkLenAngle = Math<T>::ASin( ( GetLinkLength() / m_HeadNeedleCirclePath.Radius )*T(0.5) ) * T(2);
00676     std::cout << "m_HeadNeedleCirclePath.LinkLenAngle (radians): " << m_HeadNeedleCirclePath.LinkLenAngle << "\n";
00677     std::cout << "m_HeadNeedleCirclePath.LinkLenAngle (degrees): " << m_HeadNeedleCirclePath.LinkLenAngle * Math<T>::RAD_TO_DEG << "\n";
00678     
00679     //
00680     // Interpolate points
00681     //
00682     Vector3<T> pos;
00683     T y, z;
00684     int i = 0;
00685     //for ( T a = 0; a > -2*Math<T>::PI; a+=m_HeadNeedleCirclePath.LinkLenAngle ) { // sutureLinkLenAngle is negative
00686     T angle = 0;
00687     bool isSet = false;
00688     for ( T a = Math<T>::PI; a > -Math<T>::PI; a+=m_HeadNeedleCirclePath.LinkLenAngle ) {   // sutureLinkLenAngle is negative
00689         y = cos( a );
00690         z = sin( a );
00691         pos = m_HeadNeedleCirclePath.Center + Vector3<T>( 0, y, z )*m_HeadNeedleCirclePath.Radius;
00692         m_HeadNeedleCirclePath.InterpolatedPts.push_back( pos );
00693 
00694         if ( !isSet && angle < m_HeadNeedleCirclePath.CoverAngle ) {
00695             m_HeadNeedleCirclePath.IDOfFirstInterpolatedPtBeforeSharpPt = i-1;
00696             isSet = true;
00697         }
00698 
00699         ++i;
00700         angle += m_HeadNeedleCirclePath.LinkLenAngle;
00701     }
00702 
00703     m_HeadNeedleCirclePath.Radius *= -1;    // change to positive
00704     //m_HeadNeedleCirclePath.pCDSphereNode = new BVHNodeLeaf<T>( Enum::BVH_NODE_LEAF_SPHERE );
00705     //m_HeadNeedleCirclePath.pCDSphereNode->SetRadius( m_HeadNeedleCirclePath.Radius );
00706 
00707     std::cout << "Number of interpolated points: " << m_HeadNeedleCirclePath.InterpolatedPts.size() << "\n";
00708     std::cout << "ID of the first interpolated points after the sharp point: " << m_HeadNeedleCirclePath.IDOfFirstInterpolatedPtBeforeSharpPt << "\n";
00709     std::cout << "m_HeadNeedleCirclePath.Radius: " << m_HeadNeedleCirclePath.Radius << "\n";
00710 }
00711 //-----------------------------------------------------------------------------
00712 //=============================================================================
00713 
00714 
00715 
00716 
00717 //=============================================================================
00718 // OpenGL
00719 #if defined(__gl_h_) || defined(__GL_H__)
00720 //-----------------------------------------------------------------------------
00721 template <typename T>
00722 void ModelSurgicalSutureWithHeadNeedle<T>::Draw ()
00723 {
00724     #if defined(DEBUG) || defined(_DEBUG)
00725     if ( m_pHeadNeedle ) {
00726     #endif
00727         #ifdef  TAPs_ADD_MODEL_DISABLE_OPTIONS
00728         if ( !IsHeadNeedleDisabled() ) {
00729         #endif//TAPs_ADD_MODEL_DISABLE_OPTIONS
00730 
00731             m_pHeadNeedle->Draw();
00732 
00733             //DrawClue_GrabbingLocation();
00734             //DrawClue_CirclePath();
00735         #ifdef  TAPs_ADD_MODEL_DISABLE_OPTIONS
00736         }
00737         #endif//TAPs_ADD_MODEL_DISABLE_OPTIONS
00738 
00739     #if defined(DEBUG) || defined(_DEBUG)
00740     }
00741     #endif
00742 
00743     ModelSurgicalSutureThread<T>::Draw();   // draw the suture's thread
00744 }
00745 //-----------------------------------------------------------------------------
00746 template <typename T>
00747 void ModelSurgicalSutureWithHeadNeedle<T>::DrawOnlyHeadNeedle ()
00748 {
00749     #ifdef  TAPs_ADD_MODEL_DISABLE_OPTIONS
00750     if ( IsHeadNeedleDisabled() ) { return; }
00751     #endif//TAPs_ADD_MODEL_DISABLE_OPTIONS
00752 
00753     #if defined(DEBUG) || defined(_DEBUG)
00754     if ( m_pHeadNeedle ) {
00755     #endif
00756         m_pHeadNeedle->Draw();
00757     #if defined(DEBUG) || defined(_DEBUG)
00758     }
00759     #endif
00760 }
00761 //-----------------------------------------------------------------------------
00762 template <typename T>
00763 void ModelSurgicalSutureWithHeadNeedle<T>::DrawOnlySutureThread ()
00764 {
00765     ModelSurgicalSutureThread<T>::Draw();
00766 }
00767 //-----------------------------------------------------------------------------
00768 template <typename T>
00769 void ModelSurgicalSutureWithHeadNeedle<T>::DrawForDebugging ()
00770 {
00771     #if defined(DEBUG) || defined(_DEBUG)
00772     if ( m_pHeadNeedle ) {
00773     #endif
00774         // Drawing for DEBUG
00775         m_pHeadNeedle->DrawForDebugging();
00776         //m_pHeadNeedle->DrawInteractionPointGroup();
00777         //m_pHeadNeedle->DrawCenterOfMass();
00778         //m_pHeadNeedle->DrawOrigin();
00779         //m_pHeadNeedle->DrawOrientation();
00780 
00781         //m_CDUnit_HeadNeedle.Draw();   // from interaction point group
00782 
00783     #if defined(DEBUG) || defined(_DEBUG)
00784     }
00785     #endif
00786 
00787     ModelSurgicalSutureThread<T>::DrawForDebugging();   // draw the suture's thread
00788 }
00789 //-----------------------------------------------------------------------------
00790 template <typename T>
00791 void ModelSurgicalSutureWithHeadNeedle<T>::DrawClue_GrabbingLocation ()
00792 {
00793     #ifdef  TAPs_ADD_MODEL_DISABLE_OPTIONS
00794     if ( IsHeadNeedleDisabled() ) return;
00795     #endif//TAPs_ADD_MODEL_DISABLE_OPTIONS
00796 
00797     glPushAttrib( GL_ALL_ATTRIB_BITS );
00798     glEnable( GL_COLOR_MATERIAL );
00799     glEnable( GL_BLEND );
00800     Vector4<T> color( 1, 1, 0.5f, 0.25f );
00801     //glColor4f( 1, 1, 0.5, 0.25 );
00802 
00803     // Total IP points
00804     int n = GetHeadNeedle().RefToInteractionPointGroup().GetNumOfInteractionPoints();
00805     T twoThird = n * T(2) / T(3);   // twoThird is roughly at the 2/3 position from the head needle's sharp point
00806     n = floor( twoThird );
00807     int m = ceil( twoThird );
00808 
00809     Matrix4x4<T> Trx( 1, 0, 0, GetHeadNeedle().GetOriginPoint()[0], 0, 1, 0, GetHeadNeedle().GetOriginPoint()[1], 0, 0, 1, GetHeadNeedle().GetOriginPoint()[2], 0, 0, 0, 1 );
00810     Trx *= GetHeadNeedle().GetOrientation().GetRotationMatrix4x4();
00811     Trx *= GetHeadNeedle().GetPtrToModel()->GetTransform().RefToMatrixTransform();
00812 
00813     Vector3<T> N = Trx * GetHeadNeedle().RefToInteractionPointGroup().GetInteractionPointAtIndex( n ).GetPosition();
00814     Vector3<T> M = Trx * GetHeadNeedle().RefToInteractionPointGroup().GetInteractionPointAtIndex( m ).GetPosition();
00815     Vector3<T> MnN = M-N;
00816     Vector3<T> MpN = M+N;
00817 
00818     BoundingCylinder<T> bv;
00819     bv.SetRadius( GetHeadNeedle().RefToInteractionPointGroup().GetInteractionPointAtIndex( n ).GetRadius() * T(1.5) );
00820     bv.SetHeight( MnN.Length() );
00821     //bv.SetCenter( MpN*T(0.5) );
00822     Trx = Matrix4x4<T>( CGMath<T>::CreateRotationMatrix3x3FromVectorAtoVectorB( Vector3<T>(0,0,1), MnN ) );
00823     Trx = CGMath<T>::MatrixTranslation( MpN*T(0.5) ) * Trx;
00824     bv.GetTransform().SetMatrixTransform( Trx );
00825 
00826     //bv.Draw( GLU_POINT );
00827     //bv.Draw( GLU_LINE );  // default
00828 
00829     bv.Draw( GLU_FILL, color );
00830     //bv.Draw( GLU_SILHOUETTE );
00831 
00832     glPopAttrib();
00833 }
00834 //-----------------------------------------------------------------------------
00835 template <typename T>
00836 void ModelSurgicalSutureWithHeadNeedle<T>::DrawClue_CirclePath ()
00837 {
00838     #ifdef  TAPs_ADD_MODEL_DISABLE_OPTIONS
00839     if ( IsHeadNeedleDisabled() ) return;
00840     #endif//TAPs_ADD_MODEL_DISABLE_OPTIONS
00841 
00842     glPushAttrib( GL_ALL_ATTRIB_BITS );
00843 
00844     glDisable( GL_LIGHTING );
00845     glColor3f( 0.3, 0.6, 0.9 );
00846 
00847     /*
00848     // Draw collided nodes
00849     glPushMatrix();
00850     m_HeadNeedleCirclePath.Trx.TransformByOpenGLForDrawing();
00851     for ( std::vector< BVHNode<T> * >::iterator it = m_HeadNeedleCirclePath.pListOfCDNodes.begin(); it != m_HeadNeedleCirclePath.pListOfCDNodes.end(); ++it ) {
00852         (*it)->Draw();
00853     }
00854     glPopMatrix();
00855     //*/
00856 
00857     Matrix4x4<T> Trx = GetHeadNeedle().CalMatrixTransform();
00858 
00859     /*
00860     // Draw main points
00861     Vector3<T> C = Trx * m_HeadNeedleCirclePath.Center;
00862     Vector3<T> S = Trx * m_HeadNeedleCirclePath.SharpPt;
00863     Vector3<T> E = Trx * m_HeadNeedleCirclePath.EndPt;
00864     Vector3<T> N = (Trx * (m_HeadNeedleCirclePath.NormalPlane + m_HeadNeedleCirclePath.Center)) - C;// * m_HeadNeedleCirclePath.Radius;
00865     //Vector3<T> D = Trx * (m_HeadNeedleCirclePath.Center*2);
00866     glPointSize( 2 );
00867     glBegin( GL_POINTS );
00868     //glVertex3fv( C.GetDataFloat() );
00869     glVertex3fv( S.GetDataFloat() );
00870     glVertex3fv( E.GetDataFloat() );
00871     glVertex3fv( N.GetDataFloat() );
00872     //glVertex3fv( D.GetDataFloat() );
00873     glEnd();
00874     //*/
00875 
00876     //*
00877     // Draw interpolated points
00878     glPointSize( 2 );
00879 
00880     //glDisable( GL_DEPTH_TEST );
00881     glBegin( GL_POINTS );
00882     T s = 0;
00883     //T as = 1.0 / m_HeadNeedleCirclePath.IDOfFirstInterpolatedPtBeforeSharpPt;
00884     T as = 1.0 / m_HeadNeedleCirclePath.InterpolatedPts.size();
00885     std::vector< Vector3<T> >::iterator it = m_HeadNeedleCirclePath.InterpolatedPts.begin();
00886     while ( it != m_HeadNeedleCirclePath.InterpolatedPts.end() ) {
00887         glColor3f( s, s, s );
00888         glVertex3fv( (Trx*(*it)).GetDataFloat() );
00889         ++it;
00890         s += as;
00891     }
00892     glColor3f( 1, 0, 0 );
00893     glVertex3fv( (Trx*(m_HeadNeedleCirclePath.InterpolatedPts[m_HeadNeedleCirclePath.IDOfFirstInterpolatedPtBeforeSharpPt-1])).GetDataFloat() );
00894     glColor3f( 0, 1, 0 );
00895     glVertex3fv( (Trx*(m_HeadNeedleCirclePath.InterpolatedPts[m_HeadNeedleCirclePath.IDOfFirstInterpolatedPtBeforeSharpPt])).GetDataFloat() );
00896     glEnd();
00897 
00898     /*
00899     Matrix4x4<T> Translation = CGMath<T>::MatrixTranslation( -C );
00900     Matrix4x4<T> Mat = CGMath<T>::CreateRotationMatrix4x4FromVectorAtoVectorB( N, CGMath<T>::VectorZ );
00901     Matrix4x4<T> TrxO = Mat * Translation;
00902     Vector3<T> O = TrxO * C;
00903     Vector3<T> P = Mat * N;
00904 
00905     // Draw normal plane
00906     glBegin( GL_LINES );
00907     glVertex3fv( (C-C).GetDataFloat() );
00908     glVertex3fv( N.GetDataFloat() );
00909     glVertex3fv( (O).GetDataFloat() );
00910     glVertex3fv( P.GetDataFloat() );
00911     glEnd();
00912     //*/
00913 
00914     /*
00915     glPointSize( 9 );
00916     glDisable( GL_LIGHTING );
00917     glDisable( GL_DEPTH_TEST );
00918     glBegin( GL_POINTS );
00919     glColor3f( 1, 0, 0 );
00920     glVertex3fv( (Trx*(m_HeadNeedleCirclePath.InterpolatedPts[0])).GetDataFloat() );
00921     glColor3f( 0, 1, 0 );
00922     glVertex3fv( (Trx*(m_HeadNeedleCirclePath.InterpolatedPts[1])).GetDataFloat() );
00923     glColor3f( 0, 0, 1 );
00924     glVertex3fv( (Trx*(m_HeadNeedleCirclePath.InterpolatedPts[2])).GetDataFloat() );
00925     glColor3f( 1, 1, 0 );
00926     glVertex3fv( (Trx*(m_HeadNeedleCirclePath.InterpolatedPts[16])).GetDataFloat() );
00927     glColor3f( 0, 1, 1 );
00928     glVertex3fv( (Trx*(m_HeadNeedleCirclePath.InterpolatedPts[17])).GetDataFloat() );
00929     glColor3f( 1, 0, 1 );
00930     glVertex3fv( (Trx*(m_HeadNeedleCirclePath.InterpolatedPts[18])).GetDataFloat() );
00931     glColor3f( 0.5, 0.5, 0.5 );
00932     glVertex3fv( (Trx*(m_HeadNeedleCirclePath.InterpolatedPts[m_HeadNeedleCirclePath.IDOfFirstInterpolatedPtBeforeSharpPt-1])).GetDataFloat() );
00933     glColor3f( 1, 1, 1 );
00934     glVertex3fv( (Trx*(m_HeadNeedleCirclePath.InterpolatedPts[m_HeadNeedleCirclePath.IDOfFirstInterpolatedPtBeforeSharpPt])).GetDataFloat() );
00935     glEnd();
00936     //*/
00937 
00938     //m_HeadNeedleCirclePath.pCDSphereNode->Draw();
00939 
00940     /*
00941     // Draw as BV
00942     Matrix4x4<T> Trx2 = Matrix4x4<T>( CGMath<T>::CreateRotationMatrix3x3( 0,1,0, 90 ) );
00943     Trx2 = GetHeadNeedle().GetOrientation().GetRotationMatrix4x4() * Trx2;
00944     Trx2 = CGMath<T>::MatrixTranslation( GetHeadNeedle().GetOriginPoint() + GetHeadNeedle().GetOrientation().GetRotationMatrix4x4() *m_HeadNeedleCirclePath.Center ) * Trx2;
00945     BoundingCylinder<T> bv;
00946     bv.SetRadius( m_HeadNeedleCirclePath.Radius );
00947     bv.SetHeight( T(0.001) );
00948     bv.GetTransform().SetMatrixTransform( Trx2 );
00949     //bv.Draw( GLU_SILHOUETTE );
00950     //bv.Draw( GLU_FILL );
00951     bv.Draw( GLU_LINE );
00952     //*/
00953 
00954     glPopAttrib();
00955 }
00956 //-----------------------------------------------------------------------------
00957 #endif // OpenGL
00958 //=============================================================================
00959 END_NAMESPACE_TAPs
00960 //34567890123456789012345678901234567890123456789012345678901234567890123456789
00961 //--+----1----+----2----+----3----+----4----+----5----+----6----+----7----+----
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines