Example #1
0
File: New.py Project: Irmitya/zpy
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
Example #2
0
    def execute(self, context):
        if context.visible_pose_bones:
            is_pose = True
            visible_bones = [b.bone for b in context.visible_pose_bones]
        else:
            is_pose = False
            visible_bones = list(context.visible_bones)

        armatures = list()
        bones = list()
        for bone in visible_bones:
            if not self.extend:
                bone.select = bone.select_head = bone.select_tail = False
            arm = bone.id_data
            if arm in armatures:
                continue
            armatures.append(arm)
            if is_pose:
                arm.bones.active = None
            else:
                arm.edit_bones.active = None

        for arm in armatures:
            if is_pose:
                bones = arm.bones
            else:
                bones = arm.edit_bones

            for bone in bones:
                if bone.hide_select and Is.visible(context, bone):
                    bone.select = True
                    bones.active = bone

        return {'FINISHED'}
Example #3
0
File: Get.py Project: Irmitya/zpy
def selected_edit_bones(context, src=None):
    "Always return edit bones as list, never as None"

    if src:
        bones = src.data.edit_bones
        selected = [
            b for b in bones if Is.selected(b) and Is.visible(context, b)
        ]
    else:
        selected = Get.as_list(context, 'selected_editable_bones')

    return selected
Example #4
0
File: Get.py Project: Irmitya/zpy
def selected_pose_bones(context,
                        src=None,
                        force: "not needed, todelete" = False):
    "Always return pose bones as list, never as None"

    if src:
        selected = [
            b for b in src.pose.bones
            if Is.selected(b) and Is.visible(context, b)
        ]
    # elif not force and context.mode not in ('POSE', 'PAINT_WEIGHT'):
    # selected = []
    else:
        selected = Get.as_list(context, 'selected_pose_bones')

    return selected
Example #5
0
    def get_rig_meshes(self, context):
        """
        Find the selected rigs and meshes, attached together.
        If only a rig is selected, find all the meshes that use it.
        """

        active = context.object

        if context.mode == 'PAINT_WEIGHT':
            meshes = {active}
            rig = None
            for mod in active.modifiers:
                if (mod.type == 'ARMATURE') and (mod.object in Get.objects(context)[:]):
                    rig = mod.object
                    if rig.mode == 'POSE':
                        break
            if not rig:
                self.report({'ERROR'}, "Can't find rig using the active mesh")
        else:
            rig = active
            meshes = set()
            for ob in context.selected_objects:
                if Is.mesh(ob):
                    for mod in ob.modifiers:
                        if (mod.type == 'ARMATURE') and (mod.object == rig):
                            meshes.add(ob)

            if not meshes:
                for ob in Get.objects(context):
                    if not Is.visible(context, ob):
                        continue

                    for mod in ob.modifiers:
                        if (mod.type == 'ARMATURE') and (mod.object == rig):
                            meshes.add(ob)

            if not meshes:
                self.report({'ERROR'}, "Can't find mesh using the active rig")

        return (rig, meshes)
Example #6
0
 def add_obj(obj):
     if show_hidden is False and not Is.visible(context, obj):
         return None
     if obj not in selected:
         selected.append(obj)
