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:
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],