示例#1
0
文件: helper.py 项目: efkomik/synfig
def animate_radial_composite(radial_composite, window):
    """
    Animates the radial composite and updates the window of frame if radial
    composite's parameters are already animated
    Also generate the Lottie path and stores in radial_composite

    Args:
        radial_composite (lxml.etree._Element) : Synfig format radial composite-> stores radius and angle
        window           (dict)                : max and min frame of overall animations stored in this

    Returns:
        (None)
    """
    for child in radial_composite:
        if child.tag == "radius":
            radius = child
        elif child.tag == "theta":
            theta = child
    update_frame_window(radius[0], window)
    update_frame_window(theta[0], window)

    radius = gen_dummy_waypoint(radius, "radius", "real")
    theta = gen_dummy_waypoint(theta, "theta", "region_angle")

    # Update the newly computed radius and theta
    update_child_at_parent(radial_composite, radius, "radius")
    update_child_at_parent(radial_composite, theta, "theta")

    append_path(radius[0], radial_composite, "radius_path")
    append_path(theta[0], radial_composite, "theta_path")
示例#2
0
文件: group.py 项目: efkomik/synfig
def gen_time_remap(lottie, time_offset, time_dilation, idx):
    """
    Time offset will be converted to time remap here
    Currently time remapping will be done for each frame, but this function can
    be intelligently written only for some particular frames,hence reducing the
    space

    Args:
        lottie (dict) : Time remapping in Lottie format
        time_offset (lxml.etree._Element) : Offset for time in Synfig format
        time_dilation (lxml.etree._Element) : Speed/dilation for time in Synfig format
        idx (itr) : Index of this property in the layer

    Returns:
        (None)
    """
    offset_dict = {}
    time_offset = gen_dummy_waypoint(time_offset, "param", "time")
    gen_value_Keyframed(offset_dict, time_offset[0], 0)

    dilation_dict = {}
    time_dilation = gen_dummy_waypoint(time_dilation, "param", "real")
    gen_value_Keyframed(dilation_dict, time_dilation[0], 0)

    fr, lst = settings.lottie_format["ip"], settings.lottie_format["op"]
    lottie["a"] = 1  # Animated
    lottie["ix"] = idx
    lottie["k"] = []

    while fr <= lst:
        lottie["k"].append({})
        gen_dict(lottie["k"][-1], offset_dict, dilation_dict, fr)
        fr += 1
示例#3
0
def gen_layer_rotate(lottie, layer):
    """
    Help generate transform properties of a rotate layer

    Args:
        lottie (dict) : Will store the transform properties in lottie format
        layer  (lxml.etree._Element) : Tranform properties in Synfig format

    Returns:
        (None)
    """
    scale = settings.DEFAULT_SCALE
    for child in layer:
        if child.tag == "param":
            if child.attrib["name"] == "origin":
                anchor = gen_dummy_waypoint(child, "param", "vector")
                pos = anchor
            elif child.attrib["name"] == "amount":  # This is rotation
                rotation = gen_dummy_waypoint(child, "param",
                                              "rotate_layer_angle")

    #print_animation(anchor, pos, rotation)
    anchor = copy.deepcopy(anchor)
    group.update_pos(anchor)
    if settings.INSIDE_PRECOMP:
        group.update_pos(pos)
    gen_helpers_transform(lottie, layer, pos[0], anchor[0], scale, rotation[0])
示例#4
0
def gen_layer_translate(lottie, layer):
    """
    Help generate transform properties of translate layer

    Args:
        lottie (dict) : Transform properties in lottie format
        layer  (lxml.etree._Element) : Transform properties in Synfig format

    Returns:
        (None)
    """

    for child in layer:
        if child.tag == "param":
            if child.attrib["name"] == "origin":
                anchor = gen_dummy_waypoint(child, "param", "vector")
                pos = anchor

    anchor = copy.deepcopy(anchor)
    for waypoint in anchor[0]:
        waypoint[0][0].text = str(0)
        waypoint[0][1].text = str(0)
    group.update_pos(anchor)

    if settings.INSIDE_PRECOMP:
        group.update_pos(pos)

    gen_helpers_transform(lottie, layer, pos[0], anchor[0])
示例#5
0
文件: group.py 项目: efkomik/synfig
def change_opacity_switch(layer, lottie):
    """
    Will make the opacity of underlying layers 0 according to the active layer

    Args:
        layer (lxml.etree._Element) : Synfig format layer
        lottie (dict)               : Lottie format layer

    Returns:
        (None)
    """
    for chld in layer:
        if chld.tag == "param":
            if chld.attrib["name"] == "layer_name":
                layer_name = chld
            elif chld.attrib["name"] == "canvas":
                canvas = chld

    layer_name = gen_dummy_waypoint(layer_name, "param", "string",
                                    "layer_name")
    for assets in settings.lottie_format["assets"]:
        if assets["id"] == lottie["refId"]:
            root = assets
            break

    it = 0
    for c_layer in reversed(canvas[0]):
        active_time = set()
        description = root["layers"][it]["nm"]

        waypoint_itr = 0
        while waypoint_itr < len(layer_name[0]):
            waypoint = layer_name[0][waypoint_itr]
            l_name = waypoint[0].text
            if (l_name == description) or (l_name is None and it == 0):
                update_time(active_time, layer_name[0], waypoint_itr)
            waypoint_itr += 1

        active_time = sorted(active_time)
        deactive_time = sorted(flip_time(active_time))

        if c_layer.attrib["type"] in set.union(settings.SHAPE_SOLID_LAYER,
                                               settings.SOLID_LAYER):
            anim_type = "effects_opacity"
            dic = root["layers"][it]["ef"][0]["ef"][-1]["v"]
        elif c_layer.attrib["type"] in set.union(settings.PRE_COMP_LAYER,
                                                 settings.GROUP_LAYER,
                                                 settings.IMAGE_LAYER):
            anim_type = "opacity"
            dic = root["layers"][it]["ks"]["o"]
        elif c_layer.attrib["type"] in settings.SHAPE_LAYER:
            anim_type = "opacity"
            dic = root["layers"][it]["shapes"][1]["o"]

        animation = gen_hold_waypoints(deactive_time, c_layer, anim_type)
        gen_value_Keyframed(dic, animation[0], 0)

        it += 1
