![]() |
TAPs 0.7.7.3
|
00001 /****************************************************************************** 00002 TAPsSimPropForMultiPartMeshModel_HalfEdge.cpp 00003 00004 SimPropForMultiPartMeshModel_HalfEdge class (cpp file). 00005 00006 SUKITTI PUNAK (07/25/2008) 00007 UPDATE (10/07/2009) 00008 ******************************************************************************/ 00009 #include "TAPsSimPropForMultiPartMeshModel_HalfEdge.hpp" 00010 // Using Inclusion Model (i.e. definitions are included in declarations) 00011 // (this name.cpp is included in name.hpp) 00012 // Each friend is defined directly inside its declaration. 00013 00014 BEGIN_NAMESPACE_TAPs 00015 //============================================================================= 00016 //----------------------------------------------------------------------------- 00017 00018 //----------------------------------------------------------------------------- 00020 template <typename T> 00021 SimPropForMultiPartMeshModel_HalfEdge<T>::SimPropForMultiPartMeshModel_HalfEdge ( 00022 T massOfPoint, 00023 T springStiffness, 00024 T springDamper, 00025 TAPs::Enum::ModelType modelType, 00026 T predefinedTimeStep, 00027 int numSimSubSteps, 00028 bool enableColDet, 00029 bool enableSimulation 00030 ) 00031 : SimPropForMultiPartMeshModel<T>( 00032 springStiffness, 00033 springDamper, 00034 massOfPoint, 00035 modelType, 00036 predefinedTimeStep, 00037 numSimSubSteps, 00038 enableColDet, 00039 enableSimulation 00040 ) 00041 , m_prODESolver( NULL ) 00042 #ifdef TAPs_USE_CUDA 00043 , m_cudaVertexList( NULL ) 00044 #endif TAPs_USE_CUDA 00045 {} 00046 00047 /* 00048 //----------------------------------------------------------------------------- 00050 template <typename T> 00051 SimPropForMultiPartMeshModel_HalfEdge<T>::SimPropForMultiPartMeshModel_HalfEdge ( 00052 SimPropForMultiPartMeshModel_HalfEdge<T> const &obj ) 00053 { 00054 // Inherited Variables 00055 m_tKStiffness = obj.m_tKStiffness; 00056 m_tKDamper = obj.m_tKDamper; 00057 m_tPtMass = obj.m_tPtMass; 00058 m_bColDetOn = obj.m_bColDetOn; 00059 m_bSimOn = obj.m_bSimOn; 00060 00061 // Local Variables 00062 m_vpSpringRef = obj.m_vpSpringRef; 00063 m_HEVertexPtrList = obj.m_HEVertexPtrList; 00064 00065 // SKIP ALL OF THESE VARIABLES 00066 //=============================================================== 00067 // For simulation by ODE solver 00068 //--------------------------------------------------------------- 00069 //TAPs::Simulation::ODESolver<T> * m_prODESolver; //!< ODE solver 00070 //Simulation::VectorSet<T> * x0; //!< pointer to x0 Data 00071 //Simulation::VectorSet<T> * xEnd; //!< pointer to xEnd Data 00072 //Simulation::VectorSet<T> xData_1; //!< temp data with size of m_iStateSize * 6 00073 //Simulation::VectorSet<T> xData_2; //!< temp data with size of m_iStateSize * 6 00074 //int m_iStateSize; //!< #Mass Points (#mesh vertices) where 6 = 3 positions + 3 velocities (for x,y,z) 00075 //int m_iLimitStepCount; //!< Limit step count 00076 00077 m_tPredefinedTimeStep = obj.m_tPredefinedTimeStep; 00078 m_iNumSimSubSteps = obj.m_iNumSimSubSteps; 00079 00080 TEST(); 00081 #ifdef TAPs_USE_CUDA 00082 CUDA_Initialize(); 00083 #endif//TAPs_USE_CUDA 00084 } 00085 //*/ 00086 00087 //----------------------------------------------------------------------------- 00089 template <typename T> 00090 SimPropForMultiPartMeshModel_HalfEdge<T>::~SimPropForMultiPartMeshModel_HalfEdge () 00091 { 00092 if ( m_prODESolver ) delete m_prODESolver; 00093 00094 #ifdef TAPs_USE_CUDA 00095 CUDA_Cleanup(); 00096 #endif//TAPs_USE_CUDA 00097 } 00098 00099 //----------------------------------------------------------------------------- 00101 template <typename T> 00102 std::string SimPropForMultiPartMeshModel_HalfEdge<T>::StrInfo () const 00103 { 00104 std::ostringstream ss; 00105 ss << "SimPropForMultiPartMeshModel_HalfEdge<" << typeid(T).name() << "> ==>" 00106 << " Spring Stiffness(" << m_tKStiffness 00107 << ") Damper(" << m_tKDamper 00108 << ") Mass of Point (" << m_tPtMass 00109 << ") Collision Detection ("; 00110 if ( m_bColDetOn ) ss << "On"; 00111 else ss << "Off"; 00112 ss << ") Simulation ("; 00113 if ( m_bSimOn ) ss << "On"; 00114 else ss << "Off"; 00115 ss << ".\n"; 00116 return ss.str(); 00117 } 00118 00119 /* 00120 //----------------------------------------------------------------------------- 00122 template <typename T> 00123 SimPropForMultiPartMeshModel_HalfEdge<T> & SimPropForMultiPartMeshModel_HalfEdge<T>::operator= ( 00124 SimPropForMultiPartMeshModel_HalfEdge<T> const &obj ) 00125 { 00126 m_tKStiffness = obj.m_tKStiffness; 00127 m_tKDamper = obj.m_tKDamper; 00128 m_tPtMass = obj.m_tPtMass; 00129 m_bColDetOn = obj.m_bColDetOn; 00130 m_bSimOn = obj.m_bSimOn; 00131 00132 return *this; 00133 } 00134 //*/ 00135 00136 //----------------------------------------------------------------------------- 00137 // DxDt 00138 template <typename T> 00139 bool SimPropForMultiPartMeshModel_HalfEdge<T>::DxDt ( 00140 T dt, // I/P: time step 00141 Simulation::VectorSet<T> & x, // I/p: array x = {pos, vel} 00142 Simulation::VectorSet<T> & xdot, // O/P: array xdot = {vel, accel} 00143 void * userData // O/P: array of user data 00144 ) 00145 { 00146 //----------------------------------------------------- 00147 // Convert userData ptr to ModelStrand ptr 00148 SimPropForMultiPartMeshModel_HalfEdge<T> *pThis = static_cast<SimPropForMultiPartMeshModel_HalfEdge<T> *>( userData ); 00149 assert( pThis ); 00150 pThis->ClearAllForces(); 00151 //----------------------------------------------------- 00152 // Calculate and Set Spring Forces 00153 for ( int i = 0; i < static_cast<int>( pThis->m_vpSpringRef.size() ); ++i ) { 00154 pThis->m_vpSpringRef[i]->CalAndSetForce(); 00155 } 00156 //----------------------------------------------------- 00157 pThis->DdtStateToArray( &xdot[0], dt ); 00158 //----------------------------------------------------- 00159 return true; 00160 } 00161 00162 //----------------------------------------------------------------------------- 00163 // StateToArray 00164 template <typename T> 00165 void SimPropForMultiPartMeshModel_HalfEdge<T>::StateToArray ( T *dst ) 00166 { 00167 for ( int i = 0; i < m_iStateSize; ++i ) { 00168 *(dst++) = m_HEVertexPtrList[i]->GetParticleRef()->GetPosition()[0]; 00169 *(dst++) = m_HEVertexPtrList[i]->GetParticleRef()->GetPosition()[1]; 00170 *(dst++) = m_HEVertexPtrList[i]->GetParticleRef()->GetPosition()[2]; 00171 *(dst++) = m_HEVertexPtrList[i]->GetParticleRef()->GetVelocity()[0]; 00172 *(dst++) = m_HEVertexPtrList[i]->GetParticleRef()->GetVelocity()[1]; 00173 *(dst++) = m_HEVertexPtrList[i]->GetParticleRef()->GetVelocity()[2]; 00174 } 00175 } 00176 00177 //----------------------------------------------------------------------------- 00178 // ArrayToState 00179 template <typename T> 00180 void SimPropForMultiPartMeshModel_HalfEdge<T>::ArrayToState ( T *src ) 00181 { 00182 for ( int i = 0; i < m_iStateSize; ++i ) { 00183 m_HEVertexPtrList[i]->GetParticleRef()->SetPosition( *src, *(src+1), *(src+2) ); 00184 src += 3; 00185 m_HEVertexPtrList[i]->GetParticleRef()->SetVelocity( *src, *(src+1), *(src+2) ); 00186 src += 3; 00187 } 00188 } 00189 00190 //----------------------------------------------------------------------------- 00191 // DdtStateToArray 00192 template <typename T> 00193 void SimPropForMultiPartMeshModel_HalfEdge<T>::DdtStateToArray ( T *xdot, T dt ) 00194 { 00195 for ( int i = 0; i < m_iStateSize; ++i ) { 00196 if ( m_HEVertexPtrList[i]->GetParticleRef()->GetFixStatus() ) { 00197 *(xdot++) = 00198 *(xdot++) = 00199 *(xdot++) = 00200 *(xdot++) = 00201 *(xdot++) = 00202 *(xdot++) = 0; 00203 } 00204 else { 00205 //m_prForce[i] = m_StructForce[i].gravity; 00206 //m_prVelocity[i][1] = m_prForce[i][1] * m_prVertex[i][1] * dt; 00207 //---------------------------------------- 00208 *(xdot++) = m_HEVertexPtrList[i]->GetParticleRef()->GetVelocity()[0]; 00209 *(xdot++) = m_HEVertexPtrList[i]->GetParticleRef()->GetVelocity()[1]; 00210 *(xdot++) = m_HEVertexPtrList[i]->GetParticleRef()->GetVelocity()[2]; 00211 *(xdot++) = m_HEVertexPtrList[i]->GetParticleRef()->GetForce()[0]; 00212 *(xdot++) = m_HEVertexPtrList[i]->GetParticleRef()->GetForce()[1]; 00213 *(xdot++) = m_HEVertexPtrList[i]->GetParticleRef()->GetForce()[2]; 00214 } 00215 } 00216 } 00217 00218 //----------------------------------------------------------------------------- 00219 // ClearForces 00220 template <typename T> 00221 void SimPropForMultiPartMeshModel_HalfEdge<T>::ClearAllForces () 00222 { 00223 for ( int i = 0; i < static_cast<int>( m_HEVertexPtrList.size() ); ++i ) { 00224 m_HEVertexPtrList[i]->GetParticleRef()->SetForce( 0, 0, 0 ); 00225 m_HEVertexPtrList[i]->GetHomeParticle().SetForce( 0, 0, 0 ); 00226 } 00227 } 00228 00229 //----------------------------------------------------------------------------- 00230 // SetODESolver 00231 template <typename T> 00232 bool SimPropForMultiPartMeshModel_HalfEdge<T>::SetODESolver ( 00233 TAPs::Enum::ODESolver solverMethod ) 00234 { 00235 // Delete the current ODE solver 00236 if ( m_prODESolver ) delete m_prODESolver; 00237 00238 bool result = true; 00239 //--------------------------------------------------------------- 00240 // For Simulation 00241 switch ( solverMethod ) { 00242 case TAPs::Enum::EULER: 00243 if ( ( m_prODESolver = new Simulation::ODESolverEuler<T>() ) == NULL ) { 00244 result = false; 00245 } 00246 break; 00247 case TAPs::Enum::MIDPOINT: 00248 if ( ( m_prODESolver = new Simulation::ODESolverMidpoint<T>() ) == NULL ) { 00249 result = false; 00250 } 00251 break; 00252 case TAPs::Enum::RUNGE_KUTTA_4: 00253 if ( ( m_prODESolver = new Simulation::ODESolverRungeKutta4<T>() ) == NULL ) { 00254 result = false; 00255 } 00256 break; 00257 default: 00258 result = false; 00259 break; 00260 } 00261 00262 if ( result ) { 00263 m_iStateSize = static_cast<int>( m_HEVertexPtrList.size() ); 00264 int size = m_iStateSize * 6; 00265 m_prODESolver->SetSize( size ); 00266 x0 = &xData_1; 00267 xEnd = &xData_2; 00268 x0->resize( size ); 00269 xEnd->resize( size ); 00270 StateToArray( &(*xEnd)[0] ); 00271 } 00272 else { 00273 #ifdef TAPs_ENABLE_DEBUG 00274 std::cerr << "ERROR => HETriMeshOneModelMultiParts Constructor:" 00275 << " Cannot allocate memory for an ODE solver!" 00276 << std::endl; 00277 #endif 00278 delete this; 00279 } 00280 00281 return result; 00282 } 00283 00284 //----------------------------------------------------------------------------- 00285 // AdvSim 00286 template <typename T> 00287 void SimPropForMultiPartMeshModel_HalfEdge<T>::AdvSim ( T tCurrent, T tNext ) 00288 { 00289 if ( IsSimOn() == false ) return; 00290 00291 switch ( GetModelType() ) { 00292 case TAPs::Enum::MODEL_DEFORM: 00293 //std::cout << "\tMODEL_DEFORM\n"; 00294 //break; 00295 00296 #ifdef TAPs_USE_CUDA 00297 CUDA_CopyVertexToMem(); 00298 TAPs::CUDA::Global__SimPropForMultiPartMeshModel_HalfEdge_AdvSim( 00299 m_HEVertexPtrList.size(), 00300 64, 00301 tCurrent, tNext, 00302 m_cudaVertexList 00303 ); 00304 CUDA_CopyMemToVertex(); 00305 #else //TAPs_USE_CUDA 00306 { 00307 T tSubStepTime = ( tNext - tCurrent ) / m_iNumSimSubSteps; 00308 tNext = tCurrent + tSubStepTime; 00309 for ( int i = 0; i < m_iNumSimSubSteps; ++i ) 00310 { 00311 //----------------------------------------------------- 00312 // Swap pointers 00313 Simulation::VectorSet<T> * tmpPtr = x0; 00314 x0 = xEnd; 00315 xEnd = tmpPtr; 00316 //----------------------------------------------------- 00317 // ODE Solver 00318 m_prODESolver->Solve( *x0, *xEnd, tCurrent, tNext, DxDt, this ); 00319 //----------------------------------------------------- 00320 // Copy xEnd to object state (position and velocity of particles) 00321 ArrayToState( &(*xEnd)[0] ); 00322 //----------------------------------------------------- 00323 //SimGravity( tCurrent, tNext ); 00324 //----------------------------------------------------- 00325 //GetBVHTree()->Update(); 00326 //CalAndSetNormals(); 00327 tCurrent = tNext; 00328 tNext += tSubStepTime; 00329 } 00330 } 00331 #endif//TAPs_USE_CUDA 00332 break; 00333 00334 case TAPs::Enum::MODEL_DEFORM_ELASTIC: 00335 //std::cout << "\tMODEL_DEFORM_ELASTIC\n"; 00336 //break; 00337 { 00338 std::vector< HEVertexPtrWithExtraInfo<T> * >::iterator pos = m_HEVertexPtrList.begin(); 00339 while ( pos != m_HEVertexPtrList.end() ) { 00340 //(*pos)->SetHomePosition( (*pos)->GetHomePosition() + Vector3<T>(0,0,-0.001) ); 00341 (*pos)->GetParticleRef()->SetPosition( (*pos)->GetHomePosition() ); 00342 ++pos; 00343 } 00344 } 00345 break; 00346 case TAPs::Enum::MODEL_DEFORM_PLASTIC: 00347 std::cout << "\tMODEL_DEFORM_PLASTIC -- NOT IMPLEMENTED YET\n"; 00348 break; 00349 case TAPs::Enum::MODEL_RIGID: 00350 std::cout << "\tMODEL_RIGID -- NOT IMPLEMENTED YET\n"; 00351 break; 00352 case TAPs::Enum::MODEL_FIXED: 00353 std::cout << "\tMODEL_FIXED -- NOT IMPLEMENTED YET\n"; 00354 break; 00355 } 00356 } 00357 00358 //----------------------------------------------------------------------------- 00359 00360 00361 #ifdef TAPs_USE_CUDA 00362 //----------------------------------------------------------------------------- 00363 00364 template <typename T> 00365 bool SimPropForMultiPartMeshModel_HalfEdge<T>::CUDA_Initialize () 00366 { 00367 CUDA_Cleanup(); 00368 00369 //m_cudaVertexList = new float[ m_HEVertexPtrList.size() * 3 ]; 00370 unsigned int size = sizeof(float) * m_HEVertexPtrList.size() * 3; 00371 m_cudaVertexList = (float *)malloc( size ); 00372 00373 std::cout << "SimPropForMultiPartMeshModel_HalfEdge -- m_cudaVertexList size: " << m_HEVertexPtrList.size() * 3 << "\n"; 00374 00375 if ( !m_cudaVertexList ) { 00376 std::cout << "ERROR: Could not allocate memory for CUDA!" << std::endl; 00377 exit( -1 ); 00378 } 00379 return true; 00380 } 00381 00382 template <typename T> 00383 void SimPropForMultiPartMeshModel_HalfEdge<T>::CUDA_Cleanup () 00384 { 00385 if ( m_cudaVertexList ) { 00386 //delete [] m_cudaVertexList; 00387 free( m_cudaVertexList ); 00388 m_cudaVertexList = NULL; 00389 } 00390 } 00391 00392 template <typename T> 00393 void SimPropForMultiPartMeshModel_HalfEdge<T>::CUDA_CopyVertexToMem () 00394 { 00395 if ( !m_cudaVertexList ) return; 00396 for ( unsigned int i = 0, p = 0; i < static_cast<unsigned int>( m_HEVertexPtrList.size() ); ++i ) { 00397 m_cudaVertexList[p++] = m_HEVertexPtrList[i]->GetHEVertexPtr()->GetPosition()[0]; 00398 m_cudaVertexList[p++] = m_HEVertexPtrList[i]->GetHEVertexPtr()->GetPosition()[1]; 00399 m_cudaVertexList[p++] = m_HEVertexPtrList[i]->GetHEVertexPtr()->GetPosition()[2]; 00400 } 00401 } 00402 00403 template <typename T> 00404 void SimPropForMultiPartMeshModel_HalfEdge<T>::CUDA_CopyMemToVertex () 00405 { 00406 if ( !m_cudaVertexList ) return; 00407 for ( unsigned int i = 0, p = 0; i < static_cast<unsigned int>( m_HEVertexPtrList.size() ); ++i ) { 00408 m_HEVertexPtrList[i]->GetHEVertexPtr()->SetPosition( 00409 m_cudaVertexList[p], 00410 m_cudaVertexList[p+1], 00411 m_cudaVertexList[p+2] 00412 ); 00413 p += 3; 00414 } 00415 } 00416 00417 //----------------------------------------------------------------------------- 00418 #endif//TAPs_USE_CUDA 00419 00420 00421 //============================================================================= 00422 END_NAMESPACE_TAPs 00423 //34567890123456789012345678901234567890123456789012345678901234567890123456789 00424 //--+----1----+----2----+----3----+----4----+----5----+----6----+----7----+----