[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