Example #7
0
def get_selected_keys_and_extents():
    context = bpy.context
    pbones = context.selected_pose_bones
    if pbones is None:
        pbones = []
    curve_datas = []
    selected = []
    objects = []
    bones = []
    fcurves = []

    try:
        only_selected = context.space_data.dopesheet.show_only_selected
        show_hidden = context.space_data.dopesheet.show_hidden
    except:
        only_selected = True
        show_hidden = False

    def add_obj(obj):
        if show_hidden is False and not Is.visible(context, obj):
            return None
        if obj not in selected:
            selected.append(obj)

    def add_bone(b):
        if only_selected and not b.bone.select:
            return None
        add_obj(b.id_data)
        bones.append(b)

    for obj in Get.objects(context):
        if show_hidden is False and not Is.visible(context, obj):
            continue

        # Add object and bones
        if not (only_selected and not Is.selected(obj)):
            add_obj(obj)
        if obj.pose is not None:
            for (name, pbone) in obj.pose.bones.items():
                if any((only_selected is False, Is.selected(obj), pbone in pbones,)):
                    add_bone(pbone)

    # Add fcurves from objects
    for obj in selected:
        anim = obj.animation_data
        if anim and anim.action:
            fcurves.extend([(obj, fc) for fc in anim.action.fcurves])

    # Scan fcurves for keyframes
    for obj, curve in fcurves:
        if curve.hide or curve.lock or not curve.select:
            continue
        first_co = None
        points = None
        last_co = None
        path = curve.data_path

        # Read path to get target's name
        if (path.startswith('pose.bones')):
            # btype =   'BONE'
            # bpath =   path.split('"]', 1)[1]      ## Transforms and custom prop
            # if (bpath.startswith('.')):       ## constraints?
                # bpath =   bpath.split('.', 1)[1]
            bname = (path.split('["', 1)[1].split('"]', 1)[0])
            bone = obj.pose.bones.get(bname)
        elif (path.startswith('bones')):  # data.bones
            # btype = 'BONE'
            # bpath = path.split('"].', 1)[1]
            bname = (path.split('["', 1)[1].split('"]', 1)[0])
            bone = obj.bones.get(bname)
        else:
            # btype = 'OBJECT'
            # bpath = path
            bname = obj.name
            bone = obj

        if (bone is None and curve.is_valid is True) or (bone is not None and bone != obj and bone not in bones):
            # Bone not selected
            continue

        keyframes_referenced = []
        keyframes_data = []
        for keyframe in curve.keyframe_points:
            if keyframe.select_control_point:
                if first_co is None:
                    first_co = keyframe.co
                else:
                    last_co = keyframe.co
                keyframes_referenced.append(keyframe)
                keyframes_data.append({
                    'co': deepcopy(keyframe.co),
                    'handle_left': deepcopy(keyframe.handle_left),
                    'handle_right': deepcopy(keyframe.handle_right)
                })  # needs to be all three data points!
        if last_co is not None:
            curve_datas.append([keyframes_referenced, first_co, last_co, keyframes_data, curve])
    return curve_datas
def scan_actions(context, sub, selected):
    scn = context.scene
    fc = (int(scn.frame_current_final), scn.frame_current_final)[sub]
    frames = list()

    for obj in selected:
        if Is.gpencil(obj):
            for layer in obj.data.layers:
                for frame in layer.frames:
                    frames.append(frame.frame_number)

    for obj in Get.objects_nla(context):
        # Poll object
        if pose(context):
            if not pose(obj):
                continue
            elif selected:
                bones = [
                    f'pose.bones[\"{b.name}\"]'
                    for b in Get.selected_pose_bones(context, src=obj)
                ]
                if not bones:
                    continue
            else:
                bones = list()
        else:
            if (selected and obj not in selected):
                continue
            else:
                bones = list()

        for anim in Get.animation_datas(obj):
            if (not anim.action):
                continue
            if anim.use_tweak_mode:
                for s in Get.strips(anim.id_data):
                    if s.action == anim.action:
                        strip = s
                        if s.active: break

                # Get loop ends
                cycle = list()
                afe = strip.action_frame_end
                fel = fer = Get.frame_from_strip(context, strip, afe)
                while fel < strip.frame_end:
                    offset = (fer - strip.frame_start)
                    cycle.append(offset)
                    fel += abs(offset)
                    # If offset becomes negative, it "should" create an infinite loop
                    # abs() forces positive, which "should" prevent loop
            else:
                strip = None

            for fcurve in anim.action.fcurves:
                path = fcurve.data_path
                if bones:
                    # Bones are selected, so verify this fcurve if for one of them
                    for bpath in bones:
                        if path.startswith(bpath):
                            break
                    else:
                        continue
                elif path.startswith('pose.bones[\"'):
                    try:
                        eval(repr(obj) + '.' + path)  # Validate path
                        bpath = path.split('\"]', 1)[0] + '\"]'
                        bone = eval(repr(obj) + '.' + bpath)
                        if not Is.visible(context, bone):
                            continue
                    except:
                        # curve points to a removed bone or something
                        continue

                scan_fcurve(context, sub, fcurve, frames, strip=strip)

    return sorted(set(frames))
