[Bf-blender-cvs] [710e1285c15] soc-2020-soft-body: fixed blender file read write for admmpd data

mattoverby noreply at git.blender.org
Wed Aug 12 20:29:21 CEST 2020


Commit: 710e1285c150e1119ec6f991e88804057c5640c5
Author: mattoverby
Date:   Wed Aug 12 13:29:16 2020 -0500
Branches: soc-2020-soft-body
https://developer.blender.org/rB710e1285c150e1119ec6f991e88804057c5640c5

fixed blender file read write for admmpd data

===================================================================

M	extern/softbody/src/admmpd_collision.cpp
M	extern/softbody/src/admmpd_types.h
M	intern/softbody/admmpd_api.cpp
M	intern/softbody/admmpd_api.h
M	release/scripts/startup/bl_ui/properties_physics_softbody.py
M	source/blender/blenkernel/BKE_softbody.h
M	source/blender/blenkernel/intern/softbody.c
M	source/blender/blenloader/intern/readfile.c
M	source/blender/blenloader/intern/writefile.c
M	source/blender/makesdna/DNA_object_force_types.h
M	source/blender/makesrna/intern/rna_object_force.c

===================================================================

diff --git a/extern/softbody/src/admmpd_collision.cpp b/extern/softbody/src/admmpd_collision.cpp
index c9609c1da03..9e63ab70575 100644
--- a/extern/softbody/src/admmpd_collision.cpp
+++ b/extern/softbody/src/admmpd_collision.cpp
@@ -221,8 +221,18 @@ int EmbeddedMeshCollision::detect(
 			}
 		}
 
+		// We perform self collision if the self_collision flag is true and either:
+		// a) the set of vertices (vertex group) to do self collision is empty
+		// b) the vertex is in the set of self collision vertices
+		bool do_self_collision = td->options->self_collision;
+		if (do_self_collision) {
+			if (td->data->col.selfcollision_verts.size()>0) {
+				do_self_collision = td->data->col.selfcollision_verts.count(vi)>0;
+			}
+		}
+
 		// Detect against self
