Example #1
0
    def execute(self, context):
        if self.bones:
            bones = eval(self.bones)
        else:
            bones = Get.selected_pose_bones(context)

        if not bones:
            return {'CANCELLED'}

        wgts = readWidgets()
        if self.widget:
            widget = wgts[self.widget]
        else:
            widget = wgts[context.scene.widget_list]

        for bone in bones:
            if bone.id_data.proxy:
                continue
            slide = list(self.slide)
            rotate = list(self.rotate)
            if self.mirror:
                mirror = findMirrorObject(bone)
                if mirror and mirror in bones and bone.name.endswith(
                    ('L', 'l')):
                    slide[0] *= -1
                    rotate[1] *= -1
                    rotate[2] *= -1

            createWidget(
                context,
                bone,
                widget,
                self.relative_size,
                self.global_size,
                [*self.scale],
                slide,
                rotate,
                get_collection(context),
            )

        utils.update(context)

        pr = utils.prefs(__addon__).bone_widgets
        # pr = prefs.prefs().bone_widgets
        if pr.keep_settings:
            pr.slide = self.slide
            pr.rotate = self.rotate
            pr.relative_size = self.relative_size
            pr.global_size = self.global_size
            pr.scale = self.scale
            pr.mirror = self.mirror

        # Create new object then delete it.
        # When creating multiple widgets, if the last one tries to enter edit
        # mode before a particular update occurs, Blender will crash.
        # If the last object created (I.E. this empty) is not the widget,
        # Blender can enter edit mode without crash
        Get.objects(context, link=True).unlink(New.object(context))

        return {'FINISHED'}
Example #2
0
    def invoke(self, context, event):
        # Get current pose
        selected = Get.selected(context, mirror=True)
        for src in selected:
            pose.base[repr(src)] = Get.matrix(src, basis=True)

        # Disable animation and get pose from lower layers
        base_anim = dict()
        for src in selected:
            obj = src.id_data
            anim = obj.animation_data

            if (anim) and (obj not in base_anim):
                tracks = list()

                if anim.use_tweak_mode:
                    # Find the strip to disable

                    for track in reversed(anim.nla_tracks):
                        for _strip in track.strips:
                            if _strip.active:
                                strip = _strip
                                break
                            elif _strip.action == anim.action:
                                # backup in case strip isn't "active"
                                strip = _strip
                        else:
                            tracks.append((track, track.mute))
                            # track.mute = True
                            continue
                        break

                    base_anim[obj] = [strip, strip.mute, tracks]
                    strip.mute = True
                    # anim.use_tweak_mode = False
                else:
                    base_anim[obj] = [None, anim.action_influence, tracks]
                    anim.action_influence = 0
                utils.update(context)

            pose.reset[repr(src)] = Get.matrix(src, basis=True)

        # Re-enable animation
        for obj in base_anim:
            anim = obj.animation_data
            (strip, value, tracks) = base_anim[obj]
            if strip:
                # for (track, track_mute) in tracks:
                # track.mute = track_mute
                strip.mute = value
                # anim.use_tweak_mode = True
            else:
                anim.action_influence = value
            utils.update(context)

        # context.window_manager.modal_handler_add(self)
        # return {'RUNNING_MODAL'}
        return self.execute(context)
Example #3
0
File: Set.py Project: Irmitya/zpy
    def update_constraint_matrix(mats):
        from zpy import utils

        # Set the matrix
        for con in constraints:
            if hasattr(con, 'use_offset') and con.use_offset:
                utils.update(context)
        # utils.update(context)
        for src in srcs:
            new_mat = Get.matrix_constraints(context, src, mats[src],
                                             constraints)
            mats[src] = new_mat
Example #4
0
def rigify_to_meta(rigify, metarig):
    """Retarget Rigify meshes to Metarig"""

    pose = (metarig.data.pose_position, rigify.data.pose_position)
    (metarig.data.pose_position, rigify.data.pose_position) = ('REST', 'REST')
    utils.update(bpy.context)

    for obj in bpy.data.objects:
        if Is.curve(obj) and obj.name.startswith(rigify.name + '-MCH-'):
            # Splines from angavrilov's spline rig
            continue
        for mod in obj.modifiers:
            if hasattr(mod, 'object') and mod.object == rigify:
                mod.object = metarig
                metafy_vgroups(rigify, obj, metarig)

        if (obj.parent == rigify):
            rigify_bone = obj.parent_bone

            if rigify_bone:
                if rigify_bone.startswith('DEF-'):
                    meta_bone = rigify_bone[4:]
                else:
                    meta_bone = rigify_bone

                if meta_bone in metarig.data.bones:
                    mat = Get.matrix(obj)
                    # pmat = obj.matrix_parent_inverse.copy()
                    obj.parent = metarig
                    obj.parent_bone = meta_bone
                    # obj.matrix_parent_inverse = pmat
                    Set.matrix(obj, mat)
            else:
                obj.parent = metarig

        if Is.mesh(obj):
            meshes = {obj.data}
            if hasattr(obj, 'variants'):
                # The LoDs store the mesh datas and drivers without an object
                for layer in obj.variants.layers:
                    if layer.mesh:
                        meshes.add(layer.mesh)
                    for lod in layer.lods:
                        meshes.add(lod.mesh)

            for mesh in meshes:
                if mesh:
                    rigify_drivers(rigify, metarig, mesh.shape_keys)
    for mat in bpy.data.materials:
        rigify_drivers(rigify, metarig, mat)
        rigify_drivers(rigify, metarig, mat.node_tree)

    (metarig.data.pose_position, rigify.data.pose_position) = pose
