[Bf-blender-cvs] [7b271f1] compositor-2016: Bendy Bones: Advanced B-Bones for Easier + Simple Rigging

Joshua Leung noreply at git.blender.org
Wed Jun 8 21:47:27 CEST 2016


Commit: 7b271f17a7aa0b9b275b65d4c0c4a205f7dcd01d
Author: Joshua Leung
Date:   Wed May 18 03:19:06 2016 +1200
Branches: compositor-2016
https://developer.blender.org/rB7b271f17a7aa0b9b275b65d4c0c4a205f7dcd01d

Bendy Bones: Advanced B-Bones for Easier + Simple Rigging

This commit/patch/branch brings a bunch of powerful new options for B-Bones and
for working with B-Bones, making it easier for animators to create their own
rigs, using fewer bones (which also means hopefully lighter + faster rigs ;)
This functionality was first demoed by Daniel at BConf15

Some highlights from this patch include:
* You can now directly control the shape of B-Bones using a series of properties
  instead of being restricted to trying to indirectly control them through the
  neighbouring bones.  See the "Bendy Bones" panel...

* B-Bones can be shaped in EditMode to define a "curved rest pose" for the bone.
  This is useful for things like eyebrows and mouths/eyelids

* You can now make B-Bones use custom bones as their reference bone handles,
  instead of only using the parent/child bones. To do so, enable the
  "Use Custom Reference Handles" toggle. If none are specified, then the BBone will
  only use the Bendy Bone properties.

* Constraints Head/Tail option can now slide along the B-Bone shape, instead of
  just linearly interpolating between the endpoints of the bone.

For more details, see:
* http://aligorith.blogspot.co.nz/2016/05/bendy-bones-dev-update.html
* http://aligorith.blogspot.co.nz/2016/05/an-in-depth-look-at-how-b-bones-work.html



-- Credits --
Original Idea: Daniel M Lara (pepeland)
Original Patch/Research: Jose Molina
Additional Development + Polish: Joshua Leung (aligorith)
Testing/Feedback: Daniel M Lara (pepeland), Juan Pablo Bouza (jpbouza)

===================================================================

M	release/scripts/modules/keyingsets_utils.py
M	release/scripts/startup/bl_ui/properties_constraint.py
M	release/scripts/startup/bl_ui/properties_data_bone.py
M	release/scripts/startup/keyingsets_builtins.py
M	source/blender/blenkernel/BKE_action.h
M	source/blender/blenkernel/BKE_armature.h
M	source/blender/blenkernel/intern/action.c
M	source/blender/blenkernel/intern/armature.c
M	source/blender/blenkernel/intern/constraint.c
M	source/blender/blenloader/intern/readfile.c
M	source/blender/blenloader/intern/versioning_270.c
M	source/blender/editors/armature/armature_add.c
M	source/blender/editors/armature/armature_intern.h
M	source/blender/editors/armature/armature_utils.c
M	source/blender/editors/armature/editarmature_retarget.c
M	source/blender/editors/armature/pose_slide.c
M	source/blender/editors/armature/pose_transform.c
M	source/blender/editors/armature/pose_utils.c
M	source/blender/editors/include/ED_armature.h
M	source/blender/editors/space_view3d/drawarmature.c
M	source/blender/makesdna/DNA_action_types.h
M	source/blender/makesdna/DNA_armature_types.h
M	source/blender/makesdna/DNA_constraint_types.h
M	source/blender/makesrna/intern/rna_armature.c
M	source/blender/makesrna/intern/rna_constraint.c
M	source/blender/makesrna/intern/rna_internal.h
M	source/blender/makesrna/intern/rna_pose.c

===================================================================

