- particle drawing was using invalid memory with weights.
authorCampbell Barton <ideasman42@gmail.com>
Fri, 15 Jan 2010 17:28:00 +0000 (17:28 +0000)
committerCampbell Barton <ideasman42@gmail.com>
Fri, 15 Jan 2010 17:28:00 +0000 (17:28 +0000)
- particle set weight operator (Shift + K) and from the menu.
- mirror vertex groups operator can also flip weight group names.

a number of utility functions for weight groups added
 int *get_defgroup_flip_map(struct Object *ob);
 void flip_vertexgroup_name (char *name_r, const char *name, int strip_number); // moved from modifier.c
 void copy_defvert (struct MDeformVert *dvert_r, const struct MDeformVert *dvert);
 void flip_defvert (struct MDeformVert *dvert, int *flip_map);

12 files changed:
release/scripts/ui/space_view3d.py
source/blender/blenkernel/BKE_deform.h
source/blender/blenkernel/intern/deform.c
source/blender/blenkernel/intern/modifier.c
source/blender/blenkernel/intern/particle.c
source/blender/editors/mesh/editmesh_mods.c
source/blender/editors/object/object_intern.h
source/blender/editors/object/object_ops.c
source/blender/editors/object/object_vgroup.c
source/blender/editors/physics/particle_edit.c
source/blender/editors/physics/physics_intern.h
source/blender/editors/physics/physics_ops.c

index bb369b5aa227059ba242a8bd9c422b369fef0289..4e394839166ecf00c5acb3a3315a118376a981f8 100644 (file)
@@ -186,6 +186,8 @@ class VIEW3D_MT_mirror(bpy.types.Menu):
             props.constraint_axis = (False, False, True)
             props.constraint_orientation = 'LOCAL'
 
+            layout.operator("object.vertex_group_mirror")
+
 
 class VIEW3D_MT_snap(bpy.types.Menu):
     bl_label = "Snap"
@@ -898,6 +900,7 @@ class VIEW3D_MT_particle(bpy.types.Menu):
             layout.operator("particle.subdivide")
 
         layout.operator("particle.rekey")
+        layout.operator("particle.weight_set")
 
         layout.separator()
 
index 8a34b286881cd2f49a4f5b9590620e193d0309c7..d9cf6bc8feb6530ba696c02e77aa628c6ed93c08 100644 (file)
@@ -44,11 +44,16 @@ void copy_defgroups (struct ListBase *lb1, struct ListBase *lb2);
 struct bDeformGroup *copy_defgroup (struct bDeformGroup *ingroup);
 struct bDeformGroup *get_named_vertexgroup (Object *ob, char *name);
 int get_defgroup_num (struct Object *ob, struct bDeformGroup *dg);
+int *get_defgroup_flip_map(struct Object *ob);
 int get_named_vertexgroup_num (Object *ob, const char *name);
 void unique_vertexgroup_name (struct bDeformGroup *dg, struct Object *ob);
+void flip_vertexgroup_name (char *name_r, const char *name, int strip_number);
 
 float deformvert_get_weight(const struct MDeformVert *dvert, int group_num);
 float vertexgroup_get_vertex_weight(const struct MDeformVert *dvert, int index, int group_num);
 
+void copy_defvert (struct MDeformVert *dvert_r, const struct MDeformVert *dvert);
+void flip_defvert (struct MDeformVert *dvert, int *flip_map);
+
 #endif
 
index c1e45243bb505961330c58e73999b3050620406a..620e114bad2b202024a81a507ea6e205920f2cb7 100644 (file)
@@ -34,6 +34,7 @@
 
 #include <string.h>
 #include <math.h>
+#include "ctype.h"
 
 #include "MEM_guardedalloc.h"
 
@@ -95,6 +96,36 @@ bDeformGroup *copy_defgroup (bDeformGroup *ingroup)
        return outgroup;
 }
 
