From 23d0361b30da481ffe71142d4efd336dfb1f27f2 Mon Sep 17 00:00:00 2001 From: Pablo Dobarro Date: Fri, 12 Jun 2020 17:13:42 +0200 Subject: [PATCH] Sculpt: Fix creation of repeated constraints in the Cloth Brush Previously, constraints were added multiple times from different vertices. This adds a GSet to check that the same constraint is not being added twice when iterating over the neighbors of two different vertices. Reviewed By: zeddb Differential Revision: https://developer.blender.org/D8007 --- source/blender/blenkernel/BKE_paint.h | 2 ++ .../editors/sculpt_paint/sculpt_cloth.c | 34 ++++++++++++++++++- 2 files changed, 35 insertions(+), 1 deletion(-) diff --git a/source/blender/blenkernel/BKE_paint.h b/source/blender/blenkernel/BKE_paint.h index 4d30c5c7fce..144e091d971 100644 --- a/source/blender/blenkernel/BKE_paint.h +++ b/source/blender/blenkernel/BKE_paint.h @@ -24,6 +24,7 @@ * \ingroup bke */ +#include "BLI_ghash.h" #include "BLI_utildefines.h" #include "DNA_object_enums.h" @@ -268,6 +269,7 @@ typedef struct SculptClothLengthConstraint { typedef struct SculptClothSimulation { SculptClothLengthConstraint *length_constraints; int tot_length_constraints; + GSet *created_length_constraints; int capacity_length_constraints; float *length_constraint_tweak; diff --git a/source/blender/editors/sculpt_paint/sculpt_cloth.c b/source/blender/editors/sculpt_paint/sculpt_cloth.c index 3203282c30c..7776af11a77 100644 --- a/source/blender/editors/sculpt_paint/sculpt_cloth.c +++ b/source/blender/editors/sculpt_paint/sculpt_cloth.c @@ -106,6 +106,27 @@ #define CLOTH_MAX_CONSTRAINTS_PER_VERTEX 1024 #define CLOTH_SIMULATION_TIME_STEP 0.01f +static void cloth_brush_constraint_key_get(int r_key[2], const int v1, const int v2) +{ + if (v1 < v2) { + r_key[0] = v1; + r_key[1] = v2; + } + else { + r_key[0] = v2; + r_key[1] = v1; + } +} + +static bool cloth_brush_sim_has_length_constraint(SculptClothSimulation *cloth_sim, + const int v1, + const int v2) +{ + int constraint[2]; + cloth_brush_constraint_key_get(constraint, v1, v2); + return BLI_gset_haskey(cloth_sim->created_length_constraints, constraint); +} + static void cloth_brush_add_length_constraint(SculptSession *ss, SculptClothSimulation *cloth_sim, const int v1, @@ -126,6 +147,11 @@ static void cloth_brush_add_length_constraint(SculptSession *ss, sizeof(SculptClothLengthConstraint), "length constraints"); } + + /* Add the constraint to the GSet to avoid creating it again. */ + int constraint[2]; + cloth_brush_constraint_key_get(constraint, v1, v2); + BLI_gset_add(cloth_sim->created_length_constraints, constraint); } static void do_cloth_brush_build_constraints_task_cb_ex( @@ -159,7 +185,8 @@ static void do_cloth_brush_build_constraints_task_cb_ex( for (int c_i = 0; c_i < tot_indices; c_i++) { for (int c_j = 0; c_j < tot_indices; c_j++) { - if (c_i != c_j) { + if (c_i != c_j && !cloth_brush_sim_has_length_constraint( + data->cloth_sim, build_indices[c_i], build_indices[c_j])) { cloth_brush_add_length_constraint( ss, data->cloth_sim, build_indices[c_i], build_indices[c_j]); } @@ -445,6 +472,9 @@ static void cloth_brush_build_nodes_constraints(Sculpt *sd, TaskParallelSettings settings; BKE_pbvh_parallel_range_settings(&settings, false, totnode); + cloth_sim->created_length_constraints = BLI_gset_new( + BLI_ghashutil_inthash_v2_p, BLI_ghashutil_inthash_v2_cmp, "created length constraints"); + SculptThreadedTaskData build_constraints_data = { .sd = sd, .ob = ob, @@ -456,6 +486,8 @@ static void cloth_brush_build_nodes_constraints(Sculpt *sd, }; BLI_task_parallel_range( 0, totnode, &build_constraints_data, do_cloth_brush_build_constraints_task_cb_ex, &settings); + + BLI_gset_free(cloth_sim->created_length_constraints, NULL); } static void cloth_brush_satisfy_constraints(SculptSession *ss,