![]() |
TAPs 0.7.7.3
|
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----+----