+void copy_defvert (MDeformVert *dvert_r, const MDeformVert *dvert)
+{
+       if(dvert_r->totweight == dvert->totweight) {
+               if(dvert->totweight)
+                       memcpy(dvert_r->dw, dvert->dw, dvert->totweight * sizeof(MDeformWeight));
+       }
+       else {
+               if(dvert_r->dw)
+                       MEM_freeN(dvert_r->dw);
+
+               if(dvert->totweight)
+                       dvert_r->dw= MEM_dupallocN(dvert->dw);
+               else
+                       dvert_r->dw= NULL;
+
+               dvert_r->totweight = dvert->totweight;
+       }
+}
+
+void flip_defvert (MDeformVert *dvert, int *flip_map)
+{
+       MDeformWeight *dw;
+       int i;
+
+       for(dw= dvert->dw, i=0; i<dvert->totweight; dw++, i++)
+               if(flip_map[dw->def_nr] >= 0)
+                       dw->def_nr= flip_map[dw->def_nr];
+}
+
+
 bDeformGroup *get_named_vertexgroup (Object *ob, char *name)
 {
        /* return a pointer to the deform group with this name
@@ -167,6 +198,36 @@ int get_defgroup_num (Object *ob, bDeformGroup *dg)
     
 }
 
+/* note, must be freed */
+int *get_defgroup_flip_map(Object *ob)
+{
+       bDeformGroup *dg;
+       int totdg= BLI_countlist(&ob->defbase);
+
+       if(totdg==0) {
+               return NULL;
+       }
+       else {
+               char name[sizeof(dg->name)];
+               int i, flip_num, *map= MEM_mallocN(totdg * sizeof(int), "get_defgroup_flip_map");
+               memset(map, -1, totdg * sizeof(int));
+
+               for (dg=ob->defbase.first, i=0; dg; dg=dg->next, i++) {
+                       if(map[i] == -1) { /* may be calculated previously */
+                               flip_vertexgroup_name(name, dg->name, 0);
+                               if(strcmp(name, dg->name)) {
+                                       flip_num= get_named_vertexgroup_num(ob, name);
+                                       if(flip_num > -1) {
+                                               map[i]= flip_num;
+                                               map[flip_num]= i; /* save an extra lookup */
+                                       }
+                               }
+                       }
+               }
+               return map;
+       }
+}
+
 void unique_vertexgroup_name (bDeformGroup *dg, Object *ob)
 {
        bDeformGroup *curdef;
@@ -221,6 +282,121 @@ void unique_vertexgroup_name (bDeformGroup *dg, Object *ob)
        }       
 }
 