Example #9
0
    def get_keys(self, context):
        scn_frame = context.scene.frame_current_final
        fcurves = dict()
        quats = dict()
        updates = dict()

        break_sync = False
        if hasattr(context.scene, 'sync'):
            break_sync = context.scene.sync.sync_3d and context.scene.sync.sync_between_3d

        if context.mode == 'POSE':
            # objects = [o for o in Get.objects(context) if o.mode == 'POSE']
            objects = list()

            for ob in Get.objects(context):
                if ob.mode != 'POSE':
                    continue
                bones = tuple([f"pose.bones[\"{b.name}\"]"
                    for b in Get.selected_pose_bones(context, ob)])
                if bones:
                    objects.append((ob, bones))

            if not objects:
                for ob in Get.objects(context):
                    if ob.mode != 'POSE':
                        continue
                    bones = tuple([f"pose.bones[\"{b.name}\"]"
                        for b in ob.pose.bones if Is.visible(context, b)])
                    if bones:
                        objects.append((ob, bones))
        else:
            objects = [(o, list()) for o in Get.selected_objects(context)]

        for (ob, bones) in objects:
            for anim in Get.animation_datas(ob):
                action = anim.action
                if not action:
                    continue

                if anim.use_tweak_mode:
                    frame = Get.frame_to_strip(context, anim, scn_frame)
                    for s in Get.strips(anim.id_data):
                        if s.action == action:
                            strip = s
                            if s.active: break
                    blend = strip.blend_type
                else:
                    frame = scn_frame
                    blend = anim.action_blend_type

                offset = abs(frame - scn_frame)
                if (scn_frame < frame):
                    offset *= -1

                for fc in anim.action.fcurves:
                    path = fc.data_path
                    index = fc.array_index

                    if len(fc.keyframe_points) < 2:
                        continue
                    if bones:
                        src = None
                        for bone in bones:
                            if path.startswith(bone):
                                try:
                                    eval(repr(ob) + '.' + path)  # Validate path
                                    src = eval(repr(ob) + '.' + bone)
                                    attr = path.replace(bone, '', 1)
                                    if attr.startswith('.'):
                                        attr = attr.replace('.', '', 1)
                                        is_custom = False
                                    else:
                                        is_custom = True
                                except:
                                    # curve points to a removed bone or something
                                    src = None
                                break
                        else:
                            # Pose mode but bone not selected
                            continue
                        if src is None:
                            # Missing bone
                            continue
                    else:
                        attr = path
                        src = ob

                        if attr in transforms:
                            is_custom = False
                        elif attr.startswith('["'):
                            is_custom = True
                        else:
                            # if attr.startswith(('pose.bones', 'bones')):
                            continue

                    # Find the property to be able to manipulate, and its current value
                    if is_custom:
                        prop = src
                        split = attr.rsplit('"]["', 1)
                        if len(split) == 2:
                            prop = eval(repr(src) + split[0] + '"]')
                            attr = '["' + split[1]
                        prop_value = getattr(prop, attr)
                    elif hasattr(src, attr):
                        prop = getattr(src, attr)
                        if Is.iterable(prop):
                            # elif attr in transforms:
                                # prop = src.path_resolve(attr)
                            prop_value = prop[index]
                        else:
                            prop = src
                            prop_value = getattr(prop, attr)
                    else:
                        # maybe a constraint:
                            # pose.bones[bone.name].constraints[con.name].influence
                        continue

                    # Function to apply values to the bone/object, later
                    if Is.iterable(prop):
                        def apply(self, val):
                            "Function to apply values to (array) in bone/object, later"
                            self.prop[self.index] = val

                        prop = src.path_resolve(attr)
                        prop_value = prop[index]
                        is_array = True
                    else:
                        def apply(self, val):
                            setattr(self.prop, self.attr, val)
                        is_array = False

                    cache = dict(
                        attr=attr,
                        apply=apply,
                        index=index,
                        is_array=is_array,
                        key=None,
                        quat=None,
                        prop=prop,
                        src=src,
                        value=fc.evaluate(frame),
                    )
                    left = type('', (), cache)
                    current = type('', (), cache)
                    current.found = False
                    right = type('', (), cache)

                    pre_key = None

                    # Find the current keyframe, and keys left and right
                    if break_sync:
                        # types = context.scene.keyframe_navigation_types
                        types = ('KEYFRAME', 'MOVING_HOLD')
                        for key in fc.keyframe_points:
                            if key.co.x < frame:
                                if (left.key is None) or (key.type in types):
                                    left.key = key
                                    left.value = key.co.y
                                    right.key = key
                                    right.value = key.co.y
                            elif key.co.x == frame:
                                if left.key is None:
                                    left.key = key
                                    left.value = key.co.y
                                current.key = key
                                current.found = True
                                right.key = key
                                right.value = key.co.y
                            elif key.co.x > frame:
                                if left.key is None:
                                    left.key = key
                                    left.value = key.co.y
                                if (key.type in types) or key == fc.keyframe_points[-1]:
                                    right.key = key
                                    right.value = key.co.y
                                    break

                    if not (left.key and right.key):
                        for key in fc.keyframe_points:
                            if key.co.x < frame:
                                left.key = key
                                left.value = key.co.y
                                right.key = key
                                right.value = key.co.y
                            elif key.co.x == frame:
                                if left.key is None:
                                    left.key = key
                                    left.value = key.co.y
                                current.key = key
                                current.found = True
                                right.key = key
                                right.value = key.co.y
                            elif key.co.x > frame:
                                if left.key is None:
                                    left.key = key
                                    left.value = key.co.y
                                right.key = key
                                right.value = key.co.y
                                break

                    if not (left.key and right.key):
                        # Nothing to tween
                        continue

                    # Get info for current keyframe's defaults

                    sVal = left.key.co.x + offset
                    eVal = right.key.co.x + offset

                    current.w1 = frame - sVal
                    current.w2 = eVal - frame

                    left.frame = left.key.co.x
                    current.frame = frame
                    right.frame = right.key.co.x

                    current.in_range = False
                    if frame < left.frame:
                        left.value = prop_value
                    elif right.frame < frame:
                        right.value = prop_value
                    else:
                        current.in_range = True

                    if blend == 'REPLACE':
                        current.value = prop_value
                    else:
                        if not self.has_additive:
                            self.has_additive = True

                        if current.key:
                            value = current.key.co.y
                        else:
                            value = fc.evaluate(frame)

                        left.value = prop_value + (left.value - value)
                        current.value = prop_value  # + (value - value)
                        right.value = prop_value + (right.value - value)

                        if tween.update:
                            if sVal not in updates:
                                updates[sVal] = list()
                            if eVal not in updates:
                                updates[eVal] = list()
                            updates[sVal].append(left)
                            updates[eVal].append(right)

                    # Add classes to memory
                    fcurves[fc] = [left, current, right]

                    if attr == 'rotation_quaternion':
                        # Do math for quaternions
                        if (action, path) not in quats:
                            quats[(action, path)] = dict()

                        if (src.lock_rotations_4d or not src.lock_rotation_w) \
                            and True not in src.lock_rotation[:]:
                            quats[(action, path)][index] = (left, current, right)

        if updates:
            for frame in updates:
                context.scene.frame_set(frame)

                for (cls) in updates[frame]:
                    if Is.iterable(prop):
                        cls.value = cls.prop[cls.index]
                    else:
                        cls.value = getattr(cls.prop, cls.attr)

            context.scene.frame_set(scn_frame)

        for (action, path) in quats:
            if len(quats[action, path]) < 4:
                continue
            (w_left, w_current, w_right) = quats[action, path][0]
            (x_left, x_current, x_right) = quats[action, path][1]
            (y_left, y_current, y_right) = quats[action, path][2]
            (z_left, z_current, z_right) = quats[action, path][3]

            left_quat = [x.value for x in (w_left, x_left, y_left, z_left)]
            current_quat = [x.value for x in (w_current, x_current, y_current, z_current)]
            right_quat = [x.value for x in (w_right, x_right, y_right, z_right)]

            cpp.normalize_qt(left_quat)
            cpp.normalize_qt(current_quat)
            cpp.normalize_qt(right_quat)

            for x in (w_left, x_left, y_left, z_left):
                x.quat = left_quat
            for x in (w_current, x_current, y_current, z_current):
                x.quat = current_quat
            for x in (w_right, x_right, y_right, z_right):
                x.quat = right_quat

        return fcurves