-		if (td->options->self_collision)
+		if (do_self_collision)
 		{
 			std::pair<bool,VFCollisionPair> pt_hit_self =
 				td->collision->detect_against_self(
diff --git a/extern/softbody/src/admmpd_types.h b/extern/softbody/src/admmpd_types.h
index e3d5e796504..f6e8db6666f 100644
--- a/extern/softbody/src/admmpd_types.h
+++ b/extern/softbody/src/admmpd_types.h
@@ -140,6 +140,7 @@ public:
         Eigen::MatrixXd Ap;
     } ls;
     struct CollisionData {
+        std::set<int> selfcollision_verts; // inds to test self collision
         std::vector<Eigen::AlignedBox<double,3> > prim_boxes;
         AABBTree<double,3> prim_tree;
     } col;
diff --git a/intern/softbody/admmpd_api.cpp b/intern/softbody/admmpd_api.cpp
index db9bfee8f9d..63a884d5828 100644
--- a/intern/softbody/admmpd_api.cpp
+++ b/intern/softbody/admmpd_api.cpp
@@ -82,8 +82,9 @@ static inline void options_from_object(
   (void)(iface);
 
   SoftBody *sb = ob->soft;
-  if (sb==NULL)
+  if (sb==NULL) {
     return;
+  }
 
   // Set options that don't require a re-initialization
   op->max_admm_iters = std::max(1,sb->admmpd_max_admm_iters);
@@ -119,8 +120,9 @@ static inline void vecs_from_object(
   std::vector<float> &v,
   std::vector<unsigned int> &f)
 {
-  if(ob->type != OB_MESH)
+  if(ob->type != OB_MESH) {
     return;
+  }
 
   Mesh *me = (Mesh*)ob->data;
 
@@ -215,8 +217,7 @@ static inline int admmpd_init_with_tetgen(ADMMPDInterfaceData *iface, Object *ob
     tg.out_tets,
     tg.out_tottets);
 
-  if (!success)
-  {
+  if (!success) {
     strcpy_error(iface, "TetMesh failed on creation");
     return 0;
   }
@@ -246,8 +247,7 @@ static inline int admmpd_init_with_lattice(ADMMPDInterfaceData *iface, Object *o
     nullptr,
     0);
 
-  if (!success)
-  {
+  if (!success) {
     strcpy_error(iface, "EmbeddedMesh failed on creation");
     return 0;
   }
@@ -271,8 +271,7 @@ static inline int admmpd_init_as_cloth(ADMMPDInterfaceData *iface, Object *ob, f
     nullptr,
     0);
 
-  if (!success)
-  {
+  if (!success) {
     strcpy_error(iface, "TriangleMesh failed on creation");
     return 0;
   }
@@ -290,15 +289,13 @@ static inline int admmpd_reinit_solver(ADMMPDInterfaceData *iface)
   if (!iface->idata->options) { return 0; }
   if (!iface->idata->data) { return 0; }
 
-  try
-  {
+  try {
     admmpd::Solver().init(
       iface->idata->mesh.get(),
       iface->idata->options.get(),
       iface->idata->data.get());
   }
-  catch(const std::exception &e)
-  {
+  catch(const std::exception &e) {
     strcpy_error(iface, e.what());
     return 0;
   }
@@ -313,7 +310,6 @@ int admmpd_mesh_needs_update(ADMMPDInterfaceData *iface, Object *ob)
   if (!ob->data) { return 0; }
   if (!iface->idata) { return 1; }
   if (!iface->idata->mesh) { return 1; }
-
   Mesh *mesh = (Mesh*)ob->data;
   if (!mesh) { return 0; }
 
@@ -342,8 +338,7 @@ int admmpd_update_mesh(ADMMPDInterfaceData *iface, Object *ob, float (*vertexCos
 
   // Try to initialize the mesh
   const Eigen::MatrixXd *x0 = nullptr;
-  try
-  {
+  try {
     int gen_success = 0;
     switch (mode)
     {
@@ -367,14 +362,12 @@ int admmpd_update_mesh(ADMMPDInterfaceData *iface, Object *ob, float (*vertexCos
         }
       } break;
     }
-    if (!gen_success || !iface->idata->mesh || x0==nullptr)
-    {
+    if (!gen_success || !iface->idata->mesh || x0==nullptr) {
       strcpy_error(iface, "failed to init mesh");
       return 0;
     }
   }
-  catch(const std::exception &e)
-  {
+  catch(const std::exception &e) {
     strcpy_error(iface, e.what());
     return 0;
   }
@@ -382,8 +375,9 @@ int admmpd_update_mesh(ADMMPDInterfaceData *iface, Object *ob, float (*vertexCos
   // Set up softbody to store defo verts
   int n_defo_verts = x0->rows();
   SoftBody *sb = ob->soft;
-  if (sb->bpoint)
+  if (sb->bpoint) {
     MEM_freeN(sb->bpoint);
+  }
 
   sb->totpoint = n_defo_verts;
   sb->totspring = 0;
@@ -391,11 +385,9 @@ int admmpd_update_mesh(ADMMPDInterfaceData *iface, Object *ob, float (*vertexCos
 
   // Copy init data to BodyPoint
   BodyPoint *pts = sb->bpoint;
-  for (int i=0; i<n_defo_verts; ++i)
-  {
+  for (int i=0; i<n_defo_verts; ++i) {
     BodyPoint *pt = &pts[i];
-    for(int j=0; j<3; ++j)
-    {
+    for(int j=0; j<3; ++j) {
       pt->pos[j] = x0->operator()(i,j);
       pt->vec[j] = 0;
     }
@@ -449,15 +441,13 @@ int admmpd_update_solver(ADMMPDInterfaceData *iface,  Scene *sc, Object *ob, flo
   admmpd::Options *op = iface->idata->options.get();
   options_from_object(iface,sc,ob,op,false);
 
-  try
-  {
+  try {
     admmpd::Solver().init(
       iface->idata->mesh.get(),
       iface->idata->options.get(),
       iface->idata->data.get());
   }
-  catch(const std::exception &e)
-  {
+  catch(const std::exception &e) {
     strcpy_error(iface, e.what());
     return 0;
   }
@@ -478,11 +468,9 @@ void admmpd_copy_from_object(ADMMPDInterfaceData *iface, Object *ob)
   // copy over up to the amount that we can.
   int nx = iface->idata->data->x.rows();
   int nv = std::min(ob->soft->totpoint, nx);
-  for (int i=0; i<nv; ++i)
-  {
+  for (int i=0; i<nv; ++i) {
     const BodyPoint *pt = &ob->soft->bpoint[i];
-    for(int j=0; j<3; ++j)
-    {
+    for(int j=0; j<3; ++j) {
       iface->idata->data->x(i,j)=pt->pos[j];
       iface->idata->data->v(i,j)=pt->vec[j];
     }
@@ -499,13 +487,12 @@ void admmpd_copy_to_object(ADMMPDInterfaceData *iface, Object *ob, float (*verte
 
   int nx = iface->idata->data->x.rows();
 
-  if (ob && ob->soft)
-  {
+  if (ob && ob->soft) {
     SoftBody *sb = ob->soft;
-    if (!sb->bpoint)
-    {
-      if (!ob->soft->bpoint)
+    if (!sb->bpoint) {
+      if (!ob->soft->bpoint) {
         sb->bpoint = (BodyPoint*)MEM_callocN(nx*sizeof(BodyPoint), "ADMMPD_bpoint");
+      }
 
       sb->totpoint = nx;
       sb->totspring = 0;
@@ -513,11 +500,9 @@ void admmpd_copy_to_object(ADMMPDInterfaceData *iface, Object *ob, float (*verte
 
     // Copy internal data to BodyPoint
     int np = std::min(ob->soft->totpoint, nx);
-    for (int i=0; i<np; ++i)
-    {
+    for (int i=0; i<np; ++i) {
       BodyPoint *pt = &ob->soft->bpoint[i];
-      for(int j=0; j<3; ++j)
-      {
+      for(int j=0; j<3; ++j) {
         pt->pos[j] = iface->idata->data->x(i,j);
         pt->vec[j] = iface->idata->data->v(i,j);
       }
@@ -526,18 +511,15 @@ void admmpd_copy_to_object(ADMMPDInterfaceData *iface, Object *ob, float (*verte
 
   // Copy to vertexCos
   int nfv = iface->idata->mesh->rest_facet_verts()->rows();
-  if (vertexCos != NULL)
-  {
-    for (int i=0; i<nfv; ++i)
-    {
+  if (vertexCos != NULL) {
+    for (int i=0; i<nfv; ++i) {
       Eigen::Vector3d xi =
         iface->idata->mesh->get_mapped_facet_vertex(
         &iface->idata->data->x, i);
       vertexCos[i][0] = xi[0];
       vertexCos[i][1] = xi[1];
       vertexCos[i][2] = xi[2];
-      if (ob && ob->soft && ob->soft->local==0)
-      {
+      if (ob && ob->soft && ob->soft->local==0) {
         mul_m4_v3(ob->imat, vertexCos[i]);
       }
     }
@@ -552,8 +534,9 @@ void admmpd_update_obstacles(
     unsigned int *in_faces,
     int nf)
 {
-  if (iface==NULL || in_verts_0==NULL || in_verts_1==NULL || in_faces==NULL)
+  if (iface==NULL || in_verts_0==NULL || in_verts_1==NULL || in_faces==NULL) {
     return;
+  }
   if (!iface->idata) { return; }
   if (!iface->idata->collision) { return; }
   if (nf==0 || nv==0) { return; }
@@ -564,17 +547,17 @@ void admmpd_update_obstacles(
   int nf3 = nf*3;
   iface->idata->obs.F.resize(nf3);
 
-  for (int i=0; i<nv3; ++i)
-  {
+  for (int i=0; i<nv3; ++i) {
     iface->idata->obs.x0[i] = in_verts_0[i];
     iface->idata->obs.x1[i] = in_verts_1[i];
   }
-  for (int i=0; i<nf3; ++i)
+  for (int i=0; i<nf3; ++i) {
     iface->idata->obs.F[i] = in_faces[i];
+  }
 
 }
 
-void admmpd_update_goals(ADMMPDInterfaceData *iface, Object *ob, float (*vertexCos)[3])
+static inline void admmpd_update_goals(ADMMPDInterfaceData *iface, Object *ob, float (*vertexCos)[3])
 {
   if (!iface) { return; }
   if (!iface->idata) { return; }
@@ -587,8 +570,7 @@ void admmpd_update_goals(ADMMPDInterfaceData *iface, Object *ob, float (*vertexC
   if (!me) { return; }
 
   // Goal positions turned off
-  if (!(ob->softflag & OB_SB_GOAL))
-  {
+  if (!(ob->softflag & OB_SB_GOAL)) {
     iface->idata->mesh->clear_pins();
     return;
   }
@@ -619,34 +601,77 @@ void admmpd_update_goals(ADMMPDInterfaceData *iface, Object *ob, float (*vertexC
     iface->idata->mesh->set_pin(i,goal_pos,k);
 
   } // end loop verts
+} // end update goals
+
+static inline void update_selfcollision_group(ADMMPDInterfaceData *iface, Object *ob)
+{
+  if (!iface) { return; }
+  if (!iface->idata) { return; }
+  if (!iface->idata->options) { return; }
+  if (!iface->idata->data) { return; }
+  if (!iface->idata->options->self_collision) { return; }
+
+  if (!ob) { return; }
+  if (!ob->soft) { return; }
+  Mesh *me = (Mesh*)ob->data;
+  if (!me) { return; }
+  SoftBody *sb = ob->soft;
+
+  int defgroup_idx_selfcollide = me->dvert ?
+    BKE_object_defgroup_name_index(ob, sb->admmpd_namedVG_selfcollision) : -1;
+
+  // If we do not have a self collision vertex group, we want to
+  // do self collision on all vertices. If the selfcollision_verts set
+  // is empty, the collider will test all verts.
+  iface->idata->data->col.selfcollision_verts.clear();
+  if (defgroup_idx_selfcollide == -1) {
+    return;
+  }
+
+  // Otherwise, we need to set which vertices are to be tested.
+  int nv = me->totvert;
+  

@@ Diff output truncated at 10240 characters. @@



More information about the Bf-blender-cvs mailing list