diff --git a/release/scripts/modules/keyingsets_utils.py b/release/scripts/modules/keyingsets_utils.py
index 03400ed..375ee3f 100644
--- a/release/scripts/modules/keyingsets_utils.py
+++ b/release/scripts/modules/keyingsets_utils.py
@@ -28,11 +28,14 @@ __all__ = (
     "RKS_POLL_selected_objects",
     "RKS_POLL_selected_bones",
     "RKS_POLL_selected_items",
+    "RKS_ITER_selected_object",
+    "RKS_ITER_selected_bones",
     "RKS_ITER_selected_item",
     "RKS_GEN_available",
     "RKS_GEN_location",
     "RKS_GEN_rotation",
     "RKS_GEN_scaling",
+    "RKS_GEN_bendy_bones",
     )
 
 import bpy
@@ -93,11 +96,17 @@ def RKS_ITER_selected_item(ksi, context, ks):
             ksi.generate(context, ks, ob)
 
 
-# all select objects only
+# all selected objects only
 def RKS_ITER_selected_objects(ksi, context, ks):
     for ob in context.selected_objects:
         ksi.generate(context, ks, ob)
 
+
+# all seelcted bones only
+def RKS_ITER_selected_bones(ksi, context, ks):
+    for bone in context.selected_pose_bones:
+        ksi.generate(context, ks, bone)
+
 ###########################
 # Generate Callbacks
 
@@ -207,3 +216,43 @@ def RKS_GEN_scaling(ksi, context, ks, data):
         ks.paths.add(id_block, path, group_method='NAMED', group_name=grouping)
     else:
         ks.paths.add(id_block, path)
+
+# ------
+
+# Property identifiers for Bendy Bones
+bbone_property_ids = (
+    "bbone_curveinx",
+    "bbone_curveiny",
+    "bbone_curveoutx",
+    "bbone_curveouty",
+
+    "bbone_rollin",
+    "bbone_rollout",
+
+    "bbone_scalein",
+    "bbone_scaleout",
+
+    # NOTE: These are in the nested bone struct 
+    # Do it this way to force them to be included
+    # in whatever actions are being keyed here
+    "bone.bbone_in",
+    "bone.bbone_out",
+)
+
+# Add Keying Set entries for bendy bones
+def RKS_GEN_bendy_bones(ksi, context, ks, data):
+    # get id-block and path info
+    # NOTE: This assumes that we're dealing with a bone here...
+    id_block, base_path, grouping = get_transform_generators_base_info(data)
+
+    # for each of the bendy bone properties, add a Keying Set entry for it...
+    for propname in bbone_property_ids:
+        # add the property name to the base path
+        path = path_add_property(base_path, propname)
+
+        # add Keying Set entry for this...
+        if grouping:
+            ks.paths.add(id_block, path, group_method='NAMED', group_name=grouping)
+        else:
+            ks.paths.add(id_block, path)
+
diff --git a/release/scripts/startup/bl_ui/properties_constraint.py b/release/scripts/startup/bl_ui/properties_constraint.py
index ef0fc9c..4ca2f77 100644
--- a/release/scripts/startup/bl_ui/properties_constraint.py
+++ b/release/scripts/startup/bl_ui/properties_constraint.py
@@ -65,9 +65,10 @@ class ConstraintButtonsPanel:
                 layout.prop_search(con, "subtarget", con.target.data, "bones", text="Bone")
 
                 if hasattr(con, "head_tail"):
-                    row = layout.row()
+                    row = layout.row(align=True)
                     row.label(text="Head/Tail:")
                     row.prop(con, "head_tail", text="")
+                    row.prop(con, "use_bbone_shape", text="", icon='IPO_BEZIER')  # XXX icon, and only when bone has segments?
             elif con.target.type in {'MESH', 'LATTICE'}:
                 layout.prop_search(con, "subtarget", con.target, "vertex_groups", text="Vertex Group")
 
