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'}
Exemple #2
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
Exemple #3
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 execute(self, context):
        area = context.area
        view = area.spaces.active
        reg = view.region_3d

        # Create new camera object, add to scene, and select it
        camo = New.camera(context, name="Viewport", size=0.5)
        cam = camo.data
        Set.active(context, camo)
        # Set.active_select(camo)

        # Set Lock viewport to the camera
        view.camera = camo
        view.use_local_camera = True
        view.lock_camera = True

        # Send camera object to the current viewport rotation/location
        Set.matrix(camo, reg.view_matrix.inverted())

        # Switch to camera view
        if reg.view_perspective != 'CAMERA':
            bpy.ops.view3d.view_camera()
            # run op to prevent changing the (actual) viewport's position
        # reg.view_perspective = 'CAMERA'

        # Mirror viewport properties to the camera
        cam.lens = view.lens / 2
        cam.clip_start = view.clip_start
        cam.clip_end = view.clip_end

        # Re-center the camera view window if it was changed
        bpy.ops.view3d.view_center_camera()
        # reg.view_camera_offset = [0.0, 0.0]
        # reg.view_camera_zoom = 28

        # Setup Deph of Field
        cam.dof.use_dof = True
        # cam.dof.aperture_fstop = 0.5  # Blur amount
        # cam.dof.aperture_fstop = 2.8
        # cam.dof.focus_distance = reg.view_distance
        bpy.ops.ui.eyedropper_depth('INVOKE_DEFAULT')

        return {'FINISHED'}
Exemple #5
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)
Exemple #7
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)
Exemple #8
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'}