示例#6
0
def gen_layer_scale(lottie, layer):
    """
    Help generate transform properties of a scale layer

    Args:
        lottie (dict) : Store transform properties in lottie format
        layer  (lxml.etree._Element) Transform properties in Synfig format

    Returns:
        (None)
    """
    for child in layer:
        if child.tag == "param":
            if child.attrib["name"] == "center":
                anchor = gen_dummy_waypoint(child, "param", "vector")
                pos = anchor
            elif child.attrib["name"] == "amount":  # This is scale
                scale = gen_dummy_waypoint(child, "param", "scale_layer_zoom")

    anchor = copy.deepcopy(anchor)
    group.update_pos(anchor)
    if settings.INSIDE_PRECOMP:
        group.update_pos(pos)
    gen_helpers_transform(lottie, layer, pos[0], anchor[0], scale[0])
示例#7
0
文件: group.py 项目: efkomik/synfig
def gen_hold_waypoints(deactive_time, layer, anim_type):
    """
    Will only be used to modify opacity waypoints, and set zero values where the
    layer is deactive

    Args:
        deactive_time (set) : Range of time when the layer will be deactive
        layer (lxml.etree._Element) : Synfig format layer
        anim_type (str) : Specifies whether it is effects_opacity or opacity (it
                          will effect a factor of 100)

    Returns:
        (lxml.etree._Element) : Modified opacity animation is returned
    """
    for chld in layer:
        if chld.tag == "param" and chld.attrib["name"] == "amount":
            opacity = chld

    opacity = gen_dummy_waypoint(opacity, "param", anim_type, "amount")
    opacity_dict = {}
    gen_value_Keyframed(opacity_dict, opacity[0], 0)

    for it in deactive_time:
        # First add waypoints at both points, make it constant interval
        # then remove any in-between waypoints
        first = round(it[0] * settings.lottie_format["fr"])
        second = round(it[1] * settings.lottie_format["fr"])
        insert_waypoint_at_frame(opacity[0], opacity_dict, first, anim_type)
        insert_waypoint_at_frame(opacity[0], opacity_dict, second, anim_type)

        # Making it a constant interval
        for waypoint in opacity[0]:
            if approximate_equal(get_frame(waypoint), first):
                st_waypoint = waypoint
                break
        st_waypoint.attrib["after"] = "constant"
        st_waypoint[0].attrib["value"] = str(0)

        # removing the in between waypoints
        for waypoint in opacity[0]:
            this_frame = get_frame(waypoint)
            if (not approximate_equal(this_frame, first)) and \
               (not approximate_equal(this_frame, second)) and \
               (this_frame > first and this_frame < second):
                waypoint.getparent().remove(waypoint)

    return opacity
