svn merge ^/trunk/blender -r48592:HEAD
[blender-staging.git] / source / blender / editors / object / object_vgroup.c
index c5296d0f7a75fb8425b17305b564b886051df7f1..a07bc3edda0ed88fb9e8d0479b3517ad9ccf9419 100644 (file)
@@ -61,6 +61,7 @@
 #include "BKE_tessmesh.h"
 #include "BKE_report.h"
 #include "BKE_DerivedMesh.h"
+#include "BKE_object_deform.h"
 
 #include "RNA_access.h"
 #include "RNA_define.h"
@@ -994,8 +995,9 @@ static void vgroup_duplicate(Object *ob)
                        dw_org = defvert_find_index(dv, idg);
                        if (dw_org) {
                                /* defvert_verify_index re-allocs org so need to store the weight first */
+                               const float weight = dw_org->weight;
                                dw_cpy = defvert_verify_index(dv, icdg);
-                               dw_cpy->weight = dw_org->weight;
+                               dw_cpy->weight = weight;
                        }
                }
 
@@ -1262,7 +1264,7 @@ static void moveCloserToDistanceFromPlane(Scene *scene, Object *ob, Mesh *me, in
                                        dist = dists[i];
                                }
                                else {
-                                       if (fabs(dist - distToBe) < fabs(dists[i] - distToBe)) {
+                                       if (fabsf(dist - distToBe) < fabsf(dists[i] - distToBe)) {
                                                upDown[i] = 0;
                                                changes[i][0] = vc;
                                                changes[i][1] = hc;
@@ -1271,7 +1273,7 @@ static void moveCloserToDistanceFromPlane(Scene *scene, Object *ob, Mesh *me, in
                                        else {
                                                upDown[i] = 1;
                                        }
-                                       if (fabs(dists[i] - distToBe) > fabs(distToStart - distToBe)) {
+                                       if (fabsf(dists[i] - distToBe) > fabsf(distToStart - distToBe)) {
                                                changes[i][0] = 0;
                                                changes[i][1] = 0;
                                                dists[i] = distToStart;
@@ -1287,7 +1289,7 @@ static void moveCloserToDistanceFromPlane(Scene *scene, Object *ob, Mesh *me, in
                        for (i = k + 1; i < totweight; i++) {
                                dist = dists[i];
 
-                               if (fabs(dist) > fabs(dists[i])) {
+                               if (fabsf(dist) > fabsf(dists[i])) {
                                        bestIndex = i;
                                }
                        }
@@ -1315,17 +1317,17 @@ static void moveCloserToDistanceFromPlane(Scene *scene, Object *ob, Mesh *me, in
                        }
                }
                bestIndex = -1;
-               // find the best change with an acceptable horizontal change
+               /* find the best change with an acceptable horizontal change */
                for (i = 0; i < totweight; i++) {
-                       if (fabs(changes[i][0]) > fabs(changes[i][1] * 2.0f)) {
+                       if (fabsf(changes[i][0]) > fabsf(changes[i][1] * 2.0f)) {
                                bestIndex = i;
                                break;
                        }
                }
                if (bestIndex != -1) {
                        wasChange = TRUE;
-                       // it is a good place to stop if it tries to move the opposite direction
-                       // (relative to the plane) of last time
+                       /* it is a good place to stop if it tries to move the opposite direction
+                        * (relative to the plane) of last time */
                        if (lastIndex != -1) {
                                if (wasUp != upDown[bestIndex]) {
                                        wasChange = FALSE;
@@ -1443,7 +1445,6 @@ static void vgroup_levels(Object *ob, float offset, float gain)
        }
 }
 
-/* TODO - select between groups */
 static void vgroup_normalize_all(Object *ob, int lock_active)
 {
        MDeformVert *dv, **dvert_array = NULL;
@@ -1459,29 +1460,35 @@ static void vgroup_normalize_all(Object *ob, int lock_active)
        ED_vgroup_give_parray(ob->data, &dvert_array, &dvert_tot, use_vert_sel);
 
        if (dvert_array) {
-               if (lock_active) {
+               const int defbase_tot = BLI_countlist(&ob->defbase);
+               char *lock_flags = BKE_objdef_lock_flags_get(ob, defbase_tot);
 
-                       for (i = 0; i < dvert_tot; i++) {
-                               /* in case its not selected */
-                               if (!(dv = dvert_array[i])) {
-                                       continue;
-                               }
-
-                               defvert_normalize_lock(dv, def_nr);
-                       }
+               if ((lock_active == TRUE) &&
+                   (lock_flags != NULL) &&
+                   (def_nr < defbase_tot))
+               {
+                       lock_flags[def_nr] = TRUE;
                }
-               else {
-                       for (i = 0; i < dvert_tot; i++) {
 
-                               /* in case its not selected */
-                               if (!(dv = dvert_array[i])) {
-                                       continue;
+               for (i = 0; i < dvert_tot; i++) {
+                       /* in case its not selected */
+                       if ((dv = dvert_array[i])) {
+                               if (lock_flags) {
+                                       defvert_normalize_lock_map(dv, lock_flags, defbase_tot);
+                               }
+                               else if (lock_active) {
+                                       defvert_normalize_lock_single(dv, def_nr);
+                               }
+                               else {
+                                       defvert_normalize(dv);
                                }
-
-                               defvert_normalize(dv);
                        }
                }
 
+               if (lock_flags) {
+                       MEM_freeN(lock_flags);
+               }
+
                MEM_freeN(dvert_array);
        }
 }
@@ -1843,8 +1850,8 @@ void ED_vgroup_mirror(Object *ob, const short mirror_weights, const short flip_v
        int *flip_map, flip_map_len;
        const int def_nr = ob->actdef - 1;
 
-       if ( (mirror_weights == 0 && flip_vgroups == 0) ||
-            (BLI_findlink(&ob->defbase, def_nr) == NULL) )
+       if ((mirror_weights == 0 && flip_vgroups == 0) ||
+           (BLI_findlink(&ob->defbase, def_nr) == NULL))
        {
                return;
        }
@@ -1989,6 +1996,10 @@ void ED_vgroup_mirror(Object *ob, const short mirror_weights, const short flip_v
                }
        }
 
+       /* flip active group index */
+       if (flip_vgroups && flip_map[def_nr] >= 0)
+               ob->actdef = flip_map[def_nr] + 1;
+
 cleanup:
        if (flip_map) MEM_freeN(flip_map);
 
@@ -2089,6 +2100,21 @@ static void vgroup_delete_object_mode(Object *ob, bDeformGroup *dg)
        if (ob->actdef < 1 && ob->defbase.first)
                ob->actdef = 1;
 
+       /* remove all dverts */
+       if (ob->defbase.first == NULL) {
+               if (ob->type == OB_MESH) {
+                       Mesh *me = ob->data;
+                       CustomData_free_layer_active(&me->vdata, CD_MDEFORMVERT, me->totvert);
+                       me->dvert = NULL;
+               }
+               else if (ob->type == OB_LATTICE) {
+                       Lattice *lt = ob->data;
+                       if (lt->dvert) {
+                               MEM_freeN(lt->dvert);
+                               lt->dvert = NULL;
+                       }
+               }
+       }
 }
 
 /* only in editmode */
@@ -2981,7 +3007,7 @@ void OBJECT_OT_vertex_group_mirror(wmOperatorType *ot)
 
        /* 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");
+       RNA_def_boolean(ot->srna, "flip_group_names", TRUE, "Flip Group Names", "Flip vertex group names");
        RNA_def_boolean(ot->srna, "all_groups", FALSE, "All Groups", "Mirror all vertex groups weights");
 
 }
@@ -3202,7 +3228,7 @@ void OBJECT_OT_vertex_group_set_active(wmOperatorType *ot)
 }
 
 /* creates the name_array parameter for vgroup_do_remap, call this before fiddling
- * with the order of vgroups then call vgroup_do_remap after*/
+ * with the order of vgroups then call vgroup_do_remap after */
 static char *vgroup_init_remap(Object *ob)
 {
        bDeformGroup *def;