diff options
author | Pablo Dobarro <pablodp606@gmail.com> | 2020-06-12 18:13:42 +0300 |
---|---|---|
committer | Pablo Dobarro <pablodp606@gmail.com> | 2020-06-13 20:15:29 +0300 |
commit | 23d0361b30da481ffe71142d4efd336dfb1f27f2 (patch) | |
tree | 9f6aed26d86008afbc05300fef4667ec3056c835 /source | |
parent | fe3ca3f6cef9a852ee0596b28341c519c7870d9c (diff) |
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
Diffstat (limited to 'source')
-rw-r--r-- | source/blender/blenkernel/BKE_paint.h | 2 | ||||
-rw-r--r-- | source/blender/editors/sculpt_paint/sculpt_cloth.c | 34 |
2 files changed, 35 insertions, 1 deletions
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, |