示例#8
0
文件: group.py 项目: efkomik/synfig
def gen_layer_group(lottie, layer, idx):
    """
    Will generate a pre composition but has small differences than pre-comp layer used in
    layers/preComp.py
    This function will be used for group layer as well as switch group layer

    Args:
        lottie (dict)               : Lottie format layer will be stored here
        layer (lxml.etree._Element) : Synfig format group/switch layer
        idx   (int)                 : Index of the layer

    Returns:
        (None)
    """
    lottie["ddd"] = settings.DEFAULT_3D
    lottie["ind"] = idx
    lottie["ty"] = settings.LAYER_PRECOMP_TYPE
    lottie["sr"] = settings.LAYER_DEFAULT_STRETCH
    lottie["ks"] = {}  # Transform properties to be filled
    set_layer_desc(layer, settings.LAYER_PRECOMP_NAME + str(idx), lottie)
    index = Count()

    for chld in layer:
        if chld.tag == "param":
            if chld.attrib["name"] == "canvas":
                canvas = chld
            elif chld.attrib["name"] == "transformation":
                transform = chld[0]
                for child in transform:
                    if child.tag == "scale":
                        scale = child
                    elif child.tag == "offset":
                        pos = child
                    elif child.tag == "angle":
                        angle = child
            elif chld.attrib["name"] == "origin":
                origin = chld
            elif chld.attrib["name"] == "amount":
                opacity = chld
            elif chld.attrib["name"] == "outline_grow":
                outline_grow = chld
            elif chld.attrib["name"] == "time_offset":
                time_offset = chld
            elif chld.attrib["name"] == "time_dilation":
                time_dilation = chld

    outline_grow = gen_dummy_waypoint(outline_grow, "param", "real")
    append_path(outline_grow[0], outline_grow, "outline_grow_path")

    origin = gen_dummy_waypoint(origin, "param", "vector")
    anchor = origin
    group.update_pos(anchor)

    angle = gen_dummy_waypoint(angle, "angle", "rotate_layer_angle")

    pos = gen_dummy_waypoint(pos, "offset", "vector")
    if settings.INSIDE_PRECOMP:
        group.update_pos(pos)

    scale = gen_dummy_waypoint(scale, "scale", "group_layer_scale")
    # Generate the transform properties here
    gen_helpers_transform(lottie["ks"], layer, pos[0], anchor[0], scale[0],
                          angle[0], opacity[0])

    # Store previous states, to be recovered at the end of group layer
    prev_state = settings.INSIDE_PRECOMP

    settings.OUTLINE_GROW.append(outline_grow)
    settings.INSIDE_PRECOMP = True

    settings.lottie_format["assets"].append({})
    asset = add_precomp_asset(settings.lottie_format["assets"][-1], canvas[0],
                              len(canvas[0]))
    lottie["refId"] = asset

    lottie["w"] = settings.lottie_format[
        "w"] + settings.ADDITIONAL_PRECOMP_WIDTH  # Experimental increase in width and height of precomposition
    lottie[
        "h"] = settings.lottie_format["h"] + settings.ADDITIONAL_PRECOMP_HEIGHT
    lottie["ao"] = settings.LAYER_DEFAULT_AUTO_ORIENT
    lottie["ip"] = settings.lottie_format["ip"]
    lottie["op"] = settings.lottie_format["op"]
    lottie["st"] = 0  # Don't know yet
    get_blend(lottie, layer)

    # Time offset and speed
    lottie["tm"] = {}
    gen_time_remap(lottie["tm"], time_offset, time_dilation, index.inc())

    # Change opacity of layers for switch-group layers
    if layer.attrib["type"] == "switch":
        change_opacity_switch(layer, lottie)
    # Change opacity of layers for group layers
    elif layer.attrib["type"] == "group":
        change_opacity_group(layer, lottie)

    # Return to previous state, when we go outside the group layer
    settings.INSIDE_PRECOMP = prev_state
    settings.OUTLINE_GROW.pop()
示例#9
0
文件: group.py 项目: efkomik/synfig
def change_opacity_group(layer, lottie):
    """
    Will make the opacity of underlying layers 0 according to the layers lying
    inside z range(if it is active)[z-range is non-animatable]

    Args:
        layer (lxml.etree._Element) : Synfig format layer
        lottie (dict)               : Lottie format layer

    Returns:
        (None)
    """
    for chld in layer:
        if chld.tag == "param":
            if chld.attrib["name"] == "z_range":
                z_range = chld
            elif chld.attrib["name"] == "z_range_position":
                z_range_pos = chld
            elif chld.attrib["name"] == "z_range_depth":
                z_range_depth = chld
            elif chld.attrib["name"] == "canvas":
                canvas = chld

    for assets in settings.lottie_format["assets"]:
        if assets["id"] == lottie["refId"]:
            root = assets
            break

    # If z-range is non-active (static value)
    if z_range[0].attrib["value"] == "false":
        return

    pos = gen_dummy_waypoint(z_range_pos, "param", "real", "z_range_position")
    depth = gen_dummy_waypoint(z_range_depth, "param", "real", "z_range_depth")
    pos_dict, depth_dict = {}, {}
    gen_value_Keyframed(pos_dict, pos[0], 0)
    gen_value_Keyframed(depth_dict, depth[0], 0)

    z_st, z_en = float('-inf'), float('-inf')
    active_range = []  # Stores the time and change of layers in z-range
    fr = settings.lottie_format["ip"]
    while fr <= settings.lottie_format["op"]:
        pos_val = to_Synfig_axis(get_vector_at_frame(pos_dict, fr), "real")
        depth_val = to_Synfig_axis(get_vector_at_frame(depth_dict, fr), "real")
        st, en = math.ceil(pos_val), math.floor(pos_val + depth_val)
        if st > en or en < 0:
            if (fr == settings.lottie_format["ip"]) or (z_st != -1
                                                        and z_en != -1):
                z_st, z_en = -1, -1
                active_range.append([fr, z_st, z_en])
        elif (st != z_st) or (en != z_en):
            z_st, z_en = st, en
            active_range.append([fr, z_st, z_en])
        fr += 1

    z_value = 0
    for c_layer in reversed(canvas[0]):
        active_time = set()
        itr = 0
        while itr < len(active_range):
            st, en = active_range[itr][1], active_range[itr][2]
            if z_value <= en and z_value >= st:
                now = active_range[itr][0] / settings.lottie_format["fr"]
                later = get_time_bound("op")
                if itr + 1 < len(active_range):
                    later = active_range[itr +
                                         1][0] / settings.lottie_format["fr"]
                active_time.add((now, later))
            itr += 1
        active_time = sorted(active_time)
        deactive_time = sorted(flip_time(active_time))

        if c_layer.attrib["type"] in set.union(settings.SHAPE_SOLID_LAYER,
                                               settings.SOLID_LAYER):
            anim_type = "effects_opacity"
            dic = root["layers"][z_value]["ef"][0]["ef"][-1]["v"]
        elif c_layer.attrib["type"] in set.union(settings.PRE_COMP_LAYER,
                                                 settings.GROUP_LAYER,
                                                 settings.IMAGE_LAYER):
            anim_type = "opacity"
            dic = root["layers"][z_value]["ks"]["o"]
        elif c_layer.attrib["type"] in settings.SHAPE_LAYER:
            anim_type = "opacity"
            dic = root["layers"][z_value]["shapes"][1]["o"]

        animation = gen_hold_waypoints(deactive_time, c_layer, anim_type)
        gen_value_Keyframed(dic, animation[0], 0)
        z_value += 1
