TAPs 0.7.7.3
TAPsAdvSimSupport_DS.cpp
Go to the documentation of this file.
00001 /******************************************************************************
00002 TAPsAdvSimSupport_DS.cpp
00003 ******************************************************************************/
00007 /******************************************************************************
00008 SUKITTI PUNAK   (09/29/2008)
00009 UPDATE          (03/15/2011)
00010 ******************************************************************************/
00011 #include "TAPsAdvSimSupport_DS.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 //-----------------------------------------------------------------------------
00019 template <typename T, typename DATA>
00020 AdvSimSupport_DS<T,DATA>::AdvSimSupport_DS ()
00021     : m_OffsetToSutureLastSlidablePoint( 1 )
00022 {}
00023 //-----------------------------------------------------------------------------
00024 template <typename T, typename DATA>
00025 AdvSimSupport_DS<T,DATA>::~AdvSimSupport_DS ()
00026 {
00027     ClearAllConstraints();
00028 }
00029 //-----------------------------------------------------------------------------
00030 template <typename T, typename DATA>
00031 std::string AdvSimSupport_DS<T,DATA>::StrInfo () const
00032 {
00033     std::stringstream ss;
00034     ss << "AdvSimSupport_DS<T,DATA>\n";
00035     return ss.str();
00036 }
00037 //-----------------------------------------------------------------------------
00038 //=============================================================================
00039 
00040 
00041 
00042 
00043 //=============================================================================
00044 // Specific for suture models
00045 //-----------------------------------------------------------------------------
00046 template <typename T, typename DATA>
00047 unsigned int AdvSimSupport_DS<T,DATA>::GetTheOffsetToSutureLastSlidablePoint () const
00048 {
00049     return m_OffsetToSutureLastSlidablePoint;
00050 }
00051 //-----------------------------------------------------------------------------
00052 template <typename T, typename DATA>
00053 void AdvSimSupport_DS<T,DATA>::SetTheOffsetToSutureLastSlidablePoint ( unsigned int i )
00054 {
00055     m_OffsetToSutureLastSlidablePoint = i;
00056 }
00057 //-----------------------------------------------------------------------------
00058 // Specific for suture models
00059 //=============================================================================
00060 
00061 
00062 
00063 
00064 //=============================================================================
00065 // Add models
00066 //-----------------------------------------------------------------------------
00067 //template <typename T, typename DATA>
00068 //int AdvSimSupport_DS<T,DATA>::AddModel ( OpenGL::ModelSuture<T> * pModel )
00069 //{
00070 //  m_ListOfSutureModelsBasedOnMSS.push_back( pModel );
00071 //}
00072 //-----------------------------------------------------------------------------
00073 //template <typename T, typename DATA>
00074 //int AdvSimSupport_DS<T,DATA>::AddModel ( ModelForSurgery<T> * pModel )
00075 //{
00076 //  m_ModelLists.ListOfModelsForSurgeryBasedOnMSS.push_back( pModel );
00077 //
00078 //  // Add each part of the surgery model to the list of submodels
00079 //  for ( int i = 0; i < pModel->GetNumberOfParts(); ++i ) {
00080 //      m_ListOfHETriMeshOneModelMultiParts.push_back( pModel->GetPtrToPartNo(i) );
00081 //  }
00082 //}
00083 //-----------------------------------------------------------------------------
00084 template <typename T, typename DATA>
00085 int AdvSimSupport_DS<T,DATA>::AddModel ( ModelElasticRod<T> * pModel )
00086 {
00087     for ( unsigned int i = 0; i < m_ModelLists.BasedOnER.size(); ++i ) {
00088         if ( m_ModelLists.BasedOnER[i] == pModel ) {
00089             for ( unsigned int j = 0; j < m_IDForModel.size(); ++j ) {
00090                 if (    m_IDForModel[j].Type == Enum::MODEL_BASED_ON_ER
00091                     &&  m_ModelLists.BasedOnER[m_IDForModel[j].Slot] == pModel )
00092                 {
00093                     return j;
00094                 }
00095             }
00096         }
00097     }
00098 
00099     m_IDForModel.push_back( AdvSimSupport_DATA<T,DATA>::IDForModel( Enum::MODEL_BASED_ON_ER, m_ModelLists.BasedOnER.size() ) );
00100     m_ModelLists.BasedOnER.push_back( pModel );
00101     /*return*/ AddERBasedModel();
00102     return m_IDForModel.size()-1;
00103 }
00104 //-----------------------------------------------------------------------------
00105 template <typename T, typename DATA>
00106 int AdvSimSupport_DS<T,DATA>::AddModel ( ModelDefBasedOnFEM<T,DATA> * pModel )
00107 {
00108     for ( unsigned int i = 0; i < m_ModelLists.BasedOnFEM.size(); ++i ) {
00109         if ( m_ModelLists.BasedOnFEM[i] == pModel ) {
00110             for ( unsigned int j = 0; j < m_IDForModel.size(); ++j ) {
00111                 if (    m_IDForModel[j].Type == Enum::MODEL_BASED_ON_FEM
00112                     &&  m_ModelLists.BasedOnFEM[m_IDForModel[j].Slot] == pModel )
00113                 {
00114                     return j;
00115                 }
00116             }
00117         }
00118     }
00119 
00120     m_IDForModel.push_back( AdvSimSupport_DATA<T,DATA>::IDForModel( Enum::MODEL_BASED_ON_FEM, m_ModelLists.BasedOnFEM.size() ) );
00121     m_ModelLists.BasedOnFEM.push_back( pModel );
00122     /*return*/ AddHEBasedModel();
00123     return m_IDForModel.size()-1;
00124 }
00125 //-----------------------------------------------------------------------------
00126 template <typename T, typename DATA>
00127 int AdvSimSupport_DS<T,DATA>::AddModel ( RigidBodyDynamics<T> * pModel )
00128 {
00129     for ( unsigned int i = 0; i < m_ModelLists.BasedOnRBD.size(); ++i ) {
00130         if ( m_ModelLists.BasedOnRBD[i] == pModel ) {
00131             for ( unsigned int j = 0; j < m_IDForModel.size(); ++j ) {
00132                 if (    m_IDForModel[j].Type == Enum::MODEL_BASED_ON_IPG_RBD
00133                     &&  m_ModelLists.BasedOnRBD[m_IDForModel[j].Slot] == pModel )
00134                 {
00135                     return j;
00136                 }
00137             }
00138         }
00139     }
00140 
00141     m_IDForModel.push_back( AdvSimSupport_DATA<T,DATA>::IDForModel( Enum::MODEL_BASED_ON_IPG_RBD, m_ModelLists.BasedOnRBD.size() ) );
00142     m_ModelLists.BasedOnRBD.push_back( pModel );
00143     /*return*/ AddIPGBasedModel();
00144     return m_IDForModel.size()-1;
00145 }
00146 //-----------------------------------------------------------------------------
00147 template <typename T, typename DATA>
00148 int AdvSimSupport_DS<T,DATA>::AddERBasedModel ()
00149 {
00150     // Add data storage for the added model
00151     m_InteractionLists.ERModelVsERModel.push_back( std::vector< AdvSimSupport_DATA<T,DATA>::Interaction_ERModelVsERModel >() );
00152     AdvSimSupport_DATA<T,DATA>::ListOfInteractions_ERModelVsERModel::iterator it = m_InteractionLists.ERModelVsERModel.begin();
00153     while ( it != m_InteractionLists.ERModelVsERModel.end() ) {
00154         // Add data storage for the existed models with the added model
00155         it->push_back( AdvSimSupport_DATA<T,DATA>::Interaction_ERModelVsERModel() );
00156         ++it;
00157     }
00158 
00159     // Add data storage for the added ER-based model interaction with HE-based models
00160     {
00161         m_InteractionLists.ERModelVsHEModel.push_back( std::vector< AdvSimSupport_DATA<T,DATA>::Interaction_ERModelVsHEModel >() );
00162         AdvSimSupport_DATA<T,DATA>::ListOfInteractions_HEModelVsHEModel::iterator it = m_InteractionLists.HEModelVsHEModel.begin();
00163         while ( it != m_InteractionLists.HEModelVsHEModel.end() ) {
00164             // Add data storage for interaction of the existed HE-based models with the added ER-based model
00165             m_InteractionLists.ERModelVsHEModel.back().push_back( AdvSimSupport_DATA<T,DATA>::Interaction_ERModelVsHEModel() );
00166             ++it;
00167         }
00168     }
00169 
00170     // Add data storage for the added ER-based model interaction with IPG-based models
00171     {
00172         m_InteractionLists.ERModelVsIPGModel.push_back( std::vector< AdvSimSupport_DATA<T,DATA>::Interaction_ERModelVsIPGModel >() );
00173         AdvSimSupport_DATA<T,DATA>::ListOfInteractions_IPGModelVsIPGModel::iterator it = m_InteractionLists.IPGModelVsIPGModel.begin();
00174         while ( it != m_InteractionLists.IPGModelVsIPGModel.end() ) {
00175             // Add data storage for interaction of the existed IPG-based models with the added ER-based model
00176             m_InteractionLists.ERModelVsIPGModel.back().push_back( AdvSimSupport_DATA<T,DATA>::Interaction_ERModelVsIPGModel() );
00177             ++it;
00178         }
00179     }
00180 
00181     int id = m_InteractionLists.ERModelVsHEModel.size()-1;
00182     if ( id != m_InteractionLists.ERModelVsIPGModel.size()-1 ) {
00183         PrtErrorWithFileNameAndLineNumber( "Inconsistent size!" );
00184         exit(-1);
00185     }
00186 
00187     // Set data for controlling forward and backward movements of an Elastic Rod
00188     m_ModelLists.AllERNodePropsList.push_back( AdvSimSupport_DATA<T,DATA>::ERNodePropsList( m_ModelLists.BasedOnER.back()->GetNumberOfPoints() ) );
00189 
00190     // returns the assigned ID for the added ER-based model
00191     return id;
00192 }
00193 //-----------------------------------------------------------------------------
00194 template <typename T, typename DATA>
00195 int AdvSimSupport_DS<T,DATA>::AddHEBasedModel ()
00196 {
00197     // Add data storage for the added model
00198     m_InteractionLists.HEModelVsHEModel.push_back( std::vector< AdvSimSupport_DATA<T,DATA>::Interaction_HEModelVsHEModel >() );
00199     AdvSimSupport_DATA<T,DATA>::ListOfInteractions_HEModelVsHEModel::iterator it = m_InteractionLists.HEModelVsHEModel.begin();
00200     while ( it != m_InteractionLists.HEModelVsHEModel.end() ) {
00201         // Add data storage for the existed models with the added model
00202         it->push_back( AdvSimSupport_DATA<T,DATA>::Interaction_HEModelVsHEModel() );
00203         ++it;
00204     }
00205 
00206     // DEBUG
00207     //std::cout << "size of m_InteractionLists.HEModelVsHEModel: " << m_InteractionLists.HEModelVsHEModel.size() << "\n";
00208     //for ( unsigned int i = 0; i < m_InteractionLists.HEModelVsHEModel.size(); ++i ) {
00209     //  std::cout << "size of m_InteractionLists.HEModelVsHEModel["<<i<<"]: " << m_InteractionLists.HEModelVsHEModel[i].size() << "\n";
00210     //}
00211 
00212     // Add data storage for interaction with ER-based models
00213     AdvSimSupport_DATA<T,DATA>::ListOfInteractions_ERModelVsHEModel::iterator itS = m_InteractionLists.ERModelVsHEModel.begin();
00214 
00215     while ( itS != m_InteractionLists.ERModelVsHEModel.end() ) {
00216         itS->push_back( AdvSimSupport_DATA<T,DATA>::Interaction_ERModelVsHEModel() );
00217         ++itS;
00218     }
00219 
00220     // Add data storage for interaction with IPG-based models
00221     AdvSimSupport_DATA<T,DATA>::ListOfInteractions_IPGModelVsHEModel::iterator itP = m_InteractionLists.IPGModelVsHEModel.begin();
00222     while ( itP != m_InteractionLists.IPGModelVsHEModel.end() ) {
00223         itP->push_back( AdvSimSupport_DATA<T,DATA>::Interaction_IPGModelVsHEModel() );
00224         ++itP;
00225     }
00226 
00227     // returns the assigned ID for the added model
00228     return m_InteractionLists.HEModelVsHEModel.size()-1;
00229 }
00230 //-----------------------------------------------------------------------------
00231 template <typename T, typename DATA>
00232 int AdvSimSupport_DS<T,DATA>::AddIPGBasedModel ()
00233 {
00234     // Add data storage for the added model
00235     m_InteractionLists.IPGModelVsIPGModel.push_back( std::vector< AdvSimSupport_DATA<T,DATA>::Interaction_IPGModelVsIPGModel >() );
00236     AdvSimSupport_DATA<T,DATA>::ListOfInteractions_IPGModelVsIPGModel::iterator it = m_InteractionLists.IPGModelVsIPGModel.begin();
00237     while ( it != m_InteractionLists.IPGModelVsIPGModel.end() ) {
00238         // Add data storage for the existed models with the added model
00239         it->push_back( AdvSimSupport_DATA<T,DATA>::Interaction_IPGModelVsIPGModel() );
00240         ++it;
00241     }
00242 
00243     // Add data storage for interaction with ER-based models
00244     AdvSimSupport_DATA<T,DATA>::ListOfInteractions_ERModelVsIPGModel::iterator itS = m_InteractionLists.ERModelVsIPGModel.begin();
00245     while ( itS != m_InteractionLists.ERModelVsIPGModel.end() ) {
00246         itS->push_back( AdvSimSupport_DATA<T,DATA>::Interaction_ERModelVsIPGModel() );
00247         ++itS;
00248     }
00249 
00250     // Add data storage for the added IPG-based model interaction with HE-based models
00251     {
00252         m_InteractionLists.IPGModelVsHEModel.push_back( std::vector< AdvSimSupport_DATA<T,DATA>::Interaction_IPGModelVsHEModel >()  );
00253         AdvSimSupport_DATA<T,DATA>::ListOfInteractions_HEModelVsHEModel::iterator it = m_InteractionLists.HEModelVsHEModel.begin();
00254         while ( it != m_InteractionLists.HEModelVsHEModel.end() ) {
00255             // Add data storage for interaction of the existed HE-based models with the added IPG-based model
00256             m_InteractionLists.IPGModelVsHEModel.back().push_back( AdvSimSupport_DATA<T,DATA>::Interaction_IPGModelVsHEModel() );
00257             ++it;
00258         }
00259     }
00260 
00261     // returns the assigned ID for the added model
00262     return m_InteractionLists.IPGModelVsIPGModel.size()-1;
00263 }
00264 //-----------------------------------------------------------------------------
00265 // Add models
00266 //=============================================================================
00267 
00268 
00269 
00270 
00271 //=============================================================================
00272 // Add constraints
00273 //-----------------------------------------------------------------------------
00274 template <typename T, typename DATA>
00275 typename AdvSimSupport_DATA<T,DATA>::Constraint_HEModelVsHEModel * AdvSimSupport_DS<T,DATA>::AddVertexConnectionHEModelAndHEModel (
00276         unsigned int modelA,                        
00277         HEVertex<T> * pVertexA,                     
00278         enum Enum::AddOn::SimConstraints flagsA,    
00279         unsigned int modelB,                        
00280         HEVertex<T> * pVertexB,                     
00281         enum Enum::AddOn::SimConstraints flagsB,    
00282         T forceRatio,           
00283         T forceScaleForModelA,  
00284         T forceScaleForModelB,  
00285         T forceThresholdForModelA,  
00286         T forceThresholdForModelB,  
00287         bool bEnforceVertexOfModelA,    
00288         bool bEnforceVertexOfModelB     
00289 )
00290 {
00291     unsigned int locA, locB;
00292     if ( m_IDForModel[modelA].Type != Enum::MODEL_BASED_ON_FEM )    return NULL;
00293     else    locA = m_IDForModel[modelA].Slot;
00294     if ( m_IDForModel[modelB].Type != Enum::MODEL_BASED_ON_FEM )    return NULL;
00295     else    locB = m_IDForModel[modelB].Slot;
00296 
00297     pVertexA->SimFlags.SetSimulationConstraints( flagsA );
00298     pVertexB->SimFlags.SetSimulationConstraints( flagsB );
00299     m_InteractionLists.HEModelVsHEModel[locA][locB].Constraints.push_back( 
00300         new AdvSimSupport_DATA<T,DATA>::Constraint_HEModelVsHEModel( pVertexA, pVertexB, forceRatio, forceScaleForModelA, forceScaleForModelB, forceThresholdForModelA, forceThresholdForModelB, bEnforceVertexOfModelA, bEnforceVertexOfModelB ) );
00301     m_InteractionLists.HEModelVsHEModel[locA][locB].Constraints.back()->RefToSavedPositionA() = pVertexA->GetPosition();
00302     m_InteractionLists.HEModelVsHEModel[locA][locB].Constraints.back()->RefToSavedPositionB() = pVertexB->GetPosition();
00303 
00304     return m_InteractionLists.HEModelVsHEModel[locA][locB].Constraints.back();
00305 }
00306 //-----------------------------------------------------------------------------
00307 template <typename T, typename DATA>
00308 bool AdvSimSupport_DS<T,DATA>::GroupSetOfLinks (
00309     unsigned int ERModelID,     
00310     unsigned int startLink,     
00311     unsigned int numOfLinks     
00312 )
00313 {
00314     unsigned int ERloc;
00315     if ( m_IDForModel[ERModelID].Type != Enum::MODEL_BASED_ON_ER )  return false;
00316     else    ERloc = m_IDForModel[ERModelID].Slot;
00317 
00318     int endLink = numOfLinks + startLink - 1;
00319     if ( endLink > m_ModelLists.BasedOnER[ERloc]->GetNumOfPoints() )    return false;
00320 
00321     unsigned short groupID = static_cast<unsigned short>( numOfLinks );
00322     for ( int i = startLink; i <= endLink; ++i ) {
00323         m_ModelLists.AllERNodePropsList[ERloc][i].GroupID = groupID;
00324     }
00325     m_ModelLists.AllERNodePropsList[ERloc][startLink].GroupID += 2000;  // the first link of the group
00326                                                     // where 1 represents the first and last link of the group
00327     m_ModelLists.AllERNodePropsList[ERloc][endLink].GroupID += 1000;    // the last  link of the group
00328 
00329     return true;
00330 }
00331 //-----------------------------------------------------------------------------
00332 template <typename T, typename DATA>
00333 void AdvSimSupport_DS<T,DATA>::AddVertexConnectionERModelAndHEModel (
00334         unsigned int ERModelID,                         
00335         unsigned int ERModelVertexID,                   
00336         enum Enum::AddOn::SimConstraints flagsERModel,  
00337         unsigned int HEModelID,                         
00338         HEVertex<T> * pVertexHEModel,                   
00339         enum Enum::AddOn::SimConstraints flagsHEModel,  
00340         T forceRatio,           
00341         T forceScaleForERModel, 
00342         T forceScaleForHEModel, 
00343         T forceThresholdForERModel,     
00344         T forceThresholdForHEModel,     
00345         bool bEnforceERModelVertex,     
00346         bool bEnforceHEModelVertex      
00347 )
00348 {
00349     unsigned int ERloc, HEloc;
00350     if ( m_IDForModel[ERModelID].Type != Enum::MODEL_BASED_ON_ER )  return;
00351     else    ERloc = m_IDForModel[ERModelID].Slot;
00352     if ( m_IDForModel[HEModelID].Type != Enum::MODEL_BASED_ON_FEM ) return;
00353     else    HEloc = m_IDForModel[HEModelID].Slot;
00354 
00355     //std::cout << "ERModel's vertex id: " << vertexIDSuture << "\n";
00356     //std::cout << "SIM FLAG" << m_ModelLists.BasedOnER[ERloc]->GetListOfNodes()[ERModelVertexID].SimFlags << "\n";
00357     
00358     m_ModelLists.BasedOnER[ERloc]->GetListOfNodes()[ERModelVertexID].SimFlags.SetSimulationConstraints( flagsERModel );
00359     m_ModelLists.BasedOnER[ERloc]->GetListOfNodes()[ERModelVertexID].SimFlags.SetSimulationConstraints( Enum::AddOn::ATTACHED );
00360     m_ModelLists.BasedOnER[ERloc]->GetListOfNodes()[ERModelVertexID].SimFlags.SetSimulationConstraints( Enum::AddOn::IGNORE_CD_FORCE );
00361 
00362     //std::cout << "SIM FLAG" << m_ModelLists.BasedOnER[ERloc]->GetListOfNodes()[ERModelVertexID].SimFlags << "\n";
00363 
00364     pVertexHEModel->SimFlags.SetSimulationConstraints( flagsHEModel );
00365 
00366     typename AdvSimSupport_DATA<T,DATA>::Constraint_ERModelVsHEModel * pConstraint = new AdvSimSupport_DATA<T,DATA>::Constraint_ERModelVsHEModel( ERModelVertexID, pVertexHEModel, forceRatio, forceScaleForERModel, forceScaleForHEModel, forceThresholdForERModel, forceThresholdForHEModel, bEnforceERModelVertex, bEnforceHEModelVertex );
00367 
00368     // Insert to the list (sorted from low to high)
00369     unsigned int size = m_InteractionLists.ERModelVsHEModel[ERloc][HEloc].Constraints.size();
00370     if ( size == 0 ) {
00371         m_InteractionLists.ERModelVsHEModel[ERloc][HEloc].Constraints.push_back( pConstraint );
00372     }
00373     else {
00374         typename AdvSimSupport_DATA<T,DATA>::InteractionConstraints_ERModelVsHEModel & List = m_InteractionLists.ERModelVsHEModel[ERloc][HEloc].Constraints;
00375         typename AdvSimSupport_DATA<T,DATA>::InteractionConstraints_ERModelVsHEModel::iterator it = List.begin();
00376 
00377         //-----------------------------------------------------------
00378         // (binary) insert from low to high
00379         unsigned int start = 0, middle = size/2, end = size;
00380         while ( end - start > 0 ) {
00381 
00382             if ( List[middle]->GetVertexIDFromModel_1() > ERModelVertexID ) {
00383                 end = middle;
00384                 middle = (end - start)/2 + start;
00385             }
00386             else if ( List[middle]->GetVertexIDFromModel_1() < ERModelVertexID ) {
00387                 start = middle+1;
00388                 middle = (end - start)/2  + start;
00389             }
00390             else {
00391                 break;
00392             }
00393         }
00394         List.insert( it+middle, pConstraint );
00395         //-----------------------------------------------------------
00396 
00397         /*
00398         // DEBUG
00399         std::cout << "Sorted List:";
00400         for ( it = List.begin(); it != List.end(); ++it ) {
00401             std::cout << "\t" << (*it)->GetVertexIDFromModel_1();
00402         }
00403         std::cout << "\n";
00404         //*/
00405     }
00406 
00407     
00408     //pConstraint->RefToSavedPositionA() = m_ModelLists.BasedOnER[ERModelID]->GetListOfNodes()[ERModelVertexID].GetPosition();
00409     pConstraint->RefToSavedPositionB() = pVertexHEModel->GetPosition();
00410 
00411     // Set data for controlling forward and backward movements of an Elastic Rod
00412     m_ModelLists.AllERNodePropsList[ERloc][ERModelVertexID].IsConstrained = true;
00413     m_ModelLists.AllERNodePropsList[ERloc][ERModelVertexID].GroupID = 2001;
00414 }
00415 //-----------------------------------------------------------------------------
00416 template <typename T, typename DATA>
00417 void AdvSimSupport_DS<T,DATA>::AddVertexConnectionIPGModelAndHEModel (
00418         unsigned int IPGModelID,                        
00419         unsigned int IPGModelVertexID,                  
00420         enum Enum::AddOn::SimConstraints flagsIPGModel, 
00421         unsigned int HEModelID,                         
00422         HEVertex<T> * pVertexHEModel,                   
00423         enum Enum::AddOn::SimConstraints flagsHEModel,  
00424         T forceRatio,               
00425         T forceScaleForIPGModel,    
00426         T forceScaleForHEModel,     
00427         T forceThresholdForIPGModel,    
00428         T forceThresholdForHEModel,     
00429         bool bEnforceIPGModelVertex,    
00430         bool bEnforceHEModelVertex      
00431 )
00432 {
00433     unsigned int locIPG, locHE;
00434     Vector3<T> IPGVertexPos;
00435     if ( m_IDForModel[IPGModelID].Type != Enum::MODEL_BASED_ON_IPG_RBD )    return;
00436     else    locIPG = m_IDForModel[IPGModelID].Slot;
00437     if ( m_IDForModel[HEModelID].Type != Enum::MODEL_BASED_ON_FEM ) return;
00438     else    locHE = m_IDForModel[HEModelID].Slot;
00439     
00440     if ( m_IDForModel[IPGModelID].Type == Enum::MODEL_BASED_ON_IPG_RBD ) {
00441         m_ModelLists.BasedOnRBD[locIPG]->RefToInteractionPointGroup().GetInteractionPointAtIndex( IPGModelVertexID ).GetSimFlags().SetSimulationConstraints( flagsIPGModel );
00442         //m_ModelLists.BasedOnRBD[locIPG]->RefToInteractionPointGroup().GetInteractionPointAtIndex( IPGModelVertexID ).GetSimFlags().SetSimulationConstraints( Enum::AddOn::ATTACHED );
00443         //m_ModelLists.BasedOnRBD[locIPG]->RefToInteractionPointGroup().GetInteractionPointAtIndex( IPGModelVertexID ).GetFlags().SetSimulationConstraints( Enum::AddOn::IGNORE_CD_FORCE );
00444         IPGVertexPos = m_ModelLists.BasedOnRBD[locIPG]->RefToInteractionPointGroup().GetInteractionPointAtIndex( IPGModelVertexID ).GetPosition();
00445     }
00446     if ( m_IDForModel[HEModelID].Type == Enum::MODEL_BASED_ON_FEM ) {
00447         pVertexHEModel->SimFlags.SetSimulationConstraints( flagsHEModel );
00448     }
00449 
00450     // NEED TO PROTECT DUPLICATED!!!
00451 
00452     //std::cout << "TEST 1: " << m_InteractionLists.IPGModelVsHEModel.size() << "\n";
00453     //std::cout << "TEST 2: " << m_InteractionLists.IPGModelVsHEModel[locIPG].size() << "\n";
00454     //std::cout << "TEST 3: " << m_InteractionLists.IPGModelVsHEModel[locIPG][locHE].size() << "\n";
00455 
00456     m_InteractionLists.IPGModelVsHEModel[locIPG][locHE].push_back( 
00457         new AdvSimSupport_DATA<T,DATA>::Constraint_IPGModelVsHEModel( IPGModelVertexID, pVertexHEModel, forceRatio, forceScaleForIPGModel, forceScaleForHEModel, forceThresholdForIPGModel, forceThresholdForHEModel, bEnforceIPGModelVertex, bEnforceHEModelVertex ) );
00458     m_InteractionLists.IPGModelVsHEModel[locIPG][locHE].back()->RefToSavedPositionA() = IPGVertexPos;
00459     m_InteractionLists.IPGModelVsHEModel[locIPG][locHE].back()->RefToSavedPositionB() = pVertexHEModel->GetPosition();
00460 }
00461 //-----------------------------------------------------------------------------
00462 // Add constraints
00463 //=============================================================================
00464 
00465 
00466 
00467 
00468 //=============================================================================
00469 // Process specific interactions
00470 //-----------------------------------------------------------------------------
00471 template <typename T, typename DATA>
00472 void AdvSimSupport_DS<T,DATA>::ProcessPuncturingOfCurveFormedByIPGToHEModel ( unsigned int IPGModel, unsigned int HEModel )
00473 {
00474     Enum::ModelType IPGType = m_IDForModel[IPGModel].Type;
00475     Enum::ModelType HEType  = m_IDForModel[HEModel].Type;
00476     if (    IPGType == Enum::MODEL_BASED_ON_IPG_RBD 
00477         &&  HEType  == Enum::MODEL_BASED_ON_FEM ) {
00478         ProcessPuncturingOfCurveFormedByIPGonRBDModelToFEMModel( IPGModel, HEModel );
00479     }
00480     else {
00481         PrtNotImplementedYet( "Supported only IPGType == Enum::MODEL_BASED_ON_IPG_RBD and HEType == Enum::MODEL_BASED_ON_FEM" );
00482     }
00483 }
00484 //-----------------------------------------------------------------------------
00485 template <typename T, typename DATA>
00486 void AdvSimSupport_DS<T,DATA>::ProcessPuncturingOfCurveFormedByIPGonRBDModelToFEMModel ( unsigned int RBDModel, unsigned int FEMModel )
00487 {
00488 //#ifdef    TAPs_COLLISION_DETECTION_FNS_HPP
00489 
00490     unsigned int RBDloc = m_IDForModel[RBDModel].Slot;
00491     unsigned int FEMloc = m_IDForModel[FEMModel].Slot;
00492 
00493     ModelDefBasedOnFEMHex<T,DATA> * pFEMHex = dynamic_cast< ModelDefBasedOnFEMHex<T,DATA> * >( m_ModelLists.BasedOnFEM[FEMloc] );
00494     ModelDefBasedOnFEMTet<T,DATA> * pFEMTet = dynamic_cast< ModelDefBasedOnFEMTet<T,DATA> * >( m_ModelLists.BasedOnFEM[FEMloc] );
00495 
00496     if ( pFEMHex )
00497     {
00498         InteractionPointGroup<T> & IPG = m_ModelLists.BasedOnRBD[RBDloc]->RefToInteractionPointGroup();
00499         if ( IPG.GetNumOfInteractionPoints() == 0 ) return;
00500         std::vector< Vector3<T> > IPs = m_ModelLists.BasedOnRBD[RBDloc]->GetAllInteractionPointPositionsInWorldSpace();
00501         //if ( IPs.size() == 0 ) return;
00502 
00503         //bool bCheckPunctureIn  = true;
00504         bool bCheckPunctureOut = true;
00505 
00506 
00507 
00508         unsigned int sections[6];
00509         sections[0] = 0;    // always 0
00510         unsigned int i  = 0;
00511         while ( i < IPs.size() && IPG.GetInteractionPointAtIndex( i ).GetSimFlags().CheckSimulationConstraints( Enum::AddOn::SLIDABLE ) == false ) {
00512             ++i;
00513         }
00514         sections[1] = i;
00515         while ( i < IPs.size() && IPG.GetInteractionPointAtIndex( i ).GetSimFlags().CheckSimulationConstraints( Enum::AddOn::SLIDABLE ) == true ) {
00516             ++i;
00517         }
00518         sections[2] = i;
00519         while ( i < IPs.size() && IPG.GetInteractionPointAtIndex( i ).GetSimFlags().CheckSimulationConstraints( Enum::AddOn::SLIDABLE ) == false ) {
00520             ++i;
00521         }
00522         sections[3] = i;
00523         while ( i < IPs.size() && IPG.GetInteractionPointAtIndex( i ).GetSimFlags().CheckSimulationConstraints( Enum::AddOn::SLIDABLE ) == true ) {
00524             ++i;
00525         }
00526         sections[4] = i;
00527         while ( i < IPs.size() && IPG.GetInteractionPointAtIndex( i ).GetSimFlags().CheckSimulationConstraints( Enum::AddOn::SLIDABLE ) == false ) {
00528             ++i;
00529         }
00530         sections[5] = i;
00531 
00532         //*
00533         // DEBUG
00534         for ( unsigned int i = 0; i < IPs.size(); ++i ) {
00535             std::cout << i << "\t: " << IPG.GetInteractionPointAtIndex( i ).GetSimFlags() << std::endl;
00536         }
00537         std::cout << "size: " << IPs.size() << "\n";
00538         std::cout << "sections: "
00539             << "[" << sections[0] << "," << sections[1] << "), "
00540             << "[" << sections[1] << "," << sections[2] << "), "
00541             << "[" << sections[2] << "," << sections[3] << "), "
00542             << "[" << sections[3] << "," << sections[4] << "), "
00543             << "[" << sections[4] << "," << sections[5] << "), ";
00544         //*/
00545 
00546         i = 0;
00547         if ( sections[i+1] > 0 ) {
00548             ProcessForwardPuncturingIPGonRBDModelToHexFEMModel_SectionCleared( RBDModel, FEMModel, RBDloc, FEMloc, sections[i], sections[i+1], IPs );
00549         }
00550         i = 1;
00551         if ( sections[i] < IPs.size() ) {
00552             ProcessForwardPuncturingIPGonRBDModelToHexFEMModel_SectionPunctured( RBDModel, FEMModel, RBDloc, FEMloc, sections[i], sections[i+1], IPs, pFEMHex );
00553         }
00554         //i = 2;
00555         //if ( sections[i+1] > IPs.size() ) {
00556         //  ProcessForwardPuncturingIPGonRBDModelToHexFEMModel_SectionCleared( RBDModel, FEMModel, RBDloc, FEMloc, sections[i], sections[i+1], IPs );
00557         //}
00558         //i = 3;
00559         //if ( sections[i+1] > IPs.size() ) {
00560         //  ProcessForwardPuncturingIPGonRBDModelToHexFEMModel_SectionPunctured( RBDModel, FEMModel, RBDloc, FEMloc, sections[i], sections[i+1], IPs );
00561         //}
00562         //i = 4;
00563         //if ( sections[i+1] > IPs.size() ) {
00564         //  ProcessForwardPuncturingIPGonRBDModelToHexFEMModel_SectionCleared( RBDModel, FEMModel, RBDloc, FEMloc, sections[i], sections[i+1], IPs );
00565         //}
00566     }
00567 }
00568 //-----------------------------------------------------------------------------
00569 template <typename T, typename DATA>
00570 void AdvSimSupport_DS<T,DATA>::ProcessForwardPuncturingIPGonRBDModelToHexFEMModel_SectionCleared (
00571     unsigned int RBDModel, unsigned int FEMModel,
00572     unsigned int RBDloc, unsigned int FEMloc,
00573     unsigned int start, unsigned int end,
00574     std::vector< Vector3<T> > const & IPs
00575 )
00576 {
00577     if ( end - start < 2 ) return;
00578 
00579     // Check intersection
00580     AdvSimSupport_DATA<T,DATA>::TEMP_ListOfPoints.clear();
00581     AdvSimSupport_DATA<T,DATA>::TEMP_ListOfHEFaces.clear();
00582     AdvSimSupport_DATA<T,DATA>::TEMP_ListOfHEVertices.clear();
00583     AdvSimSupport_DATA<T,DATA>::TEMP_ListOfRatios.clear();
00584     CD::Fn::CD_PolygonalMesh_vs_LineSegment(
00585         &m_ModelLists.BasedOnFEM[FEMloc]->RefToSurfaceMesh(),   // HE-based mesh model
00586         &IPs[start], &IPs[start+1], // line segment
00587         &AdvSimSupport_DATA<T,DATA>::TEMP_ListOfPoints,         // list of intersected points
00588         &AdvSimSupport_DATA<T,DATA>::TEMP_ListOfHEFaces,        // list of intersected HE-based faces
00589         &AdvSimSupport_DATA<T,DATA>::TEMP_ListOfHEVertices,     // list of closest HE-based vertices to the intersected points
00590         &AdvSimSupport_DATA<T,DATA>::TEMP_ListOfRatios          // list of ratios of the closest vertices relative to the line segment [0(ptA)-1(ptB)]
00591     );
00592 
00593     if ( AdvSimSupport_DATA<T,DATA>::TEMP_ListOfHEVertices.size() > 0 ) {
00594 
00595         std::cout << "Add punctured pt\n";
00596 
00597         AddVertexConnectionIPGModelAndHEModel(
00598             RBDModel,
00599             start,
00600             Enum::AddOn::SLIDABLE,
00601             FEMModel,
00602             AdvSimSupport_DATA<T,DATA>::TEMP_ListOfHEVertices[0],   // only the first point
00603             Enum::AddOn::ATTACHED,
00604             AdvSimSupport_DATA<T,DATA>::STATE_ForceRatio,
00605             AdvSimSupport_DATA<T,DATA>::STATE_ForceScaleA,
00606             AdvSimSupport_DATA<T,DATA>::STATE_ForceScaleB,
00607             AdvSimSupport_DATA<T,DATA>::STATE_ForceThresholdA,
00608             AdvSimSupport_DATA<T,DATA>::STATE_ForceThresholdB,
00609             false, false
00610             //AdvSimSupport_DATA<T,DATA>::STATE_EnforcePositionA,
00611             //AdvSimSupport_DATA<T,DATA>::STATE_EnforcePositionB
00612         );
00613     }
00614 }
00615 //-----------------------------------------------------------------------------
00616 template <typename T, typename DATA>
00617 void AdvSimSupport_DS<T,DATA>::ProcessForwardPuncturingIPGonRBDModelToHexFEMModel_SectionPunctured (
00618     unsigned int RBDModel, unsigned int FEMModel,
00619     unsigned int RBDloc, unsigned int FEMloc,
00620     unsigned int start, unsigned int end,
00621     std::vector< Vector3<T> > const & IPs,
00622     ModelDefBasedOnFEMHex<T,DATA> * pFEMHex
00623 )
00624 {
00625 
00626     std::cout << "section#1 start: " << start << " end: " << end << std::endl;
00627 
00628     // the first IP point is still inside the HexFEMModel
00629     if ( start == 0 ) {
00630 
00631 
00632         /*
00633         // DEBUG
00634         std::cout << "_2" << std::endl;
00635         std::cout << "size: " << m_InteractionLists.IPGModelVsHEModel[RBDloc][FEMloc].size() << std::endl;
00636         for ( unsigned int i = 0; i < m_InteractionLists.IPGModelVsHEModel[RBDloc][FEMloc].size(); ++i ) {
00637             std::cout << *m_InteractionLists.IPGModelVsHEModel[RBDloc][FEMloc][i] << std::endl;
00638             std::cout << *(m_InteractionLists.IPGModelVsHEModel[RBDloc][FEMloc][i]->GetPtrToVertexFromModel_2()->GetBarycentricPtr()) << std::endl;
00639             //std::cout << m_InteractionLists.IPGModelVsHEModel[RBDloc][FEMloc][i]->GetPtrToVertexFromModel_2()->GetBarycentricPtr()->GetNewVertexLocation() << std::endl;
00640         }
00641         //*/
00642 
00643 
00644         // Check intersection
00645         AdvSimSupport_DATA<T,DATA>::TEMP_ListOfPoints.clear();
00646         AdvSimSupport_DATA<T,DATA>::TEMP_ListOfHEFaces.clear();
00647         AdvSimSupport_DATA<T,DATA>::TEMP_ListOfHEVertices.clear();
00648         AdvSimSupport_DATA<T,DATA>::TEMP_ListOfRatios.clear();
00649         CD::Fn::CD_PolygonalMesh_vs_LineSegment(
00650             &pFEMHex->RefToSurfaceMesh(),   // HE-based mesh model
00651             &IPs[0], &IPs[1],       // line segment
00652             &AdvSimSupport_DATA<T,DATA>::TEMP_ListOfPoints,     // list of intersected points
00653             &AdvSimSupport_DATA<T,DATA>::TEMP_ListOfHEFaces,    // list of intersected HE-based faces
00654             &AdvSimSupport_DATA<T,DATA>::TEMP_ListOfHEVertices, // list of closest HE-based vertices to the intersected points
00655             &AdvSimSupport_DATA<T,DATA>::TEMP_ListOfRatios      // list of ratios of the closest vertices relative to the line segment [0(ptA)-1(ptB)]
00656         );
00657 
00658         // Puncture out
00659         if ( AdvSimSupport_DATA<T,DATA>::TEMP_ListOfHEVertices.size() > 0 ) {
00660 
00661             std::cout << "Puncture out" << std::endl;
00662 
00663             //return;
00664 
00665             if ( end < IPs.size() ) {
00666 
00667                 // Add the new constraint at the end of the list of constraints
00668                 AddVertexConnectionIPGModelAndHEModel(
00669                     RBDModel,
00670                     end,
00671                     Enum::AddOn::SLIDABLE,
00672                     FEMModel,
00673                     AdvSimSupport_DATA<T,DATA>::TEMP_ListOfHEVertices[0],   // only the first point
00674                     Enum::AddOn::ATTACHED,
00675                     AdvSimSupport_DATA<T,DATA>::STATE_ForceRatio,
00676                     AdvSimSupport_DATA<T,DATA>::STATE_ForceScaleA,
00677                     AdvSimSupport_DATA<T,DATA>::STATE_ForceScaleB,
00678                     AdvSimSupport_DATA<T,DATA>::STATE_ForceThresholdA,
00679                     AdvSimSupport_DATA<T,DATA>::STATE_ForceThresholdB,
00680                     //false, false
00681                     AdvSimSupport_DATA<T,DATA>::STATE_EnforcePositionA,
00682                     AdvSimSupport_DATA<T,DATA>::STATE_EnforcePositionB
00683                 );
00684 
00685 
00686             }
00687             else {
00688                 --end;
00689 
00690                 std::cout << "end is end-1: " << end << std::endl;
00691 
00692                 std::cout << "New pt: " << AdvSimSupport_DATA<T,DATA>::TEMP_ListOfHEVertices[0] << std::endl;
00693 
00694                 // DEBUG
00695                 for ( unsigned int i = 0; i <= end; ++i ) {
00696                     std::cout << "unsort: " << m_InteractionLists.IPGModelVsHEModel[RBDloc][FEMloc][i]->GetPtrToVertexFromModel_2() << "\n";
00697                 }
00698 
00699                 //
00700                 // Arrange the data
00701                 //
00702                 std::vector< HEVertex<T> * > pHEVert;
00703                 // the second last vertex is be cleared in the first constraint
00704                 pHEVert.push_back( m_InteractionLists.IPGModelVsHEModel[RBDloc][FEMloc][end-2]->GetPtrToVertexFromModel_2() );
00705                 // the new vertex will be in the first constraint after the clear
00706                 pHEVert.push_back( AdvSimSupport_DATA<T,DATA>::TEMP_ListOfHEVertices[0] );
00707                 // the first last vertex has to be cleared
00708                 m_InteractionLists.IPGModelVsHEModel[RBDloc][FEMloc][end-1]->GetPtrToVertexFromModel_2()->SimFlags.ClearAllFlags();
00709                 // arrange the rest of HEVertices and increase the vertex IDs by one
00710                 for ( unsigned int i = 0; i < end-1; ++i ) {
00711                     pHEVert.push_back( m_InteractionLists.IPGModelVsHEModel[RBDloc][FEMloc][i]->GetPtrToVertexFromModel_2() );
00712                 }
00713                 // arrange the HEVertices
00714                 for ( unsigned int i = 0; i <= end; ++i ) {
00715                     std::cout << "sort: " << pHEVert[i] << "\n";
00716                     m_InteractionLists.IPGModelVsHEModel[RBDloc][FEMloc][i]->SetPtrToVertexFromModel_2( pHEVert[i] );
00717                 }
00718 
00719                 // Clear the first constraint
00720                 ClearTheConstraintNumberOfRBDModelAndFEMModel( RBDloc, FEMloc, 0 );
00721             }
00722         }
00723 
00724         // Still puncturing inside
00725         else {
00726 
00727             Matrix4x4<T> TrxFEMModel = m_ModelLists.BasedOnFEM[FEMloc]->RefToTransformationSupport().RefToMatrixTransform();
00728             Vector3<T>  pos1 = TrxFEMModel * m_InteractionLists.IPGModelVsHEModel[RBDloc][FEMloc][0]->GetPtrToVertexFromModel_2()->GetBarycentricPtr()->GetNewVertexLocation();
00729 
00730             T dist = (IPs[0] - pos1).Length();
00731             T distThreshold = ( IPs[0] - IPs[1] ).Length();
00732 
00733             if ( dist >= distThreshold ) {
00734                 std::cout << "dist: " << dist << std::endl;
00735 
00736                 // FIND THE VERTEX AT INTERACTION POINT#0
00737                 bool bFound = false;
00738                 unsigned int elementID;
00739                 Vector3<T> position = pFEMHex->RefToTransformationSupport().GetInverseMatrixTransform() * IPs[0];
00740 
00741                 // Create a new HEvertex to stick with IP point number 0
00742                 T coords[3];
00743                 unsigned int Es[3] = {
00744                     pFEMHex->GetNumberOfElementsPerGridSize_X(),
00745                     pFEMHex->GetNumberOfElementsPerGridSize_Y(),
00746                     pFEMHex->GetNumberOfElementsPerGridSize_Z()
00747                 };
00748 
00749                 unsigned int x = 0;
00750                 unsigned int y = 0;
00751                 unsigned int z = 0;
00752                 for ( x = 0; !bFound && x < Es[0]; ++x ) {
00753                     for ( y = 0; !bFound && y < Es[1]; ++y ) {
00754                         for ( z = 0; !bFound && z < Es[2]; ++z ) {
00755                             elementID = pFEMHex->GetElementIDFromGridLocation( x, y, z );
00756                             if ( elementID >= 0 ) {
00757                                 bFound = pFEMHex->RefToFEMMesh().RefToElement( elementID ).EstimateParametricCoords( 
00758                                     position[0], position[1], position[2], 
00759                                     coords[0], coords[1], coords[2] ) 
00760                                     > 0 ? true : false;
00761                             }
00762                         }
00763                     }
00764                 }
00765                 // Replace the surface HEVertex with a created inner HEVertex inside the FEMModel
00766                 if ( bFound ) {
00767 
00768                     if ( end < IPs.size() ) {
00769 
00770                         HEVertex<T> * pNewHEVertex = pFEMHex->AddExtraVertexInLocalSpace( 
00771                                 IPs[0], elementID, &pFEMHex->RefToFEMMesh().RefToElement( elementID ), Vector3<T>(x,y,z), coords );
00772 
00773                         AddVertexConnectionIPGModelAndHEModel(
00774                             RBDModel,
00775                             end,
00776                             Enum::AddOn::SLIDABLE,
00777                             FEMModel,
00778                             pNewHEVertex,
00779                             Enum::AddOn::ATTACHED,
00780                             AdvSimSupport_DATA<T,DATA>::STATE_ForceRatio,
00781                             AdvSimSupport_DATA<T,DATA>::STATE_ForceScaleA,
00782                             AdvSimSupport_DATA<T,DATA>::STATE_ForceScaleB,
00783                             AdvSimSupport_DATA<T,DATA>::STATE_ForceThresholdA,
00784                             AdvSimSupport_DATA<T,DATA>::STATE_ForceThresholdB,
00785                             //false, false
00786                             AdvSimSupport_DATA<T,DATA>::STATE_EnforcePositionA,
00787                             AdvSimSupport_DATA<T,DATA>::STATE_EnforcePositionB
00788                         );
00789 
00790                         // Slide the IP points from number 0 thru end-1
00791                         // pt 1 will inherit the sticked position from pt 0, and so on.
00792                         HEVertex<T> * pHEVert;
00793                         for ( unsigned int i = end; i > 0; --i ) {
00794                             //std::cout << "p1: " << m_InteractionLists.IPGModelVsHEModel[RBDloc][FEMloc][i-1]->GetPtrToVertexFromModel_2() << std::endl;
00795                             //std::cout << "p2: " << m_InteractionLists.IPGModelVsHEModel[RBDloc][FEMloc][i]->GetPtrToVertexFromModel_2() << std::endl;
00796 
00797                             pHEVert = m_InteractionLists.IPGModelVsHEModel[RBDloc][FEMloc][i-1]->GetPtrToVertexFromModel_2();
00798                             m_InteractionLists.IPGModelVsHEModel[RBDloc][FEMloc][i]->SetPtrToVertexFromModel_2( pHEVert );
00799                         }
00800                         // the fist IP pt
00801                         m_InteractionLists.IPGModelVsHEModel[RBDloc][FEMloc][0]->SetPtrToVertexFromModel_2( pNewHEVertex );
00802                     }
00803                 }
00804             }
00805         }// end puncturing inside
00806     }
00807 
00808     // The first IP point has already punctured out from the HexFEMModel
00809     else {
00810     }
00811 }
00812 //-----------------------------------------------------------------------------
00813 
00814 
00815 
00816 
00817 //-----------------------------------------------------------------------------
00818 //template <typename T, typename DATA>
00819 //void AdvSimSupport_DS<T,DATA>::ProcessPuncturingOfCurveFormedByIPGonRBDModelToFEMModel ( unsigned int RBDModel, unsigned int FEMModel )
00820 //{
00822 //
00823 //  unsigned int RBDloc = m_IDForModel[RBDModel].Slot;
00824 //  unsigned int FEMloc = m_IDForModel[FEMModel].Slot;
00825 //
00826 //  ModelDefBasedOnFEMHex<T,DATA> * pFEMHex = dynamic_cast< ModelDefBasedOnFEMHex<T,DATA> * >( m_ModelLists.BasedOnFEM[FEMloc] );
00827 //  ModelDefBasedOnFEMTet<T,DATA> * pFEMTet = dynamic_cast< ModelDefBasedOnFEMTet<T,DATA> * >( m_ModelLists.BasedOnFEM[FEMloc] );
00828 //
00829 //  if ( pFEMHex )
00830 //  {
00831 //      InteractionPointGroup<T> & IPG = m_ModelLists.BasedOnRBD[RBDloc]->RefToInteractionPointGroup();
00832 //      if ( IPG.GetNumOfInteractionPoints() == 0 ) return;
00833 //      std::vector< Vector3<T> > IPs = m_ModelLists.BasedOnRBD[RBDloc]->GetAllInteractionPointPositionsInWorldSpace();
00834 //      //if ( IPs.size() == 0 ) return;
00835 //
00836 //      //bool bCheckPunctureIn  = true;
00837 //      bool bCheckPunctureOut = true;
00838 //
00839 //      {//START: CASE PUNCTURING IN
00840 //
00841 //          // Point numbers
00842 //          unsigned int A = 0;
00843 //          unsigned int B = 1;
00844 //
00845 //          //*
00846 //          // DEBUG
00847 //          for ( unsigned int i = 0; i < IPs.size(); ++i ) {
00848 //              std::cout << i << "\t: " << IPG.GetInteractionPointAtIndex( i ).GetSimFlags() << std::endl;
00849 //          }
00850 //          //*/
00851 //
00852 //          while ( IPG.GetInteractionPointAtIndex( A ).GetSimFlags().CheckSimulationConstraints( Enum::AddOn::SLIDABLE ) ) {
00853 //              std::cout << "\t" << A;
00854 //              ++A;
00855 //              if ( A > IPs.size() - 2 ) {
00856 //                  --A;
00857 //                  break;
00858 //              }
00859 //          }
00860 //          B = A + 1;
00861 //
00862 //          // A is SLIDABLE and B is CLEARED
00863 //          if ( IPG.GetInteractionPointAtIndex( B ).GetSimFlags().CheckSimulationConstraints( Enum::AddOn::SLIDABLE ) == false )
00864 //          {
00865 //              // Check intersection
00866 //              TEMP_ListOfPoints.clear();
00867 //              TEMP_ListOfHEFaces.clear();
00868 //              TEMP_ListOfHEVertices.clear();
00869 //              TEMP_ListOfRatios.clear();
00870 //              CD::Fn::CD_PolygonalMesh_vs_LineSegment(
00871 //                  &m_ModelLists.BasedOnFEM[FEMloc]->RefToSurfaceMesh(),   // HE-based mesh model
00872 //                  &IPs[A], &IPs[B],   // line segment
00873 //                  &TEMP_ListOfPoints,     // list of intersected points
00874 //                  &TEMP_ListOfHEFaces,    // list of intersected HE-based faces
00875 //                  &TEMP_ListOfHEVertices, // list of closest HE-based vertices to the intersected points
00876 //                  &TEMP_ListOfRatios      // list of ratios of the closest vertices relative to the line segment [0(ptA)-1(ptB)]
00877 //              );
00878 //
00879 //              if ( TEMP_ListOfHEVertices.size() > 0 ) {
00880 //
00881 //                  bCheckPunctureOut = false;
00882 //
00883 //                  if ( A > 0 ) {
00884 //
00885 //                      std::cout << "IPs' size: " << IPs.size() << std::endl;
00886 //                      std::cout << "A: " << A << std::endl;
00887 //                      std::cout << "B: " << B << std::endl;
00888 //
00889 //
00890 //                      // FIND THE VERTEX AT INTERACTION POINT#0
00891 //                      bool bFound = false;
00892 //                      unsigned int elementID;
00893 //                      Vector3<T> position = IPG.GetInteractionPointAtIndex( 0 ).GetPosition();
00894 //                      position = m_ModelLists.BasedOnRBD[RBDloc]->CalMatrixTransform() * position;
00895 //                      position = pFEMHex->RefToTransformationSupport().GetInverseMatrixTransform() * position;
00896 //
00897 //                      // Create a new HEvertex to stick with IP point number 0
00898 //                      T coords[3];
00899 //                      unsigned int Es[3] = {
00900 //                          pFEMHex->GetNumberOfElementsPerGridSize_X(),
00901 //                          pFEMHex->GetNumberOfElementsPerGridSize_Y(),
00902 //                          pFEMHex->GetNumberOfElementsPerGridSize_Z()
00903 //                      };
00904 //                      for ( unsigned int x = 0; !bFound && x < Es[0]; ++x ) {
00905 //                          for ( unsigned int y = 0; !bFound && y < Es[1]; ++y ) {
00906 //                              for ( unsigned int z = 0; !bFound && z < Es[2]; ++z ) {
00907 //                                  elementID = pFEMHex->GetElementIDFromGridLocation( x, y, z );
00908 //                                  if ( elementID >= 0 ) {
00909 //                                      bFound = pFEMHex->RefToFEMMesh().RefToElement( elementID ).EstimateParametricCoords( 
00910 //                                          position[0], position[1], position[2], 
00911 //                                          coords[0], coords[1], coords[2] ) 
00912 //                                          > 0 ? true : false;
00913 //                                      //*
00914 //                                      // Replace the surface HEVertex with a created inner HEVertex inside the FEMModel
00915 //                                      if ( bFound ) {
00916 //                                          TEMP_ListOfHEVertices[0] =
00917 //                                              pFEMHex->AddExtraVertexInLocalSpace(
00918 //                                                  position, elementID, Vector3<T>(x,y,z), coords
00919 //                                              );
00920 //                                      }
00921 //                                      //*/
00922 //                                  }
00923 //                              }
00924 //                          }
00925 //                      }
00926 //
00927 //                      //*
00928 //                      if ( bFound )
00929 //                      {
00930 //                          AddVertexConnectionIPGModelAndHEModel(
00931 //                              RBDModel,
00932 //                              A,
00933 //                              Enum::AddOn::SLIDABLE,
00934 //                              FEMModel,
00935 //                              TEMP_ListOfHEVertices[0],   // only the first point
00936 //                              Enum::AddOn::ATTACHED,
00937 //                              STATE_ForceRatio,
00938 //                              STATE_ForceScaleA,
00939 //                              STATE_ForceScaleB,
00940 //                              STATE_ForceThresholdA,
00941 //                              STATE_ForceThresholdB,
00942 //                              false, false
00943 //                              //STATE_EnforcePositionA,
00944 //                              //STATE_EnforcePositionB
00945 //                          );
00946 //
00947 //                          // Slide the IP points from number 0 thru A-1
00948 //                          // pt 1 will inherit the sticked position from pt 0, and so on.
00949 //                          // So pt B will inherit the sticked position from pt A.
00950 //                          HEVertex<T> * pHEVert;
00951 //                          for ( unsigned int i = A; i > 0; --i ) {
00952 //                              pHEVert = m_InteractionLists.IPGModelVsHEModel[RBDloc][FEMloc][i-1]->GetPtrToVertexFromModel_2();
00953 //                              m_InteractionLists.IPGModelVsHEModel[RBDloc][FEMloc][i]->SetPtrToVertexFromModel_2( pHEVert );
00954 //                          }
00955 //                          // the fist IP pt
00956 //                          m_InteractionLists.IPGModelVsHEModel[RBDloc][FEMloc][0]->SetPtrToVertexFromModel_2( TEMP_ListOfHEVertices[0] );
00957 //                      }
00958 //                      //*/
00959 //
00960 //                      /*
00961 //                      // Slide the IP points from number 0 thru A-1
00962 //                      // pt 1 will inherit the sticked position from pt 0, and so on.
00963 //                      // So pt B will inherit the sticked position from pt A.
00964 //                      HEVertex<T> * pHEVert1 = TEMP_ListOfHEVertices[0];
00965 //                      HEVertex<T> * pHEVert2;
00966 //                      for ( unsigned int i = 0; i < A; ++i ) {
00967 //                          pHEVert2 = m_InteractionLists.IPGModelVsHEModel[RBDloc][FEMloc][i]->GetPtrToVertexFromModel_2();
00968 //                          m_InteractionLists.IPGModelVsHEModel[RBDloc][FEMloc][i]->SetPtrToVertexFromModel_2( pHEVert1 );
00969 //                          pHEVert1 = pHEVert2;
00970 //                      }
00971 //                      TEMP_ListOfHEVertices[0] = pHEVert1;
00972 //                      //*/
00973 //                  }
00974 //                  else
00975 //                  {// A == 0
00976 //                      AddVertexConnectionIPGModelAndHEModel(
00977 //                          RBDModel,
00978 //                          A,
00979 //                          Enum::AddOn::SLIDABLE,
00980 //                          FEMModel,
00981 //                          TEMP_ListOfHEVertices[0],   // only the first point
00982 //                          Enum::AddOn::ATTACHED,
00983 //                          STATE_ForceRatio,
00984 //                          STATE_ForceScaleA,
00985 //                          STATE_ForceScaleB,
00986 //                          STATE_ForceThresholdA,
00987 //                          STATE_ForceThresholdB,
00988 //                          false, false
00989 //                          //STATE_EnforcePositionA,
00990 //                          //STATE_EnforcePositionB
00991 //                      );
00992 //                  }
00993 //              }
00994 //          }
00995 //      }//END: CASE PUNCTURING IN
00996 //
00997 //
00998 //
00999 //
01000 //      bCheckPunctureOut = false;
01001 //
01002 //      if ( bCheckPunctureOut )
01003 //      {//START: CASE PUNCTURING OUT
01004 //          // Point numbers
01005 //          unsigned int A = 0; // start of IP pt number with flag:CLEARED (before the slidable set)
01006 //          unsigned int B = 1; // start of IP pt number with flag:SLIDABLE
01007 //          unsigned int C = 2; // start of IP pt number-1 with flag:CLEARED (after the slidable set)
01008 //
01009 //          while ( IPG.GetInteractionPointAtIndex( A ).GetSimFlags().CheckSimulationConstraints( Enum::AddOn::CLEARED ) ) {
01010 //              ++A;
01011 //              if ( A > IPs.size() - 2 ) return;
01012 //          }
01013 //          C = B = A + 1;
01014 //          while ( IPG.GetInteractionPointAtIndex( C ).GetSimFlags().CheckSimulationConstraints( Enum::AddOn::SLIDABLE ) ) {
01015 //              ++C;
01016 //              if ( C > IPs.size() - 1 ) return;
01017 //          }
01018 //          ++C;
01019 //
01020 //          // A is CLEARED, B is SLIDABLE, and C-1 is CLEARED (or not exist, i.e. beyond the end of IPG)
01021 //          if ( IPG.GetInteractionPointAtIndex( B ).GetSimFlags().CheckSimulationConstraints( Enum::AddOn::SLIDABLE ) )
01022 //          {
01023 //              // Check intersection
01024 //              TEMP_ListOfPoints.clear();
01025 //              TEMP_ListOfHEFaces.clear();
01026 //              TEMP_ListOfHEVertices.clear();
01027 //              TEMP_ListOfRatios.clear();
01028 //              CD::Fn::CD_PolygonalMesh_vs_LineSegment(
01029 //                  &m_ModelLists.BasedOnFEM[FEMloc]->RefToSurfaceMesh(),   // HE-based mesh model
01030 //                  &IPs[A], &IPs[B],   // line segment
01031 //                  &TEMP_ListOfPoints,     // list of intersected points
01032 //                  &TEMP_ListOfHEFaces,    // list of intersected HE-based faces
01033 //                  &TEMP_ListOfHEVertices, // list of closest HE-based vertices to the intersected points
01034 //                  &TEMP_ListOfRatios      // list of ratios of the closest vertices relative to the line segment [0(ptA)-1(ptB)]
01035 //              );
01036 //
01037 //              if ( TEMP_ListOfHEVertices.size() > 0 ) {
01038 //
01039 //                  // IP pt#A punctures out from the FEM model
01040 //                  if ( A == 0 && IPG.GetInteractionPointAtIndex( A ).GetSimFlags().CheckSimulationConstraints( Enum::AddOn::SLIDABLE ) ) {
01041 //                      // Add the surface point to the constraint
01042 //                      AddVertexConnectionIPGModelAndHEModel(
01043 //                          RBDModel,
01044 //                          C-1,
01045 //                          Enum::AddOn::SLIDABLE,
01046 //                          FEMModel,
01047 //                          TEMP_ListOfHEVertices[0],   // only the first point
01048 //                          Enum::AddOn::ATTACHED,
01049 //                          STATE_ForceRatio,
01050 //                          STATE_ForceScaleA,
01051 //                          STATE_ForceScaleB,
01052 //                          STATE_ForceThresholdA,
01053 //                          STATE_ForceThresholdB,
01054 //                          STATE_EnforcePositionA,
01055 //                          STATE_EnforcePositionB
01056 //                      );
01057 //
01058 //                      // Slide the IP points from number 0 thru A-1
01059 //                      // pt 1 will inherit the sticked position from pt 0, and so on.
01060 //                      // So pt B will inherit the sticked position from pt A.
01061 //                      HEVertex<T> * pHEVert;
01062 //                      for ( unsigned int i = C-1; i > 0; --i ) {
01063 //                          pHEVert = m_InteractionLists.IPGModelVsHEModel[RBDloc][FEMloc][i-1]->GetPtrToVertexFromModel_2();
01064 //                          m_InteractionLists.IPGModelVsHEModel[RBDloc][FEMloc][i]->SetPtrToVertexFromModel_2( pHEVert );
01065 //                      }
01066 //                      // the fist IP pt
01067 //                      m_InteractionLists.IPGModelVsHEModel[RBDloc][FEMloc][0]->SetPtrToVertexFromModel_2( TEMP_ListOfHEVertices[0] );
01068 //                  }
01069 //                  else {
01070 //                  }
01071 //              }
01072 //          }
01073 //      }//END: CASE PUNCTURING OUT
01074 //  }
01075 //  else if ( pFEMTet ) {
01076 //      PrtNotImplementedYet( "ProcessPuncturingOfCurveFormedByIPGonRBDModelToFEMModel for FEMTet" );
01077 //  }
01079 //}
01080 //-----------------------------------------------------------------------------
01081 // Process specific interactions
01082 //=============================================================================
01083 
01084 
01085 //-----------------------------------------------------------------------------
01086 template <typename T, typename DATA>
01087 void AdvSimSupport_DS<T,DATA>::SetERNodesForwardBackwardMovement_InteractHEModel ( unsigned int ERloc, unsigned int HEloc )
01088 {
01089     AdvSimSupport_DATA<T,DATA>::ERNodePropsList & NodeProps = m_ModelLists.AllERNodePropsList[ERloc];
01090 
01091     //
01092     // Calculate length differences and clear the move status
01093     //
01094     // The first node
01095     unsigned int i = 0;
01096     NodeProps[i].MoveStatus = 0;
01097     if ( NodeProps[i].IsConstrained ) {
01098         Vector3<T> B = m_ModelLists.BasedOnER[ERloc]->RefToCurrentVertexPositionOfNodeNumber( i );
01099         Vector3<T> C = m_ModelLists.BasedOnER[ERloc]->RefToCurrentVertexPositionOfNodeNumber( i+1 );
01100         NodeProps[i].DiffLength = (B-C).Length() - m_ModelLists.BasedOnER[ERloc]->GetListOfNodes()[i].CenterlineRestLength;
01101 
01102         //std::cout << "NodeProps[0].DiffLength: " << NodeProps[0].DiffLength << "\n";
01103     }
01104     // The nodes between the first and the last nodes
01105     for ( i = 1; i < NodeProps.size()-1; ++i ) {
01106         NodeProps[i].MoveStatus = 0; // clear the move status
01107         if ( NodeProps[i].IsConstrained ) {
01108             Vector3<T> A = m_ModelLists.BasedOnER[ERloc]->RefToCurrentVertexPositionOfNodeNumber( i-1 );
01109             Vector3<T> B = m_ModelLists.BasedOnER[ERloc]->RefToCurrentVertexPositionOfNodeNumber( i );
01110             //Vector3<T> C = m_ModelLists.BasedOnER[ERloc]->RefToCurrentVertexPositionOfNodeNumber( i+1 );
01111             //NodeProps[i].DiffLength = ( (A-B).Length() - (B-C).Length() );
01112             NodeProps[i].DiffLength = (A-B).Length() - m_ModelLists.BasedOnER[ERloc]->GetListOfNodes()[i].CenterlineRestLength;
01113             //NodeProps[i].DiffLength = (B-C).Length() - m_ModelLists.BasedOnER[ERloc]->GetListOfNodes()[i].CenterlineRestLength;
01114         }
01115     }
01116     // The last node
01117     NodeProps[i].MoveStatus = 0;
01118 
01119     //std::stringstream ss; // DEBUG
01120     //std::stringstream ss2; // DEBUG
01121 
01122     //
01123     // Assign forward move status
01124     //
01125     // The first node
01126     //T LenThreshold = 0.05;    // in unit of 1 means equal to the whole restlength of node i
01127     T ForwardMoveLenThreshold = m_InteractionLists.ERModelVsHEModel[ERloc][HEloc].Constants.DiffLengthForTriggeringForwardMove;
01128     i = 0;
01129     while ( i < NodeProps.size()-2 ) {
01130         if ( NodeProps[i].IsConstrained ) {
01131             // The first node of a group is always set to greater than 2000
01132             int numOfLinks = NodeProps[i].GroupID - 2000;
01133             if ( NodeProps[i].DiffLength / m_ModelLists.BasedOnER[ERloc]->GetListOfNodes()[i].CenterlineRestLength > ForwardMoveLenThreshold ) {
01134                 NodeProps[i].MoveStatus += 4;   // initiate move forward (4)
01135                 do {
01136                     unsigned int numOfLinks = NodeProps[i].GroupID - 2000;
01137                     unsigned int p = i + numOfLinks;
01138                     for ( ; i < p; ++i ) {
01139                         NodeProps[i].MoveStatus += 1;   // move forward (1)
01140 
01141                         //ss << ' ' << i;   // DEBUG
01142                         //ss2 << ' ' << (int) NodeProps[i].MoveStatus;  // DEBUG
01143 
01144                     }
01145                 } while ( i < NodeProps.size()-2 && NodeProps[i].IsConstrained );
01146             }
01147             else {
01148                 i += numOfLinks;
01149             }
01150         }
01151         else {
01152             ++i;
01153         }
01154     }
01155 
01156     /*
01157     gDebugStr[11] = ss.str();   // DEBUG
01158     gDebugStr[12] = ss2.str();  // DEBUG
01159     if ( ss.str().size() > 0 ) {
01160         std::cout << "Links#:  " << ss.str() << "\n";
01161         std::cout << "Forward: " << ss2.str() << "\n";
01162     }
01163     //*/
01164 
01165     // Assign backward move status
01166     //...
01167 }
01168 //-----------------------------------------------------------------------------
01169 
01170 
01171 //=============================================================================
01172 // Enfoce constraints
01173 //-----------------------------------------------------------------------------
01174 template <typename T, typename DATA>
01175 void AdvSimSupport_DS<T,DATA>::EnforceAllConstraints ()
01176 {
01177     // Clear all connection (aka interaction) loads from FEM-based models
01178     for ( unsigned int i = 0; i < m_ModelLists.BasedOnFEM.size(); ++i ) {
01179         m_ModelLists.BasedOnFEM[i]->ClearAllConnectionLoads();
01180     }
01181 
01182     // Clear all point forces
01183     AdvSimSupport_DATA<T,DATA>::ListOfPointForces::iterator it = m_ListOfPointForces.begin();
01184     while ( it != m_ListOfPointForces.end() ) {
01185         delete *it;
01186         ++it;
01187     }
01188     m_ListOfPointForces.clear();
01189 
01190     for ( unsigned int i = 0; i < GetNumberOfTotalModels(); ++i ) {
01191         for ( unsigned int j = 0; j < GetNumberOfTotalModels(); ++j ) {
01192             EnforceAllConstraintsBetweenTwoModels( i, j );
01193         }
01194     }
01195 
01196     #ifdef  TAPs_MODEL_SURGICAL_SUTURE_WITH_HEAD_NEEDLE_HPP
01197     for ( unsigned int i = 0; i < m_ListOfInteraction_SwHDModelVsHEModel.size(); ++i ) {
01198         EnforceAllConstraintsOfSutureWithHeadNeedle( i );
01199     }
01200     #endif//TAPs_MODEL_SURGICAL_SUTURE_WITH_HEAD_NEEDLE_HPP
01201 }
01202 //-----------------------------------------------------------------------------
01203 template <typename T, typename DATA>
01204 void AdvSimSupport_DS<T,DATA>::EnforceAllConstraintsBetweenTwoModels ( unsigned int modelA, unsigned int modelB )
01205 {
01206     Enum::ModelType typeA = m_IDForModel[modelA].Type;
01207     Enum::ModelType typeB = m_IDForModel[modelB].Type;
01208 
01209     // MODEL_BASED_ON_FEM vs MODEL_BASED_ON_FEM
01210     if      (   typeA == Enum::MODEL_BASED_ON_FEM 
01211             &&  typeB == Enum::MODEL_BASED_ON_FEM )
01212     {
01213         unsigned int locA = m_IDForModel[modelA].Slot;
01214         unsigned int locB = m_IDForModel[modelB].Slot;
01215         if ( locA > locB ) return;
01216         Matrix4x4<T> TrxModelA = m_ModelLists.BasedOnFEM[locA]->RefToTransformationSupport().RefToMatrixTransform();
01217         Matrix4x4<T> InvTrxModelA = TrxModelA.GetInverse();
01218         Matrix4x4<T> TrxModelB = m_ModelLists.BasedOnFEM[locB]->RefToTransformationSupport().RefToMatrixTransform();
01219         Matrix4x4<T> InvTrxModelB = TrxModelB.GetInverse();
01220         locB -= locA;   // since the data in the std::vector starts from 0, not from the model id
01221         for ( unsigned int i = 0; i < m_InteractionLists.HEModelVsHEModel[locA][locB].Constraints.size(); ++i ) {
01222             EnforceTheConstraintNumberOfFEMModelAndFEMModel( locA, TrxModelA, InvTrxModelA, locB, TrxModelB, InvTrxModelB, i );
01223         }
01224     }
01225     // MODEL_BASED_ON_ER vs MODEL_BASED_ON_FEM
01226     else if (   typeA == Enum::MODEL_BASED_ON_ER 
01227             &&  typeB == Enum::MODEL_BASED_ON_FEM )
01228     {
01229         unsigned int locER = m_IDForModel[modelA].Slot;
01230         unsigned int locFEM = m_IDForModel[modelB].Slot;
01231         Matrix4x4<T> TrxFEMModel = m_ModelLists.BasedOnFEM[locFEM]->RefToTransformationSupport().RefToMatrixTransform();
01232         Matrix4x4<T> InvTrxFEMModel = TrxFEMModel.GetInverse();
01233 
01234         SetERNodesForwardBackwardMovement_InteractHEModel( locER, locFEM );
01235 
01236         EnforceForwardAndBackwardMovementOfERModelAndFEMModel( locER, locFEM, TrxFEMModel, InvTrxFEMModel );
01237 
01238         /*
01239         // DEBUG
01240         AdvSimSupport_DATA<T,DATA>::ERNodePropsList & NodeProps = m_ModelLists.AllERNodePropsList[locER];
01241         for ( unsigned int i = 0; i < NodeProps.size(); ++i ) {
01242             std::cout << "Check: " << i << "\t" << static_cast<int>( NodeProps[i].MoveStatus ) << "\n";
01243         }
01244         //*/
01245 
01246 
01247         //
01248         // For moving forward
01249         //
01250         // The constraints are sorted from low to high (of ERVertexID).
01251         // For forwarding moving, running backward from high to low to propagate the free ER node from the back to the front
01252         for ( int i =  static_cast<int>( m_InteractionLists.ERModelVsHEModel[locER][locFEM].Constraints.size() ) - 1; i >= 0; --i ) {
01253             EnforceTheConstraintNumberOfERModelAndFEMModel( locER, locFEM, TrxFEMModel, InvTrxFEMModel, i );
01254         }
01255 
01256         /*
01257         // DEBUG
01258         {
01259             std::stringstream ss;
01260             ss << "#constraints: " << static_cast<int>( m_InteractionLists.ERModelVsHEModel[locER][locFEM].Constraints.size() );
01261             gDebugStr[12] = ss.str();
01262         }
01263         //*/
01264 
01265         //
01266         // For moving backward -- HAS TO DO SOMETHING WITH MOVING FORWARD -- TO AVOID BOTH FORWARD AND BACKWARD MOVING AT THE SAME TIME
01267         //
01268         //for ( unsigned int i = 0; i < m_InteractionLists.ERModelVsHEModel[locER][locFEM].size(); ++i ) {
01269         //  ...
01270         //}
01271     }
01272 
01273     //*
01274     // MODEL_BASED_ON_IPG_RBD vs MODEL_BASED_ON_FEM
01275     else if (   typeA == Enum::MODEL_BASED_ON_IPG_RBD
01276             &&  typeB == Enum::MODEL_BASED_ON_FEM )
01277     {
01278         unsigned int locRBD = m_IDForModel[modelA].Slot;
01279         Matrix4x4<T> TrxModelRBD = m_ModelLists.BasedOnRBD[locRBD]->CalMatrixTransform();
01280         Matrix4x4<T> InvTrxModelRBD = TrxModelRBD.GetInverse();
01281         unsigned int locFEM = m_IDForModel[modelB].Slot;
01282         Matrix4x4<T> TrxModelFEM = m_ModelLists.BasedOnFEM[locFEM]->RefToTransformationSupport().RefToMatrixTransform();
01283         Matrix4x4<T> InvTrxModelFEM = TrxModelFEM.GetInverse();
01284         for ( unsigned int i = 0; i < m_InteractionLists.IPGModelVsHEModel[locRBD][locFEM].Constraints.size(); ++i ) {
01285             EnforceTheConstraintNumberOfRBDModelAndFEMModel( locRBD, TrxModelRBD, InvTrxModelRBD, locFEM, TrxModelFEM, InvTrxModelFEM, i );
01286         }
01287     }
01288     //*/
01289 }
01290 //-----------------------------------------------------------------------------
01291 template <typename T, typename DATA>
01292 void AdvSimSupport_DS<T,DATA>::EnforceTheConstraintNumberOfFEMModelAndFEMModel (
01293     unsigned int locA,                  
01294     Matrix4x4<T> const & TrxModelA,     
01295     Matrix4x4<T> const & InvTrxModelA,  
01296     unsigned int locB,                  
01297     Matrix4x4<T> const & TrxModelB,     
01298     Matrix4x4<T> const & InvTrxModelB,  
01299     unsigned int constraintNumber       
01300 )
01301 {
01302     typename AdvSimSupport_DATA<T,DATA>::Constraint_HEModelVsHEModel * pConstraint = m_InteractionLists.HEModelVsHEModel[locA][locB].Constraints[constraintNumber];
01303 
01304     HEVertex<T> * heA = pConstraint->GetPtrToVertexFromModel_1();
01305     HEVertex<T> * heB = pConstraint->GetPtrToVertexFromModel_2();
01306     Vector3<T> V1 = heA->GetProtectedPosition() = pConstraint->RefToSavedPositionA();
01307     Vector3<T> V2 = heB->GetProtectedPosition() = pConstraint->RefToSavedPositionB();
01308     V1 = TrxModelA * V1;
01309     V2 = TrxModelB * V2;
01310     T ratio = pConstraint->GetForceRatio();
01311     pConstraint->RefToTargetPositionA() = pConstraint->RefToTargetPositionB() = ratio*V1 + (1-ratio)*V2;
01312     V1 = InvTrxModelA * pConstraint->RefToTargetPositionA();
01313     V2 = InvTrxModelB * pConstraint->RefToTargetPositionB();
01314     pConstraint->RefToTargetPositionA() = V1;
01315     pConstraint->RefToTargetPositionB() = V2;
01316 
01317     // locA is FEM-based, add the connection as a point force.
01318     {
01319         Vector3<T> Fa = V1 - heA->GetProtectedPosition();
01320         PointForce<T> * pF = new PointForce<T>();
01321         m_ListOfPointForces.push_back( pF );
01322 
01323         // Set connection (i.e. point) force
01324         pF->SetID( heA->GetID() );
01325         pF->RefToPosition() = heA->GetBarycentricPtr()->RetGenBaryCoords();
01326         pF->RefToForce() = Fa * pConstraint->GetForceScaleA();
01327 
01328         // Scale by the timestep and mass
01329         pF->RefToForce() /= m_ModelLists.BasedOnFEM[locA]->GetTimeStep()
01330                             * m_ModelLists.BasedOnFEM[locA]->PtrToFEMMesh()->MassOfNode( 0 ).Length();
01331 
01332         m_ModelLists.BasedOnFEM[locA]->AddConnectionForceInLocalCoordinates( m_ListOfPointForces.back() );
01333     }
01334     // locB is FEM-based, add the connection as a point force.
01335     {
01336         Vector3<T> Fb = V2 - heB->GetProtectedPosition();
01337         PointForce<T> * pF = new PointForce<T>();
01338         m_ListOfPointForces.push_back( pF );
01339 
01340         // Set connection (i.e. point) force
01341         pF->SetID( heB->GetID() );
01342         pF->RefToPosition() = heB->GetBarycentricPtr()->RetGenBaryCoords();
01343         pF->RefToForce() = Fb * pConstraint->GetForceScaleB();
01344 
01345         // Scale by the timestep and mass
01346         pF->RefToForce() /= m_ModelLists.BasedOnFEM[locB]->GetTimeStep()
01347                             * m_ModelLists.BasedOnFEM[locB]->PtrToFEMMesh()->MassOfNode( 0 ).Length();
01348 
01349         m_ModelLists.BasedOnFEM[locB]->AddConnectionForceInLocalCoordinates( m_ListOfPointForces.back() );
01350     }
01351 }
01352 //-----------------------------------------------------------------------------
01353 template <typename T, typename DATA>
01354 void AdvSimSupport_DS<T,DATA>::EnforceForwardAndBackwardMovementOfERModelAndFEMModel (
01355     unsigned int ERloc,                     
01356     unsigned int FEMloc,                    
01357     Matrix4x4<T> const & TrxFEMModel,       
01358     Matrix4x4<T> const & InvTrxFEMModel     
01359 )
01360 {
01361     // Set the ERModel's last slidable point
01362     int ERModel_last_slidable_point = m_ModelLists.BasedOnER[ERloc]->GetNumberOfLinks() - m_OffsetToSutureLastSlidablePoint;
01363 
01364     //
01365     // For moving forward
01366     //
01367     // The constraints are sorted from low to high (of ERVertexID).
01368     // For forwarding moving, running backward from high to low to propagate the free ER node from the back to the front
01369     for ( int i =  static_cast<int>( m_InteractionLists.ERModelVsHEModel[ERloc][FEMloc].Constraints.size() ) - 1; i >= 0; --i ) {
01370 
01371         AdvSimSupport_DATA<T,DATA>::Constraint_ERModelVsHEModel * pConstraint = m_InteractionLists.ERModelVsHEModel[ERloc][FEMloc].Constraints[i];
01372         int ERModelPt = pConstraint->GetVertexIDFromModel_1();
01373 
01374         if ( ERModelPt < ERModel_last_slidable_point ) {    // PROTECTED FROM REACHING THE LAST POINT
01375             if (
01376                 // Check if the ERModel's point is slidable
01377                 m_ModelLists.BasedOnER[ERloc]->GetListOfNodes()[ERModelPt].SimFlags.CheckSimulationConstraints( Enum::AddOn::SLIDABLE )
01378             &&
01379                 // Check if the next ERModel's point is not attached
01380                 m_ModelLists.BasedOnER[ERloc]->GetListOfNodes()[ERModelPt+1].SimFlags.CheckSimulationConstraints( Enum::AddOn::ATTACHED ) == false
01381             )
01382             {
01383                 bool bMoveForward = m_ModelLists.AllERNodePropsList[ERloc][ERModelPt].MoveStatus & 0x01;
01384                 if ( bMoveForward )
01385                 {
01386                     //if (
01387                     // Backward ???
01388 
01389                     //-----------------------------------------------
01390                     // Forward
01391                     //-----------------------------------------------
01392                     // Clear simulation states of the current node, e.g. clear ATTACHED status
01393                     m_ModelLists.BasedOnER[ERloc]->GetListOfNodes()[ERModelPt].ExternalForce_ForAdvSimCtrl.Clear();
01394                     m_ModelLists.BasedOnER[ERloc]->GetListOfNodes()[ERModelPt].SimFlags.ClearSimulationConstraints( Enum::AddOn::ATTACHED );
01395                     m_ModelLists.BasedOnER[ERloc]->GetListOfNodes()[ERModelPt].SimFlags.ClearSimulationConstraints( Enum::AddOn::IGNORE_CD_FORCE );
01396 
01397                     // Setting PropsList
01398                     int savedGroupID = m_ModelLists.AllERNodePropsList[ERloc][ERModelPt].GroupID;
01399                     m_ModelLists.AllERNodePropsList[ERloc][ERModelPt].GroupID = 0;
01400                     m_ModelLists.AllERNodePropsList[ERloc][ERModelPt].IsConstrained = false;
01401 
01402                     bool bEnforcedPos = m_ModelLists.BasedOnER[ERloc]->GetListOfNodes()[ERModelPt].UseEnforcedPosition;
01403                     if ( bEnforcedPos ) {
01404                         m_ModelLists.BasedOnER[ERloc]->GetListOfNodes()[ERModelPt].UseEnforcedPosition = false;
01405                     }
01406 
01407                     ++ERModelPt;    // move to next ERModel's point
01408 
01409                     pConstraint->SetVertexIDFromModel_1( ERModelPt );
01410 
01411                     // Set the status of the new ERModel's point
01412 
01413                     // Set ERModel's point's status
01414                     if ( ERModelPt < ERModel_last_slidable_point ) {
01415                         m_ModelLists.BasedOnER[ERloc]->GetListOfNodes()[ERModelPt].SimFlags.SetSimulationConstraints( Enum::AddOn::SLIDABLE );
01416                     }
01417                     m_ModelLists.BasedOnER[ERloc]->GetListOfNodes()[ERModelPt].SimFlags.SetSimulationConstraints( Enum::AddOn::ATTACHED );
01418                     m_ModelLists.BasedOnER[ERloc]->GetListOfNodes()[ERModelPt].SimFlags.SetSimulationConstraints( Enum::AddOn::IGNORE_CD_FORCE );
01419 
01420                     // Setting PropsList
01421                     m_ModelLists.BasedOnER[ERloc]->GetListOfNodes()[ERModelPt].UseEnforcedPosition = bEnforcedPos;
01422                     m_ModelLists.AllERNodePropsList[ERloc][ERModelPt].GroupID = savedGroupID;
01423                     m_ModelLists.AllERNodePropsList[ERloc][ERModelPt].IsConstrained = true;
01424                 }
01425             }
01426         }
01427     }
01428 }
01429 //-----------------------------------------------------------------------------
01430 template <typename T, typename DATA>
01431 void AdvSimSupport_DS<T,DATA>::EnforceTheConstraintNumberOfERModelAndFEMModel (
01432     unsigned int ERloc,                     
01433     unsigned int FEMloc,                    
01434     Matrix4x4<T> const & TrxFEMModel,       
01435     Matrix4x4<T> const & InvTrxFEMModel,    
01436     unsigned int constraintNumber           
01437 )
01438 {
01439     AdvSimSupport_DATA<T,DATA>::Constraint_ERModelVsHEModel * pConstraint = m_InteractionLists.ERModelVsHEModel[ERloc][FEMloc].Constraints[constraintNumber];
01440     int ERModelPt = pConstraint->GetVertexIDFromModel_1();
01441 
01442 
01443     // DEBUG
01444     //std::cout << "Constraint# " << constraintNumber << " has ERvertex# " << ERModelPt << "\n";
01445 
01446     {
01447         Vector3<T> & S = m_ModelLists.BasedOnER[ERloc]->RefToCurrentVertexPositionOfNodeNumber( ERModelPt );
01448         HEVertex<T> * he = pConstraint->GetPtrToVertexFromModel_2();
01449         Vector3<T> V = he->GetProtectedPosition() = pConstraint->RefToSavedPositionB();
01450         V = TrxFEMModel * V;
01451         T ratio = pConstraint->GetForceRatio();
01452         pConstraint->RefToTargetPositionA() = 
01453         pConstraint->RefToTargetPositionB() = ratio*S + (1-ratio)*V;
01454         //S = pConstraint->RefToTargetPositionA();  // ERModel's point's current position
01455         V = InvTrxFEMModel * pConstraint->RefToTargetPositionB();
01456         pConstraint->RefToTargetPositionB() = V;
01457 
01458         // FEM-based model, add the connection as a point force.
01459         {
01460             Vector3<T> F = V - he->GetProtectedPosition();
01461             PointForce<T> * pF = new PointForce<T>();
01462             m_ListOfPointForces.push_back( pF );
01463 
01464             pF->SetID( he->GetID() );
01465             pF->RefToPosition() = he->GetBarycentricPtr()->RetGenBaryCoords();
01466 
01467             #ifdef  TAPs_USE_NONLINEAR_FORCES
01468                 T mag = F.Length();
01469                 F /= mag;
01470                 pF->RefToForce() = F * pConstraint->GetForceScaleB() * ( pow( 2.718281828, mag ) - 1 );
01471                 //pF->RefToForce() = F * pConstraint->GetForceScaleB() * ( pow( 10, mag ) - 1 );
01472             #else //TAPs_USE_NONLINEAR_FORCES
01473                 pF->RefToForce() = F * pConstraint->GetForceScaleB();
01474             #endif//TAPs_USE_NONLINEAR_FORCES
01475 
01476             // Scale pF by the timestep and mass
01477             pF->RefToForce() /= m_ModelLists.BasedOnFEM[FEMloc]->GetTimeStep()
01478                                 * m_ModelLists.BasedOnFEM[FEMloc]->PtrToFEMMesh()->MassOfNode( 0 ).Length();
01479 
01480             m_ModelLists.BasedOnFEM[FEMloc]->AddConnectionForceInLocalCoordinates( m_ListOfPointForces.back() );
01481 
01482             // ???????
01483             //std::cout << "WHY THE SIMFLAGS IS NOT SET PROPERLY (GOT RESET SOMEWHERE) ???\n";
01484 
01485             //std::cout << "F mag: " << pF->RefToForce().Magnitude() << "\n";
01486             //std::cout << "Force Ratio: " << pConstraint->GetForceRatio() << "\n";
01487             //std::cout << "Force Scale A: " << pConstraint->GetForceScaleA() << "\n";
01488             //std::cout << "Force Threshold A: " << pConstraint->GetForceThresholdA() << "\n";
01489             //std::cout << "Force Scale B: " << pConstraint->GetForceScaleB() << "\n";
01490             //std::cout << "Force Threshold B: " << pConstraint->GetForceThresholdB() << "\n";
01491             //std::cout << "SuturePt: " << SuturePt << "\n";
01492             //std::cout << m_ModelLists.BasedOnER[ERModel]->GetListOfNodes()[SuturePt].SimFlags << "\n";
01493 
01494             //if ( SuturePt < m_ModelLists.BasedOnER[ERModel]->GetNumberOfLinks()-1 ) {
01495             //  //if ( m_ModelLists.BasedOnER[ERModel]->GetListOfNodes()[SuturePt].SimFlags.CheckSimulationConstraints( Enum::AddOn::SLIDABLE ) )
01496             //  // WHY THE SIMFLAGS IS NOT SET PROPERLY (GOT RESET SOMEWHERE) ???
01497             //  {
01498             //      if ( pF->RefToForce().Magnitude() > pConstraint->GetForceThresholdA() )
01499             //      {
01500             //          //if (
01501             //          // Backward ???
01502 
01503             //          // Forward
01504             //          ++SuturePt;
01505 
01506             //          std::cout << "SuturePt after: " << SuturePt << "\n";
01507 
01508             //          pConstraint->SetVertexIDFromSuture( SuturePt );
01509             //          m_ModelLists.BasedOnER[ERModel]->GetListOfNodes()[SuturePt].SimFlags.SetSimulationConstraints( Enum::AddOn::SLIDABLE );
01510             //      }
01511             //  }
01512             //}
01513         }
01514 
01515         // Calculate the external force apply to Suture
01516         Vector3<T> Fs = pConstraint->RefToTargetPositionA() - S;
01517 
01518         //-----------------------------------------
01519         #ifdef  TAPs_USE_NONLINEAR_FORCES
01520             T mag = Fs.Length();
01521             Fs /= mag;
01522             Fs *= pConstraint->GetForceScaleA() * ( pow( 2.718281828, mag ) - 1 );
01523             //Fs *= pConstraint->GetForceScaleA() * ( pow( 10, mag ) - 1 );
01524         #else //TAPs_USE_NONLINEAR_FORCES
01525             Fs *= pConstraint->GetForceScaleA();
01526         #endif//TAPs_USE_NONLINEAR_FORCES
01527         //-----------------------------------------
01528 
01529         // Scale Fs by the timestep, iteration times, and mass
01530         Fs /= m_ModelLists.BasedOnER[ERloc]->GetSimTimeStep() 
01531             * m_ModelLists.BasedOnER[ERloc]->GetSimIterationTimes() 
01532             * m_ModelLists.BasedOnER[ERloc]->GetListOfNodes()[ERModelPt].GetMass();
01533 
01534         T SforceMag = Fs.Magnitude();
01535         //Fs /= m_ModelLists.BasedOnER[ERModel]->GetSimTimeStep();
01536 
01537         //std::cout << "GetForceScaleA: " << pConstraint->GetForceScaleA() << "\n";
01538         //std::cout << "Fs: " << Fs << "\n";
01539         m_ModelLists.BasedOnER[ERloc]->GetListOfNodes()[ERModelPt].ExternalForce_ForAdvSimCtrl = Fs;
01540 
01541         //
01542         // Move the current centerline position to the (current) target position
01543         //
01544         //m_ModelLists.BasedOnER[ERloc]->GetListOfNodes()[ERModelPt].Centerline[m_ModelLists.BasedOnER[ERloc]->GetPreviousIndex()].SetPosition( pConstraint->RefToTargetPositionA() );
01545         m_ModelLists.BasedOnER[ERloc]->GetListOfNodes()[ERModelPt].Centerline[m_ModelLists.BasedOnER[ERloc]->GetCurrentIndex()].SetPosition( pConstraint->RefToTargetPositionA() );
01546 
01547         // Set the ERModel's last slidable point
01548         int ERModel_last_slidable_point = m_ModelLists.BasedOnER[ERloc]->GetNumberOfLinks() - m_OffsetToSutureLastSlidablePoint;
01549 
01550         //std::cout << "Enforced ERModelPt: " << ERModelPt << "\n";
01551 
01552         // For slidable ERModel's points FORWARD
01553         //if ( !m_ModelLists.BasedOnER[ERModel]->GetListOfNodes()[SuturePt].UseEnforcedPosition ... && ...
01554         //if ( false ) {
01556         //  if (
01557         //      // Check if the ERModel's point is slidable
01558         //      m_ModelLists.BasedOnER[ERloc]->GetListOfNodes()[ERModelPt].SimFlags.CheckSimulationConstraints( Enum::AddOn::SLIDABLE )
01559         //  &&
01560         //      // Check if the next ERModel's point is not attached
01561         //      m_ModelLists.BasedOnER[ERloc]->GetListOfNodes()[ERModelPt+1].SimFlags.CheckSimulationConstraints( Enum::AddOn::ATTACHED ) == false 
01562         //  ) {
01563         //  // WHY THE SIMFLAGS IS NOT SET PROPERLY (GOT RESET SOMEWHERE) ???
01564         //      // If the next ERModel's point is not attached, then check if the ERModel's point will slide due to the high force.
01565         //      //if ( m_ModelLists.BasedOnER[ERModel]->GetListOfNodes()[ERModelPt+1].SimFlags.CheckSimulationConstraints( Enum::AddOn::ATTACHED ) ) 
01566         //      {
01567         //          /*
01568         //          // Calculate distance
01569         //          T distDiff = 0;
01570         //          if ( ERModelPt > 0 ) {
01571         //              Vector3<T> A = m_ModelLists.BasedOnER[ERloc]->RefToCurrentVertexPositionOfNodeNumber( ERModelPt-1 );
01572         //              Vector3<T> B = m_ModelLists.BasedOnER[ERloc]->RefToCurrentVertexPositionOfNodeNumber( ERModelPt );
01573         //              Vector3<T> C = m_ModelLists.BasedOnER[ERloc]->RefToCurrentVertexPositionOfNodeNumber( ERModelPt+1 );
01574         //              distDiff = (A-B).Length() - (B-C).Length();
01575 
01576         //              //std::cout << "distDiff: " << distDiff << "\n";
01577         //              //std::cout << "ERModelPt: " << ERModelPt << "\n";
01578         //          }
01579         //          if ( SforceMag > pConstraint->GetForceThresholdA() || distDiff > 0.001 )
01580         //          //*/
01581 
01582         //          //*
01583         //          bool bMoveForward = m_ModelLists.AllERNodePropsList[ERloc][ERModelPt].MoveStatus & 0x01;
01584         //          if ( bMoveForward || SforceMag > pConstraint->GetForceThresholdA() )
01585         //          //*/
01586 
01587         //          {
01588         //              //if (
01589         //              // Backward ???
01590 
01591         //              //-----------------------------------------------
01592         //              // Forward
01593         //              //-----------------------------------------------
01594         //              // Clear simulation states of the current node, e.g. clear ATTACHED status
01595         //              m_ModelLists.BasedOnER[ERloc]->GetListOfNodes()[ERModelPt].ExternalForce_ForAdvSimCtrl.Clear();
01596         //              m_ModelLists.BasedOnER[ERloc]->GetListOfNodes()[ERModelPt].SimFlags.ClearSimulationConstraints( Enum::AddOn::ATTACHED );
01597         //              m_ModelLists.BasedOnER[ERloc]->GetListOfNodes()[ERModelPt].SimFlags.ClearSimulationConstraints( Enum::AddOn::IGNORE_CD_FORCE );
01598 
01599         //              // Setting PropsList
01600         //              int savedGroupID = m_ModelLists.AllERNodePropsList[ERloc][ERModelPt].GroupID;
01601         //              m_ModelLists.AllERNodePropsList[ERloc][ERModelPt].GroupID = 0;
01602         //              m_ModelLists.AllERNodePropsList[ERloc][ERModelPt].IsConstrained = false;
01603 
01604         //              bool bEnforcedPos = m_ModelLists.BasedOnER[ERloc]->GetListOfNodes()[ERModelPt].UseEnforcedPosition;
01605         //              if ( bEnforcedPos ) {
01606         //                  m_ModelLists.BasedOnER[ERloc]->GetListOfNodes()[ERModelPt].UseEnforcedPosition = false;
01607         //              }
01608 
01609         //              {
01610         //                  ++ERModelPt;    // move to next ERModel's point
01611 
01612         //                  pConstraint->SetVertexIDFromModel_1( ERModelPt );
01613 
01614         //                  // Set the status of the new ERModel's point
01615 
01616         //                  // Calculate the external force apply to ERModel's point
01617         //                  Vector3<T> Fs = pConstraint->RefToTargetPositionA() - m_ModelLists.BasedOnER[ERloc]->RefToCurrentVertexPositionOfNodeNumber( ERModelPt );
01618 
01619         //                  //-----------------------------------------
01620         //                  #ifdef  TAPs_USE_NONLINEAR_FORCES
01621         //                      T mag = Fs.Length();
01622         //                      Fs /= mag;
01623         //                      Fs *= pConstraint->GetForceScaleA() * ( pow( 2.718281828, mag ) - 1 );
01624         //                      //Fs *= pConstraint->GetForceScaleA() * ( pow( 10, mag ) - 1 );
01625         //                  #else //TAPs_USE_NONLINEAR_FORCES
01626         //                      Fs *= pConstraint->GetForceScaleA();
01627         //                  #endif//TAPs_USE_NONLINEAR_FORCES
01628         //                  //-----------------------------------------
01629 
01630         //                  // Scale Fs by the timestep, iteration times, and mass
01631         //                  Fs /= m_ModelLists.BasedOnER[ERloc]->GetSimTimeStep() 
01632         //                      * m_ModelLists.BasedOnER[ERloc]->GetSimIterationTimes() 
01633         //                      * m_ModelLists.BasedOnER[ERloc]->GetListOfNodes()[ERModelPt].GetMass();
01634 
01635         //                  // Set ERModel's point's status
01636         //                  m_ModelLists.BasedOnER[ERloc]->GetListOfNodes()[ERModelPt].ExternalForce_ForAdvSimCtrl = Fs;
01637         //                  if ( ERModelPt < ERModel_last_slidable_point ) {
01638         //                      m_ModelLists.BasedOnER[ERloc]->GetListOfNodes()[ERModelPt].SimFlags.SetSimulationConstraints( Enum::AddOn::SLIDABLE );
01639         //                  }
01640         //                  m_ModelLists.BasedOnER[ERloc]->GetListOfNodes()[ERModelPt].SimFlags.SetSimulationConstraints( Enum::AddOn::ATTACHED );
01641         //                  m_ModelLists.BasedOnER[ERloc]->GetListOfNodes()[ERModelPt].SimFlags.SetSimulationConstraints( Enum::AddOn::IGNORE_CD_FORCE );
01642 
01643         //                  // Setting PropsList
01644         //                  m_ModelLists.BasedOnER[ERloc]->GetListOfNodes()[ERModelPt].UseEnforcedPosition = bEnforcedPos;
01645         //                  m_ModelLists.AllERNodePropsList[ERloc][ERModelPt].GroupID = savedGroupID;
01646         //                  m_ModelLists.AllERNodePropsList[ERloc][ERModelPt].IsConstrained = true;
01647         //              }
01648         //          }
01649         //      }
01650         //  }
01651         //}
01652     }
01653 }
01654 //-----------------------------------------------------------------------------
01655 template <typename T, typename DATA>
01656 void AdvSimSupport_DS<T,DATA>::EnforceTheConstraintNumberOfRBDModelAndFEMModel (
01657     unsigned int RBDloc,                    
01658     Matrix4x4<T> const & TrxRBDModel,       
01659     Matrix4x4<T> const & InvTrxRBDModel,    
01660     unsigned int FEMloc,                    
01661     Matrix4x4<T> const & TrxFEMModel,       
01662     Matrix4x4<T> const & InvTrxFEMModel,    
01663     unsigned int constraintNumber           
01664 )
01665 {
01666     //return;
01667 
01668     AdvSimSupport_DATA<T,DATA>::Constraint_IPGModelVsHEModel * pConstraint = m_InteractionLists.IPGModelVsHEModel[RBDloc][FEMloc].Constraints[constraintNumber];
01669 
01670     unsigned int vertID = pConstraint->GetVertexIDFromModel_1();
01671     HEVertex<T> * pHEvert = pConstraint->GetPtrToVertexFromModel_2();
01672     Vector3<T> V1 = m_ModelLists.BasedOnRBD[RBDloc]->RefToInteractionPointGroup().GetInteractionPointAtIndex( vertID ).GetPosition();
01673     Vector3<T> V2 = pHEvert->GetProtectedPosition() = pConstraint->RefToSavedPositionB();
01674     V1 = TrxRBDModel * V1;
01675     V2 = TrxFEMModel * V2;
01676     T ratio = pConstraint->GetForceRatio();
01677     pConstraint->RefToTargetPositionA() = pConstraint->RefToTargetPositionB() = ratio*V1 + (1-ratio)*V2;
01678     V1 = InvTrxRBDModel * pConstraint->RefToTargetPositionA();
01679     V2 = InvTrxFEMModel * pConstraint->RefToTargetPositionB();
01680     pConstraint->RefToTargetPositionA() = V1;
01681     pConstraint->RefToTargetPositionB() = V2;
01682 
01683     // RBD-based, add the connection as a point force.
01684     {
01685     }
01686     // FEM-based, add the connection as a point force.
01687     {
01688         Vector3<T> Fb = V2 - pHEvert->GetProtectedPosition();
01689         PointForce<T> * pF = new PointForce<T>();
01690         m_ListOfPointForces.push_back( pF );
01691 
01692         // Set connection (i.e. point) force
01693         pF->SetID( pHEvert->GetID() );
01694         pF->RefToPosition() = pHEvert->GetBarycentricPtr()->RetGenBaryCoords();
01695         pF->RefToForce() = Fb * pConstraint->GetForceScaleB();
01696 
01697         // Scale pF by the timestep and mass
01698         pF->RefToForce() /= m_ModelLists.BasedOnFEM[FEMloc]->GetTimeStep()
01699                             * m_ModelLists.BasedOnFEM[FEMloc]->PtrToFEMMesh()->MassOfNode( 0 ).Length();
01700 
01701         m_ModelLists.BasedOnFEM[FEMloc]->AddConnectionForceInLocalCoordinates( m_ListOfPointForces.back() );
01702     }
01703 }
01704 //-----------------------------------------------------------------------------
01705 // Enfoce constraints
01706 //=============================================================================
01707 
01708 
01709 
01710 
01711 //=============================================================================
01712 // Enforce consistent positions
01713 //-----------------------------------------------------------------------------
01714 template <typename T, typename DATA>
01715 void AdvSimSupport_DS<T,DATA>::EnforceAllConsistentPositions ()
01716 {
01717     // HEModel-HEModel interactions
01718     for ( unsigned int i = 0; i < m_InteractionLists.HEModelVsHEModel.size(); ++i ) {
01719         for ( unsigned int j = i; j < m_InteractionLists.HEModelVsHEModel[i].size(); ++j ) {
01720             EnforceAllConsistentPositionsOfHEModelAndHEModel( i, j );
01721         }
01722     }
01723 
01724     // ERModel-HEModel interactions
01725     for ( unsigned int i = 0; i < m_InteractionLists.ERModelVsHEModel.size(); ++i ) {
01726         for ( unsigned int j = 0; j < m_InteractionLists.ERModelVsHEModel[i].size(); ++j ) {
01727             EnforceAllConsistentPositionsOfERModelAndHEModel( i, j );
01728         }
01729     }
01730 
01731     // IPGModel-HEModel interactions
01732     for ( unsigned int i = 0; i < m_InteractionLists.IPGModelVsHEModel.size(); ++i ) {
01733         for ( unsigned int j = 0; j < m_InteractionLists.IPGModelVsHEModel[i].size(); ++j ) {
01734             EnforceAllConsistentPositionsOfIPGModelAndHEModel( i, j );
01735         }
01736     }
01737 
01738     #ifdef  TAPs_MODEL_SURGICAL_SUTURE_WITH_HEAD_NEEDLE_HPP
01739     // Head needles with FEM-based models
01740     // For the head needle's IPG
01741     for ( unsigned int i = 0; i < m_ListOfInteraction_SwHDModelVsHEModel.size(); ++i ) {
01742         m_ListOfInteraction_SwHDModelVsHEModel[i]->EnforceAllConsistentPositions_ForIPG(
01743             m_IDForModel,               
01744             m_ModelLists.BasedOnER,     
01745             m_ModelLists.BasedOnFEM,    
01746             m_ModelLists.BasedOnRBD     
01747         );
01748     }
01749     // For the head needle's circle path
01750     for ( unsigned int i = 0; i < m_ListOfInteraction_SwHDModelVsHEModel.size(); ++i ) {
01751         m_ListOfInteraction_SwHDModelVsHEModel[i]->EnforceAllConsistentPositions_ForCirclePath(
01752             m_IDForModel,               
01753             m_ModelLists.BasedOnER,     
01754             m_ModelLists.BasedOnFEM,    
01755             m_ModelLists.BasedOnRBD     
01756         );
01757     }
01758     #endif//TAPs_MODEL_SURGICAL_SUTURE_WITH_HEAD_NEEDLE_HPP
01759 }
01760 //-----------------------------------------------------------------------------
01761 template <typename T, typename DATA>
01762 void AdvSimSupport_DS<T,DATA>::EnforceAllConsistentPositionsOfHEModelAndHEModel ( unsigned int locA, unsigned int locB )
01763 {
01764     locB -= locA;   // since the data in the std::vector starts from 0, not from the model id
01765     AdvSimSupport_DATA<T,DATA>::InteractionConstraints_HEModelVsHEModel::iterator it = m_InteractionLists.HEModelVsHEModel[locA][locB].Constraints.begin();
01766     while ( it != m_InteractionLists.HEModelVsHEModel[locA][locB].Constraints.end() ) {
01767         (*it)->RefToSavedPositionA() = (*it)->GetPtrToVertexFromModel_1()->GetProtectedPosition();
01768         (*it)->RefToSavedPositionB() = (*it)->GetPtrToVertexFromModel_2()->GetProtectedPosition();
01769         (*it)->GetPtrToVertexFromModel_1()->GetProtectedPosition() = (*it)->RefToTargetPositionA();
01770         (*it)->GetPtrToVertexFromModel_2()->GetProtectedPosition() = (*it)->RefToTargetPositionB();
01771         ++it;
01772     }
01773 }
01774 //-----------------------------------------------------------------------------
01775 template <typename T, typename DATA>
01776 void AdvSimSupport_DS<T,DATA>::EnforceAllConsistentPositionsOfERModelAndHEModel ( unsigned int ERloc, unsigned int HEloc )
01777 {
01778     Matrix4x4<T> TrxModel = m_ModelLists.BasedOnFEM[HEloc]->RefToTransformationSupport().RefToMatrixTransform();
01779     Matrix4x4<T> InvTrxModel = TrxModel.GetInverse();
01780 
01781     AdvSimSupport_DATA<T,DATA>::InteractionConstraints_ERModelVsHEModel::iterator it = m_InteractionLists.ERModelVsHEModel[ERloc][HEloc].Constraints.begin();
01782     while ( it != m_InteractionLists.ERModelVsHEModel[ERloc][HEloc].Constraints.end() ) {
01783 
01784         // Move the ERModel's constrained point to the target point
01785         //Vector3<T> & Sp = m_ModelLists.BasedOnER[ERloc]->RefToPreviousVertexPositionOfNodeNumber( (*it)->GetVertexIDFromModel_1() );
01786         //Vector3<T> & Sc = m_ModelLists.BasedOnER[ERloc]->RefToCurrentVertexPositionOfNodeNumber( (*it)->GetVertexIDFromModel_1() );
01787         //Sp = Sc = (*it)->RefToTargetPositionA();
01788 
01789         unsigned int nodeID = (*it)->GetVertexIDFromModel_1();
01790 
01791         // Enforce ER-based model's Position
01792         if ( (*it)->GetEnforcePositionStatusA() ) {
01793             m_ModelLists.BasedOnER[ERloc]->GetListOfNodes()[nodeID].UseEnforcedPosition = true;
01794             m_ModelLists.BasedOnER[ERloc]->GetListOfNodes()[nodeID].EnforcedPosition = (*it)->RefToTargetPositionA();
01795         }
01796         else {
01797         }
01798 
01799         (*it)->RefToSavedPositionB() = (*it)->GetPtrToVertexFromModel_2()->GetProtectedPosition();
01800 
01801         // Move the model's constrained point to the target point
01802         if ( false )
01803         {
01804             // TO THE TARGET POSITION B
01805             if ( (*it)->GetEnforcePositionStatusB() ) {
01806                 (*it)->GetPtrToVertexFromModel_2()->GetProtectedPosition() = (*it)->RefToTargetPositionB();
01807             }
01808         }
01809         else {
01810             // TO THE SUTURE POINT
01811             if ( (*it)->GetEnforcePositionStatusB() ) {
01812 
01813                 //#ifdef    TAPs_USE_VERTEX_POSITION_AVERAGING
01814                 //  std::vector< HEVertex<T> * > firstRing = (*it)->GetPtrToVertexFromModel_2()->FindTheFirstRingOfVertices();
01815                 //  unsigned int size = firstRing.size();
01816                 //  if ( size > 0 ) {
01817                 //      Vector3<T> avgPos;
01818                 //      for ( unsigned int i = 0; i < size; ++i ) {
01819                 //          avgPos += firstRing[i]->GetPosition();
01820                 //      }
01821                 //      T scale = size;// / T(1);
01822                 //      Vector3<T> targetPos = InvTrxModel * m_ModelLists.BasedOnER[ERloc]->RefToCurrentVertexPositionOfNodeNumber( (*it)->GetVertexIDFromModel_1() );
01823                 //      avgPos = ( avgPos + targetPos*scale ) / ( size + scale );
01824                 //      (*it)->GetPtrToVertexFromModel_2()->GetProtectedPosition() = avgPos;
01825                 //  }
01826                 //  else {
01827                 //      (*it)->GetPtrToVertexFromModel_2()->GetProtectedPosition() = InvTrxModel * 
01828                 //      m_ModelLists.BasedOnER[ERloc]->RefToCurrentVertexPositionOfNodeNumber( 
01829                 //          (*it)->GetVertexIDFromModel_1() );
01830                 //  }
01831                 //#else //TAPs_USE_VERTEX_POSITION_AVERAGING
01832                     //(*it)->GetPtrToVertexFromModel_2()->GetProtectedPosition() = InvTrxModel * 
01833                     //m_ModelLists.BasedOnER[ERloc]->RefToCurrentVertexPositionOfNodeNumber( 
01834                     //  (*it)->GetVertexIDFromModel_1() );
01835                 //#endif//TAPs_USE_VERTEX_POSITION_AVERAGING
01836 
01837 
01838                 #ifdef  TAPs_USE_VERTEX_POSITION_AVERAGING
01839                     std::vector< HEVertex<T> * > firstRing = (*it)->GetPtrToVertexFromModel_2()->FindTheFirstRingOfVertices();
01840                     unsigned int size = firstRing.size();
01841                     if ( size > 0 ) {
01842                         Vector3<T> targetPos = InvTrxModel * m_ModelLists.BasedOnER[ERloc]->RefToCurrentVertexPositionOfNodeNumber( (*it)->GetVertexIDFromModel_1() );
01843                         Vector3<T> avgPos;
01844                         for ( unsigned int i = 0; i < size; ++i ) {
01845                             avgPos = ( firstRing[i]->GetPosition() + targetPos ) / 2;
01846                             firstRing[i]->GetProtectedPosition() = avgPos;
01847                         }
01848                         (*it)->GetPtrToVertexFromModel_2()->GetProtectedPosition() = targetPos;
01849                     }
01850                     else {
01851                         (*it)->GetPtrToVertexFromModel_2()->GetProtectedPosition() = InvTrxModel * 
01852                         m_ModelLists.BasedOnER[ERloc]->RefToCurrentVertexPositionOfNodeNumber( 
01853                             (*it)->GetVertexIDFromModel_1() );
01854                     }
01855                 #else //TAPs_USE_VERTEX_POSITION_AVERAGING
01856                     (*it)->GetPtrToVertexFromModel_2()->GetProtectedPosition() = InvTrxModel * 
01857                     m_ModelLists.BasedOnER[ERloc]->RefToCurrentVertexPositionOfNodeNumber( 
01858                         (*it)->GetVertexIDFromModel_1() );
01859                 #endif//TAPs_USE_VERTEX_POSITION_AVERAGING
01860 
01861             }
01862         }
01863 
01864         ++it;
01865     }
01866 }
01867 //-----------------------------------------------------------------------------
01868 template <typename T, typename DATA>
01869 void AdvSimSupport_DS<T,DATA>::EnforceAllConsistentPositionsOfIPGModelAndHEModel ( unsigned int IPGloc, unsigned int HEloc )
01870 {
01871     AdvSimSupport_DATA<T,DATA>::InteractionConstraints_IPGModelVsHEModel::iterator it = m_InteractionLists.IPGModelVsHEModel[IPGloc][HEloc].Constraints.begin();
01872     while ( it != m_InteractionLists.IPGModelVsHEModel[IPGloc][HEloc].Constraints.end() ) {
01873         //(*it)->RefToSavedPositionA() = (*it)->GetPtrToVertexFromModel_1()->GetProtectedPosition();
01874         (*it)->RefToSavedPositionB() = (*it)->GetPtrToVertexFromModel_2()->GetProtectedPosition();
01875         //(*it)->GetPtrToVertexFromModel_1()->GetProtectedPosition() = (*it)->RefToTargetPositionA();
01876         (*it)->GetPtrToVertexFromModel_2()->GetProtectedPosition() = (*it)->RefToTargetPositionB();
01877         ++it;
01878     }
01879 }
01880 //-----------------------------------------------------------------------------
01881 // Enforce consistent positions
01882 //=============================================================================
01883 
01884 
01885 
01886 
01887 //=============================================================================
01888 // Clear constraints
01889 //-----------------------------------------------------------------------------
01890 template <typename T, typename DATA>
01891 void AdvSimSupport_DS<T,DATA>::ClearAllConstraints ()
01892 {
01893     for ( unsigned int i = 0; i < GetNumberOfTotalModels(); ++i ) {
01894         for ( unsigned int j = 0; j < GetNumberOfTotalModels(); ++j ) {
01895             ClearAllConstraintsBetweenTwoModels( i, j );
01896         }
01897     }
01898 
01899     #ifdef  TAPs_MODEL_SURGICAL_SUTURE_WITH_HEAD_NEEDLE_HPP
01900     for ( unsigned int i = 0; i < m_ListOfInteraction_SwHDModelVsHEModel.size(); ++i ) {
01901         ClearAllConstraintsOfSutureWithHeadNeedle( i );
01902     }
01903     #endif//TAPs_MODEL_SURGICAL_SUTURE_WITH_HEAD_NEEDLE_HPP
01904 
01905     // Clear all point forces
01906     AdvSimSupport_DATA<T,DATA>::ListOfPointForces::iterator it = m_ListOfPointForces.begin();
01907     while ( it != m_ListOfPointForces.end() ) {
01908         delete *it;
01909         ++it;
01910     }
01911     m_ListOfPointForces.clear();
01912 
01913     // Clear data for controlling forward and backward movements of an Elastic Rod
01914     m_ModelLists.ResetAllERNodePropsList();
01915 }
01916 //-----------------------------------------------------------------------------
01917 template <typename T, typename DATA>
01918 void AdvSimSupport_DS<T,DATA>::ClearAllConstraintsBetweenTwoModels ( unsigned int modelA, unsigned int modelB )
01919 {
01920     Enum::ModelType typeA = m_IDForModel[modelA].Type;
01921     Enum::ModelType typeB = m_IDForModel[modelB].Type;
01922 
01923     // Clear FEMModel-FEMModel interactions
01924     if      (   typeA == Enum::MODEL_BASED_ON_FEM
01925             &&  typeB == Enum::MODEL_BASED_ON_FEM )
01926     {
01927         unsigned int locA = m_IDForModel[modelA].Slot;
01928         unsigned int locB = m_IDForModel[modelB].Slot;
01929         if ( locA > locB ) return;
01930         ClearAllConstraintsOfFEMModelAndFEMModel( locA, locB );
01931     }
01932     // Clear ERModel-FEMModel interactions
01933     else if (   typeA == Enum::MODEL_BASED_ON_ER
01934             &&  typeB == Enum::MODEL_BASED_ON_FEM )
01935     {
01936         unsigned int locA = m_IDForModel[modelA].Slot;
01937         unsigned int locB = m_IDForModel[modelB].Slot;
01938         ClearAllConstraintsOfERModelAndFEMModel( locA, locB );
01939     }
01940     // Clear RBDModel-FEMModel interactions
01941     else if (   typeA == Enum::MODEL_BASED_ON_IPG_RBD
01942             &&  typeB == Enum::MODEL_BASED_ON_FEM )
01943     {
01944         unsigned int locA = m_IDForModel[modelA].Slot;
01945         unsigned int locB = m_IDForModel[modelB].Slot;
01946         ClearAllConstraintsOfRBDModelAndFEMModel( locA, locB );
01947     }
01948 
01949 
01950 
01951     /*
01952     for ( unsigned int i = 0; i < m_InteractionLists.HEModelVsHEModel.size(); ++i ) {
01953         for ( unsigned int j = i; j < m_InteractionLists.HEModelVsHEModel.size(); ++j ) {
01954             ClearAllConstraintsOfFEMModelAndFEMModel
01955         }
01956     }
01957 
01958     // Clear ERModel-HEModel interactions
01959     for ( unsigned int i = 0; i < m_InteractionLists.ERModelVsHEModel.size(); ++i ) {
01960         for ( unsigned int j = 0; j < m_InteractionLists.ERModelVsHEModel[i].size(); ++j ) {
01961             ClearAllConstraintsOfERModelAndFEMModel
01962         }
01963     }
01964 
01965     // Clear IPGModel-HEModel interactions
01966     for ( unsigned int i = 0; i < m_InteractionLists.IPGModelVsHEModel.size(); ++i ) {
01967         for ( unsigned int j = 0; j < m_InteractionLists.IPGModelVsHEModel[i].size(); ++j ) {
01968             ClearAllConstraintsOfRBDModelAndFEMModel
01969         }
01970     }
01971     //*/
01972 }
01973 //-----------------------------------------------------------------------------
01974 template <typename T, typename DATA>
01975 void AdvSimSupport_DS<T,DATA>::ClearAllConstraintsOfFEMModelAndFEMModel ( unsigned int locA, unsigned int locB )
01976 {
01977     //*
01978     unsigned int i = m_InteractionLists.HEModelVsHEModel[locA][locB].Constraints.size();
01979     while ( i > 0 ) {
01980         ClearTheConstraintNumberOfFEMModelAndFEMModel( locA, locB, i-1 );
01981         i = m_InteractionLists.HEModelVsHEModel[locA][locB].Constraints.size();
01982     }
01983     //*/
01984     /*
01985     locB -= locA;   // since the data in the std::vector starts from 0, not from the model id
01986     AdvSimSupport_DATA<T,DATA>::InteractionConstraints_HEModelVsHEModel::iterator it = m_InteractionLists.HEModelVsHEModel[locA][locB].begin();
01987     while ( it != m_InteractionLists.HEModelVsHEModel[locA][locB].end() ) {
01988 
01989         //
01990 
01991         delete *it;
01992         ++it;
01993     }
01994     m_InteractionLists.HEModelVsHEModel[locA][locB].clear();
01995     //*/
01996 }
01997 //-----------------------------------------------------------------------------
01998 template <typename T, typename DATA>
01999 void AdvSimSupport_DS<T,DATA>::ClearAllConstraintsOfERModelAndFEMModel ( unsigned int ERloc, unsigned int FEMloc )
02000 {
02001     //*
02002     unsigned int i = m_InteractionLists.ERModelVsHEModel[ERloc][FEMloc].Constraints.size();
02003     while ( i > 0 ) {
02004         ClearTheConstraintNumberOfERModelAndFEMModel( ERloc, FEMloc, i-1 );
02005         i = m_InteractionLists.ERModelVsHEModel[ERloc][FEMloc].Constraints.size();
02006     }
02007     //*/
02008     /*
02009     AdvSimSupport_DATA<T,DATA>::InteractionConstraints_ERModelVsHEModel::iterator it = m_InteractionLists.ERModelVsHEModel[ERloc].Constraints[FEMloc].begin();
02010     while ( it != m_InteractionLists.ERModelVsHEModel[ERloc].Constraints[FEMloc].end() ) {
02011 
02012         // COMMENTED OUT BECAUSE IT CAUSES A RUN-TIME ERROR DURING THE EXIT OF THE PROGRAM
02013         // SO ALL OF THESE COMMENTED STATEMENTS BELOW ARE ADDED INTO ModelElasticRod's Reset().
02014         //m_ModelLists.BasedOnER[ERloc]->GetListOfNodes()[(*it)->GetVertexIDFromModel_1()].EnforcedPosition.Clear();
02015         //m_ModelLists.BasedOnER[ERloc]->GetListOfNodes()[(*it)->GetVertexIDFromModel_1()].UseEnforcedPosition = false;
02016         //m_ModelLists.BasedOnER[ERloc]->GetListOfNodes()[(*it)->GetVertexIDFromModel_1()].ExternalForce_ForAdvSimCtrl.Clear();
02017 
02018         delete *it;
02019         ++it;
02020     }
02021     m_InteractionLists.ERModelVsHEModel[ERloc][FEMloc].clear();
02022     //*/
02023 }
02024 //-----------------------------------------------------------------------------
02025 template <typename T, typename DATA>
02026 void AdvSimSupport_DS<T,DATA>::ClearAllConstraintsOfRBDModelAndFEMModel ( unsigned int RBDloc, unsigned int FEMloc )
02027 {
02028     //*
02029     unsigned int i = m_InteractionLists.IPGModelVsHEModel[RBDloc][FEMloc].Constraints.size();
02030     while ( i > 0 ) {
02031         ClearTheConstraintNumberOfRBDModelAndFEMModel( RBDloc, FEMloc, i-1 );
02032         i = m_InteractionLists.IPGModelVsHEModel[RBDloc][FEMloc].Constraints.size();
02033     }
02034     //*/
02035     /*
02036     AdvSimSupport_DATA<T,DATA>::InteractionConstraints_IPGModelVsHEModel::iterator it = m_InteractionLists.IPGModelVsHEModel[RBDloc].Constraints[FEMloc].begin();
02037     while ( it != m_InteractionLists.IPGModelVsHEModel[RBDloc].Constraints[FEMloc].end() ) {
02038         delete *it;
02039         ++it;
02040     }
02041     m_InteractionLists.IPGModelVsHEModel[RBDloc][FEMloc].clear();
02042     //*/
02043 }
02044 //-----------------------------------------------------------------------------
02045 template <typename T, typename DATA>
02046 void AdvSimSupport_DS<T,DATA>::ClearAContraintBetweenTwoModels ( unsigned int modelA, unsigned int modelB, unsigned int constraintNumber )
02047 {
02048     Enum::ModelType typeA = m_IDForModel[modelA].Type;
02049     Enum::ModelType typeB = m_IDForModel[modelB].Type;
02050 
02051     if      (   typeA == Enum::MODEL_BASED_ON_FEM
02052             &&  typeB == Enum::MODEL_BASED_ON_FEM )
02053     {
02054         unsigned int locA = m_IDForModel[modelA].Slot;
02055         unsigned int locB = m_IDForModel[modelB].Slot;
02056         if ( locA > locB ) return;
02057         ClearTheConstraintNumberOfFEMModelAndFEMModel( locA, locB, constraintNumber );
02058     }
02059     else if (   typeA == Enum::MODEL_BASED_ON_ER
02060             &&  typeB == Enum::MODEL_BASED_ON_FEM )
02061     {
02062         unsigned int locA = m_IDForModel[modelA].Slot;
02063         unsigned int locB = m_IDForModel[modelB].Slot;
02064         ClearTheConstraintNumberOfERModelAndFEMModel( locA, locB, constraintNumber );
02065     }
02066     else if (   typeA == Enum::MODEL_BASED_ON_IPG_RBD
02067             &&  typeB == Enum::MODEL_BASED_ON_FEM )
02068     {
02069         unsigned int locA = m_IDForModel[modelA].Slot;
02070         unsigned int locB = m_IDForModel[modelB].Slot;
02071         ClearTheConstraintNumberOfRBDModelAndFEMModel( locA, locB, constraintNumber );
02072     }
02073 }
02074 //-----------------------------------------------------------------------------
02075 template <typename T, typename DATA>
02076 void AdvSimSupport_DS<T,DATA>::ClearTheConstraintNumberOfFEMModelAndFEMModel ( unsigned int locA, unsigned int locB, unsigned int constraintNumber )
02077 {
02078     locB -= locA;   // since the data in the std::vector starts from 0, not from the model number
02079     if ( constraintNumber >= m_InteractionLists.HEModelVsHEModel[locA][locB].Constraints.size() )   return;
02080 
02081     AdvSimSupport_DATA<T,DATA>::InteractionConstraints_HEModelVsHEModel::iterator it = m_InteractionLists.HEModelVsHEModel[locA][locB].Constraints.begin() + constraintNumber;
02082 
02083     // Clear simulation related data
02084     (*it)->GetPtrToVertexFromModel_1()->SimFlags.ClearAllFlags();
02085     (*it)->GetPtrToVertexFromModel_2()->SimFlags.ClearAllFlags();
02086 
02087     // REMARK: The erased element's destructor is called before it is removed from the std::vector.
02088     // Therefore, calling the desctructor after the erase will generate a runtime error.
02089     m_InteractionLists.HEModelVsHEModel[locA][locB].Constraints.erase( it );
02090 }
02091 //-----------------------------------------------------------------------------
02092 template <typename T, typename DATA>
02093 void AdvSimSupport_DS<T,DATA>::ClearTheConstraintNumberOfERModelAndFEMModel ( unsigned int ERloc, unsigned int HEloc, unsigned int constraintNumber )
02094 {
02095     if ( constraintNumber >= m_InteractionLists.ERModelVsHEModel[ERloc][HEloc].Constraints.size() ) return;
02096 
02097     AdvSimSupport_DATA<T,DATA>::InteractionConstraints_ERModelVsHEModel::iterator it = m_InteractionLists.ERModelVsHEModel[ERloc][HEloc].Constraints.begin() + constraintNumber;
02098 
02099     // Clear simulation related data
02100     //m_ModelLists.BasedOnER[ERloc]->GetListOfNodes()[(*it)->GetVertexIDFromModel_1()].EnforcedPosition.Clear();
02101     //m_ModelLists.BasedOnER[ERloc]->GetListOfNodes()[(*it)->GetVertexIDFromModel_1()].UseEnforcedPosition = false;
02102     m_ModelLists.BasedOnER[ERloc]->GetListOfNodes()[(*it)->GetVertexIDFromModel_1()].ExternalForce_ForAdvSimCtrl.Clear();
02103     m_ModelLists.BasedOnER[ERloc]->GetListOfNodes()[(*it)->GetVertexIDFromModel_1()].SimFlags.ClearAllFlags();
02104     (*it)->GetPtrToVertexFromModel_2()->SimFlags.ClearAllFlags();
02105 
02106     // REMARK: The erased element's destructor is called before it is removed from the std::vector.
02107     // Therefore, calling the desctructor after the erase will generate a runtime error.
02108     m_InteractionLists.ERModelVsHEModel[ERloc][HEloc].Constraints.erase( it );
02109 }
02110 //-----------------------------------------------------------------------------
02111 template <typename T, typename DATA>
02112 void AdvSimSupport_DS<T,DATA>::ClearTheConstraintNumberOfRBDModelAndFEMModel ( unsigned int IPGloc, unsigned int HEloc, unsigned int constraintNumber )
02113 {
02114     if ( constraintNumber >= m_InteractionLists.IPGModelVsHEModel[IPGloc][HEloc].Constraints.size() )   return;
02115 
02116     AdvSimSupport_DATA<T,DATA>::InteractionConstraints_IPGModelVsHEModel::iterator it = m_InteractionLists.IPGModelVsHEModel[IPGloc][HEloc].Constraints.begin() + constraintNumber;
02117 
02118     // Clear simulation related data
02119     m_ModelLists.BasedOnRBD[IPGloc]->RefToInteractionPointGroup().GetInteractionPointAtIndex( (*it)->GetVertexIDFromModel_1() ).GetSimFlags().ClearAllFlags();
02120     (*it)->GetPtrToVertexFromModel_2()->SimFlags.ClearAllFlags();
02121 
02122     // REMARK: The erased element's destructor is called before it is removed from the std::vector.
02123     // Therefore, calling the desctructor after the erase will generate a runtime error.
02124     m_InteractionLists.IPGModelVsHEModel[IPGloc][HEloc].Constraints.erase( it );
02125 }
02126 //-----------------------------------------------------------------------------
02127 // Clear constraints
02128 //=============================================================================
02129 
02130 
02131 
02132 
02133 //-----------------------------------------------------------------------------
02134 template <typename T, typename DATA>
02135 void AdvSimSupport_DS<T,DATA>::AdvSimAllModels (
02136     T timestep,                         
02137     bool bEnforceAllConstraints,        
02138     bool bEnforceAllConsistentPositions 
02139 )
02140 {
02141     //static int ITERATE_LIMIT = 2;
02142     //for ( int iterate = 1; iterate >= ITERATE_LIMIT; ++iterate )
02143     {
02144 
02145         // Enforce all constraints
02146         if ( bEnforceAllConstraints ) {
02147             EnforceAllConstraints();
02148         }
02149 
02150         //for ( unsigned int i = 0; i < m_ListOfSutureModelsBasedOnMSS.size(); ++i ) {
02151         //  AdvSimSutureModelBasedOnMSS( i, timestep );
02152         //}
02153         //for ( unsigned int i = 0; i < m_ModelLists.ListOfModelsForSurgeryBasedOnMSS.size(); ++i ) {
02154         //  AdvSimModelForSurgeryBasedOnMSS( i, timestep );
02155         //}
02156 
02157         //const int NUM_OF_SUTURE_LOOPS = 1;
02158         for ( unsigned int i = 0; i < m_ModelLists.BasedOnER.size(); ++i ) {
02159             //for ( int s = 0; s < NUM_OF_SUTURE_LOOPS; ++s ) {
02160                 AdvSimModelBasedOnER( i, timestep );
02161             //}
02162         }
02163         for ( unsigned int i = 0; i < m_ModelLists.BasedOnFEM.size(); ++i ) {
02164             AdvSimModelBasedOnFEM( i, timestep );
02165         }
02166 
02167         if ( bEnforceAllConsistentPositions ) {
02168             EnforceAllConsistentPositions();
02169         }
02170     }
02171 
02172     // Update surface mesh models
02173     for ( unsigned int i = 0; i < m_ModelLists.BasedOnFEM.size(); ++i ) {
02174         m_ModelLists.BasedOnFEM[i]->UpdateSurfaceMeshNormals();
02175     }
02176 }
02177 //-----------------------------------------------------------------------------
02178 //template <typename T, typename DATA>
02179 //void AdvSimSupport_DS<T,DATA>::AdvSimSutureModelBasedOnMSS ( unsigned int sutureID, T timestep )
02180 //{
02181 //  m_ListOfSutureModelsBasedOnMSS[sutureID]->AdvanceSimulation( 0, timestep );
02182 //}
02183 //-----------------------------------------------------------------------------
02184 //template <typename T, typename DATA>
02185 //void AdvSimSupport_DS<T,DATA>::AdvSimModelForSurgeryBasedOnMSS ( unsigned int sutureID, T timestep )
02186 //{
02187 //  m_ModelLists.ListOfModelsForSurgeryBasedOnMSS[sutureID]->AdvanceSimulation( 0, timestep );
02188 //}
02189 //-----------------------------------------------------------------------------
02190 template <typename T, typename DATA>
02191 void AdvSimSupport_DS<T,DATA>::AdvSimModelBasedOnER ( unsigned int ERModelID, T timestep )
02192 {
02193     m_ModelLists.BasedOnER[ERModelID]->AdvanceSimulation();
02194 }
02195 //-----------------------------------------------------------------------------
02196 template <typename T, typename DATA>
02197 void AdvSimSupport_DS<T,DATA>::AdvSimModelBasedOnFEM ( unsigned int sutureID, T timestep )
02198 {
02199     m_ModelLists.BasedOnFEM[sutureID]->AdvanceSimulationDynamic();
02200 }
02201 //-----------------------------------------------------------------------------
02202 
02203 
02204 
02205 
02206 //=============================================================================
02207 #ifdef  TAPs_MODEL_SURGICAL_SUTURE_WITH_HEAD_NEEDLE_HPP
02208 //-----------------------------------------------------------------------------
02209 template <typename T, typename DATA>
02210 int AdvSimSupport_DS<T,DATA>::AddModelSutureWithHeadNeedle ( ModelSurgicalSutureWithHeadNeedle<T> * pModel )
02211 {
02212     // Add suture's head needle
02213     // Check whether the suture's head needle, which is an RBD-based model, is already added.
02214     bool bNotFound = true;
02215     int sutureHeadNeedleID = -1;
02216     for ( unsigned int i = 0; i < m_ModelLists.BasedOnRBD.size() && bNotFound; ++i ) {
02217         if ( m_ModelLists.BasedOnRBD[i] == &pModel->GetHeadNeedle() ) {
02218             bNotFound = false;
02219         }
02220     }
02221     if ( bNotFound )    sutureHeadNeedleID = AddModel( &pModel->GetHeadNeedle() );  // Add the suture's head needle as an RBD-based model
02222     else {
02223         for ( unsigned int i = 0; i < m_IDForModel.size(); ++i ) {
02224             if (    m_IDForModel[i].Type == Enum::MODEL_BASED_ON_IPG_RBD
02225                 &&  m_ModelLists.BasedOnRBD[m_IDForModel[i].Slot] == &pModel->GetHeadNeedle() )
02226             {
02227                 sutureHeadNeedleID = i;
02228                 break;
02229             }
02230         }
02231     }
02232 
02233     // Add suture's thread
02234     // Check whether the suture's thread, which is an ER-based model, is already added.
02235     bNotFound = true;
02236     int sutureThreadID = -1;
02237     for ( unsigned int i = 0; i < m_ModelLists.BasedOnER.size() && bNotFound; ++i ) {
02238         if ( m_ModelLists.BasedOnER[i] == pModel ) {
02239             bNotFound = false;
02240         }
02241     }
02242     if ( bNotFound )    sutureThreadID = AddModel( pModel );    // Add the suture's thread as an ER-based model
02243     else {
02244         for ( unsigned int i = 0; i < m_IDForModel.size(); ++i ) {
02245             if (    m_IDForModel[i].Type == Enum::MODEL_BASED_ON_ER
02246                 &&  m_ModelLists.BasedOnER[m_IDForModel[i].Slot] == pModel )
02247             {
02248                 sutureThreadID = i;
02249                 break;
02250             }
02251         }
02252     }
02253 
02254     // Add the set of contraints for this suture with head needle for interaction with HE-based models
02255     AdvSimConstraint_ForModelSurgicalSutureWithHeadNeedle<T> * pData = new 
02256         AdvSimConstraint_ForModelSurgicalSutureWithHeadNeedle<T>(
02257             pModel->GetHeadNeedle().RefToInteractionPointGroup().GetNumOfInteractionPoints(),
02258             pModel->RefToHeadNeedleCirclePathCtrl().InterpolatedPts.size(),
02259             sutureHeadNeedleID,
02260             sutureThreadID
02261         );
02262     m_ListOfInteraction_SwHDModelVsHEModel.push_back( pData );
02263 
02264     m_IDForHeadNeedlesInTheMainModelList.push_back( sutureHeadNeedleID );
02265 
02266     std::cout << *pData << "\n";
02267 
02268     return m_ListOfInteraction_SwHDModelVsHEModel.size()-1; // return the suture's head needle ID
02269 }
02270 //-----------------------------------------------------------------------------
02271 template <typename T, typename DATA>
02272 void AdvSimSupport_DS<T,DATA>::EnforceAllConstraintsOfSutureWithHeadNeedle ( unsigned int SwHDModel )
02273 {
02274     //std::cout << "m_InteractionLists.SwHDModelVsHEModel[SwHDModel]->EnforceAllConstraints\n";
02275     // For the head needle's IPG
02276     m_ListOfInteraction_SwHDModelVsHEModel[SwHDModel]->EnforceAllConstraints_ForIPG(
02277         m_IDForModel,               
02278         m_ModelLists.BasedOnER,     
02279         m_ModelLists.BasedOnFEM,    
02280         m_ModelLists.BasedOnRBD,    
02281         m_ListOfPointForces         
02282     );
02283     // For the head needle's circle path
02284     m_ListOfInteraction_SwHDModelVsHEModel[SwHDModel]->EnforceAllConstraints_ForCirclePath(
02285         m_IDForModel,               
02286         m_ModelLists.BasedOnER,     
02287         m_ModelLists.BasedOnFEM,    
02288         m_ModelLists.BasedOnRBD,    
02289         m_ListOfPointForces         
02290     );
02291 }
02292 //-----------------------------------------------------------------------------
02293 template <typename T, typename DATA>
02294 void AdvSimSupport_DS<T,DATA>::ClearAllConstraintsOfSutureWithHeadNeedle ( unsigned int SwHDModel )
02295 {
02296     //std::cout << "m_InteractionLists.SwHDModelVsHEModel[SwHDModel]->ClearAllConstraints\n";
02297 
02298     // For both of the head needle's IPG and circle path
02299     m_ListOfInteraction_SwHDModelVsHEModel[SwHDModel]->ResetPunctureController();
02300     // For the head needle's IPG
02301     m_ListOfInteraction_SwHDModelVsHEModel[SwHDModel]->ClearAllConstraints_ForIPG();
02302     // For the head needle's circle path
02303     m_ListOfInteraction_SwHDModelVsHEModel[SwHDModel]->ClearAllConstraints_ForCirclePath();
02304 }
02305 //-----------------------------------------------------------------------------
02306 template <typename T, typename DATA>
02307 HEVertex<T> * AdvSimSupport_DS<T,DATA>::ProcessPuncturingOfSwHDRepresentedByIPGToHEModel (
02308     unsigned int SwHDModel, 
02309     unsigned int HEModel,   
02310     bool & bPunctureIn,     
02311     bool & bPunctureOut,    
02312     bool & bAborted,        
02313     std::string * info      
02314 )
02315 {
02316     HEVertex<T> * pHEVertex = NULL;
02317     Enum::ModelType IPGType = m_IDForModel[m_IDForHeadNeedlesInTheMainModelList[SwHDModel]].Type;
02318     Enum::ModelType HEType  = m_IDForModel[HEModel].Type;
02319     if (    IPGType == Enum::MODEL_BASED_ON_IPG_RBD 
02320         &&  HEType  == Enum::MODEL_BASED_ON_FEM ) {
02321         pHEVertex = m_ListOfInteraction_SwHDModelVsHEModel[SwHDModel]->ProcessPuncturingOfHeadNeedleRepresentedByIPGWithFEMModel( 
02322             HEModel,
02323             m_IDForModel,
02324             m_ModelLists,
02325             m_InteractionLists.ERModelVsHEModel,
02326             bPunctureIn,
02327             bPunctureOut,
02328             bAborted
02329         );
02330 
02331         if ( info ) {
02332             *info = m_ListOfInteraction_SwHDModelVsHEModel[SwHDModel]->GetPunctureControllerCurrentInfo();
02333         }
02334     }
02335     else {
02336         PrtNotImplementedYet( "Supported only IPGType == Enum::MODEL_BASED_ON_IPG_RBD and HEType == Enum::MODEL_BASED_ON_FEM" );
02337     }
02338     return pHEVertex;
02339 }
02340 //-----------------------------------------------------------------------------
02341 template <typename T, typename DATA>
02342 HEVertex<T> * AdvSimSupport_DS<T,DATA>::ProcessPuncturingOfSwHDUsingCirclePathToHEModel (
02343     typename ModelSurgicalSutureWithHeadNeedle<T>::CirclePath & CirclePathCtrl, 
02344     unsigned int SwHDModel, 
02345     unsigned int HEModel,   
02346     bool & bPunctureIn,     
02347     bool & bPunctureOut,    
02348     bool & bAborted,        
02349     bool & bSuccess         
02350 )
02351 {
02352     HEVertex<T> * pHEVertex = NULL;
02353     Enum::ModelType IPGType = m_IDForModel[m_IDForHeadNeedlesInTheMainModelList[SwHDModel]].Type;
02354     Enum::ModelType HEType  = m_IDForModel[HEModel].Type;
02355     if (    IPGType == Enum::MODEL_BASED_ON_IPG_RBD 
02356         &&  HEType  == Enum::MODEL_BASED_ON_FEM ) {
02357         pHEVertex = m_ListOfInteraction_SwHDModelVsHEModel[SwHDModel]->ProcessPuncturingOfHeadNeedleUsingCirclePathWithFEMModel( 
02358             CirclePathCtrl,
02359             HEModel,
02360             m_IDForModel,
02361             m_ModelLists,
02362             m_InteractionLists.ERModelVsHEModel,
02363             bPunctureIn,
02364             bPunctureOut,
02365             bAborted,
02366             bSuccess
02367         );
02368     }
02369     else {
02370         PrtNotImplementedYet( "Supported only IPGType == Enum::MODEL_BASED_ON_IPG_RBD and HEType == Enum::MODEL_BASED_ON_FEM" );
02371     }
02372     return pHEVertex;
02373 }
02374 //-----------------------------------------------------------------------------
02375 template <typename T, typename DATA>
02376 HEVertex<T> * AdvSimSupport_DS<T,DATA>::ProcessPuncturingOfSwHDUsingCirclePathToHEModel_MoreAccuButUnfinishYet (
02377     typename ModelSurgicalSutureWithHeadNeedle<T>::CirclePath & CirclePathCtrl, 
02378     unsigned int SwHDModel, 
02379     unsigned int HEModel,   
02380     bool & bPunctureIn,     
02381     bool & bPunctureOut,    
02382     bool & bAborted         
02383 )
02384 {
02385     HEVertex<T> * pHEVertex = NULL;
02386     Enum::ModelType IPGType = m_IDForModel[m_IDForHeadNeedlesInTheMainModelList[SwHDModel]].Type;
02387     Enum::ModelType HEType  = m_IDForModel[HEModel].Type;
02388     if (    IPGType == Enum::MODEL_BASED_ON_IPG_RBD 
02389         &&  HEType  == Enum::MODEL_BASED_ON_FEM ) {
02390         pHEVertex = m_ListOfInteraction_SwHDModelVsHEModel[SwHDModel]->ProcessPuncturingOfHeadNeedleUsingCirclePathWithFEMModel_MoreAccuButUnfinishYet( 
02391             CirclePathCtrl,
02392             HEModel,
02393             m_IDForModel,
02394             m_ModelLists,
02395             m_InteractionLists.ERModelVsHEModel,
02396             bPunctureIn,
02397             bPunctureOut,
02398             bAborted
02399         );
02400     }
02401     else {
02402         PrtNotImplementedYet( "Supported only IPGType == Enum::MODEL_BASED_ON_IPG_RBD and HEType == Enum::MODEL_BASED_ON_FEM" );
02403     }
02404     return pHEVertex;
02405 }
02406 //-----------------------------------------------------------------------------
02407 #endif//TAPs_MODEL_SURGICAL_SUTURE_WITH_HEAD_NEEDLE_HPP
02408 //=============================================================================
02409 
02410 
02411 
02412 
02413 //=============================================================================
02414 #if defined(__gl_h_) || defined(__GL_H__)
02415 //-----------------------------------------------------------------------------
02416 template <typename T, typename DATA>
02417 void AdvSimSupport_DS<T,DATA>::DrawAllModels ()
02418 {
02419     //std::vector< OpenGL::ModelSuture<T> * >::iterator A = m_ListOfSutureModelsBasedOnMSS.begin();
02420     //while ( A != m_ListOfSutureModelsBasedOnMSS.end() ) {
02421     //  (*A)->Draw();
02422     //  ++A;
02423     //}
02424     //std::vector< ModelForSurgery<T> * >::iterator B = m_ModelLists.ListOfModelsForSurgeryBasedOnMSS.begin();
02425     //while ( B != m_ModelLists.ListOfModelsForSurgeryBasedOnMSS.end() ) {
02426     //  (*B)->Draw();
02427     //  ++B;
02428     //}
02429     std::vector< ModelElasticRod<T> * >::iterator C = m_ModelLists.BasedOnER.begin();
02430     while ( C != m_ModelLists.BasedOnER.end() ) {
02431         (*C)->Draw();
02432         ++C;
02433     }
02434     std::vector< ModelDefBasedOnFEM<T,DATA> * >::iterator D = m_ModelLists.BasedOnFEM.begin();
02435     while ( D != m_ModelLists.BasedOnFEM.end() ) {
02436         (*D)->Draw();
02437         ++D;
02438     }
02439 }
02440 //-----------------------------------------------------------------------------
02441 template <typename T, typename DATA>
02442 void AdvSimSupport_DS<T,DATA>::DrawAddedInteractions ()
02443 {
02444     // Draw model-model interactions
02445     for ( unsigned int i = 0; i < GetNumberOfTotalModels(); ++i ) {
02446         for ( unsigned int j = 0; j < GetNumberOfTotalModels(); ++j ) {
02447             DrawAddedInteractionsBetweenTwoModels( i, j );
02448         }
02449     }
02450 
02451     // DEBUG
02452     #ifdef  TAPs_MODEL_SURGICAL_SUTURE_WITH_HEAD_NEEDLE_HPP
02453     m_ListOfInteraction_SwHDModelVsHEModel[0]->Draw();
02454     #endif//TAPs_MODEL_SURGICAL_SUTURE_WITH_HEAD_NEEDLE_HPP
02455 }
02456 //-----------------------------------------------------------------------------
02457 template <typename T, typename DATA>
02458 void AdvSimSupport_DS<T,DATA>::DrawAddedInteractionsBetweenTwoModels ( unsigned int modelA, unsigned int modelB )
02459 {
02460     Enum::ModelType typeA = m_IDForModel[modelA].Type;
02461     Enum::ModelType typeB = m_IDForModel[modelB].Type;
02462     if      (   typeA == Enum::MODEL_BASED_ON_FEM
02463             &&  typeB == Enum::MODEL_BASED_ON_FEM )
02464     {
02465         unsigned int locA = m_IDForModel[modelA].Slot;
02466         unsigned int locB = m_IDForModel[modelB].Slot;
02467         if ( locA > locB ) return;
02468         DrawAddedInteractionsBetweenFEMModelAndFEMModel( locA, locB );
02469     }
02470     else if (   typeA == Enum::MODEL_BASED_ON_ER
02471             &&  typeB == Enum::MODEL_BASED_ON_FEM )
02472     {
02473         unsigned int locA = m_IDForModel[modelA].Slot;
02474         unsigned int locB = m_IDForModel[modelB].Slot;
02475         DrawAddedInteractionsBetweenERModelAndFEMModel( locA, locB );
02476     }
02477     else if (   typeA == Enum::MODEL_BASED_ON_IPG_RBD
02478             &&  typeB == Enum::MODEL_BASED_ON_FEM )
02479     {
02480         unsigned int locA = m_IDForModel[modelA].Slot;
02481         unsigned int locB = m_IDForModel[modelB].Slot;
02482         DrawAddedInteractionsBetweenRBDModelAndFEMModel( locA, locB );
02483     }
02484 }
02485 //-----------------------------------------------------------------------------
02486 template <typename T, typename DATA>
02487 void AdvSimSupport_DS<T,DATA>::DrawAddedInteractionsBetweenFEMModelAndFEMModel ( unsigned int locA, unsigned int locB )
02488 {
02489     glPushAttrib( GL_ALL_ATTRIB_BITS );
02490     glDisable( GL_LIGHTING );
02491     glLineWidth( 2 );
02492     glPointSize( 5 );
02493     GLfloat V[2][3];
02494 
02495     Matrix4x4<T> Trx1 = m_ModelLists.BasedOnFEM[locA]->RefToTransformationSupport().RefToMatrixTransform();
02496     Matrix4x4<T> Trx2 = m_ModelLists.BasedOnFEM[locB]->RefToTransformationSupport().RefToMatrixTransform();
02497 
02498     locB -= locA;   // since the data in the std::vector starts from 0, not from the model id
02499     AdvSimSupport_DATA<T,DATA>::InteractionConstraints_HEModelVsHEModel::iterator it = m_InteractionLists.HEModelVsHEModel[locA][locB].Constraints.begin();
02500     while ( it != m_InteractionLists.HEModelVsHEModel[locA][locB].Constraints.end() ) {
02501         Vector3<T> v1 = (Trx1 * Vector4<T>( (*it)->GetPtrToVertexFromModel_1()->GetPosition() ) ).GetVector3();
02502         Vector3<T> v2 = (Trx2 * Vector4<T>( (*it)->GetPtrToVertexFromModel_2()->GetPosition() ) ).GetVector3();
02503         V[0][0] = v1[0];    V[0][1] = v1[1];    V[0][2] = v1[2];
02504         V[1][0] = v2[0];    V[1][1] = v2[1];    V[1][2] = v2[2];
02505         glBegin( GL_POINTS );
02506             glColor3f( 0.3f, 0.7f, 0.2f );
02507             glVertex3fv( V[0] );
02508             glVertex3fv( V[1] );
02509             glColor3f( 1.0f, 1.0f, 0.0f );
02510             glVertex3fv( (Trx1*Vector4<T>((*it)->RefToTargetPositionA())).GetVector3().GetDataFloat() );
02511             glColor3f( 1.0f, 0.0f, 1.0f );
02512             glVertex3fv( (Trx2*Vector4<T>((*it)->RefToTargetPositionB())).GetVector3().GetDataFloat() );
02513         glEnd();
02514         glBegin( GL_LINES );
02515             glColor3f( 0.3f, 0.7f, 0.5f );
02516             glVertex3fv( V[0] );
02517             glVertex3fv( V[1] );
02518         glEnd();
02519         ++it;
02520     }
02521     glPopAttrib();
02522 }
02523 //-----------------------------------------------------------------------------
02524 template <typename T, typename DATA>
02525 void AdvSimSupport_DS<T,DATA>::DrawAddedInteractionsBetweenERModelAndFEMModel ( unsigned int ERloc, unsigned int FEMloc )
02526 {
02527     glPushAttrib( GL_ALL_ATTRIB_BITS );
02528     glDisable( GL_LIGHTING );
02529     glLineWidth( 2 );
02530     glPointSize( 5 );
02531     GLfloat V[2][3];
02532     
02533     Matrix4x4<T> Trx = m_ModelLists.BasedOnFEM[FEMloc]->RefToTransformationSupport().RefToMatrixTransform();
02534 
02535     AdvSimSupport_DATA<T,DATA>::InteractionConstraints_ERModelVsHEModel::iterator it = m_InteractionLists.ERModelVsHEModel[ERloc][FEMloc].Constraints.begin();
02536     while ( it != m_InteractionLists.ERModelVsHEModel[ERloc][FEMloc].Constraints.end() ) {
02537         Vector3<T> v1 = m_ModelLists.BasedOnER[ERloc]->RefToCurrentVertexPositionOfNodeNumber( (*it)->GetVertexIDFromModel_1() );
02538         Vector3<T> v2 = (Trx * Vector4<T>( (*it)->GetPtrToVertexFromModel_2()->GetPosition() ) ).GetVector3();
02539         V[0][0] = v1[0];    V[0][1] = v1[1];    V[0][2] = v1[2];
02540         V[1][0] = v2[0];    V[1][1] = v2[1];    V[1][2] = v2[2];
02541         glBegin( GL_POINTS );
02542             glColor3f( 0.3f, 0.7f, 0.2f );
02543             glVertex3fv( V[0] );
02544             glVertex3fv( V[1] );
02545             glColor3f( 1.0f, 1.0f, 0.0f );
02546             glVertex3fv( (*it)->RefToTargetPositionA().GetDataFloat() );
02547             glColor3f( 1.0f, 0.0f, 1.0f );
02548             glVertex3fv( (Trx*Vector4<T>((*it)->RefToTargetPositionB())).GetVector3().GetDataFloat() );
02549         glEnd();
02550         glBegin( GL_LINES );
02551             glColor3f( 0.3f, 0.7f, 0.5f );
02552             glVertex3fv( V[0] );
02553             glVertex3fv( V[1] );
02554         glEnd();
02555         ++it;
02556     }
02557     glPopAttrib();
02558 }
02559 //-----------------------------------------------------------------------------
02560 template <typename T, typename DATA>
02561 void AdvSimSupport_DS<T,DATA>::DrawAddedInteractionsBetweenRBDModelAndFEMModel ( unsigned int RBDloc, unsigned int FEMloc )
02562 {
02563     glPushAttrib( GL_ALL_ATTRIB_BITS );
02564     glDisable( GL_LIGHTING );
02565     glLineWidth( 2 );
02566     glPointSize( 15 );
02567     GLfloat V[2][3];
02568 
02569     Matrix4x4<T> TrxRBD = m_ModelLists.BasedOnRBD[RBDloc]->CalMatrixTransform();
02570     Matrix4x4<T> TrxFEM = m_ModelLists.BasedOnFEM[FEMloc]->RefToTransformationSupport().RefToMatrixTransform();
02571 
02572     AdvSimSupport_DATA<T,DATA>::InteractionConstraints_IPGModelVsHEModel::iterator it = m_InteractionLists.IPGModelVsHEModel[RBDloc][FEMloc].Constraints.begin();
02573     while ( it != m_InteractionLists.IPGModelVsHEModel[RBDloc][FEMloc].Constraints.end() ) {
02574         Vector3<T> v1 = (TrxRBD * Vector4<T>( m_ModelLists.BasedOnRBD[RBDloc]->RefToInteractionPointGroup().GetInteractionPointAtIndex( (*it)->GetVertexIDFromModel_1() ).GetPosition() ) ).GetVector3();
02575         Vector3<T> v2 = (TrxFEM * Vector4<T>( (*it)->GetPtrToVertexFromModel_2()->GetPosition() ) ).GetVector3();
02576         V[0][0] = v1[0];    V[0][1] = v1[1];    V[0][2] = v1[2];
02577         V[1][0] = v2[0];    V[1][1] = v2[1];    V[1][2] = v2[2];
02578         glBegin( GL_POINTS );
02579             glColor3f( 0.3f, 0.7f, 0.2f );
02580             //glVertex3fv( V[0] );
02581             glColor3f( 0.7f, 0.3f, 0.2f );
02582             glVertex3fv( V[1] );
02583             glColor3f( 1.0f, 1.0f, 0.0f );
02584             //glVertex3fv( (TrxRBD*Vector4<T>((*it)->RefToTargetPositionA())).GetVector3().GetDataFloat() );
02585             glColor3f( 1.0f, 0.0f, 1.0f );
02586             //glVertex3fv( (TrxFEM*Vector4<T>((*it)->RefToTargetPositionB())).GetVector3().GetDataFloat() );
02587         glEnd();
02588         glBegin( GL_LINES );
02589             glColor3f( 0.3f, 0.7f, 0.5f );
02590             glVertex3fv( V[0] );
02591             glVertex3fv( V[1] );
02592         glEnd();
02593         ++it;
02594     }
02595     glPopAttrib();
02596 }
02597 //-----------------------------------------------------------------------------
02598 #endif  // #if defined(__gl_h_) || defined(__GL_H__)
02599 //=============================================================================
02600 
02601 //=============================================================================
02602 END_NAMESPACE_TAPs
02603 //34567890123456789012345678901234567890123456789012345678901234567890123456789
02604 //--+----1----+----2----+----3----+----4----+----5----+----6----+----7----+----
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines