![]() |
TAPs 0.7.7.3
|
00001 /****************************************************************************** 00002 TAPsAdvSimConstraints.cpp 00003 ******************************************************************************/ 00007 /****************************************************************************** 00008 SUKITTI PUNAK (03/16/2011) 00009 UPDATE (03/31/2011) 00010 ******************************************************************************/ 00011 #include "TAPsAdvSimConstraints.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 // class AdvSimConstraint_ConstrainedPoint 00019 //----------------------------------------------------------------------------- 00020 template <typename T> 00021 AdvSimConstraint_ConstrainedPoint<T>::AdvSimConstraint_ConstrainedPoint () 00022 : PointID( -1 ) 00023 {} 00024 //----------------------------------------------------------------------------- 00025 template <typename T> 00026 AdvSimConstraint_ConstrainedPoint<T>::AdvSimConstraint_ConstrainedPoint ( AdvSimConstraint_ConstrainedPoint<T> const &orig ) 00027 : PointID( orig.PointID ) 00028 , HomePosition( orig.HomePosition ) 00029 , TargetPosition( orig.TargetPosition ) 00030 {} 00031 //----------------------------------------------------------------------------- 00032 template <typename T> 00033 AdvSimConstraint_ConstrainedPoint<T> & AdvSimConstraint_ConstrainedPoint<T>::operator= ( AdvSimConstraint_ConstrainedPoint<T> const &orig ) 00034 { 00035 PointID = orig.PointID; 00036 HomePosition = orig.HomePosition; 00037 TargetPosition = orig.TargetPosition; 00038 return *this; 00039 } 00040 //----------------------------------------------------------------------------- 00041 template <typename T> 00042 AdvSimConstraint_ConstrainedPoint<T>::~AdvSimConstraint_ConstrainedPoint () 00043 {} 00044 //----------------------------------------------------------------------------- 00045 template <typename T> 00046 std::string AdvSimConstraint_ConstrainedPoint<T>::StrInfo () const 00047 { 00048 std::ostringstream ss; 00049 ss << "AdvSimConstraint_ConstrainedPoint<" << typeid(T).name() << ">"; 00050 ss << "\nHome Position ("<<HomePosition; 00051 ss << "); TargetPosition ("<<TargetPosition; 00052 ss << "); PointNumber ("<<PointNumber; 00053 ss << ")\n"; 00054 return ss.str(); 00055 } 00056 //----------------------------------------------------------------------------- 00057 // class AdvSimConstraint_ConstrainedPoint 00058 //============================================================================= 00059 00060 00061 //============================================================================= 00062 // class AdvSimConstraint_GroupOfConstrainedPoints 00063 //----------------------------------------------------------------------------- 00064 template <typename T> 00065 AdvSimConstraint_GroupOfConstrainedPoints<T>::AdvSimConstraint_GroupOfConstrainedPoints () 00066 : Ratio( 0.5f ) 00067 //, ModelID( -1 ) 00068 {} 00069 //----------------------------------------------------------------------------- 00070 template <typename T> 00071 AdvSimConstraint_GroupOfConstrainedPoints<T>::AdvSimConstraint_GroupOfConstrainedPoints ( AdvSimConstraint_GroupOfConstrainedPoints<T> const &orig ) 00072 : Ratio( orig.Ratio ) 00073 //, ModelID( orig.ModelID ) 00074 , ListOfConstrainedPoints( orig.ListOfConstrainedPoints ) 00075 {} 00076 //----------------------------------------------------------------------------- 00077 template <typename T> 00078 AdvSimConstraint_GroupOfConstrainedPoints<T> & AdvSimConstraint_GroupOfConstrainedPoints<T>::operator= ( AdvSimConstraint_GroupOfConstrainedPoints<T> const &orig ) 00079 { 00080 Ratio = orig.Ratio; 00081 //ModelID = orig.ModelID; 00082 ListOfConstrainedPoints = orig.ListOfConstrainedPoints; 00083 return *this; 00084 } 00085 //----------------------------------------------------------------------------- 00086 template <typename T> 00087 AdvSimConstraint_GroupOfConstrainedPoints<T>::~AdvSimConstraint_GroupOfConstrainedPoints () 00088 { 00089 ListOfConstrainedPoints.clear(); 00090 } 00091 //----------------------------------------------------------------------------- 00092 template <typename T> 00093 std::string AdvSimConstraint_GroupOfConstrainedPoints<T>::StrInfo () const 00094 { 00095 std::ostringstream ss; 00096 ss << "AdvSimConstraint_GroupOfConstrainedPoints<" << typeid(T).name() << ">"; 00097 ss << " contains " << ListOfConstrainedPoints.size() << " of constrained points\n"; 00098 for ( unsigned int i = 0; i < ListOfConstrainedPoints.size(); ++i ) { 00099 ss << "Point#" << i << ": " << ListOfConstrainedPoints[i]; 00100 } 00101 ss << "\n"; 00102 return ss.str(); 00103 } 00104 //----------------------------------------------------------------------------- 00105 #if defined(__gl_h_) || defined(__GL_H__) 00106 template <typename T> 00107 void AdvSimConstraint_GroupOfConstrainedPoints<T>::Draw ( Vector3<T> & color, T PtSize ) const 00108 { 00109 glPushAttrib( GL_ALL_ATTRIB_BITS ); 00110 glPointSize( static_cast<float>(PtSize) ); 00111 glEnable( GL_COLOR_MATERIAL ); 00112 glColor3fv( color.GetDataFloat() ); 00113 glBegin( GL_POINTS ); 00114 for ( unsigned int i = 0; i < ListOfConstrainedPoints.size(); ++i ) { 00115 glVertex3fv( ListOfConstrainedPoints[i].TargetPosition.GetDataFloat() ); 00116 } 00117 glEnd(); 00118 glBegin( GL_LINE_STRIP ); 00119 glLineWidth( 1 ); 00120 for ( unsigned int i = 0; i < ListOfConstrainedPoints.size(); ++i ) { 00121 glVertex3fv( ListOfConstrainedPoints[i].TargetPosition.GetDataFloat() ); 00122 } 00123 glEnd(); 00124 glPopAttrib(); 00125 } 00126 #endif 00127 //----------------------------------------------------------------------------- 00128 // class AdvSimConstraint_GroupOfConstrainedPoints 00129 //============================================================================= 00130 00131 00132 //============================================================================= 00133 // class AdvSimConstraints 00134 //----------------------------------------------------------------------------- 00135 template <typename T> 00136 AdvSimConstraints<T>::AdvSimConstraints () 00137 {} 00138 //----------------------------------------------------------------------------- 00139 //template <typename T> 00140 //AdvSimConstraints<T>::AdvSimConstraints ( AdvSimConstraints<T> const &orig ) 00141 //{} 00142 //----------------------------------------------------------------------------- 00143 //template <typename T> 00144 //AdvSimConstraints<T> & AdvSimConstraints<T>::operator= ( AdvSimConstraints<T> const &orig ) 00145 //{ 00146 // return *this; 00147 //} 00148 //----------------------------------------------------------------------------- 00149 template <typename T> 00150 AdvSimConstraints<T>::~AdvSimConstraints () 00151 { 00152 m_ListOfConstrainedPtGrps.clear(); 00153 } 00154 //----------------------------------------------------------------------------- 00155 template <typename T> 00156 std::string AdvSimConstraints<T>::StrInfo () const 00157 { 00158 std::ostringstream ss; 00159 ss << "AdvSimConstraints<" << typeid(T).name() << ">"; 00160 ss << " contains " << m_ListOfConstrainedPtGrps.size << " of constrained point groups\n"; 00161 for ( unsigned int i = m_ListOfConstrainedPtGrps; i < m_ListOfConstrainedPtGrps.size(); ++i ) { 00162 ss << "Group#" << i << ": " << m_ListOfConstrainedPtGrps[i]; 00163 } 00164 ss << "\n"; 00165 return ss.str(); 00166 } 00167 //----------------------------------------------------------------------------- 00168 template <typename T> 00169 unsigned int AdvSimConstraints<T>::AddConstrainedModelER ( 00170 ModelElasticRod<T> & ModelER 00171 ) 00172 { 00173 m_ListOfConstrainedERs.push_back( AdvSimConstraint_ConstrainedER<T>() ); 00174 m_ListOfConstrainedERs.back().pModelER = &ModelER; 00175 return m_ListOfConstrainedERs.size() - 1; 00176 } 00177 //----------------------------------------------------------------------------- 00178 template <typename T> 00179 void AdvSimConstraints<T>::AssociateCPtsGrpWithModelER ( 00180 unsigned int CPtsGrp_ID, 00181 unsigned int ModelER_ID 00182 ) 00183 { 00184 assert( CPtsGrp_ID < m_ListOfConstrainedPtGrps.size() ); 00185 assert( ModelER_ID < m_ListOfConstrainedERs.size() ); 00186 m_ListOfConstrainedERs[ModelER_ID].ListOfCPtsGrpIDs.push_back( CPtsGrp_ID ); 00187 } 00188 //----------------------------------------------------------------------------- 00189 template <typename T> 00190 void AdvSimConstraints<T>::EnforceConstraints_A__NotForMultiGrp ( 00191 ModelElasticRod<T> * pER, 00192 int groupID 00193 ) 00194 { 00195 VectorOfCPts & CPts = m_ListOfConstrainedPtGrps[groupID].ListOfConstrainedPoints; 00196 int size = CPts.size(); 00197 T ratio = m_ListOfConstrainedPtGrps[groupID].Ratio; 00198 00199 Real val_s = 0; 00200 Real val_e = 0; 00201 Real extendThd; 00202 00203 int firstPt = 0; 00204 int lastPt = size - 1;// - firstPt; 00205 int pt_s = CPts[firstPt].PointID; 00206 int pt_e = pt_s + lastPt; 00207 00208 TAPs::Vector3<Real> & S_s2 = pER->RefToCurrentVertexPositionOfNodeNumber( pt_s ); 00209 TAPs::Vector3<Real> & S_e2 = pER->RefToCurrentVertexPositionOfNodeNumber( pt_e ); 00210 00211 // 00212 // Case the number of constrained points is more than 2 00213 // 00214 // Compare the link lengths formed by the two home positions of the 1st & 2nd constraints 00215 // with the suture link length formed by the two constrained points associated with the two constraints. 00216 // If the suture link length is longer, then prepare to check for a forward movement of the suture 00217 // by calculating the relative length of the suture link compare to the constrained link, noted as Ls. 00218 // Else mark the length as zero. 00219 // 00220 // Compare the link lengths formed by the two home positions of the last and previous one before the last constraints 00221 // with the suture link length formed by the two constrained points associated with the two constriants. 00222 // If the suture link length is longer, then prepare to check for a backward movement of the suture 00223 // by calculating the relative length of the suture link compare to the constrained link, noted as Le. 00224 // Else mark the length as zero. 00225 // 00226 // Pick one with the longer length of Ls and Le, and check it against the threshold length. 00227 // If the length is greater than the threshold, then do the move accordingly 00228 // -- If Ls is picked, then move forward, else move backward. 00229 00230 // If the first link length is longer than the last link length, then check for forward movement. 00231 // Else check for backward movement. 00232 if ( size > 2 ) { 00233 00234 extendThd = 1 + ratio*2; 00235 00236 // Find the first constrained link formed by the 1st & 2nd constraints 00237 Real LC_s = (CPts[0].HomePosition - CPts[1].HomePosition).Length(); 00238 00239 //Find the last constrained formed by the last & the previous one before the last constraints 00240 Real LC_e = (CPts[lastPt].HomePosition - CPts[lastPt-1].HomePosition).Length(); 00241 00242 //TAPs::Vector3<Real> S_s1 = pER->RefToCurrentVertexPositionOfNodeNumber( pt_s-1 ); 00243 TAPs::Vector3<Real> S_e1 = pER->RefToCurrentVertexPositionOfNodeNumber( pt_e-1 ); 00244 TAPs::Vector3<Real> S_s3 = pER->RefToCurrentVertexPositionOfNodeNumber( pt_s+1 ); 00245 //TAPs::Vector3<Real> S_e3 = pER->RefToCurrentVertexPositionOfNodeNumber( pt_e+1 ); 00246 00247 //Real L_s1 = (S_s1 - S_s2).Length(); 00248 Real L_e1 = (S_e1 - S_e2).Length(); 00249 Real L_s2 = (S_s3 - S_s2).Length(); 00250 //Real L_e2 = (S_e3 - S_e2).Length(); 00251 00252 val_s = L_s2 / LC_s; 00253 val_e = L_e1 / LC_e; 00254 } 00255 // 00256 // Case the number of constrained points is less than 3 00257 // 00258 // In this case there are only one link if the number of constraints is two 00259 // and no link if the number of constraints is one. 00260 // 00261 // The check is done by comparing the length between the two links that sandwiches the constraint(s). 00262 else { 00263 00264 extendThd = 1 + ratio*2; 00265 00266 TAPs::Vector3<Real> S_s1 = pER->RefToCurrentVertexPositionOfNodeNumber( pt_s-1 ); 00267 TAPs::Vector3<Real> S_e3 = pER->RefToCurrentVertexPositionOfNodeNumber( pt_e+1 ); 00268 Real Ls = (S_s1 - S_s2).Length(); 00269 Real Le = (S_e3 - S_e2).Length(); 00270 00271 val_s = Ls / Le; 00272 val_e = Le / Ls; 00273 } 00274 00275 // 00276 // Determine if the conditions are allowed for forward or backward movement 00277 // 00278 bool bCanMoveForward = true; 00279 bool bCanMoveBackward = true; 00280 ElasticRodNode<T> & NodeBegin = pER->GetListOfNodes()[pt_s-1]; 00281 ElasticRodNode<T> & NodeEnd = pER->GetListOfNodes()[pt_e+1]; 00282 00283 /* 00284 if ( !NodeEnd.SimFlags.CheckSimulationConstraints( Enum::AddOn::SLIDABLE ) ) { 00285 bCanMoveForward = false; 00286 } 00287 if ( !NodeBegin.SimFlags.CheckSimulationConstraints( Enum::AddOn::SLIDABLE ) ) { 00288 bCanMoveBackward = false; 00289 } 00290 //*/ 00291 00292 // 00293 // If the longer length is longer than the shorter link by 00294 // 00295 // Move forward 00296 if ( val_s > val_e ) { 00297 00298 if ( pt_e < pSuture->GetNumOfPoints()-4 ) // boundary protection 00299 if ( bCanMoveForward ) 00300 if ( val_s > extendThd ) 00301 { 00302 00303 //* 00304 // Clear the start node 00305 ElasticRodNode<T> & NodeS = pER->GetListOfNodes()[pt_s]; 00306 NodeS.ExternalForce_ForAdvSimCtrl.Clear(); 00307 NodeS.SimFlags.ClearSimulationConstraints( Enum::AddOn::IGNORE_CD_FORCE ); 00308 00309 // Set the new end node 00310 //NodeEnd.SimFlags.SetSimulationConstraints( Enum::AddOn::SLIDABLE ); 00311 NodeEnd.SimFlags.SetSimulationConstraints( Enum::AddOn::IGNORE_CD_FORCE ); 00312 //*/ 00313 00314 for ( unsigned int i = 0; i < CPts.size(); ++i ) { 00315 ++CPts[i].PointID; 00316 } 00317 } 00318 } 00319 // Move backward 00320 else { 00321 if ( pt_s > 4 ) // boundary protection 00322 if ( bCanMoveBackward ) 00323 if ( val_e > extendThd ) 00324 { 00325 00326 //* 00327 // Clear the end node 00328 ElasticRodNode<T> & NodeE = pER->GetListOfNodes()[pt_e+1]; 00329 NodeE.ExternalForce_ForAdvSimCtrl.Clear(); 00330 NodeE.SimFlags.ClearSimulationConstraints( Enum::AddOn::IGNORE_CD_FORCE ); 00331 00332 // Set the new start node 00333 //NodeBegin.SimFlags.SetSimulationConstraints( Enum::AddOn::SLIDABLE ); 00334 NodeBegin.SimFlags.SetSimulationConstraints( Enum::AddOn::IGNORE_CD_FORCE ); 00335 //*/ 00336 00337 for ( unsigned int i = 0; i < CPts.size(); ++i ) { 00338 --CPts[i].PointID; 00339 } 00340 } 00341 } 00342 } 00343 //----------------------------------------------------------------------------- 00344 template <typename T> 00345 void AdvSimConstraints<T>::EnforceConstraints_B__NotForMultiGrp ( 00346 ModelElasticRod<T> * pER, 00347 int groupID 00348 ) 00349 { 00350 VectorOfCPts & CPts = m_ListOfConstrainedPtGrps[groupID].ListOfConstrainedPoints; 00351 T ratio = m_ListOfConstrainedPtGrps[groupID].Ratio; 00352 00353 // Constraint the positions 00354 for ( unsigned int i = 0; i < CPts.size(); ++i ) { 00355 int pt = CPts[i].PointID; 00356 TAPs::Vector3<Real> Target = ratio*pER->RefToCurrentVertexPositionOfNodeNumber( pt ) + (1-ratio)*CPts[i].HomePosition; 00357 00358 pER->GetListOfNodes()[pt].Centerline[pSuture->GetCurrentIndex()].SetPosition( Target ); 00359 00360 CPts[i].TargetPosition = Target; 00361 } 00362 } 00363 //----------------------------------------------------------------------------- 00364 template <typename T> 00365 void AdvSimConstraints<T>::EnforceConstraints_A ( 00366 ModelElasticRod<T> * pER, 00367 int groupID 00368 ) 00369 { 00370 VectorOfCPts & CPts = m_ListOfConstrainedPtGrps[groupID].ListOfConstrainedPoints; 00371 int size = CPts.size(); 00372 T ratio = m_ListOfConstrainedPtGrps[groupID].Ratio; 00373 00374 Real val_s = 0; 00375 Real val_e = 0; 00376 Real extendThd; 00377 00378 int firstPt = 0; 00379 int lastPt = size - 1;// - firstPt; 00380 int pt_s = CPts[firstPt].PointID; 00381 int pt_e = pt_s + lastPt; 00382 00383 //std::cout << "Grp#" << groupID << "; pt_s: " << pt_s << ", pt_e: " << pt_e << "\n"; 00384 //std::cout << "ratio: " << ratio << "\n"; 00385 00386 //std::cout << "Aaddresses: " << &CPts << " and " << &m_ListOfConstrainedPtGrps[groupID].ListOfConstrainedPoints << "\n"; 00387 //std::cout << "Baddresses: " << &CPts[0] << " and " << &m_ListOfConstrainedPtGrps[groupID].ListOfConstrainedPoints[0] << "\n"; 00388 00389 TAPs::Vector3<Real> & S_s2 = pER->RefToCurrentVertexPositionOfNodeNumber( pt_s ); 00390 TAPs::Vector3<Real> & S_e2 = pER->RefToCurrentVertexPositionOfNodeNumber( pt_e ); 00391 00392 // 00393 // Case the number of constrained points is more than 2 00394 // 00395 // Compare the link lengths formed by the two home positions of the 1st & 2nd constraints 00396 // with the suture link length formed by the two constrained points associated with the two constraints. 00397 // If the suture link length is longer, then prepare to check for a forward movement of the suture 00398 // by calculating the relative length of the suture link compare to the constrained link, noted as Ls. 00399 // Else mark the length as zero. 00400 // 00401 // Compare the link lengths formed by the two home positions of the last and previous one before the last constraints 00402 // with the suture link length formed by the two constrained points associated with the two constriants. 00403 // If the suture link length is longer, then prepare to check for a backward movement of the suture 00404 // by calculating the relative length of the suture link compare to the constrained link, noted as Le. 00405 // Else mark the length as zero. 00406 // 00407 // Pick one with the longer length of Ls and Le, and check it against the threshold length. 00408 // If the length is greater than the threshold, then do the move accordingly 00409 // -- If Ls is picked, then move forward, else move backward. 00410 00411 // If the first link length is longer than the last link length, then check for forward movement. 00412 // Else check for backward movement. 00413 if ( size > 2 ) { 00414 //if ( false ) { 00415 00416 extendThd = 1 + ratio*2; 00417 00418 // Find the first constrained link formed by the 1st & 2nd constraints 00419 Real LC_s = (CPts[0].HomePosition - CPts[1].HomePosition).Length(); 00420 00421 //Find the last constrained formed by the last & the previous one before the last constraints 00422 Real LC_e = (CPts[lastPt].HomePosition - CPts[lastPt-1].HomePosition).Length(); 00423 00424 //TAPs::Vector3<Real> S_s1 = pER->RefToCurrentVertexPositionOfNodeNumber( pt_s-1 ); 00425 TAPs::Vector3<Real> S_e1 = pER->RefToCurrentVertexPositionOfNodeNumber( pt_e-1 ); 00426 TAPs::Vector3<Real> S_s3 = pER->RefToCurrentVertexPositionOfNodeNumber( pt_s+1 ); 00427 //TAPs::Vector3<Real> S_e3 = pER->RefToCurrentVertexPositionOfNodeNumber( pt_e+1 ); 00428 00429 //Real L_s1 = (S_s1 - S_s2).Length(); 00430 Real L_e1 = (S_e1 - S_e2).Length(); 00431 Real L_s2 = (S_s3 - S_s2).Length(); 00432 //Real L_e2 = (S_e3 - S_e2).Length(); 00433 00434 val_s = L_s2 / LC_s; 00435 val_e = L_e1 / LC_e; 00436 00437 //std::cout << "pt_s: " << pt_s << "; " << "pt_e: " << pt_e << "\n"; 00438 //std::cout << "val_s and val_e: " << val_s << ", " << val_e << "\n"; 00439 00440 } 00441 // 00442 // Case the number of constrained points is less than 3 00443 // 00444 // In this case there are only one link if the number of constraints is two 00445 // and no link if the number of constraints is one. 00446 // 00447 // The check is done by comparing the length between the two links that sandwiches the constraint(s). 00448 else { 00449 00450 extendThd = 1 + ratio*2; 00451 00452 TAPs::Vector3<Real> S_s1 = pER->RefToCurrentVertexPositionOfNodeNumber( pt_s-1 ); 00453 TAPs::Vector3<Real> S_e3 = pER->RefToCurrentVertexPositionOfNodeNumber( pt_e+1 ); 00454 Real Ls = (S_s1 - S_s2).Length(); 00455 Real Le = (S_e3 - S_e2).Length(); 00456 00457 val_s = Ls / Le; 00458 val_e = Le / Ls; 00459 } 00460 00461 00462 //std::cout << "TEST: val_s and val_e: " << val_s << ", " << val_e << "\n"; 00463 //std::cout << "extendThd: " << extendThd << "\n"; 00464 00465 00466 // 00467 // Determine if the conditions are allowed for forward or backward movement 00468 // 00469 bool bCanMoveForward = true; 00470 bool bCanMoveBackward = true; 00471 ElasticRodNode<T> & NodeBegin = pER->GetListOfNodes()[pt_s-1]; 00472 ElasticRodNode<T> & NodeEnd = pER->GetListOfNodes()[pt_e+1]; 00473 00474 if ( !NodeEnd.SimFlags.CheckSimulationConstraints( Enum::AddOn::SLIDABLE ) ) { 00475 bCanMoveForward = false; 00476 } 00477 if ( !NodeBegin.SimFlags.CheckSimulationConstraints( Enum::AddOn::SLIDABLE ) ) { 00478 bCanMoveBackward = false; 00479 } 00480 00481 //std::cout << "bCanMoveForward: " << bCanMoveForward << "\n"; 00482 //std::cout << "bCanMoveBackward: " << bCanMoveBackward << "\n"; 00483 00484 // 00485 // If the longer length is longer than the shorter link by 00486 // 00487 // Move forward 00488 if ( val_s > val_e ) { 00489 00490 if ( pt_e < pSuture->GetNumOfPoints()-4 ) // boundary protection 00491 if ( bCanMoveForward ) 00492 if ( val_s > extendThd ) 00493 { 00494 00495 //* 00496 // Clear the start node 00497 ElasticRodNode<T> & NodeS = pER->GetListOfNodes()[pt_s]; 00498 NodeS.ExternalForce_ForAdvSimCtrl.Clear(); 00499 NodeS.SimFlags.ClearSimulationConstraints( Enum::AddOn::IGNORE_CD_FORCE ); 00500 00501 // Set the new end node 00502 //NodeEnd.SimFlags.SetSimulationConstraints( Enum::AddOn::SLIDABLE ); 00503 NodeEnd.SimFlags.SetSimulationConstraints( Enum::AddOn::IGNORE_CD_FORCE ); 00504 //*/ 00505 00506 for ( unsigned int i = 0; i < CPts.size(); ++i ) { 00507 ++CPts[i].PointID; 00508 } 00509 } 00510 } 00511 // Move backward 00512 else { 00513 if ( pt_s > 4 ) // boundary protection 00514 if ( bCanMoveBackward ) 00515 if ( val_e > extendThd ) 00516 { 00517 00518 //* 00519 // Clear the end node 00520 ElasticRodNode<T> & NodeE = pER->GetListOfNodes()[pt_e+1]; 00521 NodeE.ExternalForce_ForAdvSimCtrl.Clear(); 00522 NodeE.SimFlags.ClearSimulationConstraints( Enum::AddOn::IGNORE_CD_FORCE ); 00523 00524 // Set the new start node 00525 //NodeBegin.SimFlags.SetSimulationConstraints( Enum::AddOn::SLIDABLE ); 00526 NodeBegin.SimFlags.SetSimulationConstraints( Enum::AddOn::IGNORE_CD_FORCE ); 00527 //*/ 00528 00529 for ( unsigned int i = 0; i < CPts.size(); ++i ) { 00530 --CPts[i].PointID; 00531 } 00532 } 00533 } 00534 } 00535 //----------------------------------------------------------------------------- 00536 template <typename T> 00537 void AdvSimConstraints<T>::EnforceConstraints_B ( 00538 ModelElasticRod<T> * pER, 00539 int groupID 00540 ) 00541 { 00542 VectorOfCPts & CPts = m_ListOfConstrainedPtGrps[groupID].ListOfConstrainedPoints; 00543 T ratio = m_ListOfConstrainedPtGrps[groupID].Ratio; 00544 00545 // Constraint the positions 00546 for ( unsigned int i = 0; i < CPts.size(); ++i ) { 00547 int pt = CPts[i].PointID; 00548 TAPs::Vector3<Real> Target = ratio*pER->RefToCurrentVertexPositionOfNodeNumber( pt ) + (1-ratio)*CPts[i].HomePosition; 00549 00550 pER->GetListOfNodes()[pt].Centerline[pER->GetCurrentIndex()].SetPosition( Target ); 00551 00552 CPts[i].TargetPosition = Target; 00553 } 00554 } 00555 //----------------------------------------------------------------------------- 00556 template <typename T> 00557 void AdvSimConstraints<T>::EnforceConstraints_B__ByForce ( 00558 ModelElasticRod<T> * pER, 00559 int groupID, 00560 Vector3<T> & Force 00561 ) 00562 { 00563 VectorOfCPts & CPts = m_ListOfConstrainedPtGrps[groupID].ListOfConstrainedPoints; 00564 T ratio = m_ListOfConstrainedPtGrps[groupID].Ratio; 00565 00566 // Constraint the positions 00567 for ( unsigned int i = 0; i < CPts.size(); ++i ) { 00568 int pt = CPts[i].PointID; 00569 TAPs::Vector3<Real> Target = ratio*pER->RefToCurrentVertexPositionOfNodeNumber( pt ) + (1-ratio)*CPts[i].HomePosition; 00570 00571 pER->GetListOfNodes()[pt].ExternalForce_Constrained[0] = (Target-pER->RefToCurrentVertexPositionOfNodeNumber( pt ))[0] * Force[0]; 00572 pER->GetListOfNodes()[pt].ExternalForce_Constrained[1] = (Target-pER->RefToCurrentVertexPositionOfNodeNumber( pt ))[1] * Force[1]; 00573 pER->GetListOfNodes()[pt].ExternalForce_Constrained[2] = (Target-pER->RefToCurrentVertexPositionOfNodeNumber( pt ))[2] * Force[2]; 00574 00575 CPts[i].TargetPosition = Target; 00576 } 00577 } 00578 //----------------------------------------------------------------------------- 00579 template <typename T> 00580 void AdvSimConstraints<T>::EnforceConstrainedModelER_A ( 00581 AdvSimConstraint_ConstrainedER<T> & ConstrainedER 00582 ) 00583 { 00584 ModelElasticRod<T> * pER = ConstrainedER.pModelER; 00585 00586 for ( unsigned int i = 0; i < ConstrainedER.ListOfCPtsGrpIDs.size(); ++i ) 00587 { 00588 unsigned int groupID = ConstrainedER.ListOfCPtsGrpIDs[i]; 00589 // The constrained point group that contains the start part 00590 VectorOfCPts & CPts = m_ListOfConstrainedPtGrps[groupID].ListOfConstrainedPoints; 00591 int size = CPts.size(); 00592 T ratio = m_ListOfConstrainedPtGrps[groupID].Ratio; 00593 00594 Real val_s = 0; 00595 Real val_e = 0; 00596 Real extendThd; 00597 00598 int firstPt = 0; 00599 int lastPt = size - 1;// - firstPt; 00600 int pt_s = CPts[firstPt].PointID; 00601 int pt_e = pt_s + lastPt; 00602 00603 // 00604 // Check the next constrained point groups 00605 // 00606 unsigned int i_old = i; 00607 unsigned int groupIDNext = groupID; 00608 unsigned int j = i+1; 00609 bool bKeepLooping = true; 00610 while ( bKeepLooping && j < ConstrainedER.ListOfCPtsGrpIDs.size() ) { 00611 groupIDNext = ConstrainedER.ListOfCPtsGrpIDs[j]; 00612 VectorOfCPts & CPtsNext = m_ListOfConstrainedPtGrps[groupIDNext].ListOfConstrainedPoints; 00613 int pt_s_next = CPtsNext[0].PointID; 00614 if ( pt_s_next == pt_e+1 ) { 00615 lastPt = CPtsNext.size() - 1; 00616 pt_e = pt_s_next + lastPt; 00617 groupID = groupIDNext; // add this group into the calculation 00618 i = j; // will skip the next group in the next iteration of the for loop 00619 size += lastPt + 1; 00620 } 00621 else { 00622 bKeepLooping = false; 00623 } 00624 ++j; 00625 } 00626 00627 // The constrained point group that contains the end part 00628 VectorOfCPts & CPtsNext = m_ListOfConstrainedPtGrps[groupID].ListOfConstrainedPoints; 00629 00630 00631 //std::cout << "Grp#" << groupID << "; pt_s: " << pt_s << ", pt_e: " << pt_e << "\n"; 00632 //std::cout << "ratio: " << ratio << "\n"; 00633 00634 //std::cout << "Aaddresses: " << &CPts << " and " << &m_ListOfConstrainedPtGrps[groupID].ListOfConstrainedPoints << "\n"; 00635 //std::cout << "Baddresses: " << &CPts[0] << " and " << &m_ListOfConstrainedPtGrps[groupID].ListOfConstrainedPoints[0] << "\n"; 00636 00637 TAPs::Vector3<Real> & S_s2 = pER->RefToCurrentVertexPositionOfNodeNumber( pt_s ); 00638 TAPs::Vector3<Real> & S_e2 = pER->RefToCurrentVertexPositionOfNodeNumber( pt_e ); 00639 00640 // 00641 // Case the number of constrained points is more than 2 00642 // 00643 // Compare the link lengths formed by the two home positions of the 1st & 2nd constraints 00644 // with the suture link length formed by the two constrained points associated with the two constraints. 00645 // If the suture link length is longer, then prepare to check for a forward movement of the suture 00646 // by calculating the relative length of the suture link compare to the constrained link, noted as Ls. 00647 // Else mark the length as zero. 00648 // 00649 // Compare the link lengths formed by the two home positions of the last and previous one before the last constraints 00650 // with the suture link length formed by the two constrained points associated with the two constriants. 00651 // If the suture link length is longer, then prepare to check for a backward movement of the suture 00652 // by calculating the relative length of the suture link compare to the constrained link, noted as Le. 00653 // Else mark the length as zero. 00654 // 00655 // Pick one with the longer length of Ls and Le, and check it against the threshold length. 00656 // If the length is greater than the threshold, then do the move accordingly 00657 // -- If Ls is picked, then move forward, else move backward. 00658 00659 // If the first link length is longer than the last link length, then check for forward movement. 00660 // Else check for backward movement. 00661 if ( size > 2 ) { 00662 //if ( false ) { 00663 00664 extendThd = 1 + ratio*1.25; 00665 00666 // Find the first constrained link formed by the 1st & 2nd constraints 00667 Real LC_s = (CPts[0].HomePosition - CPts[1].HomePosition).Length(); 00668 00669 //Find the last constrained formed by the last & the previous one before the last constraints 00670 Real LC_e = (CPtsNext[lastPt].HomePosition - CPtsNext[lastPt-1].HomePosition).Length(); 00671 00672 //TAPs::Vector3<Real> S_s1 = pER->RefToCurrentVertexPositionOfNodeNumber( pt_s-1 ); 00673 TAPs::Vector3<Real> S_e1 = pER->RefToCurrentVertexPositionOfNodeNumber( pt_e-1 ); 00674 TAPs::Vector3<Real> S_s3 = pER->RefToCurrentVertexPositionOfNodeNumber( pt_s+1 ); 00675 //TAPs::Vector3<Real> S_e3 = pER->RefToCurrentVertexPositionOfNodeNumber( pt_e+1 ); 00676 00677 //Real L_s1 = (S_s1 - S_s2).Length(); 00678 Real L_e1 = (S_e1 - S_e2).Length(); 00679 Real L_s2 = (S_s3 - S_s2).Length(); 00680 //Real L_e2 = (S_e3 - S_e2).Length(); 00681 00682 val_s = L_s2 / LC_s; 00683 val_e = L_e1 / LC_e; 00684 00685 //std::cout << "pt_s: " << pt_s << "; " << "pt_e: " << pt_e << "\n"; 00686 //std::cout << "val_s and val_e: " << val_s << ", " << val_e << "\n"; 00687 00688 } 00689 // 00690 // Case the number of constrained points is less than 3 00691 // 00692 // In this case there are only one link if the number of constraints is two 00693 // and no link if the number of constraints is one. 00694 // 00695 // The check is done by comparing the length between the two links that sandwiches the constraint(s). 00696 else { 00697 00698 extendThd = 1 + ratio*2; 00699 00700 TAPs::Vector3<Real> S_s1 = pER->RefToCurrentVertexPositionOfNodeNumber( pt_s-1 ); 00701 TAPs::Vector3<Real> S_e3 = pER->RefToCurrentVertexPositionOfNodeNumber( pt_e+1 ); 00702 Real Ls = (S_s1 - S_s2).Length(); 00703 Real Le = (S_e3 - S_e2).Length(); 00704 00705 val_s = Ls / Le; 00706 val_e = Le / Ls; 00707 } 00708 00709 00710 //std::cout << "TEST: val_s and val_e: " << val_s << ", " << val_e << "\n"; 00711 //std::cout << "extendThd: " << extendThd << "\n"; 00712 00713 00714 // 00715 // Determine if the conditions are allowed for forward or backward movement 00716 // 00717 bool bCanMoveForward = true; 00718 bool bCanMoveBackward = true; 00719 ElasticRodNode<T> & NodeBegin = pER->GetListOfNodes()[pt_s-1]; 00720 ElasticRodNode<T> & NodeEnd = pER->GetListOfNodes()[pt_e+1]; 00721 00722 //* 00723 if ( !NodeEnd.SimFlags.CheckSimulationConstraints( Enum::AddOn::SLIDABLE ) ) { 00724 bCanMoveForward = false; 00725 } 00726 if ( !NodeBegin.SimFlags.CheckSimulationConstraints( Enum::AddOn::SLIDABLE ) ) { 00727 bCanMoveBackward = false; 00728 } 00729 //*/ 00730 00731 //std::cout << "bCanMoveForward: " << bCanMoveForward << "\n"; 00732 //std::cout << "bCanMoveBackward: " << bCanMoveBackward << "\n"; 00733 00734 // 00735 // If the longer length is longer than the shorter link by 00736 // 00737 // Move forward 00738 if ( val_s > val_e ) { 00739 00740 if ( pt_e < pER->GetNumOfPoints()-4 ) // boundary protection 00741 if ( bCanMoveForward ) 00742 if ( val_s > extendThd ) 00743 { 00744 00745 //* 00746 // Clear the start node 00747 ElasticRodNode<T> & NodeS = pER->GetListOfNodes()[pt_s]; 00748 NodeS.ExternalForce_ForAdvSimCtrl.Clear(); 00749 NodeS.SimFlags.ClearSimulationConstraints( Enum::AddOn::IGNORE_CD_FORCE ); 00750 00751 // Set the new end node 00752 //NodeEnd.SimFlags.SetSimulationConstraints( Enum::AddOn::SLIDABLE ); 00753 NodeEnd.SimFlags.SetSimulationConstraints( Enum::AddOn::IGNORE_CD_FORCE ); 00754 //*/ 00755 00756 for ( unsigned int i = 0; i < CPts.size(); ++i ) { 00757 ++CPts[i].PointID; 00758 } 00759 } 00760 else { 00761 i = i_old; // if no moving then restore the i position 00762 } 00763 } 00764 // Move backward 00765 else { 00766 if ( pt_s > 4 ) // boundary protection 00767 if ( bCanMoveBackward ) 00768 if ( val_e > extendThd ) 00769 { 00770 00771 //* 00772 // Clear the end node 00773 ElasticRodNode<T> & NodeE = pER->GetListOfNodes()[pt_e+1]; 00774 NodeE.ExternalForce_ForAdvSimCtrl.Clear(); 00775 NodeE.SimFlags.ClearSimulationConstraints( Enum::AddOn::IGNORE_CD_FORCE ); 00776 00777 // Set the new start node 00778 //NodeBegin.SimFlags.SetSimulationConstraints( Enum::AddOn::SLIDABLE ); 00779 NodeBegin.SimFlags.SetSimulationConstraints( Enum::AddOn::IGNORE_CD_FORCE ); 00780 //*/ 00781 00782 for ( unsigned int i = 0; i < CPts.size(); ++i ) { 00783 --CPts[i].PointID; 00784 } 00785 } 00786 else { 00787 i = i_old; // if no moving then restore the i position 00788 } 00789 } 00790 } 00791 } 00792 //----------------------------------------------------------------------------- 00793 template <typename T> 00794 void AdvSimConstraints<T>::EnforceAllConstrainedModels_A () 00795 { 00796 EnforceAllConstrainedModelERs_A(); 00797 } 00798 //----------------------------------------------------------------------------- 00799 template <typename T> 00800 void AdvSimConstraints<T>::EnforceAllConstrainedModels_B () 00801 { 00802 EnforceAllConstrainedModelERs_B(); 00803 } 00804 //----------------------------------------------------------------------------- 00805 template <typename T> 00806 void AdvSimConstraints<T>::EnforceAllConstrainedModels_B__ByForce ( Vector3<T> & Force ) 00807 { 00808 EnforceAllConstrainedModelERs_B__ByForce( Force ); 00809 } 00810 //----------------------------------------------------------------------------- 00811 template <typename T> 00812 void AdvSimConstraints<T>::EnforceAllConstrainedModelERs_A () 00813 { 00814 for ( VectorOfConstrainedERs::iterator it = m_ListOfConstrainedERs.begin(); it != m_ListOfConstrainedERs.end(); ++it ) 00815 { 00816 //for ( unsigned int i = 0; i < it->ListOfCPtsGrpIDs.size(); ++i ) { 00817 // EnforceConstraints_A( it->pModelER, it->ListOfCPtsGrpIDs[i] ); 00818 // //EnforceConstraints_A__NotForMultiGrp( it->pModelER, it->ListOfCPtsGrpIDs[i] ); 00819 //} 00820 00821 EnforceConstrainedModelER_A( *it ); 00822 } 00823 } 00824 //----------------------------------------------------------------------------- 00825 template <typename T> 00826 void AdvSimConstraints<T>::EnforceAllConstrainedModelERs_B () 00827 { 00828 for ( VectorOfConstrainedERs::iterator it = m_ListOfConstrainedERs.begin(); it != m_ListOfConstrainedERs.end(); ++it ) 00829 { 00830 for ( unsigned int i = 0; i < it->ListOfCPtsGrpIDs.size(); ++i ) { 00831 EnforceConstraints_B( it->pModelER, it->ListOfCPtsGrpIDs[i] ); 00832 //EnforceConstraints_B__NotForMultiGrp( it->pModelER, it->ListOfCPtsGrpIDs[i] ); 00833 } 00834 } 00835 } 00836 //----------------------------------------------------------------------------- 00837 template <typename T> 00838 void AdvSimConstraints<T>::EnforceAllConstrainedModelERs_B__ByForce ( Vector3<T> & Force ) 00839 { 00840 for ( VectorOfConstrainedERs::iterator it = m_ListOfConstrainedERs.begin(); it != m_ListOfConstrainedERs.end(); ++it ) 00841 { 00842 for ( unsigned int i = 0; i < it->ListOfCPtsGrpIDs.size(); ++i ) { 00843 EnforceConstraints_B__ByForce( it->pModelER, it->ListOfCPtsGrpIDs[i], Force ); 00844 } 00845 } 00846 } 00847 //----------------------------------------------------------------------------- 00848 template <typename T> 00849 void AdvSimConstraints<T>::ClearAllConstraints () 00850 { 00851 //m_ListOfConstrainedERs.clear(); // this statement is replaced by the code below 00852 for ( int i = m_ListOfConstrainedERs.size()-1; i >= 0; --i ) { 00853 ClearAllConstriantsOnERatID( i ); 00854 } 00855 00856 m_ListOfConstrainedPtGrps.clear(); 00857 } 00858 //----------------------------------------------------------------------------- 00859 template <typename T> 00860 void AdvSimConstraints<T>::ClearAllConstriantsOnERatID ( unsigned int ERid ) 00861 { 00862 ModelElasticRod<T> * pModelER = m_ListOfConstrainedERs[ERid].pModelER; 00863 for ( std::vector< unsigned int >::iterator it = m_ListOfConstrainedERs[ERid].ListOfCPtsGrpIDs.begin(); it < m_ListOfConstrainedERs[ERid].ListOfCPtsGrpIDs.end(); ++it ) { 00864 unsigned int grpID = m_ListOfConstrainedERs[ERid].ListOfCPtsGrpIDs[*it]; 00865 for ( VectorOfCPts::iterator pt = m_ListOfConstrainedPtGrps[grpID].ListOfConstrainedPoints.begin(); pt < m_ListOfConstrainedPtGrps[grpID].ListOfConstrainedPoints.end(); ++pt ) { 00866 pModelER->GetListOfNodes()[pt->PointID].ExternalForce_Constrained.Clear(); 00867 } 00868 } 00869 m_ListOfConstrainedERs.erase( m_ListOfConstrainedERs.begin()+ERid ); 00870 } 00871 //----------------------------------------------------------------------------- 00872 #if defined(__gl_h_) || defined(__GL_H__) 00873 template <typename T> 00874 void AdvSimConstraints<T>::Draw ( Vector3<T> & color, T PtSize ) const 00875 { 00876 for ( unsigned int i = 0; i < m_ListOfConstrainedPtGrps.size(); ++i ) { 00877 m_ListOfConstrainedPtGrps[i].Draw( color, PtSize ); 00878 } 00879 } 00880 #endif 00881 //----------------------------------------------------------------------------- 00882 // class AdvSimConstraints 00883 //============================================================================= 00884 END_NAMESPACE_TAPs 00885 //34567890123456789012345678901234567890123456789012345678901234567890123456789 00886 //--+----1----+----2----+----3----+----4----+----5----+----6----+----7----+----