[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