[Bf-blender-cvs] [aa7fceb7a1f] soc-2021-adaptive-cloth: adaptive_cloth: set cloth information after remeshing

ishbosamiya noreply at git.blender.org
Sun Aug 22 17:23:39 CEST 2021


Commit: aa7fceb7a1f7aa2c61e0d8d107c6171e32a1e937
Author: ishbosamiya
Date:   Thu Aug 12 11:48:26 2021 +0530
Branches: soc-2021-adaptive-cloth
https://developer.blender.org/rBaa7fceb7a1f7aa2c61e0d8d107c6171e32a1e937

adaptive_cloth: set cloth information after remeshing

The cloth object doesn't know about the updated mesh, so update the
entire cloth object to utilize the new mesh.

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

M	source/blender/blenkernel/BKE_cloth.h
M	source/blender/blenkernel/intern/cloth.c
M	source/blender/blenkernel/intern/cloth_remesh.cc

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

diff --git a/source/blender/blenkernel/BKE_cloth.h b/source/blender/blenkernel/BKE_cloth.h
index 7bc042e393c..a80ba2608bd 100644
--- a/source/blender/blenkernel/BKE_cloth.h
+++ b/source/blender/blenkernel/BKE_cloth.h
@@ -257,6 +257,12 @@ struct Mesh *cloth_to_object(struct Object *ob,
                              struct ClothModifierData *clmd,
                              struct Mesh *mesh,
                              bool create_new);
+void cloth_from_mesh(struct ClothModifierData *clmd,
+                     const Object *ob,
+                     struct Mesh *mesh,
+                     bool alloc_verts);
+bool cloth_build_springs(struct ClothModifierData *clmd, struct Mesh *mesh);
+struct BVHTree *bvhtree_build_from_cloth(struct ClothModifierData *clmd, float epsilon);
 
 // needed for collision.c
 void bvhtree_update_from_cloth(struct ClothModifierData *clmd, bool moving, bool self);
diff --git a/source/blender/blenkernel/intern/cloth.c b/source/blender/blenkernel/intern/cloth.c
index 16ce1e9279c..df00dc74cbe 100644
--- a/source/blender/blenkernel/intern/cloth.c
+++ b/source/blender/blenkernel/intern/cloth.c
@@ -55,13 +55,11 @@
 /* ********** cloth engine ******* */
 /* Prototypes for internal functions.
  */
-static void cloth_from_mesh(ClothModifierData *clmd, const Object *ob, Mesh *mesh);
 static bool cloth_from_object(
     Object *ob, ClothModifierData *clmd, Mesh *mesh, float framenr, int first);
 static void cloth_update_springs(ClothModifierData *clmd);
 static void cloth_update_verts(Object *ob, ClothModifierData *clmd, Mesh *mesh);
 static void cloth_update_spring_lengths(ClothModifierData *clmd, Mesh *mesh);
