Cloth: Add support for "Self Collision Vertex Group".
authorDaniel Genrich <daniel.genrich@gmx.net>
Wed, 6 Jun 2012 13:30:05 +0000 (13:30 +0000)
committerDaniel Genrich <daniel.genrich@gmx.net>
Wed, 6 Jun 2012 13:30:05 +0000 (13:30 +0000)
Self collision vertex groups enable artists to exclude selected vertices from getting involved in self collisions. This speeds simulations and it also resolves some self collision issues.

release/scripts/startup/bl_ui/properties_physics_cloth.py
source/blender/blenkernel/BKE_cloth.h
source/blender/blenkernel/intern/cloth.c
source/blender/blenkernel/intern/collision.c
source/blender/makesdna/DNA_cloth_types.h
source/blender/makesrna/intern/rna_cloth.c

index e313112d61a36ee0e0eca9df751def01fbcfa0f0..0240335c98f98e4a1d9d695877f4aff5694154f7 100644 (file)
@@ -145,6 +145,7 @@ class PHYSICS_PT_cloth_collision(PhysicButtonsPanel, Panel):
 
         cloth = context.cloth.collision_settings
         md = context.cloth
+        ob = context.object
 
         layout.active = cloth.use_collision and cloth_panel_enabled(md)
 
@@ -163,6 +164,7 @@ class PHYSICS_PT_cloth_collision(PhysicButtonsPanel, Panel):
         sub.active = cloth.use_self_collision
         sub.prop(cloth, "self_collision_quality", slider=True, text="Quality")
         sub.prop(cloth, "self_distance_min", slider=True, text="Distance")
+        sub.prop_search(cloth, "vertex_group_self_collisions", ob, "vertex_groups", text="")
 
         layout.prop(cloth, "group")
 
index 378cc72beb1ebb15ef45f5c517b55e244be17730..3475ef532da5ccb52e91aee8e6cae7bcc6d535c7 100644 (file)
@@ -56,7 +56,7 @@ struct CollisionTree;
 
 /* Bits to or into the ClothVertex.flags. */
 #define CLOTH_VERT_FLAG_PINNED 1
-#define CLOTH_VERT_FLAG_COLLISION 2
+#define CLOTH_VERT_FLAG_NOSELFCOLL 2 /* vertex NOT used for self collisions */
 #define CLOTH_VERT_FLAG_PINNED_EM 3
 
 /**
index e067b7195ce1c75e4e29c8e3f385cc0b525994bc..b681426f8a7e687ef54926dbff27943ba36c3398 100644 (file)
@@ -143,6 +143,7 @@ void cloth_init(ClothModifierData *clmd )
        clmd->coll_parms->collision_list = NULL;
        clmd->coll_parms->self_loop_count = 1.0;
        clmd->coll_parms->selfepsilon = 0.75;
+       clmd->coll_parms->vgroup_selfcol = 0;
 
        /* These defaults are copied from softbody.c's
         * softbody_calc_forces() function.
@@ -756,10 +757,12 @@ static void cloth_to_object (Object *ob,  ClothModifierData *clmd, float (*verte
 int cloth_uses_vgroup(ClothModifierData *clmd)
 {
        return (((clmd->sim_parms->flags & CLOTH_SIMSETTINGS_FLAG_SCALING ) || 
-               (clmd->sim_parms->flags & CLOTH_SIMSETTINGS_FLAG_GOAL )) && 
+               (clmd->sim_parms->flags & CLOTH_SIMSETTINGS_FLAG_GOAL ) ||
+               (clmd->coll_parms->flags & CLOTH_COLLSETTINGS_FLAG_SELF)) && 
                ((clmd->sim_parms->vgroup_mass>0) || 
                (clmd->sim_parms->vgroup_struct>0)||
-               (clmd->sim_parms->vgroup_bend>0)));
+               (clmd->sim_parms->vgroup_bend>0)  ||
+               (clmd->coll_parms->vgroup_selfcol>0)));
 }
 
 /**
@@ -815,6 +818,13 @@ static void cloth_apply_vgroup ( ClothModifierData *clmd, DerivedMesh *dm )
                                                        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.0)
+                                                               verts->flags |= CLOTH_VERT_FLAG_NOSELFCOLL;
+                                               }
+                                       }
                                        /*
                                        // for later
                                        if ( dvert->dw[j].def_nr == (clmd->sim_parms->vgroup_weight-1))
index 32e9dd7508b50c9064fcdc63c995c051d7280071..44f524304d2db4f5b8c5163d6589dc76ca72a41a 100644 (file)
@@ -840,6 +840,10 @@ int cloth_bvh_objcollision(Object *ob, ClothModifierData * clmd, float step, flo
                                                                continue;
                                                        }
                                                }
+
+                                               if( ( cloth->verts[i].flags & CLOTH_VERT_FLAG_NOSELFCOLL ) || 
+                                                       ( cloth->verts[j].flags & CLOTH_VERT_FLAG_NOSELFCOLL ) )
+                                                       continue;
        
                                                sub_v3_v3v3(temp, verts[i].tx, verts[j].tx);
        
index fd8b08e68c64ab910bde1d37e1698964062872c0..b214186fee6eb57efc18e11988777fcc59efda1b 100644 (file)
@@ -83,7 +83,7 @@ typedef struct ClothSimSettings
        short   shapekey_rest;  /* vertex group for scaling structural stiffness */
        short   presets; /* used for presets on GUI */
        short   reset;
