示例#1
0
def get_obj_from_path(path, obj=None):
    if path.startswith('bpy.data.'):
        obj2 = eval(path.split('"]', 1)[0] + '"]')
        if Is.object(obj2):
            obj = obj2

    return obj
示例#2
0
def keyingset(context, default=True, **kargs):
    """
    Use bpy.ops to insert keyframe.
    default means to only use the keying set if the keying set button is enabled
    """

    insert_key = kargs.get('insert_key')
    if not keyframe.poll_insert(context, insert_key):
        return

    ks = context.scene.keying_sets_all.active
    if (default and not keyframe.use_keyingset(context)) or \
            ks is None:
        ks = 'LocRotScale'
    else:
        ks = ks.bl_idname

    bones = kargs.get('bones', list())
    objects = kargs.get('objects', list())
    selected = kargs.get('selected', list())

    # if bones is None: bones = Get.selected_pose_bones(context)
    # if objects is None: objects = Get.selected_objects(context)

    for src in selected:
        if Is.posebone(src):
            bones.append(src)
        elif Is.object(src):
            objects.append(src)
        else:
            assert None, ("This is not a bone or object", src)

    if kargs.get('skip_bones', False):
        # This step removes bones from badBonePrefixes
        for src in bones.copy():
            if not keyframe.poll_insert(context, insert_key, src=src):
                bones.remove(src)

    # if keyframe.use_keyingset():
    # bpy.ops.anim.keyframe_insert(type=ks, confirm_success=False)
    # # else:
    # for src in KSI.iter():
    # keyframe.all(src)

    if (bones or objects):
        try:
            return bpy.ops.anim.keyframe_insert(dict(selected_pose_bones=bones,
                                                     selected_objects=objects),
                                                type=ks,
                                                confirm_success=False)
        except Exception as ex:
            pass
    else:
        "Nothing to keyframe"
示例#3
0
文件: Get.py 项目: Irmitya/zpy
def icon_from_type(src):
    "return an Icon id for the specified item's type"

    if Is.object(src):
        if src.type == 'LIGHT_PROBE':
            icon = 'LIGHTPROBE_' + src.data.type
        else:
            icon = src.type + '_DATA'
    elif Is.bone(src) or Is.editbone(src) or Is.posebone(src):
        icon = 'BONE_DATA'
    else:
        icon = 'ERROR'
        utils.debug("Can't find icon type for ", src, type(src))

    return icon
示例#4
0
文件: Set.py 项目: Irmitya/zpy
def select(target, value=True):
    """Select or Deselect an item"""

    if Is.object(target):
        target.select_set(value)
    elif Is.posebone(target):
        target.bone.select = value
    elif Is.bone(target) or Is.editbone(target):
        target.select = value
    elif target is None:
        pass
    else:
        # Give error
        assert None, (
            "Error: zpy\\Set.select() can't use the provided target \n",
            target,
        )
示例#5
0
文件: Set.py 项目: Irmitya/zpy
def active(context, target):
    """Set target as active scene object or bone"""

    objects = Get.objects(context)

    # Remember previous active
    previous = Get.active(context)
    selected = Is.selected(target)

    # Set the active
    if Is.object(target):
        obj = target
    elif Is.posebone(target):
        obj = target.id_data
        obj.data.bones.active = obj.data.bones.get(target.name)
    elif isinstance(target, bpy.types.Armature):
        obj = Get.rig(context, target)
    elif Is.bone(target):
        obj = Get.rig(context, target)
        bones = target.id_data.bones
        bones.active = bones.get(target.name)
    elif Is.editbone(target):
        obj = Get.rig(context, target)

        if obj: in_edit = (obj.mode == 'EDIT')
        else: in_edit = (context.mode == 'EDIT_ARMATURE')

        if in_edit:
            bones = target.id_data.edit_bones
            bones.active = bones.get(target.name)
    elif target is None:
        obj = None
        # debug("Set.active() has None as the target")
    else:
        assert None, ("Set.active() can't use the provided target", target)

    if (target and Is.selected(target) != selected):
        # When setting a bone as active in a rig, it gets selected as well.
        Set.select(target, selected)
    objects.active = obj

    return previous
示例#6
0
文件: Get.py 项目: Irmitya/zpy
def action_fcurves(src, actions=None, raw_action=True):
    "Find actions used by a bone/object and return it's action + fcurves"

    fcurves = list()

    if actions is None:
        rig = src.id_data
        strips = Get.strips(rig, selected=False)
        anim = rig.animation_data
        an_act = getattr(anim, 'action', None) if raw_action else None
        actions = {an_act, *(s.action for s in strips)}

    for action in actions:
        if not action:
            continue
        for fc in action.fcurves:
            if any((
                    Is.object(src),
                    Is.posebone(src)
                    and fc.data_path.find(f'bones[\"{src.name}\"]') != -1,
            )):
                fcurves.append((action, fc))

    return fcurves