-static bool cloth_build_springs(ClothModifierData *clmd, Mesh *mesh);
 static void cloth_apply_vgroup(ClothModifierData *clmd, Mesh *mesh);
 
 typedef struct BendSpringRef {
@@ -76,7 +74,7 @@ typedef struct BendSpringRef {
  *
  ******************************************************************************/
 
-static BVHTree *bvhtree_build_from_cloth(ClothModifierData *clmd, float epsilon)
+BVHTree *bvhtree_build_from_cloth(ClothModifierData *clmd, float epsilon)
 {
   if (!clmd) {
     return NULL;
@@ -795,7 +793,7 @@ static bool cloth_from_object(
     return false;
   }
 
-  cloth_from_mesh(clmd, ob, mesh);
+  cloth_from_mesh(clmd, ob, mesh, true);
 
   /* create springs */
   clmd->clothObject->springs = NULL;
@@ -875,23 +873,25 @@ static bool cloth_from_object(
   return true;
 }
 
-static void cloth_from_mesh(ClothModifierData *clmd, const Object *ob, Mesh *mesh)
+void cloth_from_mesh(ClothModifierData *clmd, const Object *ob, Mesh *mesh, bool alloc_verts)
 {
   const MLoop *mloop = mesh->mloop;
   const MLoopTri *looptri = BKE_mesh_runtime_looptri_ensure(mesh);
   const unsigned int mvert_num = mesh->totvert;
   const unsigned int looptri_num = mesh->runtime.looptris.len;
 
-  /* Allocate our vertices. */
-  clmd->clothObject->mvert_num = mvert_num;
-  clmd->clothObject->verts = MEM_callocN(sizeof(ClothVertex) * clmd->clothObject->mvert_num,
-                                         "clothVertex");
-  if (clmd->clothObject->verts == NULL) {
-    cloth_free_modifier(clmd);
-    BKE_modifier_set_error(
-        ob, &(clmd->modifier), "Out of memory on allocating clmd->clothObject->verts");
-    printf("cloth_free_modifier clmd->clothObject->verts\n");
-    return;
+  /* Allocate vertices only if requested (alloc_verts) */
+  if (alloc_verts) {
+    clmd->clothObject->mvert_num = mvert_num;
+    clmd->clothObject->verts = MEM_callocN(sizeof(ClothVertex) * clmd->clothObject->mvert_num,
+                                           "clothVertex");
+    if (clmd->clothObject->verts == NULL) {
+      cloth_free_modifier(clmd);
+      BKE_modifier_set_error(
+          ob, &(clmd->modifier), "Out of memory on allocating clmd->clothObject->verts");
+      printf("cloth_free_modifier clmd->clothObject->verts\n");
+      return;
+    }
   }
 
   /* save face information */
@@ -917,8 +917,36 @@ static void cloth_from_mesh(ClothModifierData *clmd, const Object *ob, Mesh *mes
   /* Free the springs since they can't be correct if the vertices
    * changed.
    */
-  if (clmd->clothObject->springs != NULL) {
-    MEM_freeN(clmd->clothObject->springs);
+  {
+    if (clmd->clothObject->springs != NULL) {
+      LinkNode *search = clmd->clothObject->springs;
+      while (search) {
+        ClothSpring *spring = search->link;
+
+        MEM_SAFE_FREE(spring->pa);
+        MEM_SAFE_FREE(spring->pb);
+
+        MEM_freeN(spring);
+        search = search->next;
+      }
+      BLI_linklist_free(clmd->clothObject->springs, NULL);
+
+      clmd->clothObject->springs = NULL;
+    }
+
+    clmd->clothObject->springs = NULL;
+    clmd->clothObject->numsprings = 0;
+
+    if (clmd->clothObject->edgeset != NULL) {
+      BLI_edgeset_free(clmd->clothObject->edgeset);
+      clmd->clothObject->edgeset = NULL;
+    }
+  }
+
+  /* Free the sew edge graph since it may not be correct if vertices changed */
+  if (clmd->clothObject->sew_edge_graph != NULL) {
+    BLI_edgeset_free(clmd->clothObject->sew_edge_graph);
+    clmd->clothObject->sew_edge_graph = NULL;
   }
 }
 
@@ -1503,7 +1531,7 @@ static bool find_internal_spring_target_vertex(BVHTreeFromMesh *treedata,
   return false;
 }
 
-static bool cloth_build_springs(ClothModifierData *clmd, Mesh *mesh)
+bool cloth_build_springs(ClothModifierData *clmd, Mesh *mesh)
 {
   Cloth *cloth = clmd->clothObject;
   ClothSpring *spring = NULL, *tspring = NULL, *tspring2 = NULL;
diff --git a/source/blender/blenkernel/intern/cloth_remesh.cc b/source/blender/blenkernel/intern/cloth_remesh.cc
index 83adcf3105f..2189237a21e 100644
--- a/source/blender/blenkernel/intern/cloth_remesh.cc
+++ b/source/blender/blenkernel/intern/cloth_remesh.cc
@@ -28,6 +28,7 @@
 
 #include "BLI_assert.h"
 #include "BLI_float2x2.hh"
+#include "BLI_kdopbvh.h"
 #include "BLI_math_vector.h"
 #include "BLI_utildefines.h"
 
@@ -35,6 +36,9 @@
 
 #include "BKE_cloth.h"
 #include "BKE_cloth_remesh.hh"
+#include "BKE_modifier.h"
+
+#include "SIM_mass_spring.h"
 
 #include <algorithm>
 #include <cmath>
@@ -1196,6 +1200,46 @@ Mesh *adaptive_remesh<internal::EmptyExtraData, internal::EmptyExtraData>(
     Mesh *,
     internal::EmptyExtraData const &);
 
+/**
+ * If the mesh has been updated, the caller must ensure that
+ * clmd->clothObject->verts has been set and then call this to update
+ * the rest of the cloth modifier to reflect the changes in the mesh.
+ */
+static void set_cloth_information_when_new_mesh(Object *ob, ClothModifierData *clmd, Mesh *mesh)
+{
+  BLI_assert(clmd != nullptr);
+  BLI_assert(mesh != nullptr);
+  Cloth &cloth = *clmd->clothObject;
+  BLI_assert(cloth.verts != nullptr);
+  BLI_assert(cloth.mvert_num == mesh->totvert);
+
+  cloth_from_mesh(clmd, ob, mesh, false);
+
+  /* Build the springs */
+  if (!cloth_build_springs(clmd, mesh)) {
+    cloth_free_modifier(clmd);
+    BKE_modifier_set_error(ob, &(clmd->modifier), "Cannot build springs");
+    /* TODO(ish): error handling */
+    /* return false; */
+  }
+
+  /* Set up the cloth solver */
+  SIM_cloth_solver_free(clmd);
+  SIM_cloth_solver_init(ob, clmd);
+  SIM_cloth_solver_set_positions(clmd);
+
+  /* Free any existing bvh trees */
+  if (clmd->clothObject->bvhtree) {
+    BLI_bvhtree_free(clmd->clothObject->bvhtree);
+  }
+  if (clmd->clothObject->bvhselftree) {
+    BLI_bvhtree_free(clmd->clothObject->bvhselftree);
+  }
+
+  clmd->clothObject->bvhtree = bvhtree_build_from_cloth(clmd, clmd->coll_parms->epsilon);
+  clmd->clothObject->bvhselftree = bvhtree_build_from_cloth(clmd, clmd->coll_parms->selfepsilon);
+}
+
 Mesh *BKE_cloth_remesh(Object *ob, ClothModifierData *clmd, Mesh *mesh)
 {
   auto *cloth_to_object_res = cloth_to_object(ob, clmd, mesh, false);
@@ -1233,7 +1277,11 @@ Mesh *BKE_cloth_remesh(Object *ob, ClothModifierData *clmd, Mesh *mesh)
     cloth.mvert_num = num_nodes;
   };
 
-  return adaptive_remesh(params, mesh, *clmd->clothObject);
+  Mesh *new_mesh = adaptive_remesh(params, mesh, *clmd->clothObject);
+
+  set_cloth_information_when_new_mesh(ob, clmd, new_mesh);
+
+  return new_mesh;
 }
 
 Mesh *__temp_empty_adaptive_remesh(const TempEmptyAdaptiveRemeshParams &input_params, Mesh *mesh)



More information about the Bf-blender-cvs mailing list