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
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
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
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
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
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