+
+/* finds the best possible flipped name. For renaming; check for unique names afterwards */
+/* if strip_number: removes number extensions */
+void flip_vertexgroup_name (char *name_r, const char *name, int strip_number)
+{
+       int     len;
+       char    prefix[sizeof((bDeformGroup *)NULL)->name]={""};   /* The part before the facing */
+       char    suffix[sizeof((bDeformGroup *)NULL)->name]={""};   /* The part after the facing */
+       char    replace[sizeof((bDeformGroup *)NULL)->name]={""};  /* The replacement string */
+       char    number[sizeof((bDeformGroup *)NULL)->name]={""};   /* The number extension string */
+       char    *index=NULL;
+
+       len= strlen(name);
+       if(len<3) return; // we don't do names like .R or .L
+
+       /* We first check the case with a .### extension, let's find the last period */
+       if(isdigit(name[len-1])) {
+               index= strrchr(name, '.'); // last occurrence
+               if (index && isdigit(index[1]) ) { // doesnt handle case bone.1abc2 correct..., whatever!
+                       if(strip_number==0)
+                               strcpy(number, index);
+                       *index= 0;
+                       len= strlen(name);
+               }
+       }
+
+       strcpy (prefix, name);
+
+#define IS_SEPARATOR(a) ((a)=='.' || (a)==' ' || (a)=='-' || (a)=='_')
+
+       /* first case; separator . - _ with extensions r R l L  */
+       if( IS_SEPARATOR(name[len-2]) ) {
+               switch(name[len-1]) {
+                       case 'l':
+                               prefix[len-1]= 0;
+                               strcpy(replace, "r");
+                               break;
+                       case 'r':
+                               prefix[len-1]= 0;
+                               strcpy(replace, "l");
+                               break;
+                       case 'L':
+                               prefix[len-1]= 0;
+                               strcpy(replace, "R");
+                               break;
+                       case 'R':
+                               prefix[len-1]= 0;
+                               strcpy(replace, "L");
+                               break;
+               }
+       }
+       /* case; beginning with r R l L , with separator after it */
+       else if( IS_SEPARATOR(name[1]) ) {
+               switch(name[0]) {
+                       case 'l':
+                               strcpy(replace, "r");
+                               strcpy(suffix, name+1);
+                               prefix[0]= 0;
+                               break;
+                       case 'r':
+                               strcpy(replace, "l");
+                               strcpy(suffix, name+1);
+                               prefix[0]= 0;
+                               break;
+                       case 'L':
+                               strcpy(replace, "R");
+                               strcpy(suffix, name+1);
+                               prefix[0]= 0;
+                               break;
+                       case 'R':
+                               strcpy(replace, "L");
+                               strcpy(suffix, name+1);
+                               prefix[0]= 0;
+                               break;
+               }
+       }
+       else if(len > 5) {
+               /* hrms, why test for a separator? lets do the rule 'ultimate left or right' */
+               index = BLI_strcasestr(prefix, "right");
+               if (index==prefix || index==prefix+len-5) {
+                       if(index[0]=='r')
+                               strcpy (replace, "left");
+                       else {
+                               if(index[1]=='I')
+                                       strcpy (replace, "LEFT");
+                               else
+                                       strcpy (replace, "Left");
+                       }
+                       *index= 0;
+                       strcpy (suffix, index+5);
+               }
+               else {
+                       index = BLI_strcasestr(prefix, "left");
+                       if (index==prefix || index==prefix+len-4) {
+                               if(index[0]=='l')
+                                       strcpy (replace, "right");
+                               else {
+                                       if(index[1]=='E')
+                                               strcpy (replace, "RIGHT");
+                                       else
+                                               strcpy (replace, "Right");
+                               }
+                               *index= 0;
+                               strcpy (suffix, index+4);
+                       }
+               }
+       }
+
+#undef IS_SEPARATOR
+
+       sprintf (name_r, "%s%s%s%s", prefix, replace, suffix, number);
+}
+
+
+
 float deformvert_get_weight(const struct MDeformVert *dvert, int group_num)
 {
        if(dvert)
index 7e211f60cd5d545b734ac3eec867189e987ef302..3c925e5ff25f3eafa3f481a3829f66dc9d7c8e35 100644 (file)
@@ -39,7 +39,6 @@
 #include "stdarg.h"
 #include "math.h"
 #include "float.h"
-#include "ctype.h"
 
 #include "BLI_math.h"
 #include "BLI_blenlib.h"
@@ -1801,118 +1800,6 @@ static void mirrorModifier_updateDepgraph(ModifierData *md, DagForest *forest, S
        }
 }
 