示例#10
0
def gen_shapes_rectangle(lottie, layer, idx):
    """
    Generates the dictionary corresponding to shapes/rect.json

    Args:
        lottie (dict)               : The lottie generated rectangle layer will be stored in it
        layer  (lxml.etree._Element): Synfig format rectangle layer
        idx    (int)                : Stores the index of the rectangle layer

    Returns:
        (None)
    """
    index = Count()
    lottie["ty"] = "rc"  # Type: rectangle
    lottie["p"] = {}  # Position of rectangle
    lottie["d"] = settings.DEFAULT_DIRECTION
    lottie["s"] = {}  # Size of rectangle
    lottie["ix"] = idx  # setting the index
    lottie["r"] = {}  # Rounded corners of rectangle
    points = {}
    bevel_found = False
    expand_found = False  # For filled rectangle layers

    for child in layer:
        if child.tag == "param":
            if child.attrib["name"] == "point1":
                points["1"] = child  # Store address of child here

            elif child.attrib["name"] == "point2":
                points["2"] = child  # Store address of child here

            elif child.attrib["name"] == "expand":
                expand_found = True
                param_expand = child

            elif child.attrib["name"] == "bevel":
                bevel_found = True
                is_animate = is_animated(child[0])
                if is_animate == 2:
                    gen_value_Keyframed(lottie["r"], child[0], index.inc())
                else:
                    bevel = get_child_value(is_animate, child, "value")
                    bevel *= settings.PIX_PER_UNIT
                    gen_properties_value(lottie["r"], bevel, index.inc(),
                                         settings.DEFAULT_ANIMATED,
                                         settings.NO_INFO)
    if not bevel_found:  # For rectangle layer in stable version 1.2.2
        bevel = 0
        gen_properties_value(lottie["r"], bevel, index.inc(),
                             settings.DEFAULT_ANIMATED, settings.NO_INFO)

    if not expand_found:  # Means filled rectangle layer, gen expand param
        st = "<param name='expand'><real value='0.0'/></param>"
        param_expand = etree.fromstring(st)

    # If expand parameter is not animated
    param_expand = gen_dummy_waypoint(param_expand, "param", "real")

    # expand parameter needs to be positive: required by Synfig
    make_positive_valued(param_expand)

    # If p1 not animated
    points["1"] = gen_dummy_waypoint(points["1"], "param", "vector")

    # If p2 not animated
    points["2"] = gen_dummy_waypoint(points["2"], "param", "vector")

    both_points_animated(points["1"], points["2"], param_expand, lottie, index)
示例#11
0
文件: polygon.py 项目: efkomik/synfig
def gen_dynamic_list_polygon(lottie, dynamic_list):
    """
    Generates the bline corresponding to polygon layer

    Args:
        lottie (dict) : Lottie format polygon layer will be stored here
        dynamic_list (lxml.etree._Element) : Synfig format points of polygon

    Returns:
        (None)
    """
    ################## SECTION 1 ################
    # Inserting the waypoints if not animated, finding the first and last frame
    # Calculating the path after this
    window = {}
    window["first"] = sys.maxsize
    window["last"] = -1
    count = 0

    for entry in dynamic_list:
        pos = entry
        update_frame_window(pos[0], window)

        new_pos = gen_dummy_waypoint(pos, "entry", "vector")
        pos.getparent().remove(pos)
        dynamic_list.insert(count, new_pos)

        append_path(new_pos[0], dynamic_list[count], "pos_path", "vector")

        count += 1

    layer = dynamic_list.getparent().getparent()
    for chld in layer:
        if chld.tag == "param":
            if chld.attrib["name"] == "origin":
                origin = chld

    # Animating the origin
    update_frame_window(origin[0], window)
    origin_parent = origin.getparent()
    origin = gen_dummy_waypoint(origin, "param", "vector", "origin")
    update_child_at_parent(origin_parent, origin, "param", "origin")

    # Generate path for the origin component
    origin_dict = {}
    origin[0].attrib["transform_axis"] = "true"
    gen_properties_multi_dimensional_keyframed(origin_dict, origin[0], 0)

    if window["first"] == sys.maxsize and window["last"] == -1:
        window["first"] = window["last"] = 0
    ################ END OF SECTION 1 ##############

    ################ SECTION 2 #####################
    # Generating values for all the frames in the window
    fr = window["first"]
    while fr <= window["last"]:
        st_val, en_val = insert_dict_at(lottie, -1, fr, False)

        for entry in dynamic_list:
            # Only two childs, one should be animated, other one is path
            for child in entry:
                if child.tag == "pos_path":
                    dictionary = ast.literal_eval(child.text)
                    pos_cur = get_vector_at_frame(dictionary, fr)
                    pos_next = get_vector_at_frame(dictionary, fr + 1)

            tangent1_cur, tangent2_cur = Vector(0, 0), Vector(0, 0)
            tangent1_next, tangent2_next = Vector(0, 0), Vector(0, 0)

            # Adding origin to each vertex
            origin_cur = get_vector_at_frame(origin_dict, fr)
            origin_next = get_vector_at_frame(origin_dict, fr + 1)
            for i in range(len(pos_cur)):
                pos_cur[i] += origin_cur[i]
            for i in range(len(pos_next)):
                pos_next[i] += origin_next[i]

            # Store values in dictionary
            st_val["i"].append(tangent1_cur.get_list())
            st_val["o"].append(tangent2_cur.get_list())
            st_val["v"].append(pos_cur)
            en_val["i"].append(tangent1_next.get_list())
            en_val["o"].append(tangent2_next.get_list())
            en_val["v"].append(pos_next)
        fr += 1
    # Setting the final time
    lottie.append({})
    lottie[-1]["t"] = fr
