[Bf-blender-cvs] [50e2c479cc2] soc-2020-soft-body: changed up interface for lattice a bit
over0219
noreply at git.blender.org
Tue Jun 23 01:45:41 CEST 2020
Commit: 50e2c479cc22d0efd1d744720df64311d8fefb80
Author: over0219
Date: Mon Jun 22 18:45:38 2020 -0500
Branches: soc-2020-soft-body
https://developer.blender.org/rB50e2c479cc22d0efd1d744720df64311d8fefb80
changed up interface for lattice a bit
===================================================================
M extern/softbody/CMakeLists.txt
M extern/softbody/src/admmpd_collision.cpp
M extern/softbody/src/admmpd_collision.h
R079 extern/softbody/src/admmpd_lattice.cpp extern/softbody/src/admmpd_embeddedmesh.cpp
A extern/softbody/src/admmpd_embeddedmesh.h
D extern/softbody/src/admmpd_lattice.h
M extern/softbody/src/admmpd_solver.cpp
M extern/softbody/src/admmpd_solver.h
A extern/softbody/src/admmpd_types.h
M intern/softbody/admmpd_api.cpp
M source/blender/blenkernel/intern/softbody.c
===================================================================
diff --git a/extern/softbody/CMakeLists.txt b/extern/softbody/CMakeLists.txt
index 09fdc947dde..4d6ff3328b8 100644
--- a/extern/softbody/CMakeLists.txt
+++ b/extern/softbody/CMakeLists.txt
@@ -29,20 +29,21 @@ set(INC_SYS
)
set(SRC
- src/admmpd_math.h
- src/admmpd_math.cpp
- src/admmpd_energy.h
- src/admmpd_energy.cpp
- src/admmpd_lattice.h
- src/admmpd_lattice.cpp
- src/admmpd_solver.h
- src/admmpd_solver.cpp
- src/admmpd_collision.h
- src/admmpd_collision.cpp
src/admmpd_bvh.h
src/admmpd_bvh.cpp
src/admmpd_bvh_traverse.h
src/admmpd_bvh_traverse.cpp
+ src/admmpd_collision.h
+ src/admmpd_collision.cpp
+ src/admmpd_embeddedmesh.h
+ src/admmpd_embeddedmesh.cpp
+ src/admmpd_energy.h
+ src/admmpd_energy.cpp
+ src/admmpd_math.h
+ src/admmpd_math.cpp
+ src/admmpd_solver.h
+ src/admmpd_solver.cpp
+ src/admmpd_types.h
)
set(LIB
diff --git a/extern/softbody/src/admmpd_collision.cpp b/extern/softbody/src/admmpd_collision.cpp
index 7a53c91a150..02a197c4138 100644
--- a/extern/softbody/src/admmpd_collision.cpp
+++ b/extern/softbody/src/admmpd_collision.cpp
@@ -2,9 +2,101 @@
// Distributed under the MIT License.
#include "admmpd_collision.h"
+#include "BLI_assert.h"
namespace admmpd {
+using namespace Eigen;
+void EmbeddedMeshCollision::set_obstacles(
+ const float *v0,
+ const float *v1,
+ int nv,
+ const int *faces,
+ int nf)
+{
+ if (obs_V0.rows() != nv)
+ obs_V0.resize(nv,3);
+
+ if (obs_V1.rows() != nv)
+ obs_V1.resize(nv,3);
+
+ for (int i=0; i<nv; ++i)
+ {
+ for (int j=0; j<3; ++j)
+ {
+ obs_V0(i,j) = v0[i*3+j];
+ obs_V1(i,j) = v1[i*3+j];
+ }
+ }
+
+ if (obs_F.rows() != nf)
+ {
+ obs_F.resize(nf,3);
+ obs_aabbs.resize(nf);
+ }
+
+ for (int i=0; i<nf; ++i)
+ {
+ obs_aabbs[i].setEmpty();
+ for (int j=0; j<3; ++j)
+ {
+ int fj = faces[i*3+j];
+ obs_F(i,j) = fj;
+ obs_aabbs[i].extend(obs_V0.row(fj).transpose());
+ obs_aabbs[i].extend(obs_V1.row(fj).transpose());
+ }
+ }
+
+ obs_tree.init(obs_aabbs);
+
+} // end add obstacle
+
+void EmbeddedMeshCollision::detect(const Eigen::MatrixXd *x0, const Eigen::MatrixXd *x1)
+{
+ /*
+ // First, update the positions of the embedded vertex
+ // and perform collision detection against obstacles
+ int n_ev = emb_V0.rows();
+ std::vector<int> colliding(n_ev,0);
+ for (int i=0; i<n_ev; ++i)
+ {
+ int t = vtx_to_tet->operator[](i);
+ BLI_assert(t >= 0);
+ BLI_assert(t < tets->rows());
+ RowVector4i tet = tets->row(t);
+ Vector4d bary = emb_barys->row(i);
+// emb_V0.row(i) =
+// bary[0] * x0->row(tet[0]) +
+// bary[1] * x0->row(tet[1]) +
+// bary[2] * x0->row(tet[2]) +
+// bary[3] * x0->row(tet[3]);
+ Vector3d pt =
+ bary[0] * x1->row(tet[0]) +
+ bary[1] * x1->row(tet[1]) +
+ bary[2] * x1->row(tet[2]) +
+ bary[3] * x1->row(tet[3]);
+// emb_V1.row(i) =
+
+ // Check if we are inside the mesh.
+ // If so, find the nearest face in the rest pose.
+ PointInTriangleMeshTraverse<double> pt_in_mesh(pt, &obs_V1, &obs_F);
+ obs_tree.traverse(pt_in_mesh);
+ if (pt_in_mesh.output.num_hits() % 2 == 1)
+ {
+ // Find
+// hit = true;
+ }
+
+// colliding[i] = hit;
+ }
+
+ // Only bother with self collision if it
+ // is not colliding with an obstacle.
+ // This is only useful for discrete tests.
+*/
+} // end emb collision detect
+
+/*
void FloorCollider::detect(const Eigen::MatrixXd *x)
{
(void)(x);
@@ -32,5 +124,5 @@ void FloorCollider::jacobian(
l->emplace_back(floor_z);
}
} // end floor collider Jacobian
-
+*/
} // namespace admmpd
diff --git a/extern/softbody/src/admmpd_collision.h b/extern/softbody/src/admmpd_collision.h
index c3fd9cb8c4f..5126d1a6958 100644
--- a/extern/softbody/src/admmpd_collision.h
+++ b/extern/softbody/src/admmpd_collision.h
@@ -5,7 +5,9 @@
#define ADMMPD_COLLISION_H_
#include <Eigen/Sparse>
+#include <Eigen/Geometry>
#include <vector>
+#include "admmpd_bvh.h"
namespace admmpd {
@@ -14,21 +16,80 @@ namespace admmpd {
// Probably will work better to use uber-collision class for
// all self and obstacle collisions, reducing the amount of
// for-all vertices loops.
-class Collider {
+class Collision {
public:
- virtual void detect(
- const Eigen::MatrixXd *x) = 0;
- virtual void jacobian(
+// virtual void detect(
+// int meshnum,
+// const Eigen::MatrixXd *x,
+// const Eigen::MatrixXi *faces) = 0;
+// virtual void jacobian(
+// const Eigen::MatrixXd *x,
+// std::vector<Eigen::Triplet<double> > *trips_x,
+// std::vector<Eigen::Triplet<double> > *trips_y,
+// std::vector<Eigen::Triplet<double> > *trips_z,
+// std::vector<double> *l) = 0;
+};
+
+// Collision detection against multiple meshes
+class EmbeddedMeshCollision : public Collision {
+protected:
+ // We progressively build a list of vertices and faces with each
+ // add_obstacle call, reindexing as needed. Then we build a tree
+ // with all of them. Alternatively we could just build separate trees and combine them.
+ Eigen::MatrixXd obs_V0, obs_V1;
+ Eigen::MatrixXi obs_F;
+ std::vector<Eigen::AlignedBox<double,3> > obs_aabbs;
+ AABBTree<double,3> obs_tree;
+
+ Eigen::MatrixXd emb_V0, emb_V1; // copy of embedded vertices
+ const Eigen::MatrixXd *emb_barys; // barys of the embedded vtx
+ const Eigen::VectorXi *vtx_to_tet; // vertex to tet embedding
+ const Eigen::MatrixXi *tets; // tets that embed faces
+
+ struct CollisionPair {
+ int p; // point
+ int q; // face
+ Eigen::Vector3d barys; // barycoords of collision
+ };
+
+public:
+ // I don't really like having to switch up interface style, but we'll
+ // do so here to avoid copies that would happen in admmpd_api.
+ void set_obstacles(
+ const float *v0,
+ const float *v1,
+ int nv,
+ const int *faces,
+ int nf);
+
+ // Unlike set_obstacles, the pointers
+ void set_embedded(
+ const Eigen::MatrixXd *emb_barys,
+ const Eigen::VectorXi *vtx_to_tet,
+ const Eigen::MatrixXi *tets){}
+
+ // Given a list of deformable vertices (the lattice)
+ // perform collision detection of the surface mesh against
+ // obstacles and possibly self.
+ void detect(const Eigen::MatrixXd *x0, const Eigen::MatrixXd *x1);
+
+ void jacobian(
const Eigen::MatrixXd *x,
std::vector<Eigen::Triplet<double> > *trips_x,
std::vector<Eigen::Triplet<double> > *trips_y,
std::vector<Eigen::Triplet<double> > *trips_z,
- std::vector<double> *l) = 0;
+ std::vector<double> *l)
+ {
+
+ }
};
-
+/*
class FloorCollider : public Collider {
public:
- void detect(const Eigen::MatrixXd *x);
+ virtual void detect(
+ int meshnum,
+ const Eigen::MatrixXd *x,
+ const Eigen::MatrixXi *faces);
void jacobian(
const Eigen::MatrixXd *x,
std::vector<Eigen::Triplet<double> > *trips_x,
@@ -36,7 +97,7 @@ public:
std::vector<Eigen::Triplet<double> > *trips_z,
std::vector<double> *l);
};
-
+*/
} // namespace admmpd
#endif // ADMMPD_COLLISION_H_
diff --git a/extern/softbody/src/admmpd_lattice.cpp b/extern/softbody/src/admmpd_embeddedmesh.cpp
similarity index 79%
rename from extern/softbody/src/admmpd_lattice.cpp
rename to extern/softbody/src/admmpd_embeddedmesh.cpp
index d97ab9c7bc8..0fd012c34f3 100644
--- a/extern/softbody/src/admmpd_lattice.cpp
+++ b/extern/softbody/src/admmpd_embeddedmesh.cpp
@@ -1,7 +1,7 @@
// Copyright Matt Overby 2020.
// Distributed under the MIT License.
-#include "admmpd_lattice.h"
+#include "admmpd_embeddedmesh.h"
#include "admmpd_math.h"
#include "admmpd_bvh.h"
#include "admmpd_bvh_traverse.h"
@@ -63,12 +63,20 @@ static void parallel_keep_tet(
} // end parallel test if keep tet
-bool Lattice::generate(
- const Eigen::MatrixXd &V,
- const Eigen::MatrixXi &F,
- Eigen::MatrixXd *X, // lattice vertices, n x 3
- Eigen::MatrixXi *T) // lattice elements, m x 4
+bool EmbeddedMesh::generate(
+ const Eigen::MatrixXd &V, // embedded verts
+ const Eigen::MatrixXi &F, // embedded faces
+ EmbeddedMeshData *emb_mesh, // where embedding is stored
+ Eigen::MatrixXd *x_tets) // lattice vertices, n x 3
{
+ if (emb_mesh==NULL)
+ return false;
+ if (x_tets==NULL)
+ return false;
+
+ emb_mesh->faces = F;
+ emb_mesh->x_rest = V;
+
AlignedBox<double,3> aabb;
int nv = V.rows();
for(int i=0; i<nv; ++i)
@@ -201,8 +209,6 @@ bool Lattice::generate(
else { it = tets.erase(it); }
}
- printf("Lattice: removed %d tets\n", tet_idx-(int)tets.size());
-
} // end remove unnecessary tets
// Copy data into matrices and remove unreferenced
@@ -213,14 +219,14 @@ bool Lattice::generate(
int ntv0 = verts.size(); // original num verts
int ntv1 = refd_verts.size(); // reduced num verts
BLI_assert(ntv1 <= ntv0);
- X->resize(ntv1,3);
+ x_tets->resize(ntv1,3);
int vtx_count = 0;
for (int i=0; i<ntv0; ++i)
{
if (refd_verts.count(i)>0)
{
for(int j=0; j<3; ++j){
- X->operator()(vtx_count,j) = verts[i][j];
+ x_tets->operator()(vtx_count,j) = verts[i][j];
}
vtx_old_to_new[i] = vtx_count;
vtx_count++;
@@ -229,30 +235,27 @@ bool Lattice::generate(
// Copy tets to matrix data and update vertices
int nt = tets.size();
- T->resize(nt,4);
+ emb_mesh->tets.resize(nt,4);
for(int i=0; i<nt; ++i){
for(int j=0; j<4; ++j){
int old_idx = tets[i][j];
BLI_assert(vtx_old_to_new.count(old_idx)>0);
- T->operator()(i,j) = vtx_old_to_new[old_idx];
+ emb_mesh->tets(i,j) = vtx_old_to_new[old_idx];
}
}
}
// Now compute the baryweighting for embedded vertices
- return compute_vtx_tet_mapping(
- &V, &vtx_to_tet, &barys,
- X, T);
+ return compute_embedding(
+ emb_mesh, &V, x_tets);
} // end gen lattice
typedef struct FindTetThreadData {
AABBTree<double,3> *tree;
- const MatrixXd *pts;
- VectorXi *pts_to_tet;
- MatrixXd *barys;
- const MatrixXd *tet_x;
- const MatrixXi *tets;
+ EmbeddedMeshData *emb_mesh; // thread sets vtx_to_tet and barys
+ const Eigen::MatrixXd *x_embed;
+ const Eigen::MatrixXd *x_tets;
} FindTetThreadData;
static void parallel_point_in_tet(
@@ -261,43 +264,42 @@ static void parallel_point_in_tet(
const Ta
@@ Diff output truncated at 10240 characters. @@
More information about the Bf-blender-cvs
mailing list