diff --git a/release/scripts/startup/bl_ui/properties_data_bone.py b/release/scripts/startup/bl_ui/properties_data_bone.py
index 690c22c..99c0d7f 100644
--- a/release/scripts/startup/bl_ui/properties_data_bone.py
+++ b/release/scripts/startup/bl_ui/properties_data_bone.py
@@ -146,6 +146,81 @@ class BONE_PT_transform_locks(BoneButtonsPanel, Panel):
             sub.prop(pchan, "lock_rotation_w", text="W")
 
 
+class BONE_PT_curved(BoneButtonsPanel, Panel):
+    bl_label = "Bendy Bones"
+    #bl_options = {'DEFAULT_CLOSED'}
+
+    def draw(self, context):
+        ob = context.object
+        bone = context.bone
+        arm = context.armature
+        pchan = None
+
+        if ob and bone:
+            pchan = ob.pose.bones[bone.name]
+            bbone = pchan
+        elif bone is None:
+            bone = context.edit_bone
+            bbone = bone
+        else:
+            bbone = bone
+
+        layout = self.layout
+        layout.prop(bone, "bbone_segments", text="Segments")
+
+        col = layout.column()
+        col.active = bone.bbone_segments > 1
+
+        row = col.row()
+        sub = row.column(align=True)
+        sub.label(text="Curve XY Offsets:")
+        sub.prop(bbone, "bbone_curveinx", text="In X")
+        sub.prop(bbone, "bbone_curveiny", text="In Y")
+        sub.prop(bbone, "bbone_curveoutx", text="Out X")
+        sub.prop(bbone, "bbone_curveouty", text="Out Y")
+
+        sub = row.column(align=True)
+        sub.label("Roll:")
+        sub.prop(bbone, "bbone_rollin", text="In")
+        sub.prop(bbone, "bbone_rollout", text="Out")
+        sub.prop(bone, "use_endroll_as_inroll")
+
+        row = col.row()
+        sub = row.column(align=True)
+        sub.label(text="Scale:")
+        sub.prop(bbone, "bbone_scalein", text="Scale In")
+        sub.prop(bbone, "bbone_scaleout", text="Scale Out")
+
+        sub = row.column(align=True)
+        sub.label("Easing:")
+        if pchan:
+            # XXX: have these also be an overlay?
+            sub.prop(bbone.bone, "bbone_in", text="Ease In")
+            sub.prop(bbone.bone, "bbone_out", text="Ease Out")
+        else:
+            sub.prop(bone, "bbone_in", text="Ease In")
+            sub.prop(bone, "bbone_out", text="Ease Out")
+
+        if pchan:
+            layout.separator()
+
+            col = layout.column()
+            col.prop(pchan, "use_bbone_custom_handles")
+
+            row = col.row()
+            row.active = pchan.use_bbone_custom_handles
+
+            sub = row.column(align=True)
+            sub.label(text="In:")
+            sub.prop_search(pchan, "bbone_custom_handle_start", ob.pose, "bones", text="")
+            sub.prop(pchan, "use_bbone_relative_start_handle", text="Relative")
+
+            sub = row.column(align=True)
+            sub.label(text="Out:")
+            sub.prop_search(pchan, "bbone_custom_handle_end", ob.pose, "bones", text="")
+            sub.prop(pchan, "use_bbone_relative_end_handle", text="Relative")
+
+
 class BONE_PT_relations(BoneButtonsPanel, Panel):
     bl_label = "Relations"
 
@@ -193,6 +268,7 @@ class BONE_PT_relations(BoneButtonsPanel, Panel):
         sub.prop(bone, "use_local_location")
 
 
+
 class BONE_PT_display(BoneButtonsPanel, Panel):
     bl_label = "Display"
 
@@ -348,28 +424,18 @@ class BONE_PT_deform(BoneButtonsPanel, Panel):
 
         layout.active = bone.use_deform
 
-        split = layout.split()
+        row = layout.row()
 
-        col = split.column()
+        col = row.column(align=True)
         col.label(text="Envelope:")
