void TetrahedronSystem::createL2Vicinity() { #if PRINT_VICINITY std::cout<<" create L2 vicinity\n"; #endif const unsigned nt = numTetrahedrons(); const unsigned np = numPoints(); VicinityMap * vertTetConn = new VicinityMap[np]; getPointTetrahedronConnection(vertTetConn); VicinityMap * tetTetConn1 = new VicinityMap[nt]; getTehrahedronTehrahedronConnectionL1(tetTetConn1, vertTetConn); VicinityMap * tetTetConn2 = new VicinityMap[nt]; getTehrahedronTehrahedronConnectionL2(tetTetConn2, tetTetConn1); buildVicinityIndStart(tetTetConn2); unsigned i; for(i=0; i<np; i++) vertTetConn[i].clear(); delete[] vertTetConn; for(i=0; i<nt; i++) tetTetConn1[i].clear(); delete[] tetTetConn1; for(i=0; i<nt; i++) tetTetConn2[i].clear(); delete[] tetTetConn2; }
std::string ATetrahedronMesh::verbosestr() const { std::stringstream sst; sst<<" tetrahedron mesh nv "<<numPoints() <<"\n ntetra "<<numTetrahedrons() <<"\n volume "<<volume() <<"\n"; return sst.str(); }
void BvhTetrahedronSystem::initOnDevice() { std::cout<<"\n tetrahedron system init on device"; m_deviceTetrahedronVicinityInd->create(numTetrahedronVicinityInd() * 4); m_deviceTetrahedronVicinityStart->create((numTetrahedrons() + 1) * 4); m_deviceTetrahedronVicinityInd->hostToDevice(hostTetrahedronVicinityInd()); m_deviceTetrahedronVicinityStart->hostToDevice(hostTetrahedronVicinityStart()); m_vicinity->create(numTetrahedrons()*TETRAHEDRONSYSTEM_VICINITY_LENGTH*4); tetrasys::writeVicinity((int *)vicinity(), (int *)m_deviceTetrahedronVicinityInd->bufferOnDevice(), (int *)m_deviceTetrahedronVicinityStart->bufferOnDevice(), numTetrahedrons()); CudaMassSystem::initOnDevice(); setNumPrimitives(numTetrahedrons()); CudaLinearBvh::initOnDevice(); }
void BccLattice::extractIndices(unsigned * dst) { unsigned i, j, k = 0; for(i=0; i< numTetrahedrons(); i++) { Tetrahedron * tet = &m_tetrahedrons[i]; for(j=0; j< 4; j++) { sdb::CellValue * found = findGrid(tet->v[j]); dst[k] = found->index; k++; } } }
void TetrahedronSystem::getPointTetrahedronConnection(VicinityMap * vertTetConn) { unsigned i; unsigned *ind = hostTetrahedronIndices(); const unsigned nt = numTetrahedrons(); for(i=0; i<nt; i++) { vertTetConn[ind[0]][i] = 1; vertTetConn[ind[1]][i] = 1; vertTetConn[ind[2]][i] = 1; vertTetConn[ind[3]][i] = 1; ind += 4; } }
void BccLattice::logTetrahedronMesh() { Vector3F p; BaseLog log("./tetmesh.txt"); log.write(boost::str(boost::format("static const unsigned TetraNumVertices = %1%;\n") % numVertices())); log.write(boost::str(boost::format("static const float TetraP[%1%][3] = {\n") % numVertices())); sdb::CellHash * latticeNode = cells(); latticeNode->begin(); while(!latticeNode->end()) { if(latticeNode->value()->visited) { p = nodeCenter(latticeNode->key()); log.write(boost::str(boost::format("{%1%f,%2%f,%3%f}") % p.x % p.y % p.z)); if(latticeNode->value()->index < numVertices()-1) log.write(",\n"); else log.write("\n"); } latticeNode->next(); } log.write("};\n"); log.write(boost::str(boost::format("static const unsigned TetraNumTetrahedrons = %1%;\n") % numTetrahedrons())); log.write(boost::str(boost::format("static const unsigned TetraIndices[%1%][4] = {\n") % numTetrahedrons())); unsigned i, j; unsigned v[4]; for(i=0; i< numTetrahedrons(); i++) { Tetrahedron * tet = &m_tetrahedrons[i]; for(j=0; j< 4; j++) { sdb::CellValue * found = findGrid(tet->v[j]); v[j] = found->index; } log.write(boost::str(boost::format("{%1%,%2%,%3%,%4%}") % v[0] % v[1] % v[2] % v[3])); if(i < numTetrahedrons()-1) log.write(",\n"); else log.write("\n"); } log.write("};\n"); }
void TetrahedronSystem::getTehrahedronTehrahedronConnectionL1(VicinityMap * tetTetConn, VicinityMap * vertTetConn) { unsigned i, j; unsigned *ind = hostTetrahedronIndices(); const unsigned nt = numTetrahedrons(); for(i=0; i<nt; i++) { for(j=0; j<4; j++) { VicinityMapIter itvert = vertTetConn[ind[i*4 + j]].begin(); for(; itvert != vertTetConn[ind[i*4 + j]].end(); ++itvert) { tetTetConn[itvert->first][i] = 1; } } } }
void BvhTetrahedronSystem::formTetrahedronAabbsImpulsed() { void * pos = deviceX(); void * vel = deviceV(); void * deltaVel = deviceImpulse(); void * idx = deviceTretradhedronIndices(); void * dst = leafAabbs(); tetrasys::formTetrahedronAabbsImpulsed((Aabb *)dst, (float3 *)pos, (float3 *)vel, (float3 *)deltaVel, 1.f/60.f, (uint4 *)idx, numTetrahedrons()); CudaBase::CheckCudaError("tetrahedron system form aabb"); }
void TetrahedronSystem::getTehrahedronTehrahedronConnectionL2(VicinityMap * dstConn, VicinityMap * srcConn) { const unsigned nt = numTetrahedrons(); unsigned i, j; for(i=0; i<nt; i++) { VicinityMapIter iti = srcConn[i].begin(); for(; iti != srcConn[i].end(); ++iti) { j = iti->first; VicinityMapIter itj = srcConn[j].begin(); for(; itj != srcConn[j].end(); ++itj) { dstConn[itj->first][i] = 1; } } } }
void TetrahedronSystem::calculateMass() { const unsigned np = numPoints(); const unsigned nt = numTetrahedrons(); const float density = totalMass() / totalInitialVolume(); const float base = 1.f/(float)np; unsigned i; float * mass = hostMass(); for(i=0; i< np; i++) { if(isAnchoredPoint(i)) mass[i] = 1e9f; else mass[i] = base; } Vector3F * p = (Vector3F *)hostXi(); Vector3F v[4]; unsigned a, b, c, d; unsigned *ind = hostTetrahedronIndices(); float m; for(i=0; i<nt; i++) { a = ind[0]; b = ind[1]; c = ind[2]; d = ind[3]; v[0] = p[a]; v[1] = p[b]; v[2] = p[c]; v[3] = p[d]; m = density * tetrahedronVolume(v) * .25f; mass[a] += m; mass[b] += m; mass[c] += m; mass[d] += m; ind += 4; } /* for(i=0; i< m_numPoints; i++) { std::cout<<" m "<<mass[i]; } */ }
void BccLattice::addAnchors(unsigned * anchored, KdIntersection * tree) { Vector3F q[4]; unsigned j, i=0; for(; i< numTetrahedrons(); i++) { Tetrahedron * tet = &m_tetrahedrons[i]; for(j=0; j< 4; j++) q[j] = nodeCenter(tet->v[j]); if(!tree->intersectTetrahedron(q)) continue; for(j=0; j< 4; j++) { sdb::CellValue * found = findGrid(tet->v[j]); anchored[found->index] = 1; } } }
float ATetrahedronMesh::calculateVolume() const { Vector3F * p = points(); unsigned * v = indices(); const unsigned n = numTetrahedrons(); float sum = 0.f; Vector3F q[4]; unsigned i = 0; for(;i<n;i++) { q[0] = p[v[0]]; q[1] = p[v[1]]; q[2] = p[v[2]]; q[3] = p[v[3]]; sum+=tetrahedronVolume(q); v+=4; } return sum; }
float TetrahedronSystem::totalInitialVolume() { const unsigned n = numTetrahedrons(); Vector3F * p = (Vector3F *)hostXi(); unsigned * v = hostTetrahedronIndices(); unsigned i; Vector3F t[4]; unsigned a, b, c, d; float sum = 0.f; for(i=0; i<n; i++) { a = v[0]; b = v[1]; c = v[2]; d = v[3]; t[0] = p[a]; t[1] = p[b]; t[2] = p[c]; t[3] = p[d]; sum += tetrahedronVolume(t); v+= 4; } return sum; }
const unsigned ATetrahedronMesh::numComponents() const { return numTetrahedrons(); }
void BvhTetrahedronSystem::formTetrahedronAabbs() { void * cvs = deviceX(); void * vsrc = deviceV(); void * idx = deviceTretradhedronIndices(); void * dst = leafAabbs(); tetrasys::formTetrahedronAabbs((Aabb *)dst, (float3 *)cvs, (float3 *)vsrc, 1.f/60.f, (uint4 *)idx, numTetrahedrons()); CudaBase::CheckCudaError("tetrahedron system form aabb"); }
const unsigned TetrahedronSystem::numElements() const { return numTetrahedrons(); }
void TetrahedronSystem::buildVicinityIndStart(VicinityMap * tetTetConn) { const unsigned nt = numTetrahedrons(); m_hostTetrahedronVicinityStart->create((nt+1)*4); unsigned * tvstart = (unsigned *)m_hostTetrahedronVicinityStart->data(); std::cout<<" n tet "<<nt; unsigned maxConn = 0; unsigned minConn = 1000; unsigned count = 0; unsigned i; for(i=0; i<nt; i++) { tvstart[i] = count; count += tetTetConn[i].size(); if(maxConn < tetTetConn[i].size()) maxConn = tetTetConn[i].size(); if(minConn > tetTetConn[i].size()) minConn = tetTetConn[i].size(); } tvstart[nt] = count; std::cout<<" min/max n connections "<<minConn<<"/"<<maxConn<<"\n"; #if PRINT_VICINITY std::cout<<" vicinity size "<<tvstart[nt]; #endif m_tetrahedronVicinitySize = count; m_hostTetrahedronVicinityInd->create(count * 4); unsigned * tvind = (unsigned *)m_hostTetrahedronVicinityInd->data(); if(m_tetrahedronVicinitySize == nt) { #if PRINT_VICINITY std::cout<<" no tetrahedrons are connected to each other"; #endif for(i=0; i<nt; i++) { tvind[i] = i; } return; } count = 0; for(i=0; i<nt; i++) { #if PRINT_VICINITY std::cout<<"\n t"<<i<<" ["<<tvstart[i]<<":] "; #endif VicinityMapIter ittet = tetTetConn[i].begin(); for(; ittet != tetTetConn[i].end(); ++ittet) { #if PRINT_VICINITY std::cout<<" "<<ittet->first; #endif tvind[count] = ittet->first; count++; } } }