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 (common.Layer.Layer) : Synfig format circle layer Returns: (None) """ ################### SECTION 1 ######################### # Inserting waypoints if not animated and finding the first and last frame window = {} window["first"] = sys.maxsize window["last"] = -1 origin = layer.get_param("origin") radius = layer.get_param("radius") # Animating the origin origin.update_frame_window(window) origin.animate("vector") radius.update_frame_window(window) radius.animate("real") # 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, radius, fr) synfig_circle(en_val, origin, radius, fr + 1) 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 (common.Param.Param) : Synfig format bline points Returns: (None) """ ################### SECTION 1 ######################### # Inserting waypoints if not animated and finding the first and last frame window = {} window["first"] = sys.maxsize window["last"] = -1 bline = Bline(bline_point[0], bline_point) for entry in bline.get_entry_list(): pos = entry["point"] origin = entry["origin"] width = entry["width"] t1 = entry["t1"] t2 = entry["t2"] split_r = entry["split_radius"] split_a = entry["split_angle"] pos.update_frame_window(window) # Empty the pos and fill in the new animated pos pos.animate("vector") origin.update_frame_window(window) origin.animate("real") width.update_frame_window(window) width.animate("real") split_r.update_frame_window(window) split_r.animate_without_path("bool") split_a.update_frame_window(window) split_a.animate_without_path("bool") animate_tangents(t1, window) animate_tangents(t2, window) # Open up the window if bline points are animated entry["ActivepointList"].update_frame_window(window) layer = bline.get_layer().get_layer() outer_width = layer.get_param("width") sharp_cusps = layer.get_param("sharp_cusps") expand = layer.get_param("expand") r_tip0 = layer.get_param("round_tip[0]") r_tip1 = layer.get_param("round_tip[1]") homo_width = layer.get_param("homogeneous_width") origin = layer.get_param("origin") # Animating the origin origin.update_frame_window(window) origin.animate("vector") # Animating the outer width outer_width.update_frame_window(window) outer_width.animate("real") # Animating the sharp_cusps sharp_cusps.update_frame_window(window) sharp_cusps.animate_without_path("bool") # Animating the expand param expand.update_frame_window(window) expand.animate("real") # Animating the round tip 0 r_tip0.update_frame_window(window) r_tip0.animate_without_path("bool") # Animating the round tip 1 r_tip1.update_frame_window(window) r_tip1.animate_without_path("bool") # Animating the homogeneous width homo_width.update_frame_window(window) homo_width.animate_without_path("bool") # 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 lottie_st_list, lottie_en_list = [], [] 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 lottie_st_list.append(st_val) lottie_en_list.append(en_val) synfig_outline(bline, st_val, origin, outer_width, sharp_cusps, expand, r_tip0, r_tip1, homo_width, fr) synfig_outline(bline, en_val, origin, outer_width, sharp_cusps, expand, r_tip0, r_tip1, homo_width, fr + 1) fr += 1 equalize_length(lottie_st_list, lottie_en_list) # Setting the final time lottie.append({}) lottie[-1]["t"] = fr
def gen_bline_outline_constant(lottie, bline_point, layer, transformation, idx): """ """ index = Count() lottie["ty"] = "gr" lottie["nm"] = "Shape "+ str(idx) lottie["np"] = 3 lottie["cix"] = 2 lottie["bm"] = 0 lottie["ix"] = idx lottie["mn"] = "ADBE Vector Group " +str(idx) lottie["hd"] = "false" lottie["it"] = [] lottie["it"].append({}) lottie["it"].append({}) lottie["it"].append({}) bline = Bline(bline_point[0], bline_point) #Creating transformation dictionary lottie["it"][2]["ty"] = "tr" lottie["it"][2]["nm"] = "Transform" lottie["it"][2].update(transformation) #Creating stroke dictionary lottie["it"][1]["ty"] = "st" lottie["it"][1]["lc"] = 2 lottie["it"][1]["lj"] = 1 lottie["it"][1]["ml"] = 37 lottie["it"][1]["bm"] = 0 lottie["it"][1]["nm"] = "Stroke " + str(idx) lottie["it"][1]["mn"] = "ADBE Vector Graphic - Stroke " +str(idx) lottie["it"][1]["hd"] = "false" lottie["it"][1]["c"] = {} lottie["it"][1]["o"] = {} lottie["it"][1]["w"] = {} #Color color = layer.get_param("color").get() is_animate = is_animated(color[0]) if is_animate == settings.ANIMATED: gen_value_Keyframed(lottie["it"][1]["c"], color[0], index.inc()) else: if is_animate == settings.NOT_ANIMATED: val = color[0] else: val = color[0][0][0] red = float(val[0].text) green = float(val[1].text) blue = float(val[2].text) red, green, blue = red ** (1/settings.GAMMA[0]), green ** (1/settings.GAMMA[1]), blue ** (1/ settings.GAMMA[2]) alpha = float(val[3].text) gen_properties_value(lottie["it"][1]["c"], [red, green, blue, alpha], index.inc(), settings.DEFAULT_ANIMATED, settings.NO_INFO) #Opacity opacity = layer.get_param("amount") opacity.animate("opacity") opacity.fill_path(lottie["it"][1],"o") #Constant width loop = bline.get_loop() width = layer.get_param("width") width.scale_convert_link(1) width.animate("real") width.fill_path(lottie["it"][1],"w") #Creating shape dictionary lottie["it"][0]["ind"] = 0 lottie["it"][0]["ty"] = "sh" lottie["it"][0]["ix"] = 1 lottie["it"][0]["ks"] = {} lottie["it"][0]["nm"] = "Path 1" lottie["it"][0]["mn"] = "ADBE Vector Shape - Group" lottie["it"][0]["hd"] = "false" lottie["it"][0]["ks"]["a"] = 1 lottie["it"][0]["ks"]["ix"] = lottie["it"][0]["ix"] + 1 lottie["it"][0]["ks"]["k"] = [] window = {} window["first"] = sys.maxsize window["last"] = -1 for entry in bline.get_entry_list(): pos = entry["point"] width = entry["width"] t1 = entry["t1"] t2 = entry["t2"] split_r = entry["split_radius"] split_a = entry["split_angle"] pos.update_frame_window(window) # Empty the pos and fill in the new animated pos pos.animate("vector") width.update_frame_window(window) width.animate("real") split_r.update_frame_window(window) split_r.animate_without_path("bool") split_a.update_frame_window(window) split_a.animate_without_path("bool") animate_tangents(t1, window) animate_tangents(t2, window) outer_width = layer.get_param("width") sharp_cusps = layer.get_param("sharp_cusps") expand = layer.get_param("expand") r_tip0 = layer.get_param("round_tip[0]") r_tip1 = layer.get_param("round_tip[1]") homo_width = layer.get_param("homogeneous_width") origin = layer.get_param("origin") # Animating the origin origin.update_frame_window(window) origin.animate("vector") # Animating the outer width outer_width.update_frame_window(window) outer_width.animate("real") # Animating the sharp_cusps sharp_cusps.update_frame_window(window) sharp_cusps.animate_without_path("bool") # Animating the expand param expand.update_frame_window(window) expand.animate("real") # Animating the round tip 0 r_tip0.update_frame_window(window) r_tip0.animate_without_path("bool") # Animating the round tip 1 r_tip1.update_frame_window(window) r_tip1.animate_without_path("bool") # Animating the homogeneous width homo_width.update_frame_window(window) homo_width.animate_without_path("bool") # Minimizing the window size if window["first"] == sys.maxsize and window["last"] == -1: window["first"] = window["last"] = 0 frames = list(set(settings.WAYPOINTS_LIST)) length = bline.get_len() flag = False if loop: flag = True for fr in frames: if fr!=1: st_val = insert_dict_at(lottie["it"][0]["ks"]["k"], -1, fr, flag,True) cur_origin = origin.get_value(fr) for point in range(0,length): pos_ret, width, t1, t2, split_r_val, split_a_val = get_outline_param_at_frame(bline[point],fr) cubic_to(pos_ret,t1,t2,st_val,cur_origin,False,True)
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 (common.Param.Param) : shape/path store in Synfig format Returns: (None) """ ################### SECTION 1 ######################### # Inserting waypoints if not animated and finding the first and last frame window = {} window["first"] = sys.maxsize window["last"] = -1 bline = Bline(bline_point[0], bline_point) loop = bline.get_loop() for entry in bline.get_entry_list(): pos = entry["point"] origin = entry["origin"] t1 = entry["t1"] t2 = entry["t2"] split_r = entry["split_radius"] split_a = entry["split_angle"] width = entry["width"] # Not needed, but required by Bline class # Hence we do not update the window also width.animate("real") origin.update_frame_window(window) origin.animate("real") # Necassary to update this before inserting new waypoints, as new # waypoints might include there on time: 0 seconds pos.update_frame_window(window) pos.animate("vector", True) split_r.update_frame_window(window) split_r.animate_without_path("bool") split_a.update_frame_window(window) split_a.animate_without_path("bool") animate_tangents(t1, window) animate_tangents(t2, window) entry["ActivepointList"].update_frame_window(window) layer = bline.get_layer().get_layer() origin = layer.get_param("origin") # Animating the origin origin.update_frame_window(window) origin.animate("vector") # 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"] lottie_st_list = [] lottie_en_list = [] while fr <= window["last"]: st_val, en_val = insert_dict_at(lottie, -1, fr, loop) lottie_st_list.append(st_val) lottie_en_list.append(en_val) synfig_region(bline, st_val, origin, fr) synfig_region(bline, en_val, origin, fr + 1) fr += 1 equalize_length(lottie_st_list, lottie_en_list) # Setting 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 (common.Layer.Layer) : Synfig format rectangle layer Returns: (None) """ ################### SECTION 1 ######################### # Inserting waypoints if not animated and finding the first and last frame window = {} window["first"] = sys.maxsize window["last"] = -1 point1 = layer.get_param("point1") point2 = layer.get_param("point2") expand = layer.get_param("expand") bevel = layer.get_param("bevel") bevCircle = layer.get_param("bevCircle") if expand.get() is None: # Means filled rectangle layer st = "<param name='expand'><real value='0.0'/></param>" expand = etree.fromstring(st) expand = layer.add_param("expand", expand) if bevel.get() is None: # For rectangle layer in stable version 1.2.2 st = "<param name='bevel'><real value='0.0'/></param>" bevel = etree.fromstring(st) bevel = layer.add_param("bevel", bevel) st = "<param name='bevCircle'><bool value='false'/></param>" bevCircle = etree.fromstring(st) bevCircle = layer.add_param("bevCircle", bevCircle) # Animating point1 point1.update_frame_window(window) point1.animate("vector") # Animating point2 point2.update_frame_window(window) point2.animate("vector") # Animating expand expand.update_frame_window(window) expand.animate("real") # Animating bevel bevel.update_frame_window(window) bevel.animate("real") # Animating bevCircle bevCircle.update_frame_window(window) bevCircle.animate_without_path("bool") # 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, point1, point2, expand, bevel, bevCircle, fr) synfig_rectangle(en_val, point1, point2, expand, bevel, bevCircle, fr + 1) 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_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_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_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 (common.Param.Param) : 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 dynamic_list = Bline(dynamic_list[0], dynamic_list) for entry in dynamic_list.get_entry_list(): pos = entry["vector"] pos.update_frame_window(window) z = Param(pos.getparent(), pos.getparent().getparent()) z.animate("vector", True) entry["vector"] = z layer = dynamic_list.get_layer().get_layer() origin = layer.get_param("origin") # Animating the origin origin.update_frame_window(window) origin.animate("vector") 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.get_entry_list(): pos_cur = entry["vector"].get_value(fr) pos_next = entry["vector"].get_value(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 = origin.get_value(fr) origin_next = origin.get_value(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_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 (common.Param.Param) : shape/path store in Synfig format Returns: (None) """ ################### SECTION 1 ######################### # Inserting waypoints if not animated and finding the first and last frame window = {} window["first"] = sys.maxsize window["last"] = -1 bline = Bline(bline_point[0], bline_point) loop = bline.get_loop() for entry in bline.get_entry_list(): pos = entry["point"] t1 = entry["t1"] t2 = entry["t2"] split_r = entry["split_radius"] split_a = entry["split_angle"] # Necassary to update this before inserting new waypoints, as new # waypoints might include there on time: 0 seconds pos.update_frame_window(window) pos.animate("vector", True) split_r.update_frame_window(window) split_r.animate_without_path("bool") split_a.update_frame_window(window) split_a.animate_without_path("bool") animate_tangents(t1, window) animate_tangents(t2, window) layer = bline.get_layer().get_layer() origin = layer.get_param("origin") # Animating the origin origin.update_frame_window(window) origin.animate("vector") # 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.get_entry_list(): pos = entry["point"] pos_cur, pos_next = pos.get_value(fr), pos.get_value(fr + 1) t1 = entry["t1"] t2 = entry["t2"] split_r = entry["split_radius"] split_a = entry["split_angle"] 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 + 1) 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, origin_next = origin.get_value(fr), origin.get_value( 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_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 (common.Layer.Layer) : Synfig format rectangle layer Returns: (None) """ ################### SECTION 1 ######################### # Inserting waypoints if not animated and finding the first and last frame window = {} window["first"] = sys.maxsize window["last"] = -1 origin = layer.get_param("origin") radius1 = layer.get_param("radius1") radius2 = layer.get_param("radius2") angle = layer.get_param("angle") points = layer.get_param("points") regular_polygon = layer.get_param("regular_polygon") # Animating origin origin.update_frame_window(window) # Keeping the transform true here #origin.animate("vector", True) origin.animate("vector") # Animating radius1 radius1.update_frame_window(window) radius1.animate("real") # Animating radius2 radius2.update_frame_window(window) radius2.animate("real") # Animating angle angle.update_frame_window(window) angle.animate("star_angle_new") # Animating points points.update_frame_window(window) points.animate("real") mx_points = get_max_points(points) # Animating regular_polygon regular_polygon.update_frame_window(window) regular_polygon.animate_without_path("bool") # 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, radius1, radius2, angle, points, regular_polygon, fr) synfig_star(en_val, mx_points, origin, radius1, radius2, angle, points, regular_polygon, 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