Example #5
0
def meta_to_rigify(metarig, rigify):
    """Retarget Metarig meshes to Rigify rig"""

    pose = (metarig.data.pose_position, rigify.data.pose_position)
    (metarig.data.pose_position, rigify.data.pose_position) = ('REST', 'REST')
    utils.update(bpy.context)

    for obj in bpy.data.objects:
        for mod in obj.modifiers:
            if hasattr(mod, 'object') and mod.object == metarig:
                mod.object = rigify
                rigify_vgroups(metarig, rigify, obj)

        if obj.parent == metarig:
            if obj.parent_bone:
                rigify_bone = vg_names.get(obj.parent_bone, False)
                if rigify_bone is False:
                    rigify_bone = 'DEF-' + obj.parent_bone
                if rigify_bone and rigify_bone in rigify.data.bones:
                    mat = Get.matrix(obj)
                    # pmat = obj.matrix_parent_inverse.copy()
                    obj.parent = rigify
                    obj.parent_bone = rigify_bone
                    # obj.matrix_parent_inverse = pmat
                    Set.matrix(obj, mat)
            else:
                obj.parent = rigify

        if Is.mesh(obj):
            meshes = {obj.data}
            if hasattr(obj, 'variants'):
                # The LoDs store the mesh datas and drivers without an object
                for layer in obj.variants.layers:
                    if layer.mesh:
                        meshes.add(layer.mesh)
                    for lod in layer.lods:
                        meshes.add(lod.mesh)

            for mesh in meshes:
                if mesh:
                    rigify_drivers(metarig, rigify, mesh.shape_keys)
    for mat in bpy.data.materials:
        rigify_drivers(metarig, rigify, mat)
        rigify_drivers(metarig, rigify, mat.node_tree)

    (metarig.data.pose_position, rigify.data.pose_position) = pose
        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)
Example #7
0
    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 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)
Example #9
0
    def generate(self, context, ob, rig, coll):
        scn = context.scene

        faceverts, vertfaces = self.getVertFaces(ob)
        majors = {}
        skip = []
        for vgrp in ob.vertex_groups:
            if vgrp.name in rig.data.bones:
                majors[vgrp.index] = []
            else:
                skip.append(vgrp.index)
        for v in ob.data.vertices:
            wmax = 1e-3
            vbest = None
            for g in v.groups:
                if g.weight > wmax and g.group not in skip:
                    wmax = g.weight
                    vbest = v
                    gbest = g.group
            if vbest is not None:
                majors[gbest].append(vbest)

        roots = [bone for bone in rig.data.bones if bone.parent is None]
        for bone in roots:
            self.remapBones(bone, ob.vertex_groups, majors, None)

        face_mats = dict()
        if ob.data.materials:
            for f in ob.data.polygons:
                face_mats[(
                    f.area, *f.center,
                    *f.normal)] = ob.material_slots[f.material_index].material

        nobs = []
        for vgrp in ob.vertex_groups:
            if (vgrp.name not in rig.pose.bones.keys()
                    or vgrp.index not in majors.keys()):
                continue
            fnums = []
            for v in majors[vgrp.index]:
                for fn in vertfaces[v.index]:
                    fnums.append(fn)
            fnums = list(set(fnums))

            nverts = []
            nfaces = []
            for fn in fnums:
                f = ob.data.polygons[fn]
                nverts += f.vertices
                nfaces.append(f.vertices)
            if not nfaces:
                continue
            nverts = list(set(nverts))
            nverts.sort()

            bone = rig.pose.bones[vgrp.name]
            head = bone.bone.head_local
            # verts = [ob.data.vertices[vn].co - head for vn in nverts]
            verts = [ob.data.vertices[vn].co for vn in nverts]
            assoc = dict([(vn, n) for n, vn in enumerate(nverts)])
            faces = []
            for fverts in nfaces:
                faces.append([assoc[vn] for vn in fverts])

            name = ob.name[0:3] + "_" + vgrp.name
            me = bpy.data.meshes.new(name)
            me.from_pydata(verts, [], faces)
            nob = bpy.data.objects.new(name, me)
            coll.objects.link(nob)
            nob.DazMannequin = True
            # nob.location = head
            # nob.lock_location = nob.lock_rotation = nob.lock_scale = (True,True,True)
            nobs.append((nob, bone))

            if ob.data.materials:
                for b in me.polygons:
                    mat_i = face_mats.get((b.area, *b.center, *b.normal))
                    if mat_i is None:
                        # Add an empty material
                        if mat is None:
                            from random import random
                            mat = bpy.data.materials.new(ob.name + 'Mannequin')
                            mat.diffuse_color[0:3] = (random(), random(),
                                                      random())
                            # for omat in ob.data.materials:
                            # mat.diffuse_color = omat.diffuse_color
                        if mat.name not in me.materials:
                            me.materials.append(mat)
                        continue

                    if mat_i.name not in me.materials:
                        me.materials.append(mat_i)
                    for (i, mat_c) in enumerate(nob.material_slots):
                        if mat_c.material == mat_i:
                            b.material_index = i
                            break
            else:
                if mat is None:
                    from random import random
                    mat = bpy.data.materials.new(ob.name + 'Mannequin')
                    mat.diffuse_color[0:3] = (random(), random(), random())
                    # for omat in ob.data.materials:
                    # mat.diffuse_color = omat.diffuse_color
                if mat.name not in me.materials:
                    me.materials.append(mat)

        utils.update(context)
        for (nob, bone) in nobs:
            mat = Get.matrix(nob)
            # pmat = nob.matrix_parent_inverse.copy()
            nob.parent = rig
            nob.parent_bone = bone.name
            nob.parent_type = 'BONE'
            # nob.matrix_parent_inverse = pmat
            Set.matrix(nob, mat)
