Cloth: add a vertex group setting to exclude from object collision.

This can be useful as a workaround on the boundary with the pinned
vertices in some situations among other things, and completely copies
the existing design of the self collision vertex group setting.

Differential Revision: https://developer.blender.org/D10043
This commit is contained in:
Alexander Gavrilov 2021-01-08 13:02:40 +03:00
parent ac290bfbe4
commit e44e0e4e78
7 changed files with 51 additions and 6 deletions

View File

@ -345,6 +345,7 @@ class PHYSICS_PT_cloth_object_collision(PhysicButtonsPanel, Panel):
cloth = context.cloth.collision_settings
md = context.cloth
ob = context.object
layout.active = cloth.use_collision and cloth_panel_enabled(md)
@ -356,6 +357,9 @@ class PHYSICS_PT_cloth_object_collision(PhysicButtonsPanel, Panel):
col = flow.column()
col.prop(cloth, "impulse_clamp")
col = flow.column()
col.prop_search(cloth, "vertex_group_object_collisions", ob, "vertex_groups", text="Vertex Group")
col = flow.column()
col.prop(cloth, "collection")

View File

@ -50,6 +50,7 @@ struct Scene;
typedef enum eClothVertexFlag {
CLOTH_VERT_FLAG_PINNED = (1 << 0),
CLOTH_VERT_FLAG_NOSELFCOLL = (1 << 1), /* vertex NOT used for self collisions */
CLOTH_VERT_FLAG_NOOBJCOLL = (1 << 2), /* vertex NOT used for object collisions */
} eClothVertexFlag;
typedef struct ClothHairData {

View File

@ -611,6 +611,8 @@ int cloth_uses_vgroup(ClothModifierData *clmd)
{
return (((clmd->coll_parms->flags & CLOTH_COLLSETTINGS_FLAG_SELF) &&
(clmd->coll_parms->vgroup_selfcol > 0)) ||
((clmd->coll_parms->flags & CLOTH_COLLSETTINGS_FLAG_ENABLED) &&
(clmd->coll_parms->vgroup_objcol > 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_intern > 0) || (clmd->sim_parms->vgroup_mass > 0));
@ -644,8 +646,8 @@ static void cloth_apply_vgroup(ClothModifierData *clmd, Mesh *mesh)
verts->shrink_factor = 0.0f;
/* Reset vertex flags */
verts->flags &= ~CLOTH_VERT_FLAG_PINNED;
verts->flags &= ~CLOTH_VERT_FLAG_NOSELFCOLL;
verts->flags &= ~(CLOTH_VERT_FLAG_PINNED | CLOTH_VERT_FLAG_NOSELFCOLL |
CLOTH_VERT_FLAG_NOOBJCOLL);
MDeformVert *dvert = CustomData_get(&mesh->vdata, i, CD_MDEFORMVERT);
if (dvert) {
@ -682,6 +684,12 @@ static void cloth_apply_vgroup(ClothModifierData *clmd, Mesh *mesh)
}
}
if (dvert->dw[j].def_nr == (clmd->coll_parms->vgroup_objcol - 1)) {
if (dvert->dw[j].weight > 0.0f) {
verts->flags |= CLOTH_VERT_FLAG_NOOBJCOLL;
}
}
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. */

View File

@ -1012,7 +1012,7 @@ static bool cloth_bvh_collision_is_active(const ClothModifierData *UNUSED(clmd),
const int flags_a = verts[tri_a->tri[0]].flags & verts[tri_a->tri[1]].flags &
verts[tri_a->tri[2]].flags;
if (flags_a & CLOTH_VERT_FLAG_PINNED) {
if (flags_a & (CLOTH_VERT_FLAG_PINNED | CLOTH_VERT_FLAG_NOOBJCOLL)) {
return false;
}

View File

@ -240,9 +240,11 @@ typedef struct ClothCollSettings {
char _pad[4];
/** Only use colliders from this group of objects. */
struct Collection *group;
/** Vgroup to paint which vertices are used for self collisions. */
/** Vgroup to paint which vertices are not used for self collisions. */
short vgroup_selfcol;
char _pad2[6];
/** Vgroup to paint which vertices are not used for object collisions. */
short vgroup_objcol;
char _pad2[4];
/** Impulse clamp for object collisions. */
float clamp;
/** Impulse clamp for self collisions. */

View File

@ -179,6 +179,7 @@
.loop_count = 2, \
.group = NULL, \
.vgroup_selfcol = 0, \
.vgroup_objcol = 0, \
.clamp = 0.0f, \
.self_clamp = 0.0f, \
}

View File

@ -396,6 +396,24 @@ static void rna_CollSettings_selfcol_vgroup_set(PointerRNA *ptr, const char *val
rna_object_vgroup_name_index_set(ptr, value, &coll->vgroup_selfcol);
}
static void rna_CollSettings_objcol_vgroup_get(PointerRNA *ptr, char *value)
{
ClothCollSettings *coll = (ClothCollSettings *)ptr->data;
rna_object_vgroup_name_index_get(ptr, value, coll->vgroup_objcol);
}
static int rna_CollSettings_objcol_vgroup_length(PointerRNA *ptr)
{
ClothCollSettings *coll = (ClothCollSettings *)ptr->data;
return rna_object_vgroup_name_index_length(ptr, coll->vgroup_objcol);
}
static void rna_CollSettings_objcol_vgroup_set(PointerRNA *ptr, const char *value)
{
ClothCollSettings *coll = (ClothCollSettings *)ptr->data;
rna_object_vgroup_name_index_set(ptr, value, &coll->vgroup_objcol);
}
static PointerRNA rna_ClothSettings_rest_shape_key_get(PointerRNA *ptr)
{
Object *ob = (Object *)ptr->owner_id;
@ -1163,7 +1181,18 @@ static void rna_def_cloth_collision_settings(BlenderRNA *brna)
RNA_def_property_ui_text(
prop,
"Selfcollision Vertex Group",
"Vertex group to define vertices which are not used during self collisions");
"Triangles with all vertices in this group are not used during self collisions");
RNA_def_property_update(prop, 0, "rna_cloth_update");
prop = RNA_def_property(srna, "vertex_group_object_collisions", PROP_STRING, PROP_NONE);
RNA_def_property_string_funcs(prop,
"rna_CollSettings_objcol_vgroup_get",
"rna_CollSettings_objcol_vgroup_length",
"rna_CollSettings_objcol_vgroup_set");
RNA_def_property_ui_text(
prop,
"Collision Vertex Group",
"Triangles with all vertices in this group are not used during object collisions");
RNA_def_property_update(prop, 0, "rna_cloth_update");
prop = RNA_def_property(srna, "self_impulse_clamp", PROP_FLOAT, PROP_NONE);