示例#12
0
def gen_bline_outline(lottie, bline_point):
    """
    Generates the bline corresponding to outline layer by adding some vertices
    to bline and converting it to region layer

    Some parts are common with gen_bline_shapePropKeyframe(), which will be
    placed in a common function latter

    Args:
        lottie (dict) : Lottie format outline layer will be stored in this
        bline_point (lxml.etree._Element) : Synfig format bline points

    Returns:
        (None)
    """
    ################### SECTION 1 #########################
    # Inserting waypoints if not animated and finding the first and last frame
    # AFter that, there path will be calculated in lottie format which can
    # latter be used in get_vector_at_frame() function
    window = {}
    window["first"] = sys.maxsize
    window["last"] = -1

    for entry in bline_point:
        composite = entry[0]
        for child in composite:
            if child.tag == "point":
                pos = child
            elif child.tag == "width":
                width = child
            elif child.tag == "t1":
                t1 = child
            elif child.tag == "t2":
                t2 = child
            elif child.tag == "split_radius":
                split_r = child
            elif child.tag == "split_angle":
                split_a = child

        # Necassary to update this before inserting new waypoints, as new
        # waypoints might include there on time: 0 seconds
        update_frame_window(pos[0], window)

        # Empty the pos and fill in the new animated pos
        pos = gen_dummy_waypoint(pos, "point", "vector")
        update_child_at_parent(composite, pos, "point")

        # Empty the width and fill in the new animated width
        update_frame_window(width[0], window)
        width = gen_dummy_waypoint(width, "width", "real")
        update_child_at_parent(composite, width, "width")

        update_frame_window(split_r[0], window)
        split_r = gen_dummy_waypoint(split_r, "split_radius", "bool")
        update_child_at_parent(composite, split_r, "split_radius")

        update_frame_window(split_a[0], window)
        split_a = gen_dummy_waypoint(split_a, "split_angle", "bool")
        update_child_at_parent(composite, split_a, "split_angle")

        append_path(pos[0], composite, "point_path", "vector")
        append_path(width[0], composite, "width_path")

        animate_radial_composite(t1[0], window)
        animate_radial_composite(t2[0], window)

    layer = bline_point.getparent().getparent()
    for chld in layer:
        if chld.tag == "param":
            if chld.attrib["name"] == "width":
                outer_width = chld
            elif chld.attrib["name"] == "sharp_cusps":
                sharp_cusps = chld
            elif chld.attrib["name"] == "expand":
                expand = chld
            elif chld.attrib["name"] == "round_tip[0]":
                r_tip0 = chld
            elif chld.attrib["name"] == "round_tip[1]":
                r_tip1 = chld
            elif chld.attrib["name"] == "homogeneous_width":
                homo_width = chld
            elif chld.attrib["name"] == "origin":
                origin = chld

    # Animating the origin
    update_frame_window(origin[0], window)
    origin_parent = origin.getparent()
    origin = gen_dummy_waypoint(origin, "param", "vector", "origin")
    update_child_at_parent(origin_parent, origin, "param", "origin")
    # Generate path for the origin component
    origin_dict = {}
    origin[0].attrib["transform_axis"] = "true"
    gen_properties_multi_dimensional_keyframed(origin_dict, origin[0], 0)

    update_frame_window(outer_width[0], window)
    outer_width = gen_dummy_waypoint(outer_width, "param", "real", "width")
    # Update the layer with this animated outline width
    update_child_at_parent(layer, outer_width, "param", "width")

    # Generate outline width for Lottie format
    # No need to store this dictionary in lxml element, as it will be used in this function and will not be rewritten
    outer_width_dict = {}
    gen_value_Keyframed(outer_width_dict, outer_width[0], 0)

    # Animating the sharp_cusps
    update_frame_window(sharp_cusps[0], window)
    sharp_cusps = gen_dummy_waypoint(sharp_cusps, "param", "bool",
                                     "sharp_cusps")

    # Update the layer with this animated outline sharp cusps
    update_child_at_parent(layer, sharp_cusps, "param", "sharp_cusps")

    update_frame_window(expand[0], window)
    expand = gen_dummy_waypoint(expand, "param", "real", "expand")
    update_child_at_parent(layer, expand, "param", "expand")
    expand_dict = {}
    gen_value_Keyframed(expand_dict, expand[0], 0)

    update_frame_window(r_tip0[0], window)
    r_tip0 = gen_dummy_waypoint(r_tip0, "param", "bool", "round_tip[0]")
    update_child_at_parent(layer, r_tip0, "param", "round_tip[0]")

    update_frame_window(r_tip1[0], window)
    r_tip1 = gen_dummy_waypoint(r_tip1, "param", "bool", "round_tip[1]")
    update_child_at_parent(layer, r_tip1, "param", "round_tip[1]")

    update_frame_window(homo_width[0], window)
    homo_width = gen_dummy_waypoint(homo_width, "param", "bool",
                                    "homogeneous_width")
    update_child_at_parent(layer, homo_width, "param", "homogeneous_width")

    # Minimizing the window size
    if window["first"] == sys.maxsize and window["last"] == -1:
        window["first"] = window["last"] = 0
    ################# END OF SECTION 1 ###################

    ################ SECTION 2 ###########################
    # Generating values for all the frames in the window

    fr = window["first"]
    while fr <= window["last"]:
        st_val, en_val = insert_dict_at(
            lottie, -1, fr,
            False)  # This loop needs to be considered somewhere down

        synfig_outline(bline_point, st_val, origin_dict, outer_width_dict,
                       sharp_cusps, expand_dict, r_tip0, r_tip1, homo_width,
                       fr)
        synfig_outline(bline_point, en_val, origin_dict, outer_width_dict,
                       sharp_cusps, expand_dict, r_tip0, r_tip1, homo_width,
                       fr + 1)

        fr += 1
    # Setting the final time
    lottie.append({})
    lottie[-1]["t"] = fr
