Esempio n. 1
0
 def set_bone_groups():
     if do_mch:
         bg = Get.bone_group(rig, "BBone FK")
         if not bg:
             bg = New.bone_group(rig, "BBone FK", True)
         bone_mch.bone_group = bg
     if do_start_end:
         bg = Get.bone_group(rig, "BBone Stretch")
         if not bg:
             bg = New.bone_group(rig, "BBone Stretch", True)
         bone_start.bone_group = bone_end.bone_group = bg
         for name in self.center_bones[rig]:
             rig.pose.bones[name].bone_group = bg
     if do_in_out:
         bg = Get.bone_group(rig, "BBone Curve")
         if not bg:
             bg = New.bone_group(rig, "BBone Curve", True)
         bone_in.bone_group = bone_out.bone_group = bg
     if self.hide_bones.get(rig):
         bg = Get.bone_group(rig, "BBone Stretch [Hidden]")
         if not bg:
             bg = New.bone_group(rig, "BBone Stretch [Hidden]",
                                 'THEME20')
         for name in self.hide_bones[rig]:
             rig.pose.bones[name].bone_group = bg
Esempio n. 2
0
 class stretch:
     head = New.bone(context,
                     rig,
                     name="IK-Stretch-" + fk.head.name)
     tail = New.bone(context,
                     rig,
                     name="IK-Stretch-" + fk.tail.name)
     bone = New.bone(context,
                     rig,
                     name="IK-Stretch-" + fk.bone.name)
Esempio n. 3
0
 def add_driver(pbone, path, transform_type, name="var", **kargs):
     return New.driver(bone,
                       path,
                       target=pbone,
                       transform_type=transform_type,
                       name=name,
                       **kargs)
Esempio n. 4
0
    def execute(self, context):
        # active = Get.active(context)
        mode = context.mode
        # pose = list()

        for rig in context.selected_objects:
            if (not Is.armature(rig)) or (rig.data.get('rig_id') is None):
                continue

            meta = New.object(context, name="metarig", data=rig.data.copy())
            meta.data.animation_data_clear()
            metafy_rigify(context, meta)
            # pose.append(meta, rig)
        else:
            if context.mode != mode:
                bpy.ops.object.mode_set(mode=mode)
            # if mode == 'POSE':
            #     Set.mode(context, 'OBJECT')
            # for (meta, rig) in pose:
            #     Set.select(rig, True)
            #     Set.select(meta, False)
            #     if meta == active:
            #         Set.active(context, rig)
            # if mode == 'POSE':
            #     Set.mode(context, 'POSE')

        return {'FINISHED'}
Esempio n. 5
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'}
Esempio n. 6
0
File: New.py Progetto: Irmitya/zpy
def empty(context, name="Empty", type='PLAIN_AXES', size=1.0, link=True):
    "Create a new empty object"

    empty = New.object(context, name, None, link)
    Set.empty_type(empty, type)
    Set.empty_size(empty, size)

    return empty
Esempio n. 7
0
File: New.py Progetto: Irmitya/zpy
def camera(context, name="Camera", size=1.0, link=True):
    "Create a new camera object"

    data = bpy.data.cameras.new(name)
    obj = New.object(context, name=name, data=data, link=link)
    data.display_size = size

    return obj
Esempio n. 8
0
File: New.py Progetto: Irmitya/zpy
def armature(context, name="Armature", display_type=None, link=True):
    "Create and return a rig object"

    data = bpy.data.armatures.new(name)
    # armature.show_in_front = True

    if display_type is not None:
        Set.armature_display_type(data, display_type)

    return New.object(context, name, data, link)
Esempio n. 9
0
    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'}
Esempio n. 10
0
File: New.py Progetto: Irmitya/zpy
def curve(context, name="Spline IK", link=True):
    "Create a curve object"

    # Create curve
    data = bpy.data.curves.new(name, 'CURVE')

    # Setup curve's display settings
    data.dimensions = '3D'
    data.fill_mode = 'FULL'
    data.bevel_depth = 0.01

    curve = New.object(context, name, data, link)

    if hasattr(curve, 'display_type'):  # 2.8
        curve.display_type = 'WIRE'
    elif hasattr(curve, 'draw_type'):  # 2.7
        curve.draw_type = 'WIRE'

    return curve
Esempio n. 11
0
File: Set.py Progetto: 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
    def execute(self, context):
        an = context.space.grease_pencil
        # context.space.grease_pencil =

        ob = New.object(context, name=an.name, data=an)
        ob.location.z = 0.5
        ob.rotation_mode = 'XYZ'
        ob.rotation_euler.x = 1.5707963705062866  # Face front
        ob.scale = (0.001, ) * 3
        an.stroke_thickness_space = 'SCREENSPACE'

        # Send the color from annotations to the grease pencil object
        for layer in an.layers:
            layer.tint_color = layer.channel_color
            layer.tint_factor = 1
        """
        In addition to not "currently" knowing where individual stroke colors are
        Setting them will take longer and override any manual colors I may use.
        Setting the tint color (which annotations can only used) is faster and easier
        """

        return {'FINISHED'}
Esempio n. 13
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]
Esempio n. 14
0
File: New.py Progetto: Irmitya/zpy
def mesh(context, name='Mesh', type='PLANE', link=True, **kargs):
    "Create a box-mesh object"

    import bmesh
    from mathutils import Matrix
    # from bpy_extras.object_utils import AddObjectHelper

    width = kargs.get('width', 1.0)
    height = kargs.get('height', 1.0)
    depth = kargs.get('depth', 1.0)
    loc = kargs.get('loc', None)
    rot = kargs.get('rot', None)

    def gen_mesh():
        """
        This function takes inputs and returns vertex and face arrays.
        no actual mesh data creation is done here.
        """

        if type == 'CUBE':
            left = -1.0
            right = +1.0
            top = +1.0
            bottom = -1.0
            front = -1.0
            back = +1.0

            verts = [
                (right, front, top),  # right-front-top
                (right, front, bottom),  # right-front-bottom
                (left, front, bottom),  # left-front-bottom
                (left, front, top),  # left-front-top
                (right, back, top),  # right-back-top
                (right, back, bottom),  # right-back-bottom
                (left, back, bottom),  # left-back-bottom
                (left, back, top),  # left-back-top
            ]

            faces = [
                (3, 2, 1, 0),
                (5, 6, 7, 4),
                (1, 5, 4, 0),
                (2, 6, 5, 1),
                (3, 7, 6, 2),
                (7, 3, 0, 4),

                # (3, 2, 1, 0),
                # # (4, 7, 6, 5),
                # # (0, 4, 5, 1),
                # # (1, 5, 6, 2),
                # # (2, 6, 7, 3),
                # # (4, 0, 3, 7),
            ]
        elif type == 'PLANE':
            left = -1.0
            right = +1.0
            top = +0.0
            bottom = -0.0
            front = -1.0
            back = +1.0

            # Plane

            verts = [
                (left, back, bottom),  # left-back-bottom
                (left, front, bottom),  # left-front-bottom
                (right, front, bottom),  # right-front-bottom
                (right, back, bottom),  # right-back-bottom
            ]

            faces = [
                (0, 1, 2, 3),  # top
            ]
        elif type == 'POINT':
            verts = [(0, 0, 0)]
            faces = []
        else:  # null mesh
            verts = []
            faces = []

        # apply size
        if loc:
            for (dist, axis) in zip(loc, (0, 1, 2)):
                for i, v in enumerate(verts):
                    verts[i] = list(verts[i])
                    verts[i][axis] += dist
        for i, v in enumerate(verts):
            verts[i] = v[0] * width, v[1] * depth, v[2] * height

        return (verts, faces)

    verts_loc, faces = gen_mesh()

    mesh = bpy.data.meshes.new(name)

    bm = bmesh.new()
    for v_co in verts_loc:
        bm.verts.new(v_co)

    # if loc:
    # bm.transform(Matrix().Translation(loc))
    if rot:
        from zpy import utils
        bm.transform(utils.rotate_matrix(Matrix(), rot))

    bm.verts.ensure_lookup_table()
    for f_idx in faces:
        bm.faces.new([bm.verts[i] for i in f_idx])

    bm.to_mesh(mesh)
    mesh.update()

    # # add the mesh as an object into the scene with this utility module
    # from bpy_extras import object_utils
    # object_utils.object_data_add(context, mesh, operator=self)

    return New.object(context, name, mesh, link)
Esempio n. 15
0
    def edit_func(self, context, bone):
        rig = Get.rig(context, bone.id_data)
        ebones = rig.data.edit_bones
        (do_mch, do_start_end, do_in_out) = self.do()

        def get_disconnected_parent(bone, first_loop=True):
            if ((bone is None) or (not bone.parent)):
                if first_loop:
                    return
                else:
                    return bone
            elif Is.connected(bone):
                # Keep going up the chain until it finds a disconnected bone
                return get_disconnected_parent(bone.parent, False)
            else:
                return bone.parent

        def reset(bone, edit_bone):
            attributes = [
                'head',
                'head_radius',
                'tail',
                'tail_radius',
                'roll',
                'matrix',
                'layers',
                'bbone_x',
                'bbone_z',
            ]

            for atr in attributes:
                if hasattr(bone, atr):
                    setattr(bone, atr, getattr(edit_bone, atr))

        def edit(ebone, bbone_xz=1.0):
            reset(ebone, bone)
            ebone.bbone_x *= bbone_xz
            ebone.bbone_z *= bbone_xz
            ebone.use_deform = False
            ebone.inherit_scale = 'NONE'
            ebone.hide = True

        def edit_mch(ebone):
            edit(ebone, 1.25)
            ebone.parent = bone.parent
            ebone.inherit_scale = bone.inherit_scale
            # ebone.use_connect = bone.use_connect
            # bone.use_connect = False
            # bone.parent = ebone
            # for cbone in bone.children:
            # cbone.parent = ebone

        def edit_start(ebone):
            edit(ebone, 2.5)
            if do_mch:
                ebone.parent = bone_mch
            else:
                if Is.connected(bone):
                    ebone.parent = ebones.get(
                        get_name(bone.parent, 'bbone_end'))
                if ebone.parent:
                    self.hide_bones[rig].append(ebone.name)
                    ebone.hide = True
                else:
                    ebone.parent = bone.parent
                if not do_in_out:
                    cbone = ebones.get(get_name(bone, 'bbone_in'))
                    if cbone:
                        cbone.parent = ebone
            for cbone in bone.children_recursive:
                if (bone.head != cbone.tail):
                    continue
                cbone_end = ebones.get(get_name(cbone, 'bbone_end'))
                if cbone_end:
                    cbone_end.parent = ebone
                    self.hide_bones[rig].append(cbone_end.name)
                    cbone_end.hide = True
            ebone.tail = utils.lerp(ebone.head, ebone.tail, 0.1)

        def edit_head(ebone):
            edit(ebone, 0.5)
            ebone.parent = bone_start
            ebone.tail = utils.lerp(ebone.head, ebone.tail, 0.1)
            ebone.translate(ebone.head - ebone.tail)
            bone.bbone_custom_handle_start = ebone
            self.hide_bones[rig].append(ebone.name)

        def edit_end(ebone):
            edit(ebone, 2.5)
            if do_mch:
                ebone.parent = bone_mch
            else:
                for tbone in bone.parent_recursive:
                    if (tbone.head != bone.tail):
                        continue
                    tobone_name = get_name(tbone, 'bbone_start')
                    tobone = ebones.get(tobone_name)
                    if tobone or ((tbone, rig) in self.selected):
                        self.hide_bones[rig].append(ebone.name)
                        ebone.hide = True
                        if tobone:
                            ebone.parent = tobone
                        else:
                            self.delayed_parenting.append(
                                ebones, ebone.name, tobone_name)
                    else:
                        ebone.parent = tbone
                    break
                else:
                    ebone.parent = get_disconnected_parent(bone)
                if not do_in_out:
                    cbone = ebones.get(get_name(bone, 'bbone_out'))
                    if cbone:
                        cbone.parent = ebone
            for cbone in bone.children:
                if Is.connected(cbone):
                    cbone_start = ebones.get(get_name(cbone, 'bbone_start'))
                    if cbone_start:
                        cbone_start.parent = ebone
                        self.hide_bones[rig].append(cbone_start.name)
                        cbone_start.hide = True
            ebone.head = utils.lerp(ebone.head, ebone.tail, 0.9)
            ebone.translate(ebone.tail - ebone.head)
            bone.bbone_custom_handle_end = ebone

        def edit_in(ebone):
            edit(ebone, 2.0)
            if do_start_end:
                ebone.parent = bone_start
            else:
                ebone.parent = ebones.get(get_name(bone, 'bbone_start'), bone)
            (head, tail) = (ebone.head.copy(), ebone.tail.copy())
            ebone.head = utils.lerp(head, tail, 0.1)
            ebone.tail = utils.lerp(head, tail, 0.2)

        def edit_out(ebone):
            edit(ebone, 2.0)
            if do_start_end:
                ebone.parent = bone_end
            else:
                ebone.parent = ebones.get(get_name(bone, 'bbone_end'), bone)
            (head, tail) = (ebone.head.copy(), ebone.tail.copy())
            ebone.tail = utils.lerp(head, tail, 0.8)
            ebone.head = utils.lerp(head, tail, 0.9)
            ebone.align_roll(-bone.z_axis)
            # This bone is reversed, so the the roll needs to be flipped

        if (do_in_out and (not (do_mch or do_start_end))
                and (bone.bbone_segments < 2)):
            # parenting to the bone will cause dependency loop, with drivers
            # if the bone isn't using bbones

            if not (ebones.get(get_name(bone, 'bbone_start'),
                               ebones.get(get_name(bone, 'bbone_end')))):
                if self.warning:
                    self.warning = (
                        f"{bone.name} does not have Bendy Bone Segments;"
                        " this will cause a dependency cycle-loop with its drivers/controllers"
                    )
                else:
                    self.warning = (
                        f"{self.warnings + 1} bones don't have Bendy Bone Segments;"
                        " this will cause a dependency cycle-loop with their drivers/controllers"
                    )
                self.warnings += 1

        if do_start_end:
            bone.bbone_handle_type_start = bone.bbone_handle_type_end = 'ABSOLUTE'

        args = dict(context=context, armature=rig, overwrite=True)
        if do_mch:
            bone_mch = New.bone(**args,
                                name=get_name(bone, 'bbone'),
                                edit=edit_mch)
        if do_start_end:
            bone_start = New.bone(**args,
                                  name=get_name(bone, 'bbone_start'),
                                  edit=edit_start)
            bone_end = New.bone(**args,
                                name=get_name(bone, 'bbone_end'),
                                edit=edit_end)
            bone_head = New.bone(**args,
                                 name=get_name(bone, 'bbone_head'),
                                 edit=edit_head)
        if do_in_out:
            bone_in = New.bone(**args,
                               name=get_name(bone, 'bbone_in'),
                               edit=edit_in)
            bone_out = New.bone(**args,
                                name=get_name(bone, 'bbone_out'),
                                edit=edit_out)
