def execute(self, context): if (context.mode == 'POSE'): if self.selected: bones = context.selected_pose_bones else: bones = [context.active_pose_bone] else: if self.selected: bones = context.selected_bones else: bones = [context.active_bone] for _bone in bones: (bone, child) = self.get_bone_child(_bone) self.set_bbone(bone, child) if Is.posebone(_bone): mirror_x = (_bone.id_data.pose.use_mirror_x or bone.id_data.use_mirror_x) else: mirror_x = bone.id_data.use_mirror_x if mirror_x: m_bone = Get.mirror_bone(_bone) if m_bone and (m_bone not in bones): (mbone, mchild) = self.get_bone_child(m_bone) self.set_bbone(mbone, mchild) return {'FINISHED'}
def get_rig_bones(context): rigs = dict() # rig object with a list of selected and mirrored bones selected = list() # remember selected and non-selected mirror bones for bone in context.selected_pose_bones: rig = bone.id_data if Is.linked(rig): continue if rig not in rigs: rigs[rig] = list() if (bone not in rigs[rig]): rigs[rig].append(bone) selected.append((bone, rig)) if (rig.pose.use_mirror_x or rig.data.use_mirror_x): mirror = Get.mirror_bone(bone) if mirror and (mirror not in rigs[rig]): rigs[rig].append(mirror) selected.append((mirror, rig)) return (rigs, selected)
def pose_func(self, context, bone): rig = bone.id_data bones = rig.pose.bones bbones = ('bbone', 'bbone_start', 'bbone_end', 'bbone_head', 'bbone_in', 'bbone_out') def parse(bbone): self.bones[bbone] = rig # Prep the widget for removal wgt = bbone.custom_shape if wgt: self.widgets.add(wgt) # Remove stretch constraints for con in list(bone.constraints): if (getattr(con, 'target', None) == rig) and (con.subtarget == bbone.name): bone.constraints.remove(con) # Remove Custom Handle if bone.bbone_custom_handle_start == bbone: bone.bone.bbone_custom_handle_start = None bone.bone.bbone_handle_type_start = 'AUTO' if bone.bbone_custom_handle_end == bbone: bone.bone.bbone_custom_handle_end = None bone.bone.bbone_handle_type_end = 'AUTO' for bbone_name in bbones: bbone = bones.get(get_name(bone, bbone_name)) if not bbone: continue parse(bbone) if bbone_name in ('bbone_start', 'bbone_end') and Get.mirror_bone(bbone): (prefix, replace, suffix, number) = utils.flip_name(bone.name, only_split=True) center_name = prefix + suffix + number center = bones.get(center_name) if center: parse(center) # Remove BBone drivers if bbone_name in ('bbone_in', 'bbone_out'): in_out = bbone_name.split('_')[1] in_outs = ( f'bbone_curve{in_out}x', f'bbone_curve{in_out}y', f'bbone_roll{in_out}', f'bbone_scale{in_out}x', f'bbone_scale{in_out}y', f'bbone_ease{in_out}', ) for bbone_in_out in in_outs: Driver = Get.driver(bone, bbone_in_out) try: target = Driver.driver.variables[0].targets[0] except: continue if (target.bone_target == bbone.name) and (target.id == rig): bone.driver_remove(bbone_in_out)
def get_bones(rig, bbone): ebones = rig.data.edit_bones ebone = ebones.get(get_name(bone, bbone)) mebone = Get.mirror_bone(ebone) return (ebone, mebone)
def edit_mirror_center(self, context): def get_bones(rig, bbone): ebones = rig.data.edit_bones ebone = ebones.get(get_name(bone, bbone)) mebone = Get.mirror_bone(ebone) return (ebone, mebone) found = [] for (bone, rig) in self.selected: if not (rig.pose.use_mirror_x or rig.data.use_mirror_x): continue mbone = Get.mirror_bone(bone) if mbone in found: continue else: found.append(bone) (ebone, mebone) = get_bones(rig, 'bbone_start') if not (ebone and mebone): continue if (ebone.parent == mebone.parent): # Connect heads if Is.connected(bone): # The parent will already handle the symmetry continue parent = ebone.parent else: (ebone, mebone) = get_bones(rig, 'bbone_end') if not (ebone and mebone): continue # Find a mutual parent between the two bones parent = [ *(x for x in ebone.parent_recursive if x in mebone.parent_recursive), None ][0] distance = abs(sum(ebone.head) - sum(mebone.head)) / 2 margin = utils.lerp(bone.bone.length, mbone.bone.length, 0.5) / bone.bone.bbone_segments if distance >= margin: # Bones too far apart continue (prefix, replace, suffix, number) = utils.flip_name(bone.name, only_split=True) center_name = prefix + suffix + number center = New.bone(context, rig, name=center_name, overwrite=True) attributes = [ 'head', 'head_radius', 'tail', 'tail_radius', 'roll', 'matrix', 'layers', 'bbone_x', 'bbone_z', ] for atr in attributes: if hasattr(center, atr): setattr( center, atr, utils.lerp(getattr(ebone, atr), getattr(mebone, atr), 0.5)) center.use_deform = False center.inherit_scale = 'NONE' center.parent = parent center.hide = True ebone.parent = mebone.parent = center self.hide_bones[rig].extend((ebone.name, mebone.name)) self.center_bones[rig].append(center.name)