def add_bones_bone(self, context, rig): # Add bones then set their defaults root = self.get_root(rig) prev_bones = self.get_prev_bones(rig) bone = rig.data.edit_bones.new('Bone') bone.parent = root bone.translate( Vector( utils.multiply_list( Get.cursor(context).location, rig.matrix_world.inverted().to_scale( ), # Get the transforms for the unscaled rig )) - rig.matrix_world.to_translation()) # Use the original bone size (unscaled by the rig) bone.tail = bone.head + Vector( utils.multiply_list( Vector((0, 0, 0.1)), rig.matrix_world.inverted().to_scale(), )) - rig.matrix_world.to_translation() bone = str(bone.name) # Switch back to Pose mode and setup pose bones Set.mode(context, 'POSE', rig) bone = rig.data.bones[bone] rig.data.bones.active = bone Set.select(bone)
def returnToArmature(context, widget): bone = fromWidgetFindBone(widget) armature = bone.id_data # Unhide collection if it was hidden in a previous run if widget.users_collection: # Try to use the widget's collection collection = widget.users_collection[0] else: # otherwise use default collection = get_collection(context) Set.visible(context, collection) Set.mode(context, 'OBJECT', widget) # collection = get_collection(context) if [x for x in armature.users_collection if x != collection]: # Don't hide the active collection collection.hide_viewport = True "New version doesn't have this" # get_collection_view_layer(collection).hide_viewport = True if getattr(context.space_data, 'local_view', None): bpy.ops.view3d.localview() Set.active(context, armature) Set.select(armature, True) Set.mode(context, 'POSE', armature) # Set.select(bone, True) # Set.active(context, bone) armature.data.bones[bone.name].select = True armature.data.bones.active = armature.data.bones[bone.name]
def add_bones_root(self, context, rig): # Add bones then set their defaults root = self.get_root(rig) prev_bones = self.get_prev_bones(rig) new_root = not bool(root) if root is None: root = rig.data.edit_bones.new('root') root.tail = Vector((0, 1, 0)) root.bbone_x = 0.5 root.bbone_z = 0.01 root.layers = self.layer(27) for eb in rig.data.edit_bones: if eb.parent is None: eb.use_connect = False eb.parent = root root = str(root.name) # Switch back to Pose mode and setup pose bones Set.mode(context, 'POSE', rig) root = rig.pose.bones[root] if new_root: self.widget(root, 'Blenrig - Root') rig.data.bones.active = root.bone rig.data.layers[27] = True
def editWidget(context, active_bone): widget = active_bone.custom_shape armature = active_bone.id_data Set.mode(context, 'OBJECT', armature) Set.select(armature, False) ''' # 2.7 if context.space_data.lock_camera_and_layers == False : visibleLayers = numpy.array(bpy.context.space_data.layers)+widget.layers-armature.layers bpy.context.space_data.layers = visibleLayers.tolist() else : visibleLayers = numpy.array(bpy.context.scene.layers)+widget.layers-armature.layers bpy.context.scene.layers = visibleLayers.tolist() ''' "Commented because the new version only uses get_collection" if widget.users_collection: collection = widget.users_collection[0] else: collection = get_collection(context) collection.objects.link(widget) Set.in_scene(context, collection) Set.visible(context, collection) "Commented because new version uses operator" # get_collection_view_layer(collection).hide_viewport = False if getattr(context.space_data, 'local_view', None): bpy.ops.view3d.localview() # select object and make it active Set.select(widget, True) Set.active(context, widget) Set.mode(context, 'EDIT', widget)
def add_bones_ik(self, context, rig): # Add bones then set their defaults root = self.get_root(rig) prev_bones = self.get_prev_bones(rig) pose_bones = [] for bone_name in prev_bones: prev = rig.data.edit_bones[bone_name] bone = rig.data.edit_bones.new(self.mirror_name(prev.name, 'IK')) pose_bones.append([bone.name, prev.name]) self.reset(bone, prev) bone.parent = root bone.use_deform = False # Switch back to Pose mode and setup pose bones Set.mode(context, 'POSE', rig) for bone, prev in pose_bones: bone = rig.pose.bones[bone] prev = rig.pose.bones[prev] rig.data.bones.active = bone.bone bone.custom_shape_transform = prev self.widget(bone, 'Circle', slide=(0, 0.5, 1)) bone['IK_FK'] = prev.name prev['IK_FK'] = prev.name bone['IK_IK'] = bone.name prev['IK_IK'] = bone.name bone.rotation_mode = 'QUATERNION' bone.matrix = prev.matrix # for ct in ['COPY_LOCATION', 'COPY_ROTATION', 'COPY_SCALE']: # con = deform.constraints.new(ct) # con.name = 'DEF-'+con.name # con.target = rig # con.subtarget = stretch.name # con.target_space = 'LOCAL' # con.owner_space = 'LOCAL' # con.use_offset = True # con.show_expanded = False # con = deform.constraints.new('STRETCH_TO') # con.name = 'DEF-'+con.name # con.target = rig # con.subtarget = tail.name # con.rest_length = deform.bone.length # con.head_tail = 0 if prev.bone_group: bone.bone_group = self.bgroup(rig, 'IK-' + prev.bone_group.name) else: bone.bone_group = self.bgroup(rig, 'IK') prev.bone_group = self.bgroup(rig, 'FK')
def execute(self, context): (rigs, __) = get_rig_bones(context) for (rig, bones) in rigs.items(): for bone in bones: self.pose_func(context, rig.pose.bones[bone.name]) for rig in rigs: Set.mode(context, 'EDIT', rig) # Reparent soon-to-be orphans for (pbone, rig) in self.bones.items(): bone = rig.data.edit_bones[pbone.name] for parent in bone.parent_recursive: if (parent not in self.bones): break else: parent = None for child in bone.children: if (child not in self.bones): child.parent = parent # Remove the bbone constrollers for (pbone, rig) in self.bones.items(): ebones = rig.data.edit_bones ebones.remove(ebones[pbone.name]) for rig in rigs: Set.mode(context, 'POSE', rig) # remove unused groups groups = (rig.pose.bone_groups[bg] for bg in ("BBone FK", "BBone Stretch", "BBone Curve", "BBone Stretch [Hidden]") if rig.pose.bone_groups.get(bg)) for bg in list(groups): for bone in rig.pose.bones: if bone.bone_group == bg: break else: rig.pose.bone_groups.remove(bg) # Remove unused widgets for wgt in self.widgets: if (wgt.users < 2): # 1) mesh 2+) objects wgt_col = list(wgt.users_collection) bpy.data.objects.remove(wgt) for col in wgt_col: if not col.all_objects: bpy.data.collections.remove(col) return {'FINISHED'}
def execute(self, context): rig = context.active_object active = None if context.mode == 'PAINT_WEIGHT': for obj in context.selected_objects: if obj.type == 'ARMATURE': active = rig rig = obj Set.active(context, rig) # if rig.type =='ARMATURE' and context.mode != 'EDIT_ARMATURE': meshes = self.get_meshes(context, rig) bone1 = context.active_pose_bone # bone2 = context.selected_pose_bones[1] for bone2 in context.selected_pose_bones: if bone2 == bone1: continue found = None for mesh in meshes: utils.merge_vertex_groups( mesh, bone1.name, bone2.name, # If remove is False, and the bone stayed, it would be equivalent to transferring only partial weights remove=(self.mode == 'remove')) found = True # if found: # if self.mode == 'hide': # bone2.hide = True # elif self.mode == 'show': # bone2.hide = False # elif self.mode == 'remove': if (found and self.mode == 'remove'): for ch in bone2.id_data.children: if (ch.parent_type == 'BONE') and (ch.parent_bone == bone2.name): mat = Get.matrix(ch) ch.parent_bone = bone1.name Set.matrix(ch, mat) name2 = bone2.name Set.mode(context, mode='EDIT') bone2 = rig.data.edit_bones[name2] rig.data.edit_bones.remove(bone2) Set.mode(context, mode='POSE') if active: Set.active(context, active) return {'FINISHED'}
def add_bones_mch(self, context, rig, mch_parent=False): # Add bones then set their defaults root = self.get_root(rig) prev_bones = self.get_prev_bones(rig) pose_bones = [] # Get MCH Prefix parent_name = context.scene.mch_bone if parent_name == "": parent_name = "MCH-parent_" for bone_name in prev_bones: prev = rig.data.edit_bones[bone_name] # Replace bone prefixes with MCH instead of inserting keeping both name = parent_name + (prev.name.replace("DEF-", "", 1)).replace( "CTRL-", "", 1) bone = rig.data.edit_bones.new(name) pose_bones.append([bone.name, prev.name]) self.reset(bone, prev) bone.use_deform = False bone.use_connect = prev.use_connect bone.parent = prev.parent prev.use_connect = False prev.parent = bone # prev.select = False # prev.hide = True if not mch_parent: for c in prev.children: c.parent = bone Set.select(bone, False) # Switch back to Pose mode and setup pose bones Set.mode(context, 'POSE', rig) for bone, prev in pose_bones: bone = rig.pose.bones[bone] prev = rig.pose.bones[prev] rig.data.bones.active = bone.bone # self.widget(bone, 'Box') ... # Retarget drivers if not mch_parent: for tar in self.mch_driver_targets: if (tar.id is rig) and (tar.bone_target == prev.name): tar.bone_target = bone.name
def add_bones_vis(self, context, rig): # Add bones then set their defaults root = self.get_root(rig) prev_bones = self.get_prev_bones(rig) pose_bones = [] for bone_name in prev_bones: prev = rig.data.edit_bones[bone_name] bone = rig.data.edit_bones.new(self.mirror_name(prev.name, 'VIS')) pose_bones.append([bone.name, prev.name]) self.reset(bone, prev) bone.use_deform = False bone.parent = prev # Switch back to Pose mode and setup pose bones Set.mode(context, 'POSE', rig) for bone, prev in pose_bones: bone = rig.pose.bones[bone] prev = rig.pose.bones[prev] # rig.data.bones.active = bone.bone bone.custom_shape = prev.custom_shape bone.custom_shape_transform = prev.custom_shape_transform bone.bone.show_wire = True prev.custom_shape = None bone.bone.hide_select = True bone.matrix = prev.matrix driver = bone.bone.driver_add('hide') var = driver.driver.variables.new() var.name = 'var' driver.driver.expression = 'not var' var.type = 'SINGLE_PROP' vt = var.targets[0] vt.id = rig # vt.bone_target = target.name # vt.transform_space = 'LOCAL_SPACE' # vt.transform_type = transform # # if transform == 'SINGLE_PROP': vt.data_path = prev.bone.path_from_id('select')
def execute(self, context): obj = context.object in_edit = (obj.mode == 'EDIT') if in_edit: Set.mode(context, 'OBJECT') active = obj.active_shape_key vg = active.vertex_group index = obj.active_shape_key_index pin = obj.show_only_shape_key obj.show_only_shape_key = True active.vertex_group = '' bpy.ops.object.shape_key_add(from_mix=True) while obj.active_shape_key_index > (index + 1): bpy.ops.object.shape_key_move(type='UP') active.vertex_group = vg shape = obj.active_shape_key if self.mirror: shape.name = utils.flip_name(active.name) shape.vertex_group = utils.flip_name(vg) else: shape.vertex_group = vg shape.name = active.name for var in ('interpolation', 'mute', 'relative_key', 'slider_max', 'slider_min', 'value'): setattr(shape, var, getattr(active, var)) driver = Get.driver(active, var) if not driver: continue newdriver = utils.copy_driver(driver, shape, var) if self.mirror: for v in newdriver.driver.variables: for t in v.targets: t.bone_target = utils.flip_name(t.bone_target) # obj.active_shape_key_index = index obj.show_only_shape_key = pin if in_edit: Set.mode(context, 'EDIT') return {'FINISHED'}
def execute(self, context): (rigs, self.selected) = get_rig_bones(context) for rig in rigs: Set.mode(context, 'EDIT', rig) self.hide_bones[rig] = list() self.center_bones[rig] = list() for (rig, bones) in rigs.items(): for bone in bones: self.edit_func(context, rig.data.edit_bones[bone.name]) for (ebones, ebone, tbone) in self.delayed_parenting: ebones[ebone].parent = ebones[tbone] (do_mch, do_start_end, do_in_out) = self.do() if do_start_end: self.edit_mirror_center(context) if self.warning: self.report({'WARNING'}, self.warning) for rig in rigs: Set.mode(context, 'POSE', rig) for (rig, bones) in rigs.items(): for bone in bones: self.pose_func(context, rig.pose.bones[bone.name]) def widget(ctrl_type, wgt='Sphere', global_size=6, scale=(1, 1, 1), slide=None): from mathutils import Vector bpy.ops.bonewidget.create_widget( global_size=global_size, slide=Vector(slide) if slide else Vector(), scale=scale, bones='%r' % self.bone_widgets[ctrl_type], widget=wgt, ) widget('mch', wgt='Box', global_size=1, scale=(0.75, 0.75, 1)) # widget('start', slide=(0, -0.5, 0)) widget('start', wgt='Blenrig - Box', global_size=3) # widget('end', slide=(0, 0.5, 0)) widget('end', wgt='Blenrig - Box', global_size=3) widget('in_out', global_size=7.5, slide=(0, 0.5, 0)) return {'FINISHED'}
def add_bones_dupli(self, context, rig): # Add bones then set their defaults root = self.get_root(rig) prev_bones = self.get_prev_bones(rig) pose_bones = [] flip_bones = [] def add_bone(bone_name): prev = rig.data.edit_bones[bone_name] bone = rig.data.edit_bones.new(prev.name) pose_bones.append([bone.name, prev.name]) self.reset(bone, prev) bone.parent = prev.parent bone.use_deform = prev.use_deform for bone_name in prev_bones: add_bone(bone_name) if rig.pose.use_mirror_x: flip = utils.flip_name(bone_name) if (flip in rig.data.edit_bones) and (flip not in ( *prev_bones, *(p for (b, p) in pose_bones))): # Mirrored bone exists but not selected add_bone(flip) flip_bones.append(flip) # Switch back to Pose mode and setup pose bones Set.mode(context, 'POSE', rig) for (bone, prev) in pose_bones: bone = rig.pose.bones[bone] prev = rig.pose.bones[prev] if (prev.name not in flip_bones): rig.data.bones.active = bone.bone bone.custom_shape = prev.custom_shape bone.custom_shape_transform = prev.custom_shape_transform bone.bone.show_wire = prev.bone.show_wire bone.matrix = prev.matrix bone.bone_group = prev.bone_group for lock in [ 'location', 'rotations_4d', 'rotation_w', 'rotation', 'scale' ]: setattr(bone, 'lock_' + lock, getattr(prev, 'lock_' + lock))
def execute(self, context): obj = context.object in_edit = (obj.mode == 'EDIT') if in_edit: Set.mode(context, 'OBJECT') active = obj.active_shape_key index = obj.active_shape_key_index pin = obj.show_only_shape_key obj.show_only_shape_key = True bpy.ops.object.shape_key_add(from_mix=True) while obj.active_shape_key_index > (index + 1): bpy.ops.object.shape_key_move(type='UP') shape = obj.active_shape_key for var in ('interpolation', 'mute', 'relative_key', 'slider_max', 'slider_min', 'value'): setattr(shape, var, getattr(active, var)) # if self.keep_vertex_group: # shape.vertex_group = active.vertex_group # Redirect drivers, so that they auto update after operation for var in ('slider_max', 'slider_min', 'value'): driver = Get.driver(active, var) if driver: driver.data_path = f'key_blocks["{shape.name}"].{var}' # driver.data_path = driver.data_path.replace(active.name, shape.name, 1) name = active.name active.name += ".masked" shape.name = name obj.active_shape_key_index = index bpy.ops.object.shape_key_remove(all=False) obj.active_shape_key_index = index obj.show_only_shape_key = pin if in_edit: Set.mode(context, 'EDIT') return {'FINISHED'}
def add_placeholder_bones(rigify, obj, metarig): context = bpy.context rigify_mode = rigify.mode meta_mode = metarig.mode Set.mode(context, 'EDIT', metarig) Set.mode(context, 'EDIT', rigify) for rigify_bone in rigify.data.edit_bones.keys(): if not rigify_bone.startswith('DEF-'): # Not a DEF group, so... continue meta_bone = rigify_bone[4:] if obj.vertex_groups.get(meta_bone): # Both DEF and regular name in vertex groups continue if (meta_bone in metarig.data.edit_bones): continue rbone = rigify.data.edit_bones[rigify_bone] mbone = metarig.data.edit_bones.new(meta_bone) for attr in ( # 'bbone_curveinx', 'bbone_curveiny', # 'bbone_curveoutx', 'bbone_curveouty', # 'bbone_custom_handle_end', 'bbone_custom_handle_start', # 'bbone_easein', 'bbone_easeout', # 'bbone_handle_type_end', 'bbone_handle_type_start', # 'bbone_rollin', 'bbone_rollout', # 'bbone_scaleinx', 'bbone_scaleiny', # 'bbone_scaleoutx', 'bbone_scaleouty', # 'bbone_segments', 'bbone_x', 'bbone_z', 'envelope_distance', 'envelope_weight', 'head', 'head_radius', 'tail', 'tail_radius', 'roll', 'inherit_scale', 'use_inherit_rotation', 'use_inherit_scale', 'use_endroll_as_inroll', 'use_envelope_multiply', 'use_local_location', 'use_relative_parent', ): setattr(mbone, attr, getattr(rbone, attr)) if rbone.parent: mbone.parent = metarig.data.edit_bones.get(rbone.parent.name[4:]) if mbone.parent: mbone.layers = mbone.parent.layers Set.mode(context, meta_mode, metarig) Set.mode(context, rigify_mode, rigify)
def add_bones_stretch_tail(self, context, rig): # Add bones then set their defaults root = self.get_root(rig) prev_bones = self.get_prev_bones(rig) pose_bones = [] for bone_name in prev_bones: prev = rig.data.edit_bones[bone_name] bone = rig.data.edit_bones.new(self.mirror_name(prev.name, 'STRT')) pose_bones.append([bone.name, prev.name]) self.reset(bone, prev) bone.parent = prev.parent bone.use_deform = False # Switch back to Pose mode and setup pose bones Set.mode(context, 'POSE', rig) for bone, prev in pose_bones: bone = rig.pose.bones[bone]
def bone(context, armature, name="", edit=None, pose=None, overwrite=False): "Insert a bone into an armature object" if getattr(armature, 'type', None) != 'ARMATURE': return # active = Get.active(context) # Set.active(context, armature) # Set.select(armature, True) # Set.visible(context, armature, True) # mode = armature.mode.replace('EDIT_ARMATURE', 'EDIT') Set.in_scene(context, armature) is_visible = Is.visible(context, armature) Set.visible(context, armature, True) mode = armature.mode # mode = context.mode.replace('EDIT_ARMATURE', 'EDIT') # Go into Edit mode and create a new bone ebones = armature.data.edit_bones if armature.mode != 'EDIT': Set.mode(context, 'EDIT', armature) mirror = armature.data.use_mirror_x armature.data.use_mirror_x = False children = list() if overwrite and name in ebones: for child in ebones[name].children: children.append((child, child.use_connect)) child.use_connect = False ebones.remove(ebones[name]) bone = ebones.new(name) for child, child_connect in children: child.parent = bone child.use_connect = child_connect bone.tail = ((0, 0, 1)) # If the bone's head AND tail stay at 0, # it gets deleted when leaving edit mode name = bone.name if edit: edit(bone) armature.data.use_mirror_x = mirror pbones = armature.pose.bones if pose: Set.mode(context, 'POSE', armature) bone = pbones[name] pose(bone) # Revert mode change if mode != armature.mode: # Set.active(active) Set.mode(context, mode, armature) Set.visible(context, armature, is_visible) if armature.mode == 'EDIT': bone = ebones[name] else: bone = pbones[name] return bone
def fix_toe_roll(): """ The Toe controller bone may have a bad automated roll, so recalculate it """ mode = Get.mode(rig) Set.mode(bpy.context, 'EDIT', rig) bones = rig.data.edit_bones ebones = bpy.context.selected_bones for ebone in ebones: ebone.select = False bone = tweak = None def get(name): nonlocal bone, tweak bone = bones.get(name) tweak = bones.get(name.replace('_master', '')) return (bone and tweak) def roll(name): if get(name): bone.select = True bones.active = tweak bpy.ops.armature.calculate_roll(type='ACTIVE') bone.select = False for lr in ('L', 'R'): for ind in range(1, 6): roll(f'toe{ind}.01_master.{lr}') roll(f'thumb.01_master.{lr}') roll(f'f_index.01_master.{lr}') roll(f'f_middle.01_master.{lr}') roll(f'f_ring.01_master.{lr}') roll(f'f_pinky.01_master.{lr}') for ebone in ebones: ebone.select = True Set.mode(bpy.context, mode, rig)
def metafy_rigify(context, rig): """Isolate Org bones in rig, then mimic the likely original bone layers""" Set.mode(context, 'EDIT', rig) bones = rig.data.edit_bones for bone in bones.values(): bone.inherit_scale = 'ALIGNED' if bone.name.startswith('ORG-'): bone.layers = utils.layer(0) else: bones.remove(bone) Set.mode(context, 'POSE', rig) for bone in rig.pose.bones: bone.lock_rotation_w = False for index in range(3): bone.lock_location[index] = False bone.lock_rotation[index] = False bone.lock_scale[index] = False rig.data.layers = utils.layer(0)
def execute(self, context): active = Get.active(context) mode = context.mode pose = list() for rig in context.selected_objects: (rig, meta) = self.poll_parse(context, rig) if None in (rig, meta): continue rigify_to_meta(rig, meta) pose.append((meta, rig)) else: if mode == 'POSE': Set.mode(context, 'OBJECT') for (meta, rig) in pose: Set.select(rig, False) Set.select(meta, True) if rig == active: Set.active(context, meta) if mode == 'POSE': Set.mode(context, 'POSE') return {'FINISHED'}
def execute(self, context): objects = [context.active_object] + \ [o for o in context.selected_editable_objects if o != context.active_object] any_polled = False for rig in objects: if not Is.armature(rig) or not Set.mode(context, 'EDIT', rig): # object can't go into (armature) edit mode continue # Place driver search here to avoid scanning all datas, if nothing's being added if (not any_polled) and (self.type == 'MCH'): self.mch_driver_targets = list() # self.mch_driver_targets = self.get_drivers(objects) any_polled = True if self.type == 'BONE': self.add_bones_bone(context, rig) break # Only add one bone, to the active rig or first applicable elif self.type == 'ROOT': self.add_bones_root(context, rig) elif self.type == 'DUPLI': self.add_bones_dupli(context, rig) elif self.type == 'VIS': self.add_bones_vis(context, rig) elif self.type == 'MCH': self.add_bones_mch(context, rig) elif self.type == 'MCH_PARENT': self.add_bones_mch(context, rig, mch_parent=True) elif self.type == 'IK': self.add_bones_ik(context, rig) elif self.type == 'STRETCH': self.add_bones_stretch(context, rig) elif self.type == 'STRETCH_TAIL': self.add_bones_stretch_tail(context, rig) if any_polled and (self.type == 'DUPLI'): bpy.ops.transform.translate('INVOKE_DEFAULT') return {'FINISHED'}
def execute(self, context): # TODO: Redo / Cleanup code class props: keep_matrix = True connect = False connect_child = False stretch = False if self.type == 'BONE': pass elif self.type == 'BONE_CONNECT': connect = True elif self.type == 'STRETCH': stretch = True elif self.type == 'STRETCH_CONNECT': stretch = True connect = True elif self.type == 'CHILD_CONNECT': connect_child = True ap = context.active_pose_bone bones = dict() matrices = {b: b.matrix.copy() for b in context.selected_pose_bones} for rig in context.selected_objects: if rig.mode != 'POSE': continue Set.mode(context, 'EDIT', rig) mirror = rig.data.use_mirror_x rig.data.use_mirror_x = False ab = context.active_bone edit_bones = Get.selected_edit_bones(context, rig) if ab and ab.parent in edit_bones: for eb in [*ab.parent_recursive, None]: if eb in edit_bones: # bones.append((rig, eb.name)) continue ab.use_connect = False ab.parent = eb bones[ab.name] = rig break for eb in edit_bones: if props.connect_child: for bb in eb.children: if bb in edit_bones: eb.tail = bb.head bb.use_connect = True else: if eb == ab: # or it'll delete itself continue eb.use_connect = False if props.stretch: eb.head = ab.tail eb.parent = ab bones[eb.name] = rig if props.connect: head = ab.tail - eb.head tail = ab.tail - eb.tail connects = [] for ebc in [*eb.children_recursive, eb]: connects.append([ebc, ebc.use_connect]) ebc.use_connect = False for ebc, c in connects: ebc.translate(ab.tail - eb.head) for ebc, c in connects: ebc.use_connect = c eb.use_connect = True rig.data.use_mirror_x = mirror Set.mode(context, 'POSE', rig) if props.keep_matrix: # ap.matrix = matrices[ap] # update() for b in bones: rig = bones[b] bone = rig.pose.bones.get(b) if bone is None: print(f"{rig.name} can't find {b}", *rig.pose.bones, sep='\n\t') continue if bone == ap: # Skip changing the active bone continue if bone not in matrices: print("Skip matrix,", bone.name) continue Set.matrix(bone, matrices[bone]) utils.update(context) return {'FINISHED'}
def execute(self, context): # active = Get.active(context) for rig in context.selected_editable_objects: if not Is.armature(rig): continue mode = rig.mode if not Set.mode(context, 'EDIT', rig): Set.mode(context, mode, rig) continue mirror = rig.data.use_mirror_x rig.data.use_mirror_x = False # Set.active(context, rig) bones = Get.selected_edit_bones(context, rig) links = [] # empty list for bone in bones: if bone.parent and not Is.connected( bone): # prevent root-error link = rig.data.edit_bones.new( 'COR-%s<>%s' % (bone.parent.name, bone.name)) link.tail = bone.head link.head = bone.parent.tail link.layers = bone.layers # link.layers = utils.layer(30) # # layer 28 = IK # # Layer 32 = Gap<>fillers # if (rig.data.rigify_layers): # link.layers = [True if index in (31,) else False for index, layer in enumerate(range(32))] link.use_deform = False link.parent = bone.parent bone.parent = link connect(link) connect(bone) link.use_connect = True bone.use_connect = True # bpy.ops.object.mode_set(mode='POSE');bpy.ops.object.mode_set(mode='EDIT'); links.append(link.name) # bone = rig.pose.bones[link.name] # bone.lock_ik_x = True # bone.lock_ik_y = True # bone.lock_ik_z = True '''def gap(bone): #bpy.ops.object.mode_set(mode='POSE'); bone = C.active_object.pose.bones[bone] bone.lock_ik_x=True; bone.lock_ik_y=True; bone.lock_ik_z=True; #bpy.ops.object.mode_set(mode='EDIT'); try: bone.lock_ik_x=True; bone.lock_ik_y=True; bone.lock_ik_z=True; link = link.name except: continue ''' elif Is.connected(bone): bone.use_connect = True else: # root-ctrl-bone continue "or this will create a parent for a 'root' bone" link = rig.data.edit_bones.new('COR-%s<>%s' % (bone.name, bone.name)) link.tail = bone.tail link.head = bone.head link.layers = utils.layer(30) # link.layers = bone.layers link.use_deform = False link.show_wire = True bone.parent = link links.append(link.name) rig.data.use_mirror_x = mirror Set.mode(context, 'POSE', rig) for link in links: link = rig.pose.bones.get(link, None) if link is None: # if bone's head+tail are the same, it'll cancel itself out continue links = link.name.replace('COR-', '', 1).split('<>') # linked = rig.pose.bones.get(links[1], None) if self.lock_ik: link.ik_stiffness_x = 1 link.ik_stiffness_y = 1 link.ik_stiffness_z = 1 if (links[0] != links[1]): # Parent <x> Child link.lock_ik_x = True link.lock_ik_y = True link.lock_ik_z = True link.lock_location = [True, True, True] link.lock_rotation_w = True link.lock_rotation = [True, True, True] link.lock_scale = [True, True, True] else: # Original bone was copied for a control bone print("Original bone was copied for a control bone") # try: # linked.lock_ik_x=True; linked.lock_ik_y=True; linked.lock_ik_z=True; # linked.ik_stiffness_x=1; linked.ik_stiffness_y=1; linked.ik_stiffness_z=1; # if not 'WGT-hips' in bpy.data.objects: # bpy.context.scene.quickrig.create_wgt = 'hips' # bpy.ops.quickrig.create_widgets() # widget = bpy.data.objects['WGT-hips'] # link.custom_shape = widget # #have the bone follow the original #link.custom_shape_transform = rig.pose.bones[links[1]] # link.use_custom_shape_bone_size = False # con = widget.constraints.new('COPY_TRANSFORMS') # con.target = rig; con.subtarget = link.name; # widget.layers[9] = True; layers = 0 # for layer in widget.layers: # if layers != 9: layer = False # except: pass ... def bgroup(name): bgroups = rig.pose.bone_groups if name in bgroups: group = bgroups[name] else: group = bgroups.new(name=name) group.color_set = 'CUSTOM' black = ((0.0, 0.0, 0.0)) select = ((0.1, 0.7, 0.9)) c = group.colors c.active, c.normal, c.select = black, black, select return group link.bone_group = bgroup('<>') Set.mode(context, mode, rig) # if active: # Set.active(context, active) return {'FINISHED'}
def execute(self, context): from zpy_constraints import Constraint wgt = utils.find_op('bonewidget.create_widget') # if wgt is None: # def wgt(*nil, **null): # return for bone in Get.selected_pose_bones(context): if not (bone.parent and bone.parent.parent): continue rig = bone.id_data bone_name = bone.name # Get and create bones for edit mode Set.mode(context, 'EDIT', rig) editbone = rig.data.edit_bones[bone_name] class fk: head = editbone.parent.parent tail = editbone.parent bone = editbone class ik: head = New.bone(context, rig, name="IK-" + fk.head.name) tail = New.bone(context, rig, name="IK-" + fk.tail.name) bone = New.bone(context, rig, name="IK-" + fk.bone.name) class stretch: head = New.bone(context, rig, name="IK-Stretch-" + fk.head.name) tail = New.bone(context, rig, name="IK-Stretch-" + fk.tail.name) bone = New.bone(context, rig, name="IK-Stretch-" + fk.bone.name) fk_names = [b.name for b in cls(fk)] ik_names = [b.name for b in cls(ik)] stretch_names = [b.name for b in cls(stretch)] # Set transforms for edit bones for k in (ik, stretch): for (b, f) in zip(cls(k), cls(fk)): copy(b, f, 'bbone_x') copy(b, f, 'bbone_z') copy(b, f, 'matrix') copy(b, f, 'tail') for b in cls(stretch): b.inherit_scale = 'NONE' b.length /= 3 stretch.tail.head = fk.head.tail stretch.bone.head = fk.tail.tail ik.tail.tail = ik.bone.head # Set parenting ik.head.parent = fk.head.parent ik.tail.parent = ik.head # ik.bone.parent = fk.head.parent for (b, i) in zip(cls(stretch), cls(ik)): b.parent = i # Switch bones back to pose mode Set.mode(context, 'POSE', rig) bones = rig.pose.bones class fk: head = bones[fk_names[0]] tail = bones[fk_names[1]] bone = bones[fk_names[2]] class ik: head = bones[ik_names[0]] tail = bones[ik_names[1]] bone = bones[ik_names[2]] class stretch: head = bones[stretch_names[0]] tail = bones[stretch_names[1]] bone = bones[stretch_names[2]] # for k in ('fk', 'ik', 'stretch'): # for h in ('head', 'tail', 'bone'): # exec(f"{k}.{h} = bones[{k}.{h}.name]") # # fk.head = bones[fk.head.name] ik.head.ik_stretch = 0.10 ik.tail.ik_stretch = 0.10 # for (b, i) in zip(cls(ik), cls(fk)): # Set.matrix(b, Get.matrix(i)) # Insert constraints cc = Constraint.new(context, add_relations=False, add_drivers=False) cc.type = 'IK' cc.add_constraint(context, ik.tail, ik.bone).chain_count = 2 cc.type = 'COPY_TRANSFORMS' cc.add_constraint(context, fk.head, stretch.head) cc.add_constraint(context, fk.tail, stretch.tail) cc.add_constraint(context, fk.bone, stretch.bone) cc.type = 'STRETCH_TO' cc.add_constraint(context, fk.head, stretch.tail) cc.add_constraint(context, fk.tail, stretch.bone) fk.bone.bone.select = False ik.bone.bone.select = True if fk.bone.bone == rig.data.bones.active: rig.data.bones.active = ik.bone.bone # Hide bones fk.head.bone.hide = True ik.tail.bone.hide = True fk.tail.bone.hide = True fk.bone.bone.hide = True if not wgt: continue # wgt(cc, widget='Rigify - Arrows', slide=(0, 0, 0), rotate=(0, 0, 0), relative_size=True, global_size=1, scale=(1, 1, 1)) cc = dict(selected_pose_bones=[ik.head]) # wgt(cc, scale=(1.25, 1.50, 1), widget='Rigify - Arrows') wgt(cc, scale=(1, 1, 1), widget='Blenrig - IK Limb') cc = dict(selected_pose_bones=cls(stretch)) wgt(cc, scale=(3, ) * 3, widget='Sphere') cc = dict(selected_pose_bones=[ik.bone]) if 'hand' in ik.bone.name.lower(): wgt(cc, scale=(1, 1, 1), widget='Blenrig - Hand') elif 'foot' in ik.bone.name.lower(): wgt(cc, scale=(1, 1, 1), widget='Blenrig - Foot') else: wgt(cc, scale=(1, 1, 1), widget='Cube') return {'FINISHED'}
def fix_poles(): def op(**args): eval('bpy.ops.pose.rigify_limb_toggle_pole_' + rig.data["rig_id"])( dict(active_object=rig), 'INVOKE_DEFAULT', **args) poles = dict() def getmat(bone, active): """Helper function for visual transform copy, gets the active transform in bone space """ obj_bone = bone.id_data obj_active = active.id_data data_bone = obj_bone.data.bones[bone.name] # all matrices are in armature space unless commented otherwise active_to_selected = obj_bone.matrix_world.inverted( ) @ obj_active.matrix_world active_matrix = active_to_selected @ active.matrix otherloc = active_matrix # final 4x4 mat of target, location. bonemat_local = data_bone.matrix_local.copy() # self rest matrix if data_bone.parent: parentposemat = obj_bone.pose.bones[ data_bone.parent.name].matrix.copy() parentbonemat = data_bone.parent.matrix_local.copy() else: parentposemat = parentbonemat = Matrix() if parentbonemat == parentposemat or not data_bone.use_inherit_rotation: newmat = bonemat_local.inverted() @ otherloc else: bonemat = parentbonemat.inverted() @ bonemat_local newmat = bonemat.inverted() @ parentposemat.inverted( ) @ otherloc return newmat def rotcopy(item, mat): """Copy rotation to item from matrix mat depending on item.rotation_mode""" if item.rotation_mode == 'QUATERNION': item.rotation_quaternion = mat.to_3x3().to_quaternion() elif item.rotation_mode == 'AXIS_ANGLE': rot = mat.to_3x3().to_quaternion().to_axis_angle( ) # returns (Vector((x, y, z)), w) axis_angle = rot[1], rot[0][0], rot[0][1], rot[0][ 2] # convert to w, x, y, z item.rotation_axis_angle = axis_angle else: item.rotation_euler = mat.to_3x3().to_euler(item.rotation_mode) def get_pole(pole, line): from math import radians from mathutils import Matrix bone["pole_vector"] = 0 pole = get(pole) line = get(line) # lock rotation/scale, since bone only suppose to be moved pole.rotation_mode = 'XYZ' pole.lock_rotation_w = True pole.lock_rotation = (True, True, True) pole.lock_scale = (True, True, True) utils.update(bpy.context) mat = getmat(pole, line) @ Matrix.Rotation(radians(180), 4, 'X') rotcopy(pole, mat) utils.update(bpy.context) poles[pole.name] = Get.matrix(pole) rotcopy(pole, Matrix()) pole.location = (0, 0, 0) if get('thigh_parent.L'): op(prop_bone="thigh_parent.L", ik_bones= "[\"thigh_ik.L\", \"MCH-shin_ik.L\", \"MCH-thigh_ik_target.L\"]", ctrl_bones= "[\"thigh_ik.L\", \"foot_ik.L\", \"thigh_ik_target.L\"]", extra_ctrls= "[\"foot_ik_pivot.L\", \"foot_heel_ik.L\", \"foot_spin_ik.L\"]") get_pole('thigh_ik_target.L', 'VIS_thigh_ik_pole.L') if get('thigh_parent.R'): op(prop_bone="thigh_parent.R", ik_bones= "[\"thigh_ik.R\", \"MCH-shin_ik.R\", \"MCH-thigh_ik_target.R\"]", ctrl_bones= "[\"thigh_ik.R\", \"foot_ik.R\", \"thigh_ik_target.R\"]", extra_ctrls= "[\"foot_ik_pivot.R\", \"foot_heel_ik.R\", \"foot_spin_ik.R\"]") get_pole('thigh_ik_target.R', 'VIS_thigh_ik_pole.R') if get('upper_arm_parent.L'): op(prop_bone="upper_arm_parent.L", ik_bones= "[\"upper_arm_ik.L\", \"MCH-forearm_ik.L\", \"MCH-upper_arm_ik_target.L\"]", ctrl_bones= "[\"upper_arm_ik.L\", \"hand_ik.L\", \"upper_arm_ik_target.L\"]", extra_ctrls="[\"hand_ik_pivot.L\", \"hand_ik_wrist.L\"]") get_pole('upper_arm_ik_target.L', 'VIS_upper_arm_ik_pole.L') if get('upper_arm_parent.R'): op(prop_bone="upper_arm_parent.R", ik_bones= "[\"upper_arm_ik.R\", \"MCH-forearm_ik.R\", \"MCH-upper_arm_ik_target.R\"]", ctrl_bones= "[\"upper_arm_ik.R\", \"hand_ik.R\", \"upper_arm_ik_target.R\"]", extra_ctrls="[\"hand_ik_pivot.R\", \"hand_ik_wrist.R\"]") get_pole('upper_arm_ik_target.R', 'VIS_upper_arm_ik_pole.R') if poles: utils.update(bpy.context) mode = Get.mode(rig) Set.mode(bpy.context, 'EDIT', rig) for (name, mat) in poles.items(): edit_bone = rig.data.edit_bones[name] Set.matrix(edit_bone, mat) Set.mode(bpy.context, mode, rig)
def execute(self, context): (rig, meshes) = self.get_rig_meshes(context) if not (rig and meshes): return {'CANCELLED'} use_mask = bool((self.from_active or self.normalize_active)) active = context.object active_bone = context.active_pose_bone.bone mode = active.mode pose = rig.data.pose_position scale = rig.scale.copy() if use_mask: active_bone.select = False Set.mode(context, 'OBJECT') rig.data.pose_position = 'REST' rig.scale *= 50 for mesh in meshes: mscale = mesh.scale.copy() mp = mesh.parent while mp and mp != rig: # Sort through mesh parent hierarchy to find if the rig is a parent somewhere in there mp = mp.parent if mp != rig: # The rig/parent is already scaled, so don't scale mesh again mesh.scale *= 50 Set.active(context, mesh) Set.mode(context, 'WEIGHT_PAINT') vg = mesh.vertex_groups bone_group = vg.get(active_bone.name) do_bone = bool((use_mask and bone_group)) mindex = vg.active_index bpy.ops.paint.weight_from_bones(type='AUTOMATIC') if do_bone: vg.active_index = mindex bpy.ops.object.vertex_group_invert() for b in context.selected_pose_bones: utils.subtract_vertex_groups(mesh, active_bone.name, b.name) bpy.ops.object.vertex_group_invert() if self.normalize_active: for b in context.selected_pose_bones: utils.subtract_vertex_groups(mesh, b.name, active_bone.name) if (mindex != -1): vg.active_index = mindex Set.mode(context, 'OBJECT') mesh.scale = mscale Set.active(context, active) rig.scale = scale rig.data.pose_position = pose Set.mode(context, mode) if use_mask: active_bone.select = True if len(meshes) > 1: self.report({'INFO'}, f"Assigned weights to {len(meshes)} meshes") else: self.report({'INFO'}, f"Assigned weights to {list(meshes)[0].name}") return {'FINISHED'}
def add_bones_stretch(self, context, rig): # Add bones then set their defaults root = self.get_root(rig) prev_bones = self.get_prev_bones(rig) pose_bones = [] for bone_name in prev_bones: prev = rig.data.edit_bones[bone_name] bone = rig.data.edit_bones.new(self.mirror_name(prev.name, 'STR')) head = prev.parent.name if (prev.parent and prev.use_connect) else '' tail = [*[c.name for c in prev.children if c.use_connect], ''][0] pose_bones.append([bone.name, [prev.name, head, tail]]) self.reset(bone, prev) bone.parent = prev.parent bone.use_deform = False # use_tip = True # child = None # if edit_bone.children: # for i in edit_bone.children: # if i.use_connect: # if child is not None: # child = False # break # child = i # if child in [None, False]: # for i in edit_bone.children: # if i.head == edit_bone.tail: # if child not in [None, False]: # child = False # break # child = i # if child: # tail = rig.data.edit_bones.get('STR-'+child.name) # if tail is None: # tail = rig.data.edit_bones.new('STR-'+child.name) # tail.parent = child # tail.use_deform = False # self.reset(tail, edit_bone=child) # else: # use_tip = False # else: # create bone tip # tail = rig.data.edit_bones.new('STR_TAIL-'+bone.name) # tail.parent = edit_bone # tail.use_deform = False # self.reset(tail) # th = Vector(tail.tail-tail.head) # tail.tail += th # tail.head += th ... # Switch back to Pose mode and setup pose bones Set.mode(context, 'POSE', rig) for bone, prev in pose_bones: prev, head, tail = prev bone = rig.pose.bones[bone] prev = rig.pose.bones[prev] head = rig.pose.bones.get(head, None) if head: prev.bone.bbone_custom_handle_start = head.bone tail = rig.pose.bones.get(tail, None) if tail: prev.bone.bbone_custom_handle_end = tail.bone rig.data.bones.active = bone.bone bone.custom_shape_transform = prev self.widget(bone, 'Sphere', scale=(0, 1.5, 0)) # bone['IK_FK'] = prev.name # prev['IK_IK'] = bone.name bone.rotation_mode = prev.rotation_mode bone.lock_rotation[0] = True bone.lock_rotation[2] = True # i['IK_Deform'] = deform.name # i['IK_Stretch'] = stretch.name # i['IK_Tail'] = tail.name bone.matrix = prev.matrix if prev.bone_group: bone.bone_group = self.bgroup(rig, 'STR-' + prev.bone_group.name) else: bone.bone_group = self.bgroup(rig, 'STR') prev.bone_group = self.bgroup(rig, 'FK')