Example #10
0
    def update_pose(self, context):
        # for region in context.area.regions:
        # if region.type == 'WINDOW':
        # break
        # else:
        # return self.cancel(context)
        region = context.region
        rv3d = context.space_data.region_3d

        gp = context.annotation_data

        stroke = gp.layers.active.frames[0].strokes[0]

        for chain in Get.sorted_chains(context.selected_pose_bones):
            bone_chain = list()

            for bone in reversed(chain):
                bone_chain.insert(0, bone)
                if bone == chain[0]:
                    # Do location
                    pass
                    # continue  # or break; should do the same
                else:
                    pass

                    while bone.parent not in chain:
                        # Do unselected in betweens
                        bone = bone.parent
                        if not Is.visible(context, bone):
                            # Don't rotate hidden bones
                            continue

                        bone_chain.insert(0, bone)

            bcount = len(bone_chain) - 1
            gcount = len(stroke.points) - 1

            # if bcount:
            # while gcount > bcount * 3:
            # # Split point count in half
            # index = 0
            # while index < len(stroke.points) - 1:
            #     stroke.points.pop(index=index + 1)
            #     index += 1
            # print(bcount, gcount, '\t', index, len(stroke.points))

            # gcount = len(stroke.points) - 1

            bone_mats = list()
            con_tmp = list()

            index = 0
            for bone in bone_chain:
                if index > bcount:
                    index = bcount

                point_index = utils.scale_range(index, 0, bcount, 0, gcount)
                point = stroke.points[int(point_index)]

                if index == 0:
                    if not (bone.parent):
                        bone = bone_chain[0]
                        point = stroke.points[0]

                        to_2d = location_3d_to_region_2d(
                            region, rv3d, point.co)  # get 2d space of stroke
                        if to_2d:
                            to_3d = region_2d_to_location_3d(
                                region, rv3d, to_2d,
                                bone.head)  # keep depth of bone

                            empty = New.object(context, bone.name)
                            empty.empty_display_size = 0.25
                            empty.location = to_3d

                            con = bone.constraints.new('COPY_LOCATION')
                            con.target = empty
                            con_tmp.append((bone, con, empty))

                    if bcount == 0:
                        point = stroke.points[-1]
                    else:
                        # index += 1
                        point_index = utils.scale_range(
                            0.5, 0, bcount, 0, gcount)
                        point = stroke.points[int(point_index)]

                to_2d = location_3d_to_region_2d(
                    region, rv3d, point.co)  # get 2d space of stroke
                if to_2d:
                    to_3d = region_2d_to_location_3d(
                        region, rv3d, to_2d, bone.tail)  # keep depth of bone

                    empty = New.object(context, bone.name)
                    empty.empty_display_size = 0.1
                    empty.location = to_3d

                    con = bone.constraints.new('DAMPED_TRACK')
                    con.target = empty
                    con_tmp.append((bone, con, empty))

                index += 1

            utils.update(context)
            for (bone, con, empty) in reversed(con_tmp):
                mat = Get.matrix_constraints(context, bone)
                # mat = Get.matrix(bone)
                bone_mats.append((bone, mat))

                bone.constraints.remove(con)
                Get.objects(context, link=True).unlink(empty)

            for (bone, mat) in bone_mats:
                Set.matrix(bone, mat)
                keyframe.keyingset(context, selected=[bone], skip_bones=True)

        self.remove_annotation(context)

        return {'FINISHED'}