TAPs 0.7.7.3
TAPsAdvSimConstraints.cpp
Go to the documentation of this file.
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----+----
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines