Example #1
0
File: utils.py Project: Irmitya/zpy
def lerp(current, target, factor=1.0, falloff=False):
    """
    Blend between two values\\
    current <to> target
    """

    if falloff:
        factor = utils.proportional(factor, mode=falloff)

    def blend(current, target):
        if (Is.digit(current) and Is.digit(target)) and not \
                (Is.string(current) or Is.string(target)):
            return (current * (1.0 - factor) + target * factor)
        elif (factor):
            return target
        else:
            return current

    if (Is.matrix(current) and Is.matrix(target)):
        return current.lerp(target, factor)
    elif (Is.iterable(current) and Is.iterable(target)) and not \
            (Is.string(current) or Is.string(target)):
        # Assume the items are tuple/list/set. Not dict (but dicts can merge)
        merge = list()
        for (s, o) in zip(current, target):
            merge.append(blend(s, o))
        return merge
    else:
        return blend(current, target)
Example #2
0
File: utils.py Project: Irmitya/zpy
 def blend(current, target):
     if (Is.digit(current) and Is.digit(target)) and not \
             (Is.string(current) or Is.string(target)):
         return (current * (1.0 - factor) + target * factor)
     elif (factor):
         return target
     else:
         return current
Example #3
0
File: Get.py Project: Irmitya/zpy
def valid_op(*ops):
    """Validate whether or not an operator is in bpy.ops;
        if True, return operator"""

    valid = list()

    for op in ops:
        if not Is.string(op):
            if hasattr(op, 'bl_idname'):
                op = op.bl_idname
            else:
                continue

        try:
            exec(f'bpy.ops.{op}.get_rna_type()')
            valid.append(op)
        except:
            continue

    if len(ops) > 1:
        return valid
    elif valid:
        return valid[0]
    else:
        return None
Example #4
0
File: utils.py Project: Irmitya/zpy
def proportional(dist,
                 mode: "string or context" = None,
                 rng: "Random Seed" = None):
    """Convert a number (from 0-1) to its proportional equivalent"""
    from math import sqrt
    from random import random

    if not (0 <= dist <= 1):
        return dist

    if not Is.string(mode) and mode is not None:
        mode = mode.scene.tool_settings.proportional_edit_falloff

    if mode == 'SHARP':
        return dist * dist
    elif mode == 'SMOOTH':
        return 3.0 * dist * dist - 2.0 * dist * dist * dist
    elif mode == 'ROOT':
        return sqrt(dist)
    elif mode == 'LINEAR':
        return dist
    elif mode == 'CONSTANT':
        return 1.0
    elif mode == 'SPHERE':
        return sqrt(2 * dist - dist * dist)
    elif mode == 'RANDOM':
        if (rng is None):
            rng = random()
        return rng * dist
    elif mode == 'INVERSE_SQUARE':
        return dist * (2.0 - dist)
    else:
        # default equivalent to constant
        return 1
Example #5
0
File: New.py Project: Irmitya/zpy
def bone_group(rig, name='Group', color=None):
    ""

    if Is.posebone(rig):
        rig = rig.id_data
    group = rig.pose.bone_groups.new(name=name)

    if Is.string(color):
        group.color_set = color
        # DEFAULT = regular bone color (not unique)
        # THEME01 - THEME15 = Builtin color palettes
        # THEME16 - THEME20 = Black for user assigned templates
        # CUSTOM = manually set
    elif color is False:
        group.color_set = 'DEFAULT'
    elif color is True:
        from random import randrange as random
        rand = f"{random(1, 15):02}"
        group.color_set = f'THEME{rand}'
    elif color:
        group.color_set = 'CUSTOM'
        gc = group.colors
        if not Is.iterable(color):
            if Is.digit(color):
                color = [[color] * 3] * 3
            else:
                color = [color] * 3
        (gc.normal, gc.select, gc.active) = color

    return group
Example #6
0
File: Get.py Project: Irmitya/zpy
def macro(*ops, poll=None, **kargs):
    """Get an operator to run a sequence of operators in succession
        if they aren't cancelled"""

    idname = kargs.get('idname', '_macro_._macro_start_')

    # For defaults, insert ops as operator or bl_idname
    # For operators with props:
    # ops = (bl_idname, dict(prop=var, ))

    class MACRO(bpy.types.Macro):
        bl_idname = idname
        bl_label = "Start Macro"
        bl_options = {'MACRO'}

        @classmethod
        def poll(self, context):
            if poll:
                return poll(self, context)
            return True

    bpy.utils.register_class(MACRO)
    # bpy.macro = MACRO

    for op in ops:
        if Is.iterable(op) and not Is.string(op):
            (op, props) = (op[0], dict(*op[1:]))
        else:
            props = dict()

        if hasattr(op, 'bl_idname'):
            op = op.bl_idname

        if Is.string(op):
            if op.startswith('bpy.ops.'):
                op = eval(op)
            else:
                op = eval('bpy.ops.' + op)
        operator = MACRO.define(op.idname())
        for prop in props:
            setattr(operator.properties, prop, props[prop])

    return eval('bpy.ops.' + idname)
Example #7
0
def poll_insert(context, insert_key=None, src=None):
    if (src is not None):
        if Is.string(src):
            name = src
        else:
            name = getattr(src, 'name', '')
        if name.startswith(keyframe.badBonePrefixes):
            return False
    if insert_key is None:
        return keyframe.use_auto(context)

    return insert_key
Example #8
0
File: Set.py Project: Irmitya/zpy
def bone_group(bone, group, color=None):
    """
    Assign bone to group\\
    if group is text, find the group or create it first
    """

    if Is.string(group):
        bgs = bone.id_data.pose.bone_groups
        if group in bgs:
            group = bgs[group]
        else:
            from zpy import New
            group = New.bone_group(bone, name=group)

    if Is.string(color):
        group.color_set = color
        # DEFAULT = regular bone color (not unique)
        # THEME01 - THEME15 = Builtin color palettes
        # THEME16 - THEME20 = Black for user assigned templates
        # CUSTOM = manually set
    elif color is False:
        group.color_set = 'DEFAULT'
    elif color is True:
        from random import randrange as random
        rand = f"{random(1, 15):02}"
        group.color_set = f'THEME{rand}'
    elif color:
        group.color_set = 'CUSTOM'
        gc = group.colors
        if not Is.iterable(color):
            if Is.digit(color):
                color = [[color] * 3] * 3
            else:
                color = [color] * 3
        (gc.normal, gc.select, gc.active) = color

    bone.bone_group = group

    return group
Example #9
0
File: Get.py Project: Irmitya/zpy
def object_bone_from_string(target: "String or Object", subtarget=''):
    """Try to find an object an bone from text"""

    if Is.string(target):
        obj = bpy.data.objects.get(target)
    else:
        obj = target

    bone = None

    if Is.armature(obj) and subtarget:
        if (obj.mode == 'EDIT'):
            bones = obj.data.edit_bones
        else:
            bones = obj.pose.bones
        bone = bones.get(subtarget)

    return (obj, bone)
Example #10
0
File: New.py Project: Irmitya/zpy
def strip(anim,
          action,
          name=True,
          blend_type=None,
          extrapolation=None,
          track=None):
    """Create new strip using specifed action"""

    # Get strip blend and extend modes
    if blend_type is None:
        blend_type = anim.action_blend_type
    if extrapolation is None:
        extrapolation = anim.action_extrapolation

    # Get new strip's name
    if not Is.string(name):
        blend = Get.nla_blend_name(anim)

        if name is True:
            name = f"{blend}: {action.name}"
        elif name is None:
            name = f"{blend}: Action"  # Don't use unique names
        else:
            name = action.name

    # Find or create track to place new strip
    (astart, aend) = (action.frame_range)
    if track:
        pass
    elif anim.nla_tracks:
        active_track = anim.nla_tracks[-1]
        for strip in active_track.strips:
            if active_track.lock:
                track = anim.nla_tracks.new()
                break
            sstart = strip.frame_start
            send = strip.frame_end
            if (send <= astart) or (aend <= sstart):
                # Strip does not conflict with action
                continue
            if any((
                (sstart <= astart <= send),
                (sstart <= aend <= send),
                (astart <= sstart <= aend),
                (astart <= send <= aend),
            )):
                # The strip is in the range of the action
                track = anim.nla_tracks.new()
                break
        else:
            track = active_track
    else:
        track = anim.nla_tracks.new()

    # Create and name new strip
    strip = track.strips.new("", astart, action)
    strip.name = name
    strip.blend_type = blend_type
    strip.extrapolation = extrapolation

    return strip