Esempio n. 16
0
    def edit_mirror_center(self, context):
        def get_bones(rig, bbone):
            ebones = rig.data.edit_bones
            ebone = ebones.get(get_name(bone, bbone))
            mebone = Get.mirror_bone(ebone)
            return (ebone, mebone)

        found = []
        for (bone, rig) in self.selected:
            if not (rig.pose.use_mirror_x or rig.data.use_mirror_x):
                continue
            mbone = Get.mirror_bone(bone)
            if mbone in found:
                continue
            else:
                found.append(bone)

            (ebone, mebone) = get_bones(rig, 'bbone_start')
            if not (ebone and mebone):
                continue

            if (ebone.parent == mebone.parent):
                # Connect heads
                if Is.connected(bone):
                    # The parent will already handle the symmetry
                    continue
                parent = ebone.parent
            else:
                (ebone, mebone) = get_bones(rig, 'bbone_end')
                if not (ebone and mebone):
                    continue

                # Find a mutual parent between the two bones
                parent = [
                    *(x for x in ebone.parent_recursive
                      if x in mebone.parent_recursive), None
                ][0]

            distance = abs(sum(ebone.head) - sum(mebone.head)) / 2
            margin = utils.lerp(bone.bone.length, mbone.bone.length,
                                0.5) / bone.bone.bbone_segments
            if distance >= margin:
                # Bones too far apart
                continue

            (prefix, replace, suffix,
             number) = utils.flip_name(bone.name, only_split=True)
            center_name = prefix + suffix + number
            center = New.bone(context, rig, name=center_name, overwrite=True)

            attributes = [
                'head',
                'head_radius',
                'tail',
                'tail_radius',
                'roll',
                'matrix',
                'layers',
                'bbone_x',
                'bbone_z',
            ]
            for atr in attributes:
                if hasattr(center, atr):
                    setattr(
                        center, atr,
                        utils.lerp(getattr(ebone, atr), getattr(mebone, atr),
                                   0.5))
            center.use_deform = False
            center.inherit_scale = 'NONE'
            center.parent = parent
            center.hide = True

            ebone.parent = mebone.parent = center
            self.hide_bones[rig].extend((ebone.name, mebone.name))
            self.center_bones[rig].append(center.name)