-
-        sub = col.column(align=True)
-        sub.prop(bone, "envelope_distance", text="Distance")
-        sub.prop(bone, "envelope_weight", text="Weight")
+        col.prop(bone, "envelope_distance", text="Distance")
+        col.prop(bone, "envelope_weight", text="Weight")
         col.prop(bone, "use_envelope_multiply", text="Multiply")
 
-        sub = col.column(align=True)
-        sub.label(text="Radius:")
-        sub.prop(bone, "head_radius", text="Head")
-        sub.prop(bone, "tail_radius", text="Tail")
-
-        col = split.column()
-        col.label(text="Curved Bones:")
-
-        sub = col.column(align=True)
-        sub.prop(bone, "bbone_segments", text="Segments")
-        sub.prop(bone, "bbone_in", text="Ease In")
-        sub.prop(bone, "bbone_out", text="Ease Out")
+        col = row.column(align=True)
+        col.label(text="Envelope Radius:")
+        col.prop(bone, "head_radius", text="Head")
+        col.prop(bone, "tail_radius", text="Tail")
 
 
 class BONE_PT_custom_props(BoneButtonsPanel, PropertyPanel, Panel):
diff --git a/release/scripts/startup/keyingsets_builtins.py b/release/scripts/startup/keyingsets_builtins.py
index 6d52a81..195eaf8 100644
--- a/release/scripts/startup/keyingsets_builtins.py
+++ b/release/scripts/startup/keyingsets_builtins.py
@@ -175,6 +175,22 @@ class BUILTIN_KSI_RotScale(KeyingSetInfo):
 
 # ------------
 
+# Bendy Bones
+class BUILTIN_KSI_BendyBones(KeyingSetInfo):
+    """Insert a keyframe for each of the BBone shape properties"""
+    bl_label = "BBone Shape"
+
+    # poll - use callback for selected bones
+    poll = keyingsets_utils.RKS_POLL_selected_bones
+
+    # iterator - use callback for selected bones
+    iterator = keyingsets_utils.RKS_ITER_selected_bones
+
+    # generator - use generator for bendy bone properties
+    generate = keyingsets_utils.RKS_GEN_bendy_bones
+
+# ------------
+
 
 # VisualLocation
 class BUILTIN_KSI_VisualLoc(KeyingSetInfo):
@@ -387,6 +403,9 @@ class BUILTIN_KSI_WholeCharacter(KeyingSetInfo):
             ksi.doRot3d(ks, bone)
         ksi.doScale(ks, bone)
 
+        # bbone properties?
+        ksi.doBBone(context, ks, bone)
+
         # custom props?
         ksi.doCustomProps(ks, bone)
 
@@ -466,6 +485,19 @@ class BUILTIN_KSI_WholeCharacter(KeyingSetInfo):
 
     # ----------------
 
+    # bendy bone properties
+    def doBBone(ksi, context, ks, pchan):
+        bone = pchan.bone
+        
+        # This check is crude, but is the best we can do for now
+        # It simply adds all of these if the bbone has segments
+        # (and the bone is a control bone). This may lead to some
+        # false positives...
+        if bone.bbone_segments > 1:
+            keyingsets_utils.RKS_GEN_bendy_bones(ksi, context, ks, pchan)
+
+    # ----------------
+
     # custom properties
     def doCustomProps(ksi, ks, bone):
 
diff --git a/source/blender/blenkernel/BKE_action.h b/source/blender/blenkernel/BKE_action.h
index c164cd5..cb282b4 100644
--- a/source/blender/blenkernel/BKE_action.h
+++ b/source/blender/blenkernel/BKE_action.h
@@ -79,12 +79,15 @@ typedef enum eAction_TransformFlags {
 	ACT_TRANS_ROT   = (1 << 1),
 	/* scaling */
 	ACT_TRANS_SCALE = (1 << 2),
-
+	
+	/* bbo

@@ Diff output truncated at 10240 characters. @@




More information about the Bf-blender-cvs mailing list