Example #10
0
File: Set.py Project: Irmitya/zpy
def visible(context, object, value=True, **kargs):
    """
    Set an object's (or bone's object's) visibility to the specified value
    """

    scn = context.scene

    if not Is.object(object):
        if isinstance(object, bpy.types.Collection):
            found = False

            def loop(root, tree=list()):
                nonlocal found

                if root.collection == object:
                    return True

                for child in root.children:
                    if loop(child, tree):
                        found = True
                        tree.append(child)
                        break

                if found:
                    return tree

            view_layer = kargs.get('view_layer', False)

            if not view_layer:
                object.hide_viewport = not value
            if value or view_layer:
                # Only enables the collection for the view layer once
                tree = loop(context.view_layer.layer_collection)
                for col in tree:
                    if (col.exclude == value) and (col.name == object.name):
                        # When a collection is enabled in the view layer,
                        # all of its child collections are as well.
                        col.exclude = not value
                    if value and col.collection.hide_viewport:
                        col.collection.hide_viewport = False
        elif Is.posebone(object):
            return Set.visible(context, object.id_data, value)
        elif Is.bone(object) or Is.editbone(object):
            return Set.visible(context, Get.rig(context, object), value)
        else:
            assert None, (
                "Set.visible() does not work with the specified item",
                object,
            )
        return

    Set.in_scene(context, object)

    is_visible = Is.visible(context, object)
    object_visible = not object.hide_viewport

    # if Is.visible(context, object) is value:
    # return visible

    while (Is.visible(context, object) is not value):
        "If object isn't in the desired visiblity, loop until it is"

        if (object.hide_viewport is value):
            object.hide_viewport = not value
            continue

        is_visible = object_visible
        view = None

        for collection in object.users_collection:
            view = context.view_layer.layer_collection.children.get(
                collection.name)
            if not view:
                # collection isn't in scene or whatever
                continue
            if view.hide_viewport is value:
                view.hide_viewport = not value
            break

        if view is None:
            assert None, (
                "Set.visible(): Object[", object,
                "] \nis hidden from viewport and I don't know how to change it"
            )
            # collection.hide_viewport = value

        break

    return is_visible
