Weight Paint: implement a red shade for bones with locked weights.
authorAlexander Gavrilov <angavrilov@gmail.com>
Tue, 17 Dec 2019 13:11:31 +0000 (16:11 +0300)
committerAlexander Gavrilov <angavrilov@gmail.com>
Sat, 18 Jan 2020 08:43:31 +0000 (11:43 +0300)
Blender supports locking vertex groups to prevent changes to the
weights. However, as mentioned in comments for D3837, it is hard
to use this because there is no interface for locking in 3D View.

This adds a red shade to bones that are associated with a locked
weight group during weight paint mode, as the first step to adding
such interface. The next step is adding a pie menu for lock/unlock.

Differential Revision: https://developer.blender.org/D6533

12 files changed:
release/datafiles/userdef/userdef_default_theme.c
release/scripts/startup/bl_ui/space_userpref.py
source/blender/blenkernel/BKE_blender_version.h
source/blender/blenloader/intern/readfile.c
source/blender/blenloader/intern/versioning_userdef.c
source/blender/draw/engines/overlay/overlay_armature.c
source/blender/editors/include/UI_resources.h
source/blender/editors/interface/resources.c
source/blender/editors/object/object_vgroup.c
source/blender/makesdna/DNA_armature_types.h
source/blender/makesdna/DNA_userdef_types.h
source/blender/makesrna/intern/rna_userdef.c

index 147b55f60ef1245ed58f3a9f2ed5f4b8989f35d5..f245baa1d83a095819380cceb348fb01fd36c638 100644 (file)
@@ -339,6 +339,7 @@ const bTheme U_theme_default = {
     .bone_solid = RGBA(0xb2b2b2ff),
     .bone_pose = RGBA(0x50c8ff50),
     .bone_pose_active = RGBA(0x8cffff50),
+    .bone_locked_weight = RGBA(0xff000080),
     .cframe = RGBA(0x60c040ff),
     .time_keyframe = RGBA(0xddd700ff),
     .time_gp_keyframe = RGBA(0xb5e61dff),
index 4f35bcc29dfb01a0fab905bf0c9d057c55350f58..ad5e7b5442c4505c9789752ae7c78fc07f1e67ba 100644 (file)
@@ -997,6 +997,7 @@ class PreferenceThemeSpacePanel:
             "freestyle_face_mark",
             "split_normal",
             "bone_solid",
+            "bone_locked_weight",
             "paint_curve_pivot",
         },
         'GRAPH_EDITOR': {
index dd3e381ef5da2d544d6976c0621cb51e48f18c06..4fcb10b29f3346d9bfc5a21a76bda3117c6f7bf2 100644 (file)
@@ -27,7 +27,7 @@
  * \note Use #STRINGIFY() rather than defining with quotes.
  */
 #define BLENDER_VERSION 283
-#define BLENDER_SUBVERSION 0
+#define BLENDER_SUBVERSION 1
 /** Several breakages with 280, e.g. collections vs layers. */
 #define BLENDER_MINVERSION 280
 #define BLENDER_MINSUBVERSION 0
index 6a54fc8f59e51abf7ff5887eb2a05b64ac9a33bb..e1424da2207616e730082c5d602ed7cb7b8215b7 100644 (file)
@@ -3874,7 +3874,7 @@ static void direct_link_bones(FileData *fd, Bone *bone)
   bone->bbone_next = newdataadr(fd, bone->bbone_next);
   bone->bbone_prev = newdataadr(fd, bone->bbone_prev);
 
-  bone->flag &= ~BONE_DRAW_ACTIVE;
+  bone->flag &= ~(BONE_DRAW_ACTIVE | BONE_DRAW_LOCKED_WEIGHT);
 
   link_list(fd, &bone->childbase);
 
index b1f70848bdca06903a89216e61c32520765ffde3..e1ea4e3bb24bec32d3ab1d112f8343cb80cdbf29 100644 (file)
@@ -164,6 +164,10 @@ static void do_versions_theme(const UserDef *userdef, bTheme *btheme)
     FROM_DEFAULT_V4_UCHAR(space_view3d.face_front);
   }
 
+  if (!USER_VERSION_ATLEAST(283, 1)) {
+    FROM_DEFAULT_V4_UCHAR(space_view3d.bone_locked_weight);
+  }
+
   /**
    * Versioning code until next subversion bump goes here.
    *
index 0b77fcad2653be6b8e22a4091f84a04229657ba9..416283e321b4eadd5aef0ad30dc5c8ddbe732aef 100644 (file)
@@ -35,6 +35,7 @@
 #include "BLI_math.h"
 #include "BLI_utildefines.h"
 
+#include "BKE_action.h"
 #include "BKE_armature.h"
 #include "BKE_modifier.h"
 
@@ -974,6 +975,15 @@ static bool set_pchan_color(const ArmatureDrawContext *ctx,
 /** \name Drawing Color Helpers
  * \{ */
 