示例#13
0
def gen_bline_region(lottie, bline_point):
    """
    Generates the dictionary corresponding to properties/shapePropKeyframe.json,
    given a bline/spline

    Args:
        lottie     (dict) : Lottie generated keyframes will be stored here for shape/path
        bline_path (lxml.etree._Element) : shape/path store in Synfig format

    Returns:
        (None)
    """
    ################### SECTION 1 #########################
    # Inserting waypoints if not animated and finding the first and last frame
    # AFter that, there path will be calculated in lottie format which can
    # latter be used in get_vector_at_frame() function
    window = {}
    window["first"] = sys.maxsize
    window["last"] = -1

    loop = False
    if "loop" in bline_point.keys():
        val = bline_point.attrib["loop"]
        if val == "false":
            loop = False
        else:
            loop = True

    for entry in bline_point:
        composite = entry[0]
        for child in composite:
            if child.tag == "point":
                pos = child
            elif child.tag == "t1":
                t1 = child
            elif child.tag == "t2":
                t2 = child
            elif child.tag == "split_radius":
                split_r = child
            elif child.tag == "split_angle":
                split_a = child

        # Necassary to update this before inserting new waypoints, as new
        # waypoints might include there on time: 0 seconds
        update_frame_window(pos[0], window)

        # Empty the pos and fill in the new animated pos
        pos = gen_dummy_waypoint(pos, "point", "vector")
        update_child_at_parent(composite, pos, "point")

        update_frame_window(split_r[0], window)
        split_r = gen_dummy_waypoint(split_r, "split_radius", "bool")
        update_child_at_parent(composite, split_r, "split_radius")

        update_frame_window(split_a[0], window)
        split_a = gen_dummy_waypoint(split_a, "split_angle", "bool")
        update_child_at_parent(composite, split_a, "split_angle")

        append_path(pos[0], composite, "point_path", "vector")

        animate_radial_composite(t1[0], window)
        animate_radial_composite(t2[0], window)

    layer = bline_point.getparent().getparent()
    for chld in layer:
        if chld.tag == "param" and chld.attrib["name"] == "origin":
            origin = chld

    # Animating the origin
    update_frame_window(origin[0], window)
    origin_parent = origin.getparent()
    origin = gen_dummy_waypoint(origin, "param", "vector", "origin")
    update_child_at_parent(origin_parent, origin, "param", "origin")

    # Generate path for the origin component
    origin_dict = {}
    origin[0].attrib["transform_axis"] = "true"
    gen_properties_multi_dimensional_keyframed(origin_dict, origin[0], 0)

    # Minimizing the window size
    if window["first"] == sys.maxsize and window["last"] == -1:
        window["first"] = window["last"] = 0
    ################# END OF SECTION 1 ###################

    ################ SECTION 2 ###########################
    # Generating values for all the frames in the window
    fr = window["first"]
    while fr <= window["last"]:
        st_val, en_val = insert_dict_at(lottie, -1, fr, loop)

        for entry in bline_point:
            composite = entry[0]
            for child in composite:
                if child.tag == "point_path":
                    dictionary = ast.literal_eval(child.text)
                    pos_cur = get_vector_at_frame(dictionary, fr)
                    pos_next = get_vector_at_frame(dictionary, fr + 1)
                elif child.tag == "t1":
                    t1 = child[0]
                elif child.tag == "t2":
                    t2 = child[0]
                elif child.tag == "split_radius":
                    split_r = child
                elif child.tag == "split_angle":
                    split_a = child

            tangent1_cur, tangent2_cur = get_tangent_at_frame(
                t1, t2, split_r, split_a, fr)
            tangent1_next, tangent2_next = get_tangent_at_frame(
                t1, t2, split_r, split_a, fr)

            tangent1_cur, tangent2_cur = convert_tangent_to_lottie(
                tangent1_cur, tangent2_cur)
            tangent1_next, tangent2_next = convert_tangent_to_lottie(
                tangent1_next, tangent2_next)

            # Adding origin to each vertex
            origin_cur = get_vector_at_frame(origin_dict, fr)
            origin_next = get_vector_at_frame(origin_dict, fr + 1)
            for i in range(len(pos_cur)):
                pos_cur[i] += origin_cur[i]
            for i in range(len(pos_next)):
                pos_next[i] += origin_next[i]

            # Store values in dictionary
            st_val["i"].append(tangent1_cur.get_list())
            st_val["o"].append(tangent2_cur.get_list())
            st_val["v"].append(pos_cur)
            en_val["i"].append(tangent1_next.get_list())
            en_val["o"].append(tangent2_next.get_list())
            en_val["v"].append(pos_next)
        fr += 1
    # Setting final time
    lottie.append({})
    lottie[-1]["t"] = fr