Example #11
0
File: Set.py Project: Irmitya/zpy
def mode(context, mode, target=None, keep_visiblity=True):
    """
    Set the context.mode for an object (or bone's rig)
    """
    if not target:
        bpy.ops.object.mode_set(mode=mode)
        return context.mode == mode

    target = target.id_data
    # I can't think of a situation where I care to use
    # a bone/etc instead of the object

    # objects = context.selected_objects
    # for obj in objects:
    # select(obj, False)

    if Is.linked(target) and mode not in ('OBJECT', 'POSE'):
        return False

    class active_item:
        mode = target.mode
        is_visible = Set.visible(context, target, True)

    if mode != target.mode:
        modes = dict()
        selected = list()
        objects = list()

        # Find the visible objects of the same type as the target object
        # Remember their modes and selection, then deselect them
        for obj in Get.in_view(context):
            if obj == target or obj.type != target.type or not Is.visible(
                    context, obj):
                continue
            if obj.mode not in modes:
                modes[obj.mode] = list()
            modes[obj.mode].append(obj)

            if Is.selected(obj):
                selected.append(obj)
            Set.select(obj, False)
            objects.append(obj)

        # Remember the target's selected status
        pselect = Is.selected(target)

        # Set the mode for the target object
        previous = Set.active(context, target)
        Set.select(target, False)
        bpy.ops.object.mode_set(mode=mode)

        # Since the operator switches all objects to the specified mode
        # Go through the objects and manually set them back their previous mode
        for pmode in modes:
            for obj in modes[pmode]:
                Set.select(obj, True)
            Set.active(context, obj)
            bpy.ops.object.mode_set(mode=pmode)
            Set.active(context, None)
            for obj in modes[pmode]:
                Set.select(obj, False)

        # Re-select previously selected objects
        for obj in selected:
            Set.select(obj, True)

        # reselect target if it was selected
        Set.select(target, pselect)

        # Set the active object back to the original
        if previous is not None:
            Set.active(context, previous)
        else:
            Set.active(context, target)

    if (keep_visiblity):
        Set.visible(context, target, active_item.is_visible)

    # for obj in objects:
    # select(obj, True)

    return (target.mode == mode)