+static void bone_locked_color_shade(float color[4])
+{
+  float locked_color[4];
+
+  UI_GetThemeColor4fv(TH_BONE_LOCKED_WEIGHT, locked_color);
+
+  interp_v3_v3v3(color, color, locked_color, locked_color[3]);
+}
+
 static const float *get_bone_solid_color(const ArmatureDrawContext *ctx,
                                          const EditBone *UNUSED(eBone),
                                          const bPoseChannel *pchan,
@@ -989,6 +999,11 @@ static const float *get_bone_solid_color(const ArmatureDrawContext *ctx,
     static float disp_color[4];
     copy_v4_v4(disp_color, pchan->draw_data->solid_color);
     set_pchan_color(ctx, PCHAN_COLOR_SOLID, boneflag, constflag, disp_color);
+
+    if (boneflag & BONE_DRAW_LOCKED_WEIGHT) {
+      bone_locked_color_shade(disp_color);
+    }
+
     return disp_color;
   }
 
@@ -1009,7 +1024,7 @@ static const float *get_bone_solid_with_consts_color(const ArmatureDrawContext *
   const float *col = get_bone_solid_color(ctx, eBone, pchan, arm, boneflag, constflag);
 
   static float consts_color[4];
-  if ((arm->flag & ARM_POSEMODE) &&
+  if ((arm->flag & ARM_POSEMODE) && !(boneflag & BONE_DRAW_LOCKED_WEIGHT) &&
       set_pchan_color(ctx, PCHAN_COLOR_CONSTS, boneflag, constflag, consts_color)) {
     interp_v3_v3v3(consts_color, col, consts_color, 0.5f);
   }
@@ -1065,6 +1080,10 @@ static const float *get_bone_wire_color(const ArmatureDrawContext *ctx,
   else if (arm->flag & ARM_POSEMODE) {
     copy_v4_v4(disp_color, pchan->draw_data->wire_color);
     set_pchan_color(ctx, PCHAN_COLOR_NORMAL, boneflag, constflag, disp_color);
+
+    if (boneflag & BONE_DRAW_LOCKED_WEIGHT) {
+      bone_locked_color_shade(disp_color);
+    }
   }
   else {
     copy_v3_v3(disp_color, ctx->color.vertex);
@@ -1518,7 +1537,7 @@ static void draw_bone_custom_shape(ArmatureDrawContext *ctx,
       drw_shgroup_bone_custom_empty(ctx, disp_mat, col_wire, pchan->custom);
     }
   }
-  if ((boneflag & BONE_DRAWWIRE) == 0) {
+  if ((boneflag & BONE_DRAWWIRE) == 0 && (boneflag & BONE_DRAW_LOCKED_WEIGHT) == 0) {
     drw_shgroup_bone_custom_solid(ctx, disp_mat, col_solid, col_hint, col_wire, pchan->custom);
   }
   else {
@@ -2010,6 +2029,8 @@ static void draw_armature_edit(ArmatureDrawContext *ctx)
           boneflag |= BONE_DRAW_ACTIVE;
         }
 
+        boneflag &= ~BONE_DRAW_LOCKED_WEIGHT;
+
         draw_bone_relations(ctx, eBone, NULL, arm, boneflag, constflag);
 
         if (arm->drawtype == ARM_ENVELOPE) {
@@ -2054,6 +2075,7 @@ static void draw_armature_pose(ArmatureDrawContext *ctx)
   bPoseChannel *pchan;
   int index = -1;
   const bool show_text = DRW_state_show_text();
+  bool draw_locked_weights = false;
 
   /* We can't safely draw non-updated pose, might contain NULL bone pointers... */
   if (ob->pose->flag & POSE_RECALC) {
@@ -2089,6 +2111,28 @@ static void draw_armature_pose(ArmatureDrawContext *ctx)
     }
   }
 
+  /* In weight paint mode retrieve the vertex group lock status. */
+  if ((draw_ctx->object_mode == OB_MODE_WEIGHT_PAINT) && (draw_ctx->object_pose == ob) &&
+      (draw_ctx->obact != NULL)) {
+    draw_locked_weights = true;
+
+    for (pchan = ob->pose->chanbase.first; pchan; pchan = pchan->next) {
+      pchan->bone->flag &= ~BONE_DRAW_LOCKED_WEIGHT;
+    }
+
+    const Object *obact_orig = DEG_get_original_object(draw_ctx->obact);
+
+    LISTBASE_FOREACH (bDeformGroup *, dg, &obact_orig->defbase) {
+      if (dg->flag & DG_LOCK_WEIGHT) {
+        pchan = BKE_pose_channel_find_name(ob->pose, dg->name);
+
+        if (pchan) {
+          pchan->bone->flag |= BONE_DRAW_LOCKED_WEIGHT;
+        }
+      }
+    }
+  }
+
   for (pchan = ob->pose->chanbase.first; pchan; pchan = pchan->next, index += 0x10000) {
     Bone *bone = pchan->bone;
     const bool bone_visible = (bone->flag & (BONE_HIDDEN_P | BONE_HIDDEN_PG)) == 0;
@@ -2120,6 +2164,10 @@ static void draw_armature_pose(ArmatureDrawContext *ctx)
           boneflag |= BONE_DRAW_ACTIVE;
         }
 
+        if (!draw_locked_weights) {
+          boneflag &= ~BONE_DRAW_LOCKED_WEIGHT;
+        }
+
         draw_bone_relations(ctx, NULL, pchan, arm, boneflag, constflag);
 
         if ((pchan->custom) && !(arm->flag & ARM_NO_CUSTOM)) {
index bd8eed4e4aa5e34bd7f481b029b54af8aac0938c..66662c8c27dc299f19fed59b44d7cf41589506ee 100644 (file)
@@ -143,6 +143,7 @@ typedef enum ThemeColorID {
   TH_BONE_SOLID,
   TH_BONE_POSE,
   TH_BONE_POSE_ACTIVE,
+  TH_BONE_LOCKED_WEIGHT,
 
   TH_STRIP,
   TH_STRIP_SELECT,
index f8b4d85a212ddea1063a6118b69ed68127c02ca7..37921b48401fd2fa02e2809fbef0b5e7b0019201 100644 (file)
@@ -443,6 +443,9 @@ const uchar *UI_ThemeGetColorPtr(bTheme *btheme, int spacetype, int colorid)
         case TH_BONE_POSE_ACTIVE:
           cp = ts->bone_pose_active;
           break;
+        case TH_BONE_LOCKED_WEIGHT:
+          cp = ts->bone_locked_weight;
+          break;
         case TH_STRIP:
           cp = ts->strip;
           break;
index e8e0569f15e3ab344a0d6f5aa62c59e0021a32b1..05fa78aab1c208d016ff6bbc8b244274cfdabd7c 100644 (file)
@@ -3179,6 +3179,8 @@ static int vertex_group_lock_exec(bContext *C, wmOperator *op)
 
   vgroup_lock_all(ob, action);
 
+  WM_event_add_notifier(C, NC_OBJECT | ND_DRAW, ob);
+
   return OPERATOR_FINISHED;
 }
 
index 354344328d3c47978c4f5a29ede8a9920231e314..7192b1295aa943287d9d0f8a75974e91d5229f09 100644 (file)
@@ -252,7 +252,8 @@ typedef enum eBone_Flag {
   BONE_ADD_PARENT_END_ROLL = (1 << 24),
   /** this bone was transformed by the mirror function */
   BONE_TRANSFORM_MIRROR = (1 << 25),
-
+  /** this bone is associated with a locked vertex group, ONLY USE FOR DRAWING */
+  BONE_DRAW_LOCKED_WEIGHT = (1 << 26),
 } eBone_Flag;
 
 /* bone->inherit_scale_mode */
index f0a852a7a1a3dfc42d8d6724cd5629a42d7a8cb0..d81d8db3bd3ee7a92339a4f7d76d79d7e44c6a0e 100644 (file)
@@ -283,13 +283,12 @@ typedef struct ThemeSpace {
   unsigned char normal[4];
   unsigned char vertex_normal[4];
   unsigned char loop_normal[4];
-  unsigned char bone_solid[4], bone_pose[4], bone_pose_active[4];
+  unsigned char bone_solid[4], bone_pose[4], bone_pose_active[4], bone_locked_weight[4];
   unsigned char strip[4], strip_select[4];
   unsigned char cframe[4];
   unsigned char time_keyframe[4], time_gp_keyframe[4];
   unsigned char freestyle_edge_mark[4], freestyle_face_mark[4];
   unsigned char time_scrub_background[4];
-  char _pad5[4];
 
   unsigned char nurb_uline[4], nurb_vline[4];
   unsigned char act_spline[4], nurb_sel_uline[4], nurb_sel_vline[4], lastsel_point[4];
index 56f19d313fd9186c332794a813de9d856d2b04a7..fc2b074d6d1ee4d61bc1ef07202d73ebdb999ff8 100644 (file)
@@ -2231,6 +2231,14 @@ static void rna_def_userdef_theme_space_view3d(BlenderRNA *brna)
   RNA_def_property_ui_text(prop, "Bone Solid", "");
   RNA_def_property_update(prop, 0, "rna_userdef_theme_update");
 
+  prop = RNA_def_property(srna, "bone_locked_weight", PROP_FLOAT, PROP_COLOR_GAMMA);
+  RNA_def_property_array(prop, 4);
+  RNA_def_property_ui_text(
+      prop,
+      "Bone Locked Weight",
+      "Shade for bones corresponding to a locked weight group during painting");
+  RNA_def_property_update(prop, 0, "rna_userdef_theme_update");
+
   /* misc */
 
   prop = RNA_def_property(srna, "bundle_solid", PROP_FLOAT, PROP_COLOR_GAMMA);