示例#14
0
文件: circle.py 项目: efkomik/synfig
def gen_list_circle(lottie, layer):
    """
    Generates a shape layer corresponding to circle layer by manipulating the
    origin and radius of the circle

    Args:
        lottie (dict) : Lottie format circle layer will be stored in this
        layer (lxml.etree._Element) : Synfig format circle layer

    Returns:
        (None)
    """
    ################### SECTION 1 #########################
    # Inserting waypoints if not animated and finding the first and last frame
    # AFter that, there path will be calculated in lottie format which can
    # latter be used in get_vector_at_frame() function
    window = {}
    window["first"] = sys.maxsize
    window["last"] = -1

    for chld in layer:
        if chld.tag == "param":
            if chld.attrib["name"] == "origin":
                origin = chld
            elif chld.attrib["name"] == "radius":
                radius = chld

    # Animating the origin
    update_frame_window(origin[0], window)
    origin = gen_dummy_waypoint(origin, "param", "vector", "origin")
    update_child_at_parent(layer, origin, "param", "origin")
    # Generate path for the origin component
    origin_dict = {}
    origin[0].attrib["transform_axis"] = "true"
    gen_properties_multi_dimensional_keyframed(origin_dict, origin[0], 0)

    update_frame_window(radius[0], window)
    radius = gen_dummy_waypoint(radius, "param", "real", "radius")
    update_child_at_parent(layer, radius, "param", "width")

    # Generate radius for Lottie format
    radius_dict = {}
    gen_value_Keyframed(radius_dict, radius[0], 0)

    # Minimizing the window size
    if window["first"] == sys.maxsize and window["last"] == -1:
        window["first"] = window["last"] = 0
    ################# END OF SECTION 1 ###################

    ################ SECTION 2 ###########################
    # Generating values for all the frames in the window

    fr = window["first"]
    while fr <= window["last"]:
        st_val, en_val = insert_dict_at(
            lottie, -1, fr,
            False)  # This loop needs to be considered somewhere down

        synfig_circle(st_val, origin_dict, radius_dict, fr)
        synfig_circle(en_val, origin_dict, radius_dict, fr + 1)

        fr += 1
    # Setting the final time
    lottie.append({})
    lottie[-1]["t"] = fr
示例#15
0
def gen_list_rectangle(lottie, layer):
    """
    Generates a shape layer corresponding to rectangle layer by manipulating the
    parameters of the rectangle

    Args:
        lottie (dict) : Lottie format rectangle layer will be stored in this
        layer (lxml.etree._Element) : Synfig format rectangle layer

    Returns:
        (None)
    """
    ################### SECTION 1 #########################
    # Inserting waypoints if not animated and finding the first and last frame
    # AFter that, there path will be calculated in lottie format which can
    # latter be used in get_vector_at_frame() function
    window = {}
    window["first"] = sys.maxsize
    window["last"] = -1
    bevel_found = False
    expand_found = False

    for chld in layer:
        if chld.tag == "param":
            if chld.attrib["name"] == "point1":
                point1 = chld
            elif chld.attrib["name"] == "point2":
                point2 = chld
            elif chld.attrib["name"] == "expand":
                expand_found = True
                expand = chld
            elif chld.attrib["name"] == "bevel":
                bevel_found = True
                bevel = chld
            elif chld.attrib["name"] == "bevCircle":
                bevCircle = chld

    if not expand_found:  # Means filled rectangle layer
        st = "<param name='expand'><real value='0.0'/></param>"
        expand = etree.fromstring(st)

    if not bevel_found:  # For rectangle layer in stable version 1.2.2
        st = "<param name='bevel'><real value='0.0'/></param>"
        bevel = etree.fromstring(st)
        st = "<param name='bevCircle'><bool value='false'/></param>"
        bevCircle = etree.fromstring(st)

    # Animating point1
    update_frame_window(point1[0], window)
    point1 = gen_dummy_waypoint(point1, "param", "vector", "point1")
    update_child_at_parent(layer, point1, "param", "point1")
    # Generate path for the point1 component
    p1_dict = {}
    #point1[0].attrib["transform_axis"] = "true"
    gen_properties_multi_dimensional_keyframed(p1_dict, point1[0], 0)

    # Animating point2
    update_frame_window(point2[0], window)
    point2 = gen_dummy_waypoint(point2, "param", "vector", "point2")
    update_child_at_parent(layer, point2, "param", "point2")
    # Generate path for the point2 component
    p2_dict = {}
    gen_properties_multi_dimensional_keyframed(p2_dict, point2[0], 0)

    # Animating expand
    update_frame_window(expand[0], window)
    expand = gen_dummy_waypoint(expand, "param", "real", "expand")
    update_child_at_parent(layer, expand, "param", "expand")
    # Generate expand param for Lottie format
    expand_dict = {}
    gen_value_Keyframed(expand_dict, expand[0], 0)

    # Animating bevel
    update_frame_window(bevel[0], window)
    bevel = gen_dummy_waypoint(bevel, "param", "real", "bevel")
    update_child_at_parent(layer, bevel, "param", "bevel")
    # Generate bevel param for Lottie format
    bevel_dict = {}
    gen_value_Keyframed(bevel_dict, bevel[0], 0)

    # Animating bevCircle
    update_frame_window(bevCircle[0], window)
    bevCircle = gen_dummy_waypoint(bevCircle, "param", "bool", "bevCircle")
    update_child_at_parent(layer, bevCircle, "param", "bevCircle")

    # Minimizing the window size
    if window["first"] == sys.maxsize and window["last"] == -1:
        window["first"] = window["last"] = 0
    ################# END OF SECTION 1 ###################

    ################ SECTION 2 ###########################
    # Generating values for all the frames in the window

    fr = window["first"]
    while fr <= window["last"]:
        st_val, en_val = insert_dict_at(lottie, -1, fr, False)

        synfig_rectangle(st_val, p1_dict, p2_dict, expand_dict, bevel_dict,
                         bevCircle, fr)
        synfig_rectangle(en_val, p1_dict, p2_dict, expand_dict, bevel_dict,
                         bevCircle, fr + 1)

        fr += 1
    # Setting the final time
    lottie.append({})
    lottie[-1]["t"] = fr