示例#7
0
文件: Set.py 项目: Irmitya/zpy
def matrix(src, matrix, local=False, basis=False):
    """
    Set the visual transforms for a bone or object
    The parameters vary, so the input matrix should too:
        editbone.     matrix
        bone.         matrix, matrix_local
        posebone.     matrix, matrix_basis, matrix_channel
        object.       matrix_world, matrix_basis, matrix_local, matrix_parent_inverse
    """

    if Is.object(src):
        if basis:
            src.matrix_basis = matrix
        elif local:
            src.matrix_local = matrix
        else:
            src.matrix_world = matrix
    else:
        if basis or local:
            if Is.posebone(src): src.matrix_basis = matrix
            elif Is.bone(src): src.matrix_local = matrix
            else: src.matrix = matrix
        else:
            src.matrix = matrix
示例#8
0
文件: New.py 项目: Irmitya/zpy
def driver(src, path, **kargs):
    driver_type = kargs.get('driver_type', None)
    # 'AVERAGE', 'Sum Values', 'SCRIPTED', 'Minimum Value', 'Maximum Value
    expression = kargs.get('expression', None)
    frames = kargs.get('frames', list())  # keyframe.co for the driver's fcurve
    name = kargs.get('name', "var")  # Name of the variable added to the driver
    overwrite = kargs.get('overwrite', False)  # Delete the existing driver
    rotation_mode = kargs.get('rotation_mode', 'AUTO')
    target = kargs.get('target', None)
    target_path = kargs.get('target_path', '')
    transform_space = kargs.get('transform_space', 'LOCAL_SPACE')
    transform_type = kargs.get('transform_type', 'LOC_X')
    var_type = kargs.get('var_type', None)
    # 'SINGLE_PROP', 'TRANSFORMS', 'Rotational Difference', 'Distance'
    if var_type is None:
        if target and (not target_path):
            var_type = 'TRANSFORMS'
        else:
            var_type = 'SINGLE_PROP'

    Driver = Get.driver(src, path)

    if not Driver:
        Driver = src.driver_add(path)
        overwrite = True

    if overwrite:
        while Driver.keyframe_points:
            Driver.keyframe_points.remove(Driver.keyframe_points[0])

    if frames:
        if overwrite:
            Driver.extrapolation = 'LINEAR'
            while Driver.modifiers:
                Driver.modifiers.remove(Driver.modifiers[0])
        Driver.keyframe_points.add(len(frames))
        for key, co in zip(Driver.keyframe_points[:], frames):
            key.interpolation = 'LINEAR'
            key.co = co

    driver = Driver.driver

    if overwrite:
        if (expression is None):
            if (driver_type is None):
                driver_type = 'AVERAGE'
            elif (driver.type == 'SCRIPTED'):
                driver.expression = name

        while driver.variables:
            driver.variables.remove(driver.variables[0])

    if expression is not None:
        driver.expression = expression
    if driver_type:
        driver.type = driver_type

    var = driver.variables.new()
    var.name = name
    var.type = var_type
    var_target = var.targets[0]

    if target:
        is_pose = Is.posebone(target)
        is_bone = Is.bone(target) or Is.editbone(target)
        is_obj = Is.object(target)

        if is_obj:
            var_target.id = target
        elif (is_pose or is_bone):
            var_target.id = target.id_data
            var_target.bone_target = target.name
            if target_path and (not target_path.startswith(
                ('pose.bones', 'bones'))):
                if is_pose:
                    text = f'pose.bones["{target.name}"]'
                else:
                    text = f'bones["{target.name}"]'

                if (target_path[0] != '['):
                    text += '.'

                target_path = text + target_path
        else:
            try:
                var_target.id = target
            except:
                var_target.id = target.id_data

    var_target.data_path = target_path
    var_target.rotation_mode = rotation_mode
    var_target.transform_space = transform_space
    var_target.transform_type = transform_type

    return Driver
示例#9
0
文件: Set.py 项目: 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
示例#10
0
def group_name(src):
    if Is.object(src):
        return "Object Transforms"
    else:
        return src.name