-/* finds the best possible flipped name. For renaming; check for unique names afterwards */
-/* if strip_number: removes number extensions */
-static void vertgroup_flip_name (char *name, int strip_number)
-{
-       int     len;
-       char    prefix[128]={""};   /* The part before the facing */
-       char    suffix[128]={""};   /* The part after the facing */
-       char    replace[128]={""};  /* The replacement string */
-       char    number[128]={""};   /* The number extension string */
-       char    *index=NULL;
-
-       len= strlen(name);
-       if(len<3) return; // we don't do names like .R or .L
-
-       /* We first check the case with a .### extension, let's find the last period */
-       if(isdigit(name[len-1])) {
-               index= strrchr(name, '.'); // last occurrence
-               if (index && isdigit(index[1]) ) { // doesnt handle case bone.1abc2 correct..., whatever!
-                       if(strip_number==0) 
-                               strcpy(number, index);
-                       *index= 0;
-                       len= strlen(name);
-               }
-       }
-
-       strcpy (prefix, name);
-
-#define IS_SEPARATOR(a) ((a)=='.' || (a)==' ' || (a)=='-' || (a)=='_')
-
-       /* first case; separator . - _ with extensions r R l L  */
-       if( IS_SEPARATOR(name[len-2]) ) {
-               switch(name[len-1]) {
-                       case 'l':
-                               prefix[len-1]= 0;
-                               strcpy(replace, "r");
-                               break;
-                       case 'r':
-                               prefix[len-1]= 0;
-                               strcpy(replace, "l");
-                               break;
-                       case 'L':
-                               prefix[len-1]= 0;
-                               strcpy(replace, "R");
-                               break;
-                       case 'R':
-                               prefix[len-1]= 0;
-                               strcpy(replace, "L");
-                               break;
-               }
-       }
-       /* case; beginning with r R l L , with separator after it */
-       else if( IS_SEPARATOR(name[1]) ) {
-               switch(name[0]) {
-                       case 'l':
-                               strcpy(replace, "r");
-                               strcpy(suffix, name+1);
-                               prefix[0]= 0;
-                               break;
-                       case 'r':
-                               strcpy(replace, "l");
-                               strcpy(suffix, name+1);
-                               prefix[0]= 0;
-                               break;
-                       case 'L':
-                               strcpy(replace, "R");
-                               strcpy(suffix, name+1);
-                               prefix[0]= 0;
-                               break;
-                       case 'R':
-                               strcpy(replace, "L");
-                               strcpy(suffix, name+1);
-                               prefix[0]= 0;
-                               break;
-               }
-       }
-       else if(len > 5) {
-               /* hrms, why test for a separator? lets do the rule 'ultimate left or right' */
-               index = BLI_strcasestr(prefix, "right");
-               if (index==prefix || index==prefix+len-5) {
-                       if(index[0]=='r') 
-                               strcpy (replace, "left");
-                       else {
-                               if(index[1]=='I') 
-                                       strcpy (replace, "LEFT");
-                               else
-                                       strcpy (replace, "Left");
-                       }
-                       *index= 0;
-                       strcpy (suffix, index+5);
-               }
-               else {
-                       index = BLI_strcasestr(prefix, "left");
-                       if (index==prefix || index==prefix+len-4) {
-                               if(index[0]=='l') 
-                                       strcpy (replace, "right");
-                               else {
-                                       if(index[1]=='E') 
-                                               strcpy (replace, "RIGHT");
-                                       else
-                                               strcpy (replace, "Right");
-                               }
-                               *index= 0;
-                               strcpy (suffix, index+4);
-                       }
-               }
-       }
-
-#undef IS_SEPARATOR
-
-       sprintf (name, "%s%s%s%s", prefix, replace, suffix, number);
-}
-
 static DerivedMesh *doMirrorOnAxis(MirrorModifierData *mmd,
                Object *ob,
                DerivedMesh *dm,
@@ -2022,8 +1909,7 @@ static DerivedMesh *doMirrorOnAxis(MirrorModifierData *mmd,
                                                        continue;
                                                
                                                def = vector_def[dvert->dw[j].def_nr];
-                                               strcpy(tmpname, def->name);
-                                               vertgroup_flip_name(tmpname,0);
+                                               flip_vertexgroup_name(tmpname, def->name, 0);
                                                
                                                for(b = 0, defb = ob->defbase.first; defb;
                                                    defb = defb->next, b++)
index 63d681cce0be95f4962a9cf9f81b5cc8599e441a..006e05370b154767a4c9b13e0c09b360b586ca28 100644 (file)
@@ -2999,8 +2999,8 @@ void psys_cache_edit_paths(Scene *scene, Object *ob, PTCacheEdit *edit, float cf
 
                /* should init_particle_interpolation set this ? */
                if(pset->brushtype==PE_BRUSH_WEIGHT){
-                       pind.hkey[0] = pa->hair;
-                       pind.hkey[1] = pa->hair + 1;
+                       pind.hkey[0] = NULL;
+                       pind.hkey[1] = pa->hair;
                }
 
 
@@ -3036,12 +3036,6 @@ void psys_cache_edit_paths(Scene *scene, Object *ob, PTCacheEdit *edit, float cf
 
                        do_particle_interpolation(psys, i, pa, t, frs_sec, &pind, &result);
 
-                       /* should init_particle_interpolation set this ? */
-                       if(pset->brushtype==PE_BRUSH_WEIGHT){
-                               pind.hkey[0] = pind.hkey[1];
-                               pind.hkey[1]++;
-                       }
-
                         /* non-hair points are already in global space */
                        if(psys && !(psys->flag & PSYS_GLOBAL_HAIR)) {
                                mul_m4_v3(hairmat, result.co);
@@ -3099,10 +3093,17 @@ void psys_cache_edit_paths(Scene *scene, Object *ob, PTCacheEdit *edit, float cf
 
                        /* selection coloring in edit mode */
                        if(pset->brushtype==PE_BRUSH_WEIGHT){
-                               if(k==steps)
+                               if(k==0)
+                                       weight_to_rgb(pind.hkey[1]->weight, ca->col, ca->col+1, ca->col+2);
+                               else if(k >= steps - 1)
                                        weight_to_rgb(pind.hkey[0]->weight, ca->col, ca->col+1, ca->col+2);
                                else
                                        weight_to_rgb((1.0f - keytime) * pind.hkey[0]->weight + keytime * pind.hkey[1]->weight, ca->col, ca->col+1, ca->col+2);
+
+                               /* at the moment this is only used for weight painting.
+                                * will need to move out of this check if its used elsewhere. */
+                               pind.hkey[0] = pind.hkey[1];
+                               pind.hkey[1]++;
                        }
                        else {
                                if((ekey + (pind.ekey[0] - point->keys))->flag & PEK_SELECT){
index ab558afe8970428893097d3bd34c11870bea261e..412a733dee0aaf81c8357f3e3bc8b92b00bc8946 100644 (file)
@@ -120,7 +120,7 @@ void EM_cache_x_mirror_vert(struct Object *ob, struct EditMesh *em)
        }
 }
 
-void EM_select_mirrored(Object *obedit, EditMesh *em, int extend)
+static void EM_select_mirrored(Object *obedit, EditMesh *em, int extend)
 {
 
        EditVert *eve;
index 861b2cc0a6efb06a901b913027475af2633348bb..cfb4cda2460db1c997333c67d4b8c9a1758ba30d 100644 (file)
@@ -187,6 +187,7 @@ void OBJECT_OT_vertex_group_levels(struct wmOperatorType *ot);
 void OBJECT_OT_vertex_group_invert(struct wmOperatorType *ot);
 void OBJECT_OT_vertex_group_blend(struct wmOperatorType *ot);
 void OBJECT_OT_vertex_group_clean(struct wmOperatorType *ot);
+void OBJECT_OT_vertex_group_mirror(struct wmOperatorType *ot);
 void OBJECT_OT_vertex_group_set_active(struct wmOperatorType *ot);
 
 void OBJECT_OT_game_property_new(struct wmOperatorType *ot);
index 0837051ae0c00f4474335423b2ccdb264db881c0..8b29e2ca2ae5948d1d93467a696f3285a4f38787 100644 (file)
@@ -173,6 +173,7 @@ void ED_operatortypes_object(void)
        WM_operatortype_append(OBJECT_OT_vertex_group_levels);
        WM_operatortype_append(OBJECT_OT_vertex_group_blend);
        WM_operatortype_append(OBJECT_OT_vertex_group_clean);
+       WM_operatortype_append(OBJECT_OT_vertex_group_mirror);
        WM_operatortype_append(OBJECT_OT_vertex_group_set_active);
 
        WM_operatortype_append(OBJECT_OT_game_property_new);
index 43fabff67936acfbbcaced9f2bcff7179c5d3b19..84b70e0a6900778286a3d46ae5406cac3d2ee6a5 100644 (file)
@@ -903,6 +903,68 @@ static void vgroup_clean_all(Object *ob, float eul, int keep_single)
        }
 }
 
+static void vgroup_mirror(Object *ob, int mirror_weights, int flip_vgroups)
+{
+       EditVert *eve, *eve_mirr;
+       MDeformVert *dvert, *dvert_mirr;
+       int     *flip_map;
+
+       if(mirror_weights==0 && flip_vgroups==0)
+               return;
+
+       /* only the active group */
+       if(ob->type == OB_MESH) {
+               Mesh *me= ob->data;
+               EditMesh *em = BKE_mesh_get_editmesh(me);
+
+               EM_cache_x_mirror_vert(ob, em);
+
+               if(!CustomData_has_layer(&em->vdata, CD_MDEFORMVERT))
+                       return;
+
+               flip_map= get_defgroup_flip_map(ob);
+
+               /* Go through the list of editverts and assign them */
+               for(eve=em->verts.first; eve; eve=eve->next){
+                       if((eve_mirr=eve->tmp.v)) {
+                               if(eve_mirr->f & SELECT || eve->f & SELECT) {
+                                       dvert= CustomData_em_get(&em->vdata, eve->data, CD_MDEFORMVERT);
+                                       dvert_mirr= CustomData_em_get(&em->vdata, eve_mirr->data, CD_MDEFORMVERT);
+                                       if(dvert && dvert_mirr) {
+                                               if(eve_mirr->f & SELECT && eve->f & SELECT) {
+                                                       /* swap */
+                                                       if(mirror_weights)
+                                                               SWAP(MDeformVert, *dvert, *dvert_mirr);
+                                                       if(flip_vgroups) {
+                                                               flip_defvert(dvert, flip_map);
+                                                               flip_defvert(dvert_mirr, flip_map);
+                                                       }
+                                               }
+                                               else {
+                                                       /* dvert should always be the target */
+                                                       if(eve_mirr->f & SELECT) {
+                                                               SWAP(MDeformVert *, dvert, dvert_mirr);
+                                                       }
+
+                                                       if(mirror_weights)
+                                                               copy_defvert(dvert, dvert_mirr);
+                                                       if(flip_vgroups) {
+                                                               flip_defvert(dvert, flip_map);
+                                                       }
+                                               }
+                                       }
+                               }
+
+                               eve->tmp.v= eve_mirr->tmp.v= NULL;
+                       }
+               }
+
+               MEM_freeN(flip_map);
+
+               BKE_mesh_end_editmesh(me, em);
+       }
+}
+
 static void vgroup_delete_update_users(Object *ob, int id)
 {
        ExplodeModifierData *emd;
@@ -1026,7 +1088,7 @@ static void vgroup_active_remove_verts(Object *ob, int allverts)
                for(eve=em->verts.first; eve; eve=eve->next){
                        dvert= CustomData_em_get(&em->vdata, eve->data, CD_MDEFORMVERT);
                
-                       if(dvert && dvert->dw && ((eve->f & 1) || allverts)){
+                       if(dvert && dvert->dw && ((eve->f & SELECT) || allverts)){
                                for(i=0; i<dvert->totweight; i++){
                                        /* Find group */
                                        eg = BLI_findlink(&ob->defbase, dvert->dw[i].def_nr);
@@ -1208,7 +1270,7 @@ static void vgroup_assign_verts(Object *ob, float weight)
                for(eve=em->verts.first; eve; eve=eve->next){
                        dvert= CustomData_em_get(&em->vdata, eve->data, CD_MDEFORMVERT);
 
-                       if(dvert && (eve->f & 1)){
+                       if(dvert && (eve->f & SELECT)){
                                done=0;
                                /* See if this vert already has a reference to this group */
                                /*              If so: Change its weight */
@@ -1684,6 +1746,40 @@ void OBJECT_OT_vertex_group_clean(wmOperatorType *ot)
 }
 
 
+static int vertex_group_mirror_exec(bContext *C, wmOperator *op)
+{
+       Object *ob= CTX_data_pointer_get_type(C, "object", &RNA_Object).data;
+
+       vgroup_mirror(ob, RNA_boolean_get(op->ptr,"mirror_weights"), RNA_boolean_get(op->ptr,"flip_group_names"));
+
+       DAG_id_flush_update(&ob->id, OB_RECALC_DATA);
+       WM_event_add_notifier(C, NC_OBJECT|ND_DRAW, ob);
+       WM_event_add_notifier(C, NC_GEOM|ND_DATA, ob->data);
+
+       return OPERATOR_FINISHED;
+}
+
+void OBJECT_OT_vertex_group_mirror(wmOperatorType *ot)
+{
+       /* identifiers */
+       ot->name= "Mirror Vertex Group";
+       ot->idname= "OBJECT_OT_vertex_group_mirror";
+       ot->description= "Mirror weights, and flip vertex group names, copying when only one side is selected.";
+
+       /* api callbacks */
+       ot->poll= vertex_group_poll_edit;
+       ot->exec= vertex_group_mirror_exec;
+
+       /* flags */
+       ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
+
+       /* properties */
+       RNA_def_boolean(ot->srna, "mirror_weights", TRUE, "Mirror Weights", "Mirror weights.");
+       RNA_def_boolean(ot->srna, "flip_group_names", TRUE, "Flip Groups", "Flip vertex group names while mirroring.");
+
+}
+
+
 static int vertex_group_copy_to_linked_exec(bContext *C, wmOperator *op)
 {
        Scene *scene= CTX_data_scene(C);
index fe38d71dc928395ab848259d63e2ac3a8f674139..f0870ca97645c1d69cf7556de79f2ed808849fce 100644 (file)
@@ -2366,6 +2366,52 @@ void PARTICLE_OT_remove_doubles(wmOperatorType *ot)
        RNA_def_float(ot->srna, "threshold", 0.0002f, 0.0f, FLT_MAX, "Threshold", "Threshold distance withing which particles are removed", 0.00001f, 0.1f);
 }
 
+
+static int weight_set_exec(bContext *C, wmOperator *op)
+{
+       Scene *scene= CTX_data_scene(C);
+       ParticleEditSettings *pset= PE_settings(scene);
+       Object *ob= CTX_data_active_object(C);
+       PTCacheEdit *edit= PE_get_current(scene, ob);
+       ParticleSystem *psys = edit->psys;
+       POINT_P;
+       KEY_K;
+       HairKey *hkey;
+       float weight;
+       ParticleBrushData *brush= &pset->brush[pset->brushtype];
+       edit= psys->edit;
+
+       weight= (float)(brush->strength / 100.0f);
+
+       LOOP_SELECTED_POINTS {
+               ParticleData *pa= psys->particles + p;
+
+               LOOP_SELECTED_KEYS {
+                       hkey= pa->hair + k;
+                       hkey->weight= weight;
+               }
+       }
+
+       DAG_id_flush_update(&ob->id, OB_RECALC_DATA);
+       WM_event_add_notifier(C, NC_OBJECT|ND_PARTICLE_DATA, ob);
+
+       return OPERATOR_FINISHED;
+}
+
+void PARTICLE_OT_weight_set(wmOperatorType *ot)
+{
+       /* identifiers */
+       ot->name= "Weight Set";
+       ot->idname= "PARTICLE_OT_weight_set";
+
+       /* api callbacks */
+       ot->exec= weight_set_exec;
+       ot->poll= PE_poll;
+
+       /* flags */
+       ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
+}
+
 /************************ cursor drawing *******************************/
 
 static void brush_drawcursor(bContext *C, int x, int y, void *customdata)
index cc0a288f8be3f128f7387e720de99b932da9f8bd..3de5c256df78da621fdfea2aa575e0fddbc79e80 100644 (file)
@@ -50,6 +50,7 @@ void PARTICLE_OT_reveal(struct wmOperatorType *ot);
 void PARTICLE_OT_rekey(struct wmOperatorType *ot);
 void PARTICLE_OT_subdivide(struct wmOperatorType *ot);
 void PARTICLE_OT_remove_doubles(struct wmOperatorType *ot);
+void PARTICLE_OT_weight_set(struct wmOperatorType *ot);
 void PARTICLE_OT_delete(struct wmOperatorType *ot);
 void PARTICLE_OT_mirror(struct wmOperatorType *ot);
 
index 5cb8230e463d31d397d824847d108b228bbd2706..2728f64a777fdb501bd7127add2042810d8a5c2a 100644 (file)
@@ -57,6 +57,7 @@ static void operatortypes_particle(void)
        WM_operatortype_append(PARTICLE_OT_rekey);
        WM_operatortype_append(PARTICLE_OT_subdivide);
        WM_operatortype_append(PARTICLE_OT_remove_doubles);
+       WM_operatortype_append(PARTICLE_OT_weight_set); 
        WM_operatortype_append(PARTICLE_OT_delete);
        WM_operatortype_append(PARTICLE_OT_mirror);
 
@@ -111,6 +112,8 @@ static void keymap_particle(wmKeyConfig *keyconf)
        RNA_enum_set(WM_keymap_add_item(keymap, "PARTICLE_OT_brush_radial_control", FKEY, KM_PRESS, KM_SHIFT, 0)->ptr, "mode", WM_RADIALCONTROL_STRENGTH);
 
        WM_keymap_add_menu(keymap, "VIEW3D_MT_particle_specials", WKEY, KM_PRESS, 0, 0);
+       
+       WM_keymap_add_item(keymap, "PARTICLE_OT_weight_set", KKEY, KM_PRESS, KM_SHIFT, 0);
 
        ED_object_generic_keymap(keyconf, keymap, 1);
 }