From c325da8b34df295aad52c3a469f364e088576746 Mon Sep 17 00:00:00 2001 From: jyc-n Date: Thu, 22 Jul 2021 11:43:26 -0400 Subject: [PATCH] add new ReducedSoftBody class. move read files functions to btReducedSoftBodyHelpers --- examples/ReducedDeformableDemo/BasicTest.cpp | 16 +- .../btReducedSoftBody.cpp | 8 + .../BulletReducedSoftBody/btReducedSoftBody.h | 52 +++++ .../btReducedSoftBodyHelpers.cpp | 201 ++++++++++++++++++ .../btReducedSoftBodyHelpers.h | 22 ++ src/BulletSoftBody/CMakeLists.txt | 6 + src/BulletSoftBody/btSoftBody.h | 1 + src/BulletSoftBody/btSoftBodyHelpers.cpp | 89 -------- src/BulletSoftBody/btSoftBodyHelpers.h | 7 - 9 files changed, 298 insertions(+), 104 deletions(-) create mode 100644 src/BulletSoftBody/BulletReducedSoftBody/btReducedSoftBody.cpp create mode 100644 src/BulletSoftBody/BulletReducedSoftBody/btReducedSoftBody.h create mode 100644 src/BulletSoftBody/BulletReducedSoftBody/btReducedSoftBodyHelpers.cpp create mode 100644 src/BulletSoftBody/BulletReducedSoftBody/btReducedSoftBodyHelpers.h diff --git a/examples/ReducedDeformableDemo/BasicTest.cpp b/examples/ReducedDeformableDemo/BasicTest.cpp index ae2a81bc0..83fcd9c71 100644 --- a/examples/ReducedDeformableDemo/BasicTest.cpp +++ b/examples/ReducedDeformableDemo/BasicTest.cpp @@ -15,8 +15,8 @@ ///btBulletDynamicsCommon.h is the main Bullet include file, contains most common include files. #include "btBulletDynamicsCommon.h" #include "BulletSoftBody/btDeformableMultiBodyDynamicsWorld.h" -#include "BulletSoftBody/btSoftBody.h" -#include "BulletSoftBody/btSoftBodyHelpers.h" +#include "BulletSoftBody/BulletReducedSoftBody/btReducedSoftBody.h" +#include "BulletSoftBody/BulletReducedSoftBody/btReducedSoftBodyHelpers.h" #include "BulletSoftBody/btDeformableBodySolver.h" #include "BulletSoftBody/btSoftBodyRigidBodyCollisionConfiguration.h" #include "BulletDynamics/Featherstone/btMultiBodyConstraintSolver.h" @@ -200,22 +200,22 @@ void BasicTest::initPhysics() // create volumetric soft body { std::string filename("../../../examples/SoftDemo/mesh.vtk"); - btSoftBody* psb = btSoftBodyHelpers::CreateFromVtkFile(getDeformableDynamicsWorld()->getWorldInfo(), filename.c_str()); + btReducedSoftBody* psb = btReducedSoftBodyHelpers::CreateFromVtkFile(getDeformableDynamicsWorld()->getWorldInfo(), filename.c_str()); m_nFull = psb->m_nodes.size(); psb->m_reducedModel = true; // read in eigenmodes, stiffness and mass matrices std::string eigenvalues_file("../../../examples/SoftDemo/eigenvalues.bin"); - btSoftBodyHelpers::readBinary(psb->m_eigenvalues, m_startMode, m_nReduced, 3 * m_nFull, eigenvalues_file.c_str()); + btReducedSoftBodyHelpers::readBinary(psb->m_eigenvalues, m_startMode, m_nReduced, 3 * m_nFull, eigenvalues_file.c_str()); std::string Kr_file("../../../examples/SoftDemo/K_r_diag_mat.bin"); - btSoftBodyHelpers::readBinary(psb->m_Kr, m_startMode, m_nReduced, 3 * m_nFull, Kr_file.c_str()); + btReducedSoftBodyHelpers::readBinary(psb->m_Kr, m_startMode, m_nReduced, 3 * m_nFull, Kr_file.c_str()); std::string Mr_file("../../../examples/SoftDemo/M_r_diag_mat.bin"); - btSoftBodyHelpers::readBinary(psb->m_Mr, m_startMode, m_nReduced, 3 * m_nFull, Mr_file.c_str()); + btReducedSoftBodyHelpers::readBinary(psb->m_Mr, m_startMode, m_nReduced, 3 * m_nFull, Mr_file.c_str()); std::string modes_file("../../../examples/SoftDemo/modes.bin"); - btSoftBodyHelpers::readBinaryModes(psb->m_modes, m_startMode, m_nReduced, 3 * m_nFull, modes_file.c_str()); // default to 3D + btReducedSoftBodyHelpers::readBinaryModes(psb->m_modes, m_startMode, m_nReduced, 3 * m_nFull, modes_file.c_str()); // default to 3D // get rest position psb->m_x0.resize(3 * psb->m_nodes.size()); @@ -238,7 +238,7 @@ void BasicTest::initPhysics() std::string M_file("../../../examples/SoftDemo/M_diag_mat.bin"); btAlignedObjectArray mass_array; - btSoftBodyHelpers::readBinary(mass_array, 0, 3 * m_nFull, 3 * m_nFull, M_file.c_str()); + btReducedSoftBodyHelpers::readBinary(mass_array, 0, 3 * m_nFull, 3 * m_nFull, M_file.c_str()); // assign mass to nodes for (int i = 0; i < psb->m_nodes.size(); ++i) psb->m_nodes[i].m_im = mass_array[3 * i]; // here we use m_im as the actual mass not the mass inverse diff --git a/src/BulletSoftBody/BulletReducedSoftBody/btReducedSoftBody.cpp b/src/BulletSoftBody/BulletReducedSoftBody/btReducedSoftBody.cpp new file mode 100644 index 000000000..6f7f0cecb --- /dev/null +++ b/src/BulletSoftBody/BulletReducedSoftBody/btReducedSoftBody.cpp @@ -0,0 +1,8 @@ +#include "btReducedSoftBody.h" + +btReducedSoftBody::btReducedSoftBody(btSoftBodyWorldInfo* worldInfo, int node_count, const btVector3* x, const btScalar* m) + : btSoftBody(worldInfo, node_count, x, m) +{ + // other members + m_reducedModel = true; +} \ No newline at end of file diff --git a/src/BulletSoftBody/BulletReducedSoftBody/btReducedSoftBody.h b/src/BulletSoftBody/BulletReducedSoftBody/btReducedSoftBody.h new file mode 100644 index 000000000..c7204285c --- /dev/null +++ b/src/BulletSoftBody/BulletReducedSoftBody/btReducedSoftBody.h @@ -0,0 +1,52 @@ +#ifndef BT_REDUCED_SOFT_BODY_H +#define BT_REDUCED_SOFT_BODY_H + +#include "LinearMath/btAlignedObjectArray.h" +#include "LinearMath/btVector3.h" + +// #include "BulletDynamics/Dynamics/btRigidBody.h" +#include "../btSoftBody.h" + +// Reduced deformable body is a simplified deformable object embedded in a rigid frame. +class btReducedSoftBody : public btSoftBody +{ + public: + // + // Typedefs + // + typedef btAlignedObjectArray tVec3Array; + typedef btAlignedObjectArray tDenseArray; + typedef btAlignedObjectArray > tDenseMatrix; + + using btSoftBody::tNodeArray; + + // + // Fields + // + + // bool m_reducedModel; // Reduced deformable model flag + + // reduced space + // tDenseMatrix m_modes; // modes of the reduced deformable model. Each inner array is a mode, outer array size = n_modes + // tDenseArray m_reducedDofs; // Reduced degree of freedom + // tDenseArray m_reducedVelocity; // Reduced velocity array + // tDenseArray m_eigenvalues; // eigenvalues of the reduce deformable model + // tDenseArray m_Kr; // reduced stiffness matrix + // tDenseArray m_Mr; // reduced mass matrix //TODO: do we need this? + + // // full space + // tVec3Array m_x0; // Rest position + + // rigid frame + + + // + // Api + // + btReducedSoftBody(btSoftBodyWorldInfo* worldInfo, int node_count, const btVector3* x, const btScalar* m); + ~btReducedSoftBody() {} + + +}; + +#endif // BT_REDUCED_SOFT_BODY_H \ No newline at end of file diff --git a/src/BulletSoftBody/BulletReducedSoftBody/btReducedSoftBodyHelpers.cpp b/src/BulletSoftBody/BulletReducedSoftBody/btReducedSoftBodyHelpers.cpp new file mode 100644 index 000000000..f0066dc13 --- /dev/null +++ b/src/BulletSoftBody/BulletReducedSoftBody/btReducedSoftBodyHelpers.cpp @@ -0,0 +1,201 @@ +#include "btReducedSoftBodyHelpers.h" +#include "../btSoftBodyHelpers.h" +#include +#include +#include + +btReducedSoftBody* btReducedSoftBodyHelpers::CreateFromVtkFile(btSoftBodyWorldInfo& worldInfo, const char* vtk_file) +{ + std::ifstream fs; + fs.open(vtk_file); + btAssert(fs); + + typedef btAlignedObjectArray Index; + std::string line; + btAlignedObjectArray X; + btVector3 position; + btAlignedObjectArray indices; + bool reading_points = false; + bool reading_tets = false; + size_t n_points = 0; + size_t n_tets = 0; + size_t x_count = 0; + size_t indices_count = 0; + while (std::getline(fs, line)) + { + std::stringstream ss(line); + if (line.size() == (size_t)(0)) + { + } + else if (line.substr(0, 6) == "POINTS") + { + reading_points = true; + reading_tets = false; + ss.ignore(128, ' '); // ignore "POINTS" + ss >> n_points; + X.resize(n_points); + } + else if (line.substr(0, 5) == "CELLS") + { + reading_points = false; + reading_tets = true; + ss.ignore(128, ' '); // ignore "CELLS" + ss >> n_tets; + indices.resize(n_tets); + } + else if (line.substr(0, 10) == "CELL_TYPES") + { + reading_points = false; + reading_tets = false; + } + else if (reading_points) + { + btScalar p; + ss >> p; + position.setX(p); + ss >> p; + position.setY(p); + ss >> p; + position.setZ(p); + //printf("v %f %f %f\n", position.getX(), position.getY(), position.getZ()); + X[x_count++] = position; + } + else if (reading_tets) + { + int d; + ss >> d; + if (d != 4) + { + printf("Load deformable failed: Only Tetrahedra are supported in VTK file.\n"); + fs.close(); + return 0; + } + ss.ignore(128, ' '); // ignore "4" + Index tet; + tet.resize(4); + for (size_t i = 0; i < 4; i++) + { + ss >> tet[i]; + //printf("%d ", tet[i]); + } + //printf("\n"); + indices[indices_count++] = tet; + } + } + btReducedSoftBody* rsb = new btReducedSoftBody(&worldInfo, n_points, &X[0], 0); + + for (int i = 0; i < n_tets; ++i) + { + const Index& ni = indices[i]; + rsb->appendTetra(ni[0], ni[1], ni[2], ni[3]); + { + rsb->appendLink(ni[0], ni[1], 0, true); + rsb->appendLink(ni[1], ni[2], 0, true); + rsb->appendLink(ni[2], ni[0], 0, true); + rsb->appendLink(ni[0], ni[3], 0, true); + rsb->appendLink(ni[1], ni[3], 0, true); + rsb->appendLink(ni[2], ni[3], 0, true); + } + } + + btSoftBodyHelpers::generateBoundaryFaces(rsb); + rsb->initializeDmInverse(); + rsb->m_tetraScratches.resize(rsb->m_tetras.size()); + rsb->m_tetraScratchesTn.resize(rsb->m_tetras.size()); + printf("Nodes: %u\r\n", rsb->m_nodes.size()); + printf("Links: %u\r\n", rsb->m_links.size()); + printf("Faces: %u\r\n", rsb->m_faces.size()); + printf("Tetras: %u\r\n", rsb->m_tetras.size()); + + fs.close(); + return rsb; +} + +// read in binary files +void btReducedSoftBodyHelpers::readBinary(btAlignedObjectArray& vec, + const unsigned int n_start, // starting index + const unsigned int n_modes, // #entries read + const unsigned int n_full, // array size + const char* file) +{ + std::ifstream f_in(file, std::ios::in | std::ios::binary); + // first get size + unsigned int size; + f_in.read((char*)&size, sizeof(uint32_t)); + btAssert(size == n_full); + + // read data + vec.resize(n_modes); + double temp; + for (unsigned int i = 0; i < n_start + n_modes; ++i) + { + f_in.read((char*)&temp, sizeof(double)); + if (i >= n_start) + vec[i - n_start] = btScalar(temp); + } + f_in.close(); +} + +void btReducedSoftBodyHelpers::readBinaryMat(btSoftBody::tDenseMatrix& mat, + const unsigned int n_start, // starting mode index + const unsigned int n_modes, // #modes, outer array size + const unsigned int n_full, // inner array size + const char* file) +{ + std::ifstream f_in(file, std::ios::in | std::ios::binary); + // first get size + unsigned int v_size; + f_in.read((char*)&v_size, sizeof(uint32_t)); + btAssert(v_size == n_full * n_full); + + // read data + mat.resize(n_modes); + for (int i = 0; i < n_start + n_modes; ++i) + { + for (int j = 0; j < n_full; ++j) + { + double temp; + f_in.read((char*)&temp, sizeof(double)); + + if (i >= n_start && j >= n_start && i < n_start + n_modes && j < n_start + n_modes) + { + if (mat[i - n_start].size() != n_modes) + mat[i - n_start].resize(n_modes); + mat[i - n_start][j - n_start] = btScalar(temp); + } + } + } + f_in.close(); +} + +void btReducedSoftBodyHelpers::readBinaryModes(btSoftBody::tDenseMatrix& mat, + const unsigned int n_start, // starting mode index + const unsigned int n_modes, // #modes, outer array size + const unsigned int n_full, // inner array size + const char* file) +{ + std::ifstream f_in(file, std::ios::in | std::ios::binary); + // first get size + unsigned int v_size; + f_in.read((char*)&v_size, sizeof(uint32_t)); + btAssert(v_size == n_full * n_full); + + // read data + mat.resize(n_modes); + for (int i = 0; i < n_start + n_modes; ++i) + { + for (int j = 0; j < n_full; ++j) + { + double temp; + f_in.read((char*)&temp, sizeof(double)); + + if (i >= n_start) + { + if (mat[i - n_start].size() != n_full) + mat[i - n_start].resize(n_full); + mat[i - n_start][j] = btScalar(temp); + } + } + } + f_in.close(); +} \ No newline at end of file diff --git a/src/BulletSoftBody/BulletReducedSoftBody/btReducedSoftBodyHelpers.h b/src/BulletSoftBody/BulletReducedSoftBody/btReducedSoftBodyHelpers.h new file mode 100644 index 000000000..35de7675d --- /dev/null +++ b/src/BulletSoftBody/BulletReducedSoftBody/btReducedSoftBodyHelpers.h @@ -0,0 +1,22 @@ +#ifndef BT_REDUCED_SOFT_BODY_HELPERS_H +#define BT_REDUCED_SOFT_BODY_HELPERS_H + +#include "btReducedSoftBody.h" + +struct btReducedSoftBodyHelpers +{ + static btReducedSoftBody* CreateFromVtkFile(btSoftBodyWorldInfo& worldInfo, const char* vtk_file); + + // TODO: no world info passed in here. may be required in the future + // static btReducedSoftBody* CreateFromVtkFile(btSoftBodyWorldInfo& worldInfo, const char* vtk_file); + + // read in a binary vector + static void readBinary(btReducedSoftBody::tDenseArray& vec, const unsigned int n_start, const unsigned int n_modes, const unsigned int n_full, const char* file); + // read in a binary matrix + static void readBinaryMat(btReducedSoftBody::tDenseMatrix& mat, const unsigned int n_start, const unsigned int n_modes, const unsigned int n_full, const char* file); + // read in modes file (different version of read in matrix) + static void readBinaryModes(btReducedSoftBody::tDenseMatrix& mat, const unsigned int n_start, const unsigned int n_modes, const unsigned int n_full, const char* file); +}; + + +#endif // BT_REDUCED_SOFT_BODY_HELPERS_H \ No newline at end of file diff --git a/src/BulletSoftBody/CMakeLists.txt b/src/BulletSoftBody/CMakeLists.txt index 945276801..c900c44fc 100644 --- a/src/BulletSoftBody/CMakeLists.txt +++ b/src/BulletSoftBody/CMakeLists.txt @@ -24,6 +24,9 @@ SET(BulletSoftBody_SRCS btDeformableMultiBodyDynamicsWorld.cpp btDeformableContactConstraint.cpp poly34.cpp + + BulletReducedSoftBody/btReducedSoftBody.cpp + BulletReducedSoftBody/btReducedSoftBodyHelpers.cpp ) @@ -63,6 +66,9 @@ SET(BulletSoftBody_HDRS poly34.h btSoftBodySolverVertexBuffer.h + + BulletReducedSoftBody/btReducedSoftBody.h + BulletReducedSoftBody/btReducedSoftBodyHelpers.h ) diff --git a/src/BulletSoftBody/btSoftBody.h b/src/BulletSoftBody/btSoftBody.h index f5842995d..d36b35a65 100644 --- a/src/BulletSoftBody/btSoftBody.h +++ b/src/BulletSoftBody/btSoftBody.h @@ -856,6 +856,7 @@ public: btScalar m_restLengthScale; + // TODO: delete bool m_reducedModel; // Reduced deformable model flag btAlignedObjectArray m_reducedDofs; // Reduced degree of freedom btAlignedObjectArray m_reducedVelocity; // Reduced velocity array diff --git a/src/BulletSoftBody/btSoftBodyHelpers.cpp b/src/BulletSoftBody/btSoftBodyHelpers.cpp index a356f8115..f63e48f9a 100644 --- a/src/BulletSoftBody/btSoftBodyHelpers.cpp +++ b/src/BulletSoftBody/btSoftBodyHelpers.cpp @@ -1487,95 +1487,6 @@ void btSoftBodyHelpers::writeObj(const char* filename, const btSoftBody* psb) fs.close(); } -// read in binary files -void btSoftBodyHelpers::readBinary(btAlignedObjectArray& vec, - const unsigned int n_start, // starting index - const unsigned int n_modes, // #entries read - const unsigned int n_full, // array size - const char* file) -{ - std::ifstream f_in(file, std::ios::in | std::ios::binary); - // first get size - unsigned int size; - f_in.read((char*)&size, sizeof(uint32_t)); - btAssert(size == n_full); - - // read data - vec.resize(n_modes); - double temp; - for (unsigned int i = 0; i < n_start + n_modes; ++i) - { - f_in.read((char*)&temp, sizeof(double)); - if (i >= n_start) - vec[i - n_start] = btScalar(temp); - } - f_in.close(); -} - -void btSoftBodyHelpers::readBinaryMat(btSoftBody::tDenseMatrix& mat, - const unsigned int n_start, // starting mode index - const unsigned int n_modes, // #modes, outer array size - const unsigned int n_full, // inner array size - const char* file) -{ - std::ifstream f_in(file, std::ios::in | std::ios::binary); - // first get size - unsigned int v_size; - f_in.read((char*)&v_size, sizeof(uint32_t)); - btAssert(v_size == n_full * n_full); - - // read data - mat.resize(n_modes); - for (int i = 0; i < n_start + n_modes; ++i) - { - for (int j = 0; j < n_full; ++j) - { - double temp; - f_in.read((char*)&temp, sizeof(double)); - - if (i >= n_start && j >= n_start && i < n_start + n_modes && j < n_start + n_modes) - { - if (mat[i - n_start].size() != n_modes) - mat[i - n_start].resize(n_modes); - mat[i - n_start][j - n_start] = btScalar(temp); - } - } - } - f_in.close(); -} - -void btSoftBodyHelpers::readBinaryModes(btSoftBody::tDenseMatrix& mat, - const unsigned int n_start, // starting mode index - const unsigned int n_modes, // #modes, outer array size - const unsigned int n_full, // inner array size - const char* file) -{ - std::ifstream f_in(file, std::ios::in | std::ios::binary); - // first get size - unsigned int v_size; - f_in.read((char*)&v_size, sizeof(uint32_t)); - btAssert(v_size == n_full * n_full); - - // read data - mat.resize(n_modes); - for (int i = 0; i < n_start + n_modes; ++i) - { - for (int j = 0; j < n_full; ++j) - { - double temp; - f_in.read((char*)&temp, sizeof(double)); - - if (i >= n_start) - { - if (mat[i - n_start].size() != n_full) - mat[i - n_start].resize(n_full); - mat[i - n_start][j] = btScalar(temp); - } - } - } - f_in.close(); -} - void btSoftBodyHelpers::duplicateFaces(const char* filename, const btSoftBody* psb) { std::ifstream fs_read; diff --git a/src/BulletSoftBody/btSoftBodyHelpers.h b/src/BulletSoftBody/btSoftBodyHelpers.h index 05f53dd0a..237d29761 100644 --- a/src/BulletSoftBody/btSoftBodyHelpers.h +++ b/src/BulletSoftBody/btSoftBodyHelpers.h @@ -144,13 +144,6 @@ struct btSoftBodyHelpers bool bfacesfromtetras); static btSoftBody* CreateFromVtkFile(btSoftBodyWorldInfo& worldInfo, const char* vtk_file); - // read in a binary vector - static void readBinary(btAlignedObjectArray& vec, const unsigned int n_start, const unsigned int n_modes, const unsigned int n_full, const char* file); - // read in a binary matrix - static void readBinaryMat(btSoftBody::tDenseMatrix& mat, const unsigned int n_start, const unsigned int n_modes, const unsigned int n_full, const char* file); - // read in modes file - static void readBinaryModes(btSoftBody::tDenseMatrix& mat, const unsigned int n_start, const unsigned int n_modes, const unsigned int n_full, const char* file); - static void writeObj(const char* file, const btSoftBody* psb); static void getBarycentricWeights(const btVector3& a, const btVector3& b, const btVector3& c, const btVector3& d, const btVector3& p, btVector4& bary);