Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
path: root/source
diff options
context:
space:
mode:
authorSebastian Parborg <darkdefende@gmail.com>2019-12-04 13:24:46 +0300
committerSebastian Parborg <darkdefende@gmail.com>2019-12-04 13:30:14 +0300
commit541d0fdba61a9c99612f7532207d5ce704f10b43 (patch)
treeaccff9ec62ba963c29ffde53f3a5a52f3fcff58f /source
parentb3f388dca9e547c12db277b8422c620ca3b64eaa (diff)
Add cloth pressure vertex group and unlock cloth shrink values range
Introduced a way to specify cloth pressure force influence with a vertex group. This will allow users to only have pressure affect certain parts of the mesh. In addition to this, the "shrink factor" is now also unlocked to allow negative values and thus allowing the cloth mesh to grow as well. Reviewed By: Jaques Lucke Differential Revision: http://developer.blender.org/D6347
Diffstat (limited to 'source')
-rw-r--r--source/blender/blenkernel/BKE_cloth.h5
-rw-r--r--source/blender/blenkernel/intern/cloth.c57
-rw-r--r--source/blender/makesdna/DNA_cloth_types.h9
-rw-r--r--source/blender/makesrna/intern/rna_cloth.c43
-rw-r--r--source/blender/physics/intern/BPH_mass_spring.cpp67
-rw-r--r--source/blender/physics/intern/implicit.h8
-rw-r--r--source/blender/physics/intern/implicit_blender.c8
7 files changed, 142 insertions, 55 deletions
diff --git a/source/blender/blenkernel/BKE_cloth.h b/source/blender/blenkernel/BKE_cloth.h
index 0543021afef..d59a81c1baf 100644
--- a/source/blender/blenkernel/BKE_cloth.h
+++ b/source/blender/blenkernel/BKE_cloth.h
@@ -113,8 +113,9 @@ typedef struct ClothVertex {
float struct_stiff;
float bend_stiff;
float shear_stiff;
- int spring_count; /* how many springs attached? */
- float shrink_factor; /* how much to shrink this cloth */
+ int spring_count; /* how many springs attached? */
+ float shrink_factor; /* how much to shrink this cloth */
+ float pressure_factor; /* how much pressure should affect this vertex */
} ClothVertex;
/**
diff --git a/source/blender/blenkernel/intern/cloth.c b/source/blender/blenkernel/intern/cloth.c
index 2be312bc4d9..d26dca4a252 100644
--- a/source/blender/blenkernel/intern/cloth.c
+++ b/source/blender/blenkernel/intern/cloth.c
@@ -134,6 +134,7 @@ void cloth_init(ClothModifierData *clmd)
clmd->sim_parms->uniform_pressure_force = 0.0f;
clmd->sim_parms->target_volume = 0.0f;
clmd->sim_parms->pressure_factor = 1.0f;
+ clmd->sim_parms->vgroup_pressure = 0;
// also from softbodies
clmd->sim_parms->maxgoal = 1.0f;
@@ -651,8 +652,9 @@ int cloth_uses_vgroup(ClothModifierData *clmd)
{
return (((clmd->coll_parms->flags & CLOTH_COLLSETTINGS_FLAG_SELF) &&
(clmd->coll_parms->vgroup_selfcol > 0)) ||
- (clmd->sim_parms->vgroup_struct > 0) || (clmd->sim_parms->vgroup_bend > 0) ||
- (clmd->sim_parms->vgroup_shrink > 0) || (clmd->sim_parms->vgroup_mass > 0));
+ (clmd->sim_parms->vgroup_pressure > 0) || (clmd->sim_parms->vgroup_struct > 0) ||
+ (clmd->sim_parms->vgroup_bend > 0) || (clmd->sim_parms->vgroup_shrink > 0) ||
+ (clmd->sim_parms->vgroup_mass > 0));
}
/**
@@ -660,27 +662,16 @@ int cloth_uses_vgroup(ClothModifierData *clmd)
*/
static void cloth_apply_vgroup(ClothModifierData *clmd, Mesh *mesh)
{
- /* Can be optimized to do all groups in one loop. */
- int i = 0;
- int j = 0;
- MDeformVert *dvert = NULL;
- Cloth *clothObj = NULL;
- int mvert_num;
- /* float goalfac = 0; */ /* UNUSED */
- ClothVertex *verts = NULL;
-
if (!clmd || !mesh) {
return;
}
- clothObj = clmd->clothObject;
+ int mvert_num = mesh->totvert;
- mvert_num = mesh->totvert;
-
- verts = clothObj->verts;
+ ClothVertex *verts = clmd->clothObject->verts;
if (cloth_uses_vgroup(clmd)) {
- for (i = 0; i < mvert_num; i++, verts++) {
+ for (int i = 0; i < mvert_num; i++, verts++) {
/* Reset Goal values to standard */
if (clmd->sim_parms->vgroup_mass > 0) {
@@ -697,9 +688,9 @@ static void cloth_apply_vgroup(ClothModifierData *clmd, Mesh *mesh)
verts->flags &= ~CLOTH_VERT_FLAG_PINNED;
verts->flags &= ~CLOTH_VERT_FLAG_NOSELFCOLL;
- dvert = CustomData_get(&mesh->vdata, i, CD_MDEFORMVERT);
+ MDeformVert *dvert = CustomData_get(&mesh->vdata, i, CD_MDEFORMVERT);
if (dvert) {
- for (j = 0; j < dvert->totweight; j++) {
+ for (int j = 0; j < dvert->totweight; j++) {
if (dvert->dw[j].def_nr == (clmd->sim_parms->vgroup_mass - 1)) {
verts->goal = dvert->dw[j].weight;
@@ -726,19 +717,21 @@ static void cloth_apply_vgroup(ClothModifierData *clmd, Mesh *mesh)
verts->bend_stiff = dvert->dw[j].weight;
}
- if (clmd->coll_parms->flags & CLOTH_COLLSETTINGS_FLAG_SELF) {
- if (dvert->dw[j].def_nr == (clmd->coll_parms->vgroup_selfcol - 1)) {
- if (dvert->dw[j].weight > 0.0f) {
- verts->flags |= CLOTH_VERT_FLAG_NOSELFCOLL;
- }
+ if (dvert->dw[j].def_nr == (clmd->coll_parms->vgroup_selfcol - 1)) {
+ if (dvert->dw[j].weight > 0.0f) {
+ verts->flags |= CLOTH_VERT_FLAG_NOSELFCOLL;
}
}
- if (clmd->sim_parms->vgroup_shrink > 0) {
- if (dvert->dw[j].def_nr == (clmd->sim_parms->vgroup_shrink - 1)) {
- /* Used for linear interpolation between min and max
- * shrink factor based on weight. */
- verts->shrink_factor = dvert->dw[j].weight;
- }
+
+ if (dvert->dw[j].def_nr == (clmd->sim_parms->vgroup_shrink - 1)) {
+ /* Used for linear interpolation between min and max
+ * shrink factor based on weight. */
+ verts->shrink_factor = dvert->dw[j].weight;
+ }
+
+ if (dvert->dw[j].def_nr == (clmd->sim_parms->vgroup_pressure - 1)) {
+ /* Used to define how much the pressure settings should affect the given vertex */
+ verts->pressure_factor = dvert->dw[j].weight;
}
}
}
@@ -750,10 +743,10 @@ static float cloth_shrink_factor(ClothModifierData *clmd, ClothVertex *verts, in
{
/* Linear interpolation between min and max shrink factor based on weight. */
float base = 1.0f - clmd->sim_parms->shrink_min;
- float delta = clmd->sim_parms->shrink_min - clmd->sim_parms->shrink_max;
+ float shrink_factor_delta = clmd->sim_parms->shrink_min - clmd->sim_parms->shrink_max;
- float k1 = base + delta * verts[i1].shrink_factor;
- float k2 = base + delta * verts[i2].shrink_factor;
+ float k1 = base + shrink_factor_delta * verts[i1].shrink_factor;
+ float k2 = base + shrink_factor_delta * verts[i2].shrink_factor;
/* Use geometrical mean to average two factors since it behaves better
* for diagonals when a rectangle transforms into a trapezoid. */
diff --git a/source/blender/makesdna/DNA_cloth_types.h b/source/blender/makesdna/DNA_cloth_types.h
index 5653e8a0450..aca29fe1bdd 100644
--- a/source/blender/makesdna/DNA_cloth_types.h
+++ b/source/blender/makesdna/DNA_cloth_types.h
@@ -93,9 +93,11 @@ typedef struct ClothSimSettings {
float collider_friction;
/** Damp the velocity to speed up getting to the resting position. */
float vel_damping DNA_DEPRECATED;
- /** Min amount to shrink cloth by 0.0f (no shrink) - 1.0f (shrink to nothing). */
+ /** Min amount to shrink cloth by 0.0f (no shrink), 1.0f (shrink to nothing), -1.0f (double the
+ * edge length). */
float shrink_min;
- /** Max amount to shrink cloth by 0.0f (no shrink) - 1.0f (shrink to nothing). */
+ /** Max amount to shrink cloth by 0.0f (no shrink), 1.0f (shrink to nothing), -1.0f (double the
+ * edge length). */
float shrink_max;
/* Air pressure */
@@ -107,7 +109,8 @@ typedef struct ClothSimSettings {
pressure=( (current_volume/target_volume) - 1 + uniform_pressure_force) *
pressure_factor */
float pressure_factor;
- char _pad7[4];
+ short vgroup_pressure;
+ char _pad7[2];
/* XXX various hair stuff
* should really be separate, this struct is a horrible mess already
diff --git a/source/blender/makesrna/intern/rna_cloth.c b/source/blender/makesrna/intern/rna_cloth.c
index cf48ed549e6..9f6f15b8379 100644
--- a/source/blender/makesrna/intern/rna_cloth.c
+++ b/source/blender/makesrna/intern/rna_cloth.c
@@ -291,6 +291,24 @@ static void rna_ClothSettings_bend_vgroup_set(PointerRNA *ptr, const char *value
rna_object_vgroup_name_index_set(ptr, value, &sim->vgroup_bend);
}
+static void rna_ClothSettings_pressure_vgroup_get(PointerRNA *ptr, char *value)
+{
+ ClothSimSettings *sim = (ClothSimSettings *)ptr->data;
+ rna_object_vgroup_name_index_get(ptr, value, sim->vgroup_pressure);
+}
+
+static int rna_ClothSettings_pressure_vgroup_length(PointerRNA *ptr)
+{
+ ClothSimSettings *sim = (ClothSimSettings *)ptr->data;
+ return rna_object_vgroup_name_index_length(ptr, sim->vgroup_pressure);
+}
+
+static void rna_ClothSettings_pressure_vgroup_set(PointerRNA *ptr, const char *value)
+{
+ ClothSimSettings *sim = (ClothSimSettings *)ptr->data;
+ rna_object_vgroup_name_index_set(ptr, value, &sim->vgroup_pressure);
+}
+
static void rna_CollSettings_selfcol_vgroup_get(PointerRNA *ptr, char *value)
{
ClothCollSettings *coll = (ClothCollSettings *)ptr->data;
@@ -595,14 +613,16 @@ static void rna_def_cloth_sim_settings(BlenderRNA *brna)
prop = RNA_def_property(srna, "shrink_min", PROP_FLOAT, PROP_FACTOR);
RNA_def_property_float_sdna(prop, NULL, "shrink_min");
- RNA_def_property_range(prop, 0.0f, 1.0f);
+ RNA_def_property_range(prop, -FLT_MAX, 1.0f);
+ RNA_def_property_ui_range(prop, -1.0f, 1.0f, 0.05f, 3);
RNA_def_property_float_funcs(prop, NULL, "rna_ClothSettings_shrink_min_set", NULL);
RNA_def_property_ui_text(prop, "Shrink Factor", "Factor by which to shrink cloth");
RNA_def_property_update(prop, 0, "rna_cloth_update");
prop = RNA_def_property(srna, "shrink_max", PROP_FLOAT, PROP_FACTOR);
RNA_def_property_float_sdna(prop, NULL, "shrink_max");
- RNA_def_property_range(prop, 0.0f, 1.0f);
+ RNA_def_property_range(prop, -FLT_MAX, 1.0f);
+ RNA_def_property_ui_range(prop, -1.0f, 1.0f, 0.05f, 3);
RNA_def_property_float_funcs(prop, NULL, "rna_ClothSettings_shrink_max_set", NULL);
RNA_def_property_ui_text(prop, "Shrink Factor Max", "Max amount to shrink cloth by");
RNA_def_property_update(prop, 0, "rna_cloth_update");
@@ -803,8 +823,10 @@ static void rna_def_cloth_sim_settings(BlenderRNA *brna)
RNA_def_property_float_sdna(prop, NULL, "target_volume");
RNA_def_property_range(prop, 0.0f, 10000.0f);
RNA_def_property_float_default(prop, 0.0f);
- RNA_def_property_ui_text(
- prop, "Target Volume", "The mesh volume where the inner/outer pressure will be the same");
+ RNA_def_property_ui_text(prop,
+ "Target Volume",
+ "The mesh volume where the inner/outer pressure will be the same. If "
+ "set to zero the volume will not contribute to the total pressure");
RNA_def_property_update(prop, 0, "rna_cloth_update");
prop = RNA_def_property(srna, "pressure_factor", PROP_FLOAT, PROP_NONE);
@@ -814,6 +836,19 @@ static void rna_def_cloth_sim_settings(BlenderRNA *brna)
RNA_def_property_ui_text(prop, "Pressure Scale", "Air pressure scaling factor");
RNA_def_property_update(prop, 0, "rna_cloth_update");
+ prop = RNA_def_property(srna, "vertex_group_pressure", PROP_STRING, PROP_NONE);
+ RNA_def_property_string_funcs(prop,
+ "rna_ClothSettings_pressure_vgroup_get",
+ "rna_ClothSettings_pressure_vgroup_length",
+ "rna_ClothSettings_pressure_vgroup_set");
+ RNA_def_property_ui_text(
+ prop,
+ "Pressure Vertex Group",
+ "Vertex Group for where to apply pressure. Zero weight means no "
+ "pressure while a weight of one means full pressure. Faces with a vertex "
+ "that has zero weight will be excluded from the volume calculation");
+ RNA_def_property_update(prop, 0, "rna_cloth_update");
+
/* unused */
/* unused still */
diff --git a/source/blender/physics/intern/BPH_mass_spring.cpp b/source/blender/physics/intern/BPH_mass_spring.cpp
index 259eed88756..7521efa5cbd 100644
--- a/source/blender/physics/intern/BPH_mass_spring.cpp
+++ b/source/blender/physics/intern/BPH_mass_spring.cpp
@@ -76,18 +76,39 @@ static int cloth_count_nondiag_blocks(Cloth *cloth)
static float cloth_calc_volume(ClothModifierData *clmd)
{
- /* calc the (closed) cloth volume */
+ /* Calculate the (closed) cloth volume. */
Cloth *cloth = clmd->clothObject;
const MVertTri *tri = cloth->tri;
Implicit_Data *data = cloth->implicit;
float vol = 0;
- for (unsigned int i = 0; i < cloth->tri_num; i++) {
- const MVertTri *vt = &tri[i];
- vol += BPH_tri_tetra_volume_signed_6x(data, vt->tri[0], vt->tri[1], vt->tri[2]);
- }
+ if (clmd->sim_parms->vgroup_pressure > 0) {
+ for (unsigned int i = 0; i < cloth->tri_num; i++) {
+ bool skip_face = false;
+ /* We have custom vertex weights for pressure. */
+ const MVertTri *vt = &tri[i];
+ for (unsigned int j = 0; j < 3; j++) {
+ /* If any weight is zero, don't take this face into account for volume calculation. */
+ ClothVertex *verts = clmd->clothObject->verts;
+
+ if (verts[vt->tri[j]].pressure_factor == 0.0f) {
+ skip_face = true;
+ }
+ }
+ if (skip_face) {
+ continue;
+ }
- /* We need to divide by 6 to get the actual volume */
+ vol += BPH_tri_tetra_volume_signed_6x(data, vt->tri[0], vt->tri[1], vt->tri[2]);
+ }
+ }
+ else {
+ for (unsigned int i = 0; i < cloth->tri_num; i++) {
+ const MVertTri *vt = &tri[i];
+ vol += BPH_tri_tetra_volume_signed_6x(data, vt->tri[0], vt->tri[1], vt->tri[2]);
+ }
+ }
+ /* We need to divide by 6 to get the actual volume. */
vol = vol / 6.0f;
return vol;
@@ -634,8 +655,38 @@ static void cloth_calc_force(
for (i = 0; i < cloth->tri_num; i++) {
const MVertTri *vt = &tri[i];
if (fabs(pressure_difference) > 1E-6f) {
- BPH_mass_spring_force_pressure(
- data, vt->tri[0], vt->tri[1], vt->tri[2], pressure_difference);
+ if (clmd->sim_parms->vgroup_pressure > 0) {
+ /* We have custom vertex weights for pressure. */
+ ClothVertex *verts = clmd->clothObject->verts;
+ int v1, v2, v3;
+ v1 = vt->tri[0];
+ v2 = vt->tri[1];
+ v3 = vt->tri[2];
+
+ float weights[3];
+ bool skip_face = false;
+
+ weights[0] = verts[v1].pressure_factor;
+ weights[1] = verts[v2].pressure_factor;
+ weights[2] = verts[v3].pressure_factor;
+ for (unsigned int j = 0; j < 3; j++) {
+ if (weights[j] == 0.0f) {
+ /* Exclude faces which has a zero weight vert. */
+ skip_face = true;
+ break;
+ }
+ }
+ if (skip_face) {
+ continue;
+ }
+
+ BPH_mass_spring_force_pressure(data, v1, v2, v3, pressure_difference, weights);
+ }
+ else {
+ float weights[3] = {1.0f, 1.0f, 1.0f};
+ BPH_mass_spring_force_pressure(
+ data, vt->tri[0], vt->tri[1], vt->tri[2], pressure_difference, weights);
+ }
}
}
}
diff --git a/source/blender/physics/intern/implicit.h b/source/blender/physics/intern/implicit.h
index 82a3f61e1e1..490e727b5f2 100644
--- a/source/blender/physics/intern/implicit.h
+++ b/source/blender/physics/intern/implicit.h
@@ -184,8 +184,12 @@ bool BPH_mass_spring_force_spring_goal(struct Implicit_Data *data,
float BPH_tri_tetra_volume_signed_6x(struct Implicit_Data *data, int v1, int v2, int v3);
-void BPH_mass_spring_force_pressure(
- struct Implicit_Data *data, int v1, int v2, int v3, float pressure_difference);
+void BPH_mass_spring_force_pressure(struct Implicit_Data *data,
+ int v1,
+ int v2,
+ int v3,
+ float pressure_difference,
+ float weights[3]);
/* ======== Hair Volumetric Forces ======== */
diff --git a/source/blender/physics/intern/implicit_blender.c b/source/blender/physics/intern/implicit_blender.c
index fa093f482f7..02d7fd50797 100644
--- a/source/blender/physics/intern/implicit_blender.c
+++ b/source/blender/physics/intern/implicit_blender.c
@@ -1489,7 +1489,7 @@ float BPH_tri_tetra_volume_signed_6x(Implicit_Data *data, int v1, int v2, int v3
}
void BPH_mass_spring_force_pressure(
- Implicit_Data *data, int v1, int v2, int v3, float pressure_difference)
+ Implicit_Data *data, int v1, int v2, int v3, float pressure_difference, float weights[3])
{
float nor[3], area;
float factor;
@@ -1500,9 +1500,9 @@ void BPH_mass_spring_force_pressure(
factor = pressure_difference * area / 3.0f;
/* add pressure to each of the face verts */
- madd_v3_v3fl(data->F[v1], nor, factor);
- madd_v3_v3fl(data->F[v2], nor, factor);
- madd_v3_v3fl(data->F[v3], nor, factor);
+ madd_v3_v3fl(data->F[v1], nor, factor * weights[0]);
+ madd_v3_v3fl(data->F[v2], nor, factor * weights[1]);
+ madd_v3_v3fl(data->F[v3], nor, factor * weights[2]);
}
static void edge_wind_vertex(const float dir[3],