[Bf-blender-cvs] [72d10c1edc7] soc-2021-adaptive-cloth: adaptive_cloth: Store previous frame mesh information for remeshing

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


Commit: 72d10c1edc735dc446e7cfd23ee7e4d670b4705c
Author: ishbosamiya
Date:   Thu Aug 12 20:17:00 2021 +0530
Branches: soc-2021-adaptive-cloth
https://developer.blender.org/rB72d10c1edc735dc446e7cfd23ee7e4d670b4705c

adaptive_cloth: Store previous frame mesh information for remeshing

The modifier stack doesn't give the previously evaluated `Mesh`, this
means it needs to be stored within the `ClothModifierData`.

Some parts of the cloth modifier copy information from the given
`Mesh` to the `clothObject` every frame, this should not happen when
remeshing is on.

In `BKE_cloth_remesh()`, must use the previous frame mesh if available
for remeshing.

TODO: In case the user goes back a frame, must make the
`clmd->prev_frame_mesh` invalid otherwise the simulation will not know
that the simulation must be restart.

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

M	source/blender/blenkernel/intern/cloth.c
M	source/blender/blenkernel/intern/cloth_remesh.cc
M	source/blender/blenkernel/intern/pointcache.c
M	source/blender/makesdna/DNA_modifier_types.h
M	source/blender/modifiers/intern/MOD_cloth.c

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

diff --git a/source/blender/blenkernel/intern/cloth.c b/source/blender/blenkernel/intern/cloth.c
index df00dc74cbe..0985c7c1d1d 100644
--- a/source/blender/blenkernel/intern/cloth.c
+++ b/source/blender/blenkernel/intern/cloth.c
@@ -50,6 +50,8 @@
 
 #include "SIM_mass_spring.h"
 
+#include <stdio.h>
+
 // #include "PIL_time.h"  /* timing for debug prints */
 
 /* ********** cloth engine ******* */