Esempio n. 17
0
 class ik:
     head = New.bone(context, rig, name="IK-" + fk.head.name)
     tail = New.bone(context, rig, name="IK-" + fk.tail.name)
     bone = New.bone(context, rig, name="IK-" + fk.bone.name)
    def execute_new(self, context):
        """
        Either made this originally then scrapped for the simpler version
        above, or was making this then got distracted and never came back to it
        """
        def sync(owner, target, *attribs):
            for attrib in attribs:
                try:
                    setattr(target, attrib, getattr(owner, attrib))
                except:
                    print("Can't write", attrib, "in", target)

        gp = bpy.data.grease_pencils.new(name=an.name)
        New.object(context, name=an.name, data=gp)

        for alayer in an.layers:
            glayer = gp.layers.new(alayer.info)

            for aframe in alayer.frames:
                gframe = glayer.frames.new(aframe.frame_number)

                for astroke in aframe.strokes:
                    gstroke = gframe.strokes.new()

                    gstroke.points.add(len(astroke.points))
                    for (index, gpoint) in enumerate(gstroke.points):
                        apoint = astroke.points[index]

                        sync(apoint, gpoint, 'co', 'pressure', 'select',
                             'strength', 'uv_factor', 'uv_rotation')

                    sync(
                        astroke,
                        gstroke,
                        'draw_cyclic',
                        'end_cap_mode',
                        'gradient_factor',
                        'gradient_shape',
                        'line_width',
                        'material_index',
                        'select',
                        'start_cap_mode',
                        # 'groups', 'triangles'
                    )
                    gstroke.display_mode = '3DSPACE'

                sync(aframe, gframe, 'frame_number', 'select')

            sync(
                alayer,
                glayer,
                # 'active_frame',
                'annotation_hide',
                'annotation_onion_after_color',
                'annotation_onion_before_color',
                'annotation_onion_after_range',
                'annotation_onion_before_range',
                'blend_mode',
                'channel_color',
                'color',
                'hide',
                'line_change',
                'lock',
                'lock_frame',
                'lock_material',
                'mask_layer',
                'matrix_inverse',
                'opacity',
                'parent',
                'parent_bone',
                'parent_type',
                'pass_index',
                'select',
                'show_in_front',
                'show_points',
                'thickness',
                'tint_color',
                'tint_factor',
                'use_annotation_onion_skinning',
                'use_onion_skinning',
                'use_solo_mode',
                'viewlayer_render')

        return {'FINISHED'}
Esempio n. 19
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'}