-       short   pad;
+       short pad;
 
        struct EffectorWeights *effector_weights;
 } ClothSimSettings;
@@ -101,6 +101,9 @@ typedef struct ClothCollSettings
        short   self_loop_count;        /* How many iterations for the selfcollision loop       */
        short   loop_count;             /* How many iterations for the collision loop.          */
        struct Group *group;    /* Only use colliders from this group of objects */
+       short   vgroup_selfcol; /* vgroup to paint which vertices are used for self collisions */
+       short pad;
+       int pad2;
 } ClothCollSettings;
 
 
index 37795edb8844d5f6d1308af92ddbfdc7c70536a1..82a838010f64b108e48555ab4932673681b8ed56 100644 (file)
@@ -155,6 +155,25 @@ 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_CollSettings_selfcol_vgroup_get(PointerRNA *ptr, char *value)
+{
+       ClothCollSettings *coll = (ClothCollSettings *)ptr->data;
+       rna_object_vgroup_name_index_get(ptr, value, coll->vgroup_selfcol);
+}
+
+static int rna_CollSettings_selfcol_vgroup_length(PointerRNA *ptr)
+{
+       ClothCollSettings *coll = (ClothCollSettings *)ptr->data;
+       return rna_object_vgroup_name_index_length(ptr, coll->vgroup_selfcol);
+}
+
+static void rna_CollSettings_selfcol_vgroup_set(PointerRNA *ptr, const char *value)
+{
+       ClothCollSettings *coll = (ClothCollSettings *)ptr->data;
+       rna_object_vgroup_name_index_set(ptr, value, &coll->vgroup_selfcol);
+}
+
 static PointerRNA rna_ClothSettings_rest_shape_key_get(PointerRNA *ptr)
 {
        Object *ob = (Object *)ptr->id.data;
@@ -523,6 +542,13 @@ static void rna_def_cloth_collision_settings(BlenderRNA *brna)
        RNA_def_property_flag(prop, PROP_EDITABLE);
        RNA_def_property_ui_text(prop, "Collision Group", "Limit colliders to this Group");
        RNA_def_property_update(prop, 0, "rna_cloth_update");
+
+       prop = RNA_def_property(srna, "vertex_group_self_collisions", PROP_STRING, PROP_NONE);
+       RNA_def_property_string_funcs(prop, "rna_CollSettings_selfcol_vgroup_get", "rna_CollSettings_selfcol_vgroup_length",
+                                     "rna_CollSettings_selfcol_vgroup_set");
+       RNA_def_property_ui_text(prop, "Selfcollision Vertex Group",
+                                "Vertex group to define vertices which are not used during self collisions.");
+       RNA_def_property_update(prop, 0, "rna_cloth_update");
 }
 
 void RNA_def_cloth(BlenderRNA *brna)