Example #12
0
    def execute(self, context):
        if (self.type == 'IN_OBJECT'):
            rigs = set()
            for b in context.selected_pose_bones:
                rigs.add(b.id_data)
            for rig in rigs:
                for b in rig.data.bones:
                    if Is.visible(context, b) and (not b.hide_select):
                        Set.select(b, True)
                    elif not self.extend:
                        Set.select(b, False)
            return {'FINISHED'}
        elif (self.type == 'PSEUDO_LAYERS'):
            rigs = dict()
            for b in context.selected_pose_bones:
                rig = b.id_data
                if rig not in rigs:
                    rigs[rig] = list()
                try:
                    selected_layers = eval(b.layers_extra)
                    rigs[rig].extend(selected_layers)
                    rigs[rig] = list(set(rigs[rig]))
                except:
                    pass
            for (rig, selected_layers) in rigs.items():
                visible_layers = [
                    i for i, l in enumerate(rig.data.layers_extra.layers)
                    if l.visible
                ]
                for b in rig.pose.bones:
                    try:
                        bone_layers = eval(b.layers_extra)
                    except:
                        continue

                    if Is.visible(context, b):
                        for b_layer in bone_layers:
                            if (b_layer in selected_layers) and (
                                    b_layer in visible_layers):
                                Set.select(b, True)
                                break
                        else:
                            if not self.extend:
                                Set.select(b, False)
                    elif not self.extend:
                        Set.select(b, False)
            return {'FINISHED'}

        if self.type == 'GROUP':
            active_group = set()
            for b in context.selected_pose_bones:
                rig = b.id_data
                if (rig not in active_group) and b.bone_group:
                    rig.pose.bone_groups.active = b.bone_group
                    active_group.add(rig)

        try:
            return bpy.ops.pose.select_grouped(type=self.type,
                                               extend=self.extend)
        except RuntimeError as ex:
            self.report({'ERROR'}, str(ex).split('Error: ', 1)[-1])
            return {'CANCELLED'}
Example #13
0
    def convert(self, context, obj):
        scn = context.scene
        Set.active_select(context, obj, isolate=True)

        coll_instanced = False  # Whether or not to instance collection in full macro

        head = self.head
        group = obj.name + '-Mannequin'

        coll = bpy.data.collections.get(group)
        if coll:
            # Regenerating mannequin
            coll_instanced = True

            for ob in coll.objects.values():
                if Is.mesh(ob) and ob.DazMannequin:
                    bpy.data.objects.remove(ob)
        else:
            coll = bpy.data.collections.new(group)
            scn.collection.children.link(coll)

        # "temporarily" unhide collection if hidden
        in_view = Is.in_view(context, coll)
        if not in_view:
            Set.visible(context, coll, view_layer=True)
        visible = Is.visible(context, coll)
        if not visible:
            Set.visible(context, coll)

        # Add mannequin objects for current mesh
        self.generate(context, obj, obj.parent, coll)

        if self.macro:
            has_mann = False
            for ob in coll.objects.values():
                if Is.mesh(ob):
                    Set.select(ob)
                    has_mann = True

            if has_mann:
                bpy.ops.object.data_transfer_mannequin_preset()
                # if obj.data.materials:
                # bpy.ops.object.data_transfer_materials()

            # Hide the collection and create an instancer of it
            # if coll:
            # # Set.visible(context, obj, value=False)
            # Set.visible(context, coll, value=False, view_layer=True)
            # if not coll_instanced:
            # inst = New.object(context, name=coll.name)
            # inst.instance_type = 'COLLECTION'
            # inst.instance_collection = coll
            # Set.empty_size(inst, 0)
            # return inst

            for ob in coll.objects.values():
                Set.select(ob, value=False)

        if not visible:
            Set.visible(context, coll, False)
        if not in_view:
            Set.visible(context, coll, False, view_layer=True)

        return obj
Example #14
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'}