@@ -269,35 +271,44 @@ static Mesh *do_step_cloth(
   MVert *mvert;
   unsigned int i = 0;
   int ret = 0;
+  const bool remesh = clmd->sim_parms->flags & CLOTH_SIMSETTINGS_FLAG_REMESH;
 
   /* simulate 1 frame forward */
   cloth = clmd->clothObject;
   verts = cloth->verts;
   mvert = mesh->mvert;
 
-  /* force any pinned verts to their constrained location. */
-  for (i = 0; i < clmd->clothObject->mvert_num; i++, verts++) {
-    /* save the previous position. */
-    copy_v3_v3(verts->xold, verts->xconst);
-    copy_v3_v3(verts->txold, verts->x);
+  printf("clmd->clothObject->mvert_num: %u framenr: %d\n", clmd->clothObject->mvert_num, framenr);
+
+  /* Don't force if remesh is active */
+  if (remesh == false) {
+    /* force any pinned verts to their constrained location. */
+    for (i = 0; i < clmd->clothObject->mvert_num; i++, verts++) {
+      /* save the previous position. */
+      copy_v3_v3(verts->xold, verts->xconst);
+      copy_v3_v3(verts->txold, verts->x);
 
-    /* Get the current position. */
-    copy_v3_v3(verts->xconst, mvert[i].co);
-    mul_m4_v3(ob->obmat, verts->xconst);
+      /* Get the current position. */
+      copy_v3_v3(verts->xconst, mvert[i].co);
+      mul_m4_v3(ob->obmat, verts->xconst);
+    }
   }
 
   effectors = BKE_effectors_create(depsgraph, ob, NULL, clmd->sim_parms->effector_weights, false);
 
-  if (clmd->sim_parms->flags & CLOTH_SIMSETTINGS_FLAG_DYNAMIC_BASEMESH) {
-    cloth_update_verts(ob, clmd, mesh);
-  }
+  /* Allow updates from mesh to cloth only if remesh is not active */
+  if (remesh == false) {
+    if (clmd->sim_parms->flags & CLOTH_SIMSETTINGS_FLAG_DYNAMIC_BASEMESH) {
+      cloth_update_verts(ob, clmd, mesh);
+    }
 
-  /* Support for dynamic vertex groups, changing from frame to frame */
-  cloth_apply_vgroup(clmd, mesh);
+    /* Support for dynamic vertex groups, changing from frame to frame */
+    cloth_apply_vgroup(clmd, mesh);
 
-  if ((clmd->sim_parms->flags & CLOTH_SIMSETTINGS_FLAG_DYNAMIC_BASEMESH) ||
-      (clmd->sim_parms->vgroup_shrink > 0) || (clmd->sim_parms->shrink_min != 0.0f)) {
-    cloth_update_spring_lengths(clmd, mesh);
+    if ((clmd->sim_parms->flags & CLOTH_SIMSETTINGS_FLAG_DYNAMIC_BASEMESH) ||
+        (clmd->sim_parms->vgroup_shrink > 0) || (clmd->sim_parms->shrink_min != 0.0f)) {
+      cloth_update_spring_lengths(clmd, mesh);
+    }
   }
 
   cloth_update_springs(clmd);
@@ -317,7 +328,7 @@ static Mesh *do_step_cloth(
 
   // printf ( "%f\n", ( float ) tval() );
 
-  if (clmd->sim_parms->flags & CLOTH_SIMSETTINGS_FLAG_REMESH) {
+  if (remesh) {
     /* In case remeshing is enabled, the remeshing function will
      * return the final mesh needed */
     return BKE_cloth_remesh(ob, clmd, mesh);
@@ -347,6 +358,15 @@ Mesh *clothModifier_do(
   BKE_ptcache_id_time(&pid, scene, framenr, &startframe, &endframe, &timescale);
   clmd->sim_parms->timescale = timescale * clmd->sim_parms->time_scale;
 
+  if (clmd->clothObject) {
+    printf("mesh->totvert: %d clmd->clothObject->mvert_num: %u\n",
+           mesh->totvert,
+           clmd->clothObject->mvert_num);
+  }
+  else {
+    printf("mesh->totvert: %d clmd->clothObject not available\n", mesh->totvert);
+  }
+
   if (clmd->sim_parms->reset ||
       (clmd->clothObject && mesh->totvert != clmd->clothObject->mvert_num)) {
     clmd->sim_parms->reset = 0;
@@ -511,6 +531,11 @@ void cloth_free_modifier(ClothModifierData *clmd)
     MEM_freeN(cloth);
     clmd->clothObject = NULL;
   }
+
+  if (clmd->prev_frame_mesh) {
+    BKE_mesh_eval_delete(clmd->prev_frame_mesh);
+    clmd->prev_frame_mesh = NULL;
+  }
 }
 
 /* frees all */
@@ -593,6 +618,11 @@ void cloth_free_modifier_extern(ClothModifierData *clmd)
     MEM_freeN(cloth);
     clmd->clothObject = NULL;
   }
+
+  if (clmd->prev_frame_mesh) {
+    BKE_mesh_eval_delete(clmd->prev_frame_mesh);
+    clmd->prev_frame_mesh = NULL;
+  }
 }
 
 /******************************************************************************
@@ -882,6 +912,10 @@ void cloth_from_mesh(ClothModifierData *clmd, const Object *ob, Mesh *mesh, bool
 
   /* Allocate vertices only if requested (alloc_verts) */
   if (alloc_verts) {
+    if (clmd->clothObject->verts) {
+      MEM_freeN(clmd->clothObject->verts);
+    }
+
     clmd->clothObject->mvert_num = mvert_num;
     clmd->clothObject->verts = MEM_callocN(sizeof(ClothVertex) * clmd->clothObject->mvert_num,
                                            "clothVertex");
@@ -902,6 +936,11 @@ void cloth_from_mesh(ClothModifierData *clmd, const Object *ob, Mesh *mesh, bool
     clmd->clothObject->primitive_num = mesh->totedge;
   }
 
+  if (clmd->clothObject->tri) {
+    MEM_freeN(clmd->clothObject->tri);
+    clmd->clothObject->tri = NULL;
+  }
+
   clmd->clothObject->tri = MEM_mallocN(sizeof(MVertTri) * looptri_num, "clothLoopTris");
   if (clmd->clothObject->tri == NULL) {
     cloth_free_modifier(clmd);
diff --git a/source/blender/blenkernel/intern/cloth_remesh.cc b/source/blender/blenkernel/intern/cloth_remesh.cc
index 74d6b47a23d..32f21e709bd 100644
--- a/source/blender/blenkernel/intern/cloth_remesh.cc
+++ b/source/blender/blenkernel/intern/cloth_remesh.cc
@@ -1301,7 +1301,12 @@ static void set_cloth_information_when_new_mesh(Object *ob, ClothModifierData *c
 
 Mesh *BKE_cloth_remesh(Object *ob, ClothModifierData *clmd, Mesh *mesh)
 {
-  auto *cloth_to_object_res = cloth_to_object(ob, clmd, mesh, false);
+  if (clmd->prev_frame_mesh) {
+    mesh = clmd->prev_frame_mesh;
+  }
+
+  Mesh *cloth_to_object_res = cloth_to_object(ob, clmd, mesh, false);
+
   BLI_assert(cloth_to_object_res == nullptr);
 
   AdaptiveRemeshParams<internal::ClothNodeData, Cloth> params;
@@ -1340,6 +1345,13 @@ Mesh *BKE_cloth_remesh(Object *ob, ClothModifierData *clmd, Mesh *mesh)
 
   set_cloth_information_when_new_mesh(ob, clmd, new_mesh);
 
+  if (clmd->prev_frame_mesh) {
+    BKE_mesh_eval_delete(clmd->prev_frame_mesh);
+    clmd->prev_frame_mesh = nullptr;
+  }
+
+  clmd->prev_frame_mesh = BKE_mesh_copy_for_eval(new_mesh, false);
+
   return new_mesh;
 }
 
diff --git a/source/blender/blenkernel/intern/pointcache.c b/source/blender/blenkernel/intern/pointcache.c
index be206f8a642..8d4b7f438ab 100644
--- a/source/blender/blenkernel/intern/pointcache.c
+++ b/source/blender/blenkernel/intern/pointcache.c
@@ -32,6 +32,7 @@
 #include "MEM_guardedalloc.h"
 
 #include "DNA_ID.h"
+#include "DNA_cloth_types.h"
 #include "DNA_collection_types.h"
 #include "DNA_dynamicpaint_types.h"
 #include "DNA_fluid_types.h"
@@ -2920,7 +2921,18 @@ int BKE_ptcache_id_reset(Scene *scene, PTCacheID *pid, int mode)
     cache->flag &= ~PTCACHE_REDO_NEEDED;
 
     if (pid->type == PTCACHE_TYPE_CLOTH) {
-      cloth_free_modifier(pid->calldata);
+      ClothModifierData *clmd = (ClothModifierData *)pid->calldata;
+
+      const bool remesh = clmd->sim_parms->flags & CLOTH_SIMSETTINGS_FLAG_REMESH;
+      /* This is a hacky way to prevent deleting the previous frame
+       * information needed by the remeshing step. The remeshing step
+       * always leads to an invalid cache as of right now. Instead of
+       * disabling the point cache through the modifier, this is
+       * easier method. Will need to come around to fixing this
+       * later. */
+      if (remesh == false) {
+        cloth_free_modifier(clmd);
+      }
     }
     else if (pid->type == PTCACHE_TYPE_SOFTBODY) {
       sbFreeSimulation(pid->calldata);
diff --git a/source/blender/makesdna/DNA_modifier_types.h b/source/blender/makesdna/DNA_modifier_types.h
index 4cf74ad19d4..632f3c3d69c 100644
--- a/source/blender/makesdna/DNA_modifier_types.h
+++ b/source/blender/makesdna/DNA_modifier_types.h
@@ -829,6 +829,7 @@ typedef struct ClothModifierData {
   float hair_grid_cellsize;
 
   struct ClothSolverResult *solver_result;
+  struct Mesh *prev_frame_mesh;
 } ClothModifierData;
 
 typedef struct CollisionModifierData {
diff --git a/source/blender/modifiers/intern/MOD_cloth.c b/source/blender/modifiers/intern/MOD_cloth.c
index 2c6a4e85b93..d0036c96f71 100644
--- a/source/blender/modifiers/intern/MOD_cloth.c
+++ b/source/blender/modifiers/intern/MOD_cloth.c
@@ -87,6 +87,8 @@ static void initData(ModifierData *md)
   if (clmd->point_cache) {
     clmd->point_cache->step = 1;
   }
+
+  clmd->prev_frame_mesh = NULL;
 }
 
 static Mesh *modifyMesh(ModifierData *md, const ModifierEvalContext *ctx, Mesh *mesh)



More information about the Bf-blender-cvs mailing list