示例#11
0
def manual(context, src, path, **kargs):
    "Insert a keyframe manually. Sub is for sub targets, like constraints"
    # kargs:
    # sub=None, index=-1, frame=None, value=None,
    # group=None, insert_key=None, action=None, context=None

    insert_key = kargs.get('insert_key', None)
    sub = kargs.get('sub', None)
    index = kargs.get('index', -1)
    frame = kargs.get('frame', None)
    value = kargs.get('value', None)
    group = kargs.get('group', None)
    action = kargs.get('action', None)
    results = kargs.get('results', list())
    options = kargs.get('options', set())
    delete = kargs.get('delete', False)

    keyframe_type = kargs.get('type',
                              context.scene.tool_settings.keyframe_type)

    if not keyframe.poll_insert(context, insert_key, src=src):
        return results

    # if frame is None:
    #     frame = context.scene.frame_current
    # if group is None:
    #     group = keyframe.group_name(src)
    # src.keyframe_insert(path, index=index, frame=frame, group=group)
    # return

    if group is None:
        group = keyframe.group_name(src)

    obj = src.id_data
    anim = obj.animation_data_create()
    if action is None:
        key_in_action = True
        action = anim.action
        if action is None:
            action = anim.action = bpy.data.actions.new("Action")
    else:
        # When using a specified action, don't insert
        # keyframes later to determine the property's value
        key_in_action = False

    if frame is None:
        frame = context.scene.frame_current_final

    strip = Get.active_strip(anim) if anim.use_tweak_mode else None

    if strip:
        if not (strip.frame_start <= frame <= strip.frame_end):
            # frame outside of the strip's bounds
            key_in_action = False

        tweak_frame = Get.frame_to_strip(context, anim, frame=frame)
    else:
        tweak_frame = frame

    if Is.posebone(src) and not path.startswith('pose.bones'):
        keypath = utils.string('pose.bones[\"', src.name, '\"]',
                               '' if path.startswith('[') else '.', path)
    elif not Is.object(src) and hasattr(src, 'path_from_id'):
        keypath = src.path_from_id(path)
    else:
        keypath = path

    # Find the value(s) to insert keyframes for
    if hasattr(sub, path):
        base = getattr(sub, path)
    elif hasattr(src, path):
        base = getattr(src, path)
    else:
        base = eval(f'{obj!r}.{keypath}')

    if value is None:
        prop = base
    else:
        if Is.iterable(base) and not Is.iterable(value):
            prop = [value for i in base]
        elif not Is.iterable(base) and Is.iterable(value):
            prop = value[(index, 0)[index == -1]]
        else:
            prop = value

    if (not Is.iterable(prop)):
        if index != -1:
            index = -1
        if (not Is.iterable(prop)):
            props = [(index, prop)]
        else:
            props = [(index, prop[index])]
    elif (index == -1):
        props = list(enumerate(prop))
    else:
        props = [(index, prop[index])]

    def save_quats():
        quats = [0, 0, 0, 0]
        for index in range(4):
            fc = Get.fcurve(action, keypath, index=index)
            if fc:
                quats[index] = len(fc.keyframe_points)
        return quats

    def restore_quats(skip):
        nonlocal quats
        for index in range(4):
            if index == skip:
                continue
            fc = Get.fcurve(action, keypath, index=index)
            if fc and len(fc.keyframe_points) > quats[index]:
                for key in fc.keyframe_points:
                    if key.co.x == tweak_frame:
                        fc.keyframe_points.remove(key)
                        break
                else:
                    # Shouldn't happen but backup in case fail to find key
                    key_args = dict(index=index, frame=frame, group=group)
                    if sub is None:
                        src.keyframe_delete(path, **key_args)
                    else:
                        sub.keyframe_delete(path, **key_args)

    if path.endswith('rotation_quaternion') and (
        (strip and strip.blend_type == 'COMBINE') or
        (not strip and anim.action_blend_type == 'COMBINE')):
        # Combine forces keyframe insertion on all 4 channels, so reset them
        quats = save_quats()
    else:
        quats = None

    # Create curve(s) (if needed) and keyframe(s)
    for (i, v) in props:
        fc = Get.fcurve(action, keypath, i)
        new_fc = not bool(fc)
        if new_fc:
            fc = New.fcurve(action, keypath, index=i, group=group)

        if fc.lock:
            # Internal ops don't allow keyframing locked channels, so :p
            results.append((fc, None))
            continue

        if delete:
            results.append((fc, src.keyframe_delete(path, frame=frame)))
            continue

        count = len(fc.keyframe_points)

        if (value is None) and key_in_action:
            key_args = dict(index=i, frame=frame, group=group, options=options)
            if sub is None:
                src.keyframe_insert(path, **key_args)
            else:
                sub.keyframe_insert(path, **key_args)
            v = fc.evaluate(tweak_frame)

        key = fc.keyframe_points.insert(tweak_frame, v, options={'FAST'})
        # options=set({'REPLACE', 'NEEDED', 'FAST'})
        # src.keyframe_insert(path, index=i, frame=frame, group=group)

        if quats:
            restore_quats(skip=i)
            quats[i] = len(fc.keyframe_points)
            # Update key count for current index, to not remove it later

        # Update keyframe to use default preferences values

        edit = utils.prefs().edit

        key.handle_left_type = key.handle_right_type = \
            edit.keyframe_new_handle_type
        if new_fc:
            # When inserting keyframes, only change their interpolation type if the fcurve is new
            key.interpolation = edit.keyframe_new_interpolation_type

        if len(fc.keyframe_points) > count:
            # New keyframe was added
            key.type = keyframe_type

        results.append((fc, key))

    if kargs.get('index', -1) == -1:
        return results
    else:
        return results[0]