[Bf-blender-cvs] [2274a4e2f08] soc-2020-soft-body: added warning and disable self collisions for non closed meshes
mattoverby
noreply at git.blender.org
Fri Aug 21 16:52:14 CEST 2020
Commit: 2274a4e2f0849b9078842e7fe74b43c4483abb42
Author: mattoverby
Date: Fri Aug 21 09:52:10 2020 -0500
Branches: soc-2020-soft-body
https://developer.blender.org/rB2274a4e2f0849b9078842e7fe74b43c4483abb42
added warning and disable self collisions for non closed meshes
===================================================================
M extern/softbody/src/admmpd_mesh.cpp
M extern/softbody/src/admmpd_mesh.h
M intern/softbody/admmpd_api.cpp
M source/blender/blenkernel/intern/softbody.c
===================================================================
diff --git a/extern/softbody/src/admmpd_mesh.cpp b/extern/softbody/src/admmpd_mesh.cpp
index 193ff6313f2..e9e338a581d 100644
--- a/extern/softbody/src/admmpd_mesh.cpp
+++ b/extern/softbody/src/admmpd_mesh.cpp
@@ -75,6 +75,8 @@ bool EmbeddedMesh::create(
log.start_state(SOLVERSTATE_MESHCREATE);
P_updated = true;
+ mesh_is_closed = false;
+
if (nv<=0 || verts == nullptr) {
log.stop_state(SOLVERSTATE_MESHCREATE);
return false;
@@ -196,13 +198,14 @@ bool EmbeddedMesh::create(
if (options->log_level >= LOGLEVEL_DEBUG) {
printf("%s\n",log.to_string().c_str());
}
+
return true;
}
void EmbeddedMesh::compute_sdf(
const Eigen::MatrixXd *emb_v,
const Eigen::MatrixXi *emb_f,
- SDFType *sdf) const
+ SDFType *sdf)
{
Matrix<double,Dynamic,Dynamic,RowMajor> v_rm = *emb_v;
Matrix<unsigned int,Dynamic,Dynamic,RowMajor> f_rm = emb_f->cast<unsigned int>();
@@ -216,6 +219,8 @@ void EmbeddedMesh::compute_sdf(
domain.min() -= 1e-3 * domain.diagonal().norm() * Eigen::Vector3d::Ones();
Discregrid::TriangleMesh tm(v_rm.data(), f_rm.data(), v_rm.rows(), f_rm.rows());
+ mesh_is_closed = tm.is_closed();
+
Discregrid::MeshDistance md(tm);
std::array<unsigned int, 3> resolution;
resolution[0] = 30; resolution[1] = 30; resolution[2] = 30;
@@ -542,6 +547,7 @@ bool TetMesh::create(
int nt) // must be > 0
{
P_updated = true;
+
if (nv<=0 || verts == nullptr)
return false;
if (nf<=0 || faces == nullptr)
@@ -711,6 +717,7 @@ bool TriangleMesh::create(
{
(void)(options);
P_updated = true;
+
(void)(tets); (void)(nt);
if (nv<=0 || verts == nullptr)
return false;
diff --git a/extern/softbody/src/admmpd_mesh.h b/extern/softbody/src/admmpd_mesh.h
index d3d948f62ae..01e0f644418 100644
--- a/extern/softbody/src/admmpd_mesh.h
+++ b/extern/softbody/src/admmpd_mesh.h
@@ -36,6 +36,8 @@ public:
virtual const Eigen::MatrixXd *rest_facet_verts() const = 0;
virtual const SDFType *rest_facet_sdf() const = 0;
+ virtual bool self_collision_allowed() const = 0;
+
// Maps primitive vertex to facet vertex. For standard tet meshes
// it's just one-to-one, but embedded meshes use bary weighting.
virtual Eigen::Vector3d get_mapped_facet_vertex(
@@ -86,6 +88,7 @@ protected:
std::unordered_map<int,double> emb_pin_k;
std::unordered_map<int,Eigen::Vector3d> emb_pin_pos;
admmpd::AABBTree<double,3> emb_rest_facet_tree;
+ bool mesh_is_closed;
SDFType emb_sdf;
mutable bool P_updated; // set to false on linearize_pins
@@ -94,10 +97,11 @@ protected:
// Computes the tet mesh on a subset of faces
bool compute_lattice(const admmpd::Options *options);
+ // Sets mesh_is_closed
void compute_sdf(
const Eigen::MatrixXd *emb_v,
const Eigen::MatrixXi *emb_f,
- SDFType *sdf) const;
+ SDFType *sdf);
public:
@@ -121,6 +125,8 @@ public:
const SDFType *rest_facet_sdf() const { return &emb_sdf; }
const admmpd::AABBTree<double,3> *emb_rest_tree() const { return &emb_rest_facet_tree; }
+ bool self_collision_allowed() const { return mesh_is_closed; }
+
Eigen::Vector3d get_mapped_facet_vertex(
const Eigen::MatrixXd *prim_verts,
int facet_vertex_idx) const;
@@ -185,6 +191,9 @@ public:
const Eigen::MatrixXd *rest_prim_verts() const { return &V0; }
const SDFType *rest_facet_sdf() const { return &rest_sdf; }
+ // Not yet implemented
+ bool self_collision_allowed() const { return false; }
+
Eigen::Vector3d get_mapped_facet_vertex(
const Eigen::MatrixXd *prim_verts,
int facet_vertex_idx) const
@@ -246,6 +255,9 @@ public:
const Eigen::MatrixXd *rest_facet_verts() const { return &V0; }
const SDFType *rest_facet_sdf() const { return nullptr; }
+ // Not yet implemented
+ bool self_collision_allowed() const { return false; }
+
Eigen::Vector3d get_mapped_facet_vertex(
const Eigen::MatrixXd *prim_verts,
int facet_vertex_idx) const {
diff --git a/intern/softbody/admmpd_api.cpp b/intern/softbody/admmpd_api.cpp
index 671ecf44bf1..a9699eb936b 100644
--- a/intern/softbody/admmpd_api.cpp
+++ b/intern/softbody/admmpd_api.cpp
@@ -595,11 +595,18 @@ int admmpd_solve(ADMMPDInterfaceData *iface, Object *ob, float (*vertexCos)[3])
return 0;
}
- if (!iface->idata || !iface->idata->options || !iface->idata->data) {
+ if (!iface->idata || !iface->idata->options ||
+ !iface->idata->data || !iface->idata->mesh) {
strcpy_error(iface, "NULL internal data");
return 0;
}
+ std::string meshname(ob->id.name);
+
+ // Set to true if certain conditions should
+ // throw a warning flag.
+ bool return_warning = false;
+
// Change only options that do not cause a reset of the solver.
bool skip_solver_reset = true;
options_from_object(
@@ -609,6 +616,19 @@ int admmpd_solve(ADMMPDInterfaceData *iface, Object *ob, float (*vertexCos)[3])
iface->idata->options.get(),
skip_solver_reset);
+ // Disable self collision flag if the mesh does not support it.
+ if (iface->idata->options->self_collision &&
+ !iface->idata->mesh->self_collision_allowed()) {
+ // Special message if embedded, in which the mesh is not closed.
+ std::string err = "Cannot do self collisions on object "+meshname+" for selected mesh type";
+ if (iface->idata->mesh->type() == MESHTYPE_EMBEDDED) {
+ err = "Cannot do self collisions on object "+meshname+", mesh is not closed.";
+ }
+ strcpy_error(iface, err.c_str());
+ iface->idata->options->self_collision = false;
+ return_warning = true;
+ }
+
// Goals and self collision group can change
// between time steps. If the goal indices/weights change,
// it will trigger a refactorization in the solver.
@@ -617,12 +637,11 @@ int admmpd_solve(ADMMPDInterfaceData *iface, Object *ob, float (*vertexCos)[3])
// Obstacle collisions not yet implemented
// for cloth or tet mesh.
- bool had_set_obstacle_error = false;
if ((ob->soft->admmpd_mesh_mode == MESHTYPE_TET ||
ob->soft->admmpd_mesh_mode == MESHTYPE_TRIANGLE) &&
iface->idata->obs_x0.size()>0)
{
- had_set_obstacle_error = true;
+ return_warning = true;
strcpy_error(iface, "Obstacle collision not yet available for selected mesh mode.");
}
@@ -644,7 +663,7 @@ int admmpd_solve(ADMMPDInterfaceData *iface, Object *ob, float (*vertexCos)[3])
iface->idata->obs_x0, iface->idata->obs_x1, iface->idata->obs_F,
&set_obs_error)) {
strcpy_error(iface, set_obs_error.c_str());
- had_set_obstacle_error = true;
+ return_warning = true;
}
}
@@ -665,7 +684,7 @@ int admmpd_solve(ADMMPDInterfaceData *iface, Object *ob, float (*vertexCos)[3])
iface->idata->obs_x0, iface->idata->obs_x1, iface->idata->obs_F,
&set_obs_error)) {
strcpy_error(iface, set_obs_error.c_str());
- had_set_obstacle_error = true;
+ return_warning = true;
}
}
@@ -684,8 +703,7 @@ int admmpd_solve(ADMMPDInterfaceData *iface, Object *ob, float (*vertexCos)[3])
return 0;
}
- if (had_set_obstacle_error) {
- // Return warning (-1).
+ if (return_warning) {
// We've already copied the error message.
return -1;
}
diff --git a/source/blender/blenkernel/intern/softbody.c b/source/blender/blenkernel/intern/softbody.c
index 678e1fd225c..d73a4b08c07 100644
--- a/source/blender/blenkernel/intern/softbody.c
+++ b/source/blender/blenkernel/intern/softbody.c
@@ -3836,9 +3836,6 @@ void sbObjectStep(struct Depsgraph *depsgraph,
if (init_mesh || init_solver) {
BKE_ptcache_invalidate(cache);
- //BKE_ptcache_id_reset(scene, &pid, PTCACHE_RESET_OUTDATED);
- //return;
- //admmpd_copy_from_object(admmpd, ob);
}
}
else if (sb->solver_mode == SOLVER_MODE_LEGACY) {
More information about the Bf-blender-cvs
mailing list