示例#16
0
文件: star.py 项目: efkomik/synfig
def gen_list_star(lottie, layer):
    """
    Generates a shape layer corresponding to star layer by manipulating the
    parameters of the star

    Args:
        lottie (dict) : Lottie format rectangle layer will be stored in this
        layer (lxml.etree._Element) : Synfig format rectangle layer

    Returns:
        (None)
    """
    ################### SECTION 1 #########################
    # Inserting waypoints if not animated and finding the first and last frame
    # AFter that, there path will be calculated in lottie format which can
    # latter be used in get_vector_at_frame() function
    window = {}
    window["first"] = sys.maxsize
    window["last"] = -1

    for chld in layer:
        if chld.tag == "param":
            if chld.attrib["name"] == "origin":
                origin = chld
            elif chld.attrib["name"] == "radius1":
                radius1 = chld
            elif chld.attrib["name"] == "radius2":
                radius2 = chld
            elif chld.attrib["name"] == "angle":
                angle = chld
            elif chld.attrib["name"] == "points":
                points = chld
            elif chld.attrib["name"] == "regular_polygon":
                regular_polygon = chld

    # Animating origin
    update_frame_window(origin[0], window)
    origin = gen_dummy_waypoint(origin, "param", "vector", "origin")
    update_child_at_parent(layer, origin, "param", "origin")
    # Generate path for the origin component
    origin_dict = {}
    origin[0].attrib["transform_axis"] = "true"
    gen_properties_multi_dimensional_keyframed(origin_dict, origin[0], 0)

    # Animating radius1
    update_frame_window(radius1[0], window)
    radius1 = gen_dummy_waypoint(radius1, "param", "real", "radius1")
    update_child_at_parent(layer, radius1, "param", "radius1")
    # Generate expand param for Lottie format
    radius1_dict = {}
    gen_value_Keyframed(radius1_dict, radius1[0], 0)

    # Animating radius2
    update_frame_window(radius2[0], window)
    radius2 = gen_dummy_waypoint(radius2, "param", "real", "radius2")
    update_child_at_parent(layer, radius2, "param", "radius2")
    # Generate expand param for Lottie format
    radius2_dict = {}
    gen_value_Keyframed(radius2_dict, radius2[0], 0)

    # Animating angle
    update_frame_window(angle[0], window)
    angle = gen_dummy_waypoint(angle, "param", "star_angle_new", "angle")
    update_child_at_parent(layer, angle, "param", "angle")
    # Generate expand param for Lottie format
    angle_dict = {}
    gen_value_Keyframed(angle_dict, angle[0], 0)

    # Animating points
    update_frame_window(points[0], window)
    points = gen_dummy_waypoint(points, "param", "real", "points")
    update_child_at_parent(layer, points, "param", "points")
    # Generate expand param for Lottie format
    points_dict = {}
    gen_value_Keyframed(points_dict, points[0], 0)

    mx_points = get_max_points(points)

    # Animating regular_polygon
    update_frame_window(regular_polygon[0], window)
    regular_polygon = gen_dummy_waypoint(regular_polygon, "param", "bool",
                                         "regular_polygon")
    update_child_at_parent(layer, regular_polygon, "param", "regular_polygon")

    # Minimizing the window size
    if window["first"] == sys.maxsize and window["last"] == -1:
        window["first"] = window["last"] = 0
    ################# END OF SECTION 1 ###################

    ################ SECTION 2 ###########################
    # Generating values for all the frames in the window

    fr = window["first"]
    while fr <= window["last"]:
        st_val, en_val = insert_dict_at(lottie, -1, fr, False)
        synfig_star(st_val, mx_points, origin_dict, radius1_dict, radius2_dict,
                    angle_dict, points_dict, regular_polygon, fr)
        synfig_star(en_val, mx_points, origin_dict, radius1_dict, radius2_dict,
                    angle_dict, points_dict, regular_polygon, fr + 1)

        fr += 1
    # Setting the final time
    lottie.append({})
    lottie[-1]["t"] = fr