|
AnishGulati |
1f6b9a |
# pylint: disable=line-too-long
|
|
AnishGulati |
1f6b9a |
"""
|
|
AnishGulati |
1f6b9a |
misc.py
|
|
AnishGulati |
1f6b9a |
Some miscellaneous functions and classes will be provided here
|
|
AnishGulati |
1f6b9a |
"""
|
|
AnishGulati |
1f6b9a |
|
|
AnishGulati |
1f6b9a |
import sys
|
|
AnishGulati |
1f6b9a |
import math
|
|
AnishGulati |
1f6b9a |
import settings
|
|
AnishGulati |
1f6b9a |
from common.Vector import Vector
|
|
AnishGulati |
1f6b9a |
from common.Color import Color
|
|
AnishGulati |
1f6b9a |
sys.path.append("..")
|
|
AnishGulati |
1f6b9a |
|
|
AnishGulati |
1f6b9a |
|
|
AnishGulati |
1f6b9a |
def approximate_equal(a, b):
|
|
AnishGulati |
1f6b9a |
"""
|
|
AnishGulati |
1f6b9a |
Need to define this function somewhere else, a and b are of type "float"
|
|
AnishGulati |
1f6b9a |
|
|
AnishGulati |
1f6b9a |
Args:
|
|
AnishGulati |
1f6b9a |
a (float) : First number to be compared
|
|
AnishGulati |
1f6b9a |
b (float) : Second number to be compared
|
|
AnishGulati |
1f6b9a |
|
|
AnishGulati |
1f6b9a |
Returns:
|
|
AnishGulati |
1f6b9a |
(bool) : True if the numbers are approximately equal under precision
|
|
AnishGulati |
1f6b9a |
: False otherwise
|
|
AnishGulati |
1f6b9a |
"""
|
|
AnishGulati |
1f6b9a |
precision = 1e-8
|
|
AnishGulati |
1f6b9a |
if a < b:
|
|
AnishGulati |
1f6b9a |
return b - a < precision
|
|
AnishGulati |
1f6b9a |
return a - b < precision
|
|
AnishGulati |
1f6b9a |
|
|
AnishGulati |
1f6b9a |
|
|
AnishGulati |
1f6b9a |
def calculate_pixels_per_unit():
|
|
AnishGulati |
1f6b9a |
"""
|
|
AnishGulati |
1f6b9a |
Gives the value of 1 unit in terms of pixels according to the canvas defined
|
|
AnishGulati |
1f6b9a |
|
|
AnishGulati |
1f6b9a |
Args:
|
|
AnishGulati |
1f6b9a |
(None)
|
|
AnishGulati |
1f6b9a |
|
|
AnishGulati |
1f6b9a |
Returns:
|
|
AnishGulati |
1f6b9a |
(float) : Pixels per unit
|
|
AnishGulati |
1f6b9a |
"""
|
|
AnishGulati |
1f6b9a |
image_width = float(settings.lottie_format["w"])
|
|
AnishGulati |
1f6b9a |
image_area_width = settings.view_box_canvas["val"][2] - settings.view_box_canvas["val"][0]
|
|
AnishGulati |
1f6b9a |
settings.PIX_PER_UNIT = image_width / image_area_width
|
|
AnishGulati |
1f6b9a |
return settings.PIX_PER_UNIT
|
|
AnishGulati |
1f6b9a |
|
|
AnishGulati |
1f6b9a |
|
|
AnishGulati |
d4c500 |
def change_axis(x_val, y_val, is_transform=True):
|
|
AnishGulati |
1f6b9a |
"""
|
|
AnishGulati |
1f6b9a |
Convert synfig axis coordinates into lottie format
|
|
AnishGulati |
1f6b9a |
|
|
AnishGulati |
1f6b9a |
Args:
|
|
AnishGulati |
1f6b9a |
x_val (float | str) : x axis value in pixels
|
|
AnishGulati |
1f6b9a |
y_val (float | str) : y axis value in pixels
|
|
AnishGulati |
1f6b9a |
is_transform (`obj`: bool, optional) : Is this value used in transform module?
|
|
AnishGulati |
1f6b9a |
|
|
AnishGulati |
1f6b9a |
Returns:
|
|
AnishGulati |
1f6b9a |
(list) : x and y axis value in Lottie format
|
|
AnishGulati |
1f6b9a |
"""
|
|
AnishGulati |
1f6b9a |
x_val, y_val = float(x_val), float(y_val)
|
|
AnishGulati |
1f6b9a |
if is_transform:
|
|
AnishGulati |
1f6b9a |
x_val, y_val = x_val, -y_val
|
|
AnishGulati |
1f6b9a |
else:
|
|
AnishGulati |
1f6b9a |
x_val, y_val = x_val + settings.lottie_format["w"]/2, -y_val + settings.lottie_format["h"]/2
|
|
AnishGulati |
1f6b9a |
return [x_val, y_val]
|
|
AnishGulati |
1f6b9a |
|
|
AnishGulati |
1f6b9a |
|
|
AnishGulati |
1f6b9a |
def parse_position(animated, i):
|
|
AnishGulati |
1f6b9a |
"""
|
|
AnishGulati |
1f6b9a |
To convert the synfig coordinates from units(initially a string) to pixels
|
|
AnishGulati |
1f6b9a |
Depends on whether a vector is provided to it or a real value
|
|
AnishGulati |
1f6b9a |
If real value is provided, then time is also taken into consideration
|
|
AnishGulati |
1f6b9a |
|
|
AnishGulati |
1f6b9a |
Args:
|
|
AnishGulati |
1f6b9a |
animated (lxml.etree._Element) : Stores animation which contains waypoints
|
|
AnishGulati |
1f6b9a |
i (int) : Iterator over animation
|
|
AnishGulati |
1f6b9a |
|
|
AnishGulati |
1f6b9a |
Returns:
|
|
AnishGulati |
a3579e |
(common.Vector.Vector) If the animated type is not color
|
|
AnishGulati |
a3579e |
(common.Color.Color) Else if the animated type is color
|
|
AnishGulati |
1f6b9a |
"""
|
|
AnishGulati |
1f6b9a |
if animated.attrib["type"] == "vector":
|
|
AnishGulati |
1f6b9a |
pos = [float(animated[i][0][0].text),
|
|
AnishGulati |
1f6b9a |
float(animated[i][0][1].text)]
|
|
AnishGulati |
1f6b9a |
pos = [settings.PIX_PER_UNIT*x for x in pos]
|
|
AnishGulati |
1f6b9a |
|
|
AnishGulati |
1f6b9a |
elif animated.attrib["type"] == "real":
|
|
AnishGulati |
1f6b9a |
pos = parse_value(animated, i)
|
|
AnishGulati |
1f6b9a |
|
|
AnishGulati |
1f6b9a |
elif animated.attrib["type"] == "circle_radius":
|
|
AnishGulati |
1f6b9a |
pos = parse_value(animated, i)
|
|
AnishGulati |
1f6b9a |
pos[0] *= 2 # Diameter
|
|
AnishGulati |
1f6b9a |
|
|
AnishGulati |
1f6b9a |
elif animated.attrib["type"] == "angle":
|
|
AnishGulati |
1f6b9a |
pos = [get_angle(float(animated[i][0].attrib["value"])),
|
|
AnishGulati |
1f6b9a |
get_frame(animated[i])]
|
|
AnishGulati |
1f6b9a |
|
|
AnishGulati |
4ccde7 |
elif animated.attrib["type"] in {"composite_convert", "region_angle", "star_angle_new", "scalar_multiply"}:
|
|
AnishGulati |
1f6b9a |
pos = [float(animated[i][0].attrib["value"]),
|
|
AnishGulati |
1f6b9a |
get_frame(animated[i])]
|
|
AnishGulati |
1f6b9a |
|
|
AnishGulati |
1f6b9a |
elif animated.attrib["type"] == "rotate_layer_angle":
|
|
AnishGulati |
1f6b9a |
# Angle needs to made neg of what they are
|
|
AnishGulati |
1f6b9a |
pos = [-float(animated[i][0].attrib["value"]),
|
|
AnishGulati |
1f6b9a |
get_frame(animated[i])]
|
|
AnishGulati |
1f6b9a |
|
|
AnishGulati |
1f6b9a |
elif animated.attrib["type"] == "opacity":
|
|
AnishGulati |
1f6b9a |
pos = [float(animated[i][0].attrib["value"]) * settings.OPACITY_CONSTANT,
|
|
AnishGulati |
1f6b9a |
get_frame(animated[i])]
|
|
AnishGulati |
1f6b9a |
|
|
AnishGulati |
1f6b9a |
elif animated.attrib["type"] == "effects_opacity":
|
|
AnishGulati |
1f6b9a |
pos = [float(animated[i][0].attrib["value"]),
|
|
AnishGulati |
1f6b9a |
get_frame(animated[i])]
|
|
AnishGulati |
1f6b9a |
|
|
AnishGulati |
1f6b9a |
elif animated.attrib["type"] == "points":
|
|
AnishGulati |
1f6b9a |
pos = [int(animated[i][0].attrib["value"]),
|
|
AnishGulati |
1f6b9a |
get_frame(animated[i])]
|
|
AnishGulati |
1f6b9a |
|
|
AnishGulati |
0b69a9 |
elif animated.attrib["type"] == "bool":
|
|
AnishGulati |
0b69a9 |
val = animated[i][0].attrib["value"]
|
|
AnishGulati |
0b69a9 |
if val == "false":
|
|
AnishGulati |
0b69a9 |
val = 0
|
|
AnishGulati |
0b69a9 |
else:
|
|
AnishGulati |
0b69a9 |
val = 1
|
|
AnishGulati |
0b69a9 |
pos = [val, get_frame(animated[i])]
|
|
AnishGulati |
0b69a9 |
|
|
AnishGulati |
1f6b9a |
elif animated.attrib["type"] == "rectangle_size":
|
|
AnishGulati |
1f6b9a |
pos = parse_value(animated, i)
|
|
AnishGulati |
1f6b9a |
vec = Vector(pos[0], pos[1], animated.attrib["type"])
|
|
AnishGulati |
1f6b9a |
vec.add_new_val(float(animated[i][0].attrib["value2"]) * settings.PIX_PER_UNIT)
|
|
AnishGulati |
1f6b9a |
return vec
|
|
AnishGulati |
1f6b9a |
|
|
AnishGulati |
1f6b9a |
elif animated.attrib["type"] == "image_scale":
|
|
AnishGulati |
1f6b9a |
val = float(animated[i][0].attrib["value"])
|
|
AnishGulati |
1f6b9a |
val2 = get_frame(animated[i])
|
|
AnishGulati |
1f6b9a |
vec = Vector(val, val2, animated.attrib["type"])
|
|
AnishGulati |
1f6b9a |
vec.add_new_val(float(animated[i][0].attrib["value2"]))
|
|
AnishGulati |
1f6b9a |
return vec
|
|
AnishGulati |
1f6b9a |
|
|
AnishGulati |
1f6b9a |
elif animated.attrib["type"] == "scale_layer_zoom":
|
|
AnishGulati |
1f6b9a |
val = (math.e ** float(animated[i][0].attrib["value"])) * 100
|
|
AnishGulati |
1f6b9a |
val2 = get_frame(animated[i])
|
|
AnishGulati |
1f6b9a |
vec = Vector(val, val2, animated.attrib["type"])
|
|
AnishGulati |
1f6b9a |
vec.add_new_val(val)
|
|
AnishGulati |
1f6b9a |
return vec
|
|
AnishGulati |
1f6b9a |
|
|
AnishGulati |
9ae542 |
elif animated.attrib["type"] == "stretch_layer_scale":
|
|
AnishGulati |
9ae542 |
val1 = float(animated[i][0][0].text) * 100
|
|
AnishGulati |
9ae542 |
val3 = float(animated[i][0][1].text) * 100
|
|
AnishGulati |
9ae542 |
vec = Vector(val1, get_frame(animated[i]), animated.attrib["type"])
|
|
AnishGulati |
9ae542 |
vec.add_new_val(val3)
|
|
AnishGulati |
9ae542 |
return vec
|
|
AnishGulati |
9ae542 |
|
|
AnishGulati |
1f6b9a |
elif animated.attrib["type"] == "group_layer_scale":
|
|
AnishGulati |
1f6b9a |
val1 = float(animated[i][0][0].text) * 100
|
|
AnishGulati |
1f6b9a |
val3 = float(animated[i][0][1].text) * 100
|
|
AnishGulati |
1f6b9a |
vec = Vector(val1, get_frame(animated[i]), animated.attrib["type"])
|
|
AnishGulati |
1f6b9a |
vec.add_new_val(val3)
|
|
AnishGulati |
1f6b9a |
return vec
|
|
AnishGulati |
1f6b9a |
|
|
AnishGulati |
1f6b9a |
elif animated.attrib["type"] == "time":
|
|
AnishGulati |
1f6b9a |
val = parse_time(animated[i][0].attrib["value"]) # Needed in seconds
|
|
AnishGulati |
1f6b9a |
val2 = get_frame(animated[i]) # Needed in frames
|
|
AnishGulati |
1f6b9a |
return Vector(val, val2, animated.attrib["type"])
|
|
AnishGulati |
1f6b9a |
|
|
AnishGulati |
1f6b9a |
elif animated.attrib["type"] == "color":
|
|
AnishGulati |
1f6b9a |
red = float(animated[i][0][0].text)
|
|
AnishGulati |
1f6b9a |
green = float(animated[i][0][1].text)
|
|
AnishGulati |
1f6b9a |
blue = float(animated[i][0][2].text)
|
|
AnishGulati |
1f6b9a |
alpha = float(animated[i][0][3].text)
|
|
AnishGulati |
1f6b9a |
red = red ** (1/settings.GAMMA)
|
|
AnishGulati |
1f6b9a |
green = green ** (1/settings.GAMMA)
|
|
AnishGulati |
1f6b9a |
blue = blue ** (1/settings.GAMMA)
|
|
AnishGulati |
1f6b9a |
return Color(red, green, blue, alpha)
|
|
AnishGulati |
1f6b9a |
|
|
AnishGulati |
1f6b9a |
return Vector(pos[0], pos[1], animated.attrib["type"])
|
|
AnishGulati |
1f6b9a |
|
|
AnishGulati |
1f6b9a |
|
|
AnishGulati |
1f6b9a |
def parse_value(animated, i):
|
|
AnishGulati |
1f6b9a |
"""
|
|
AnishGulati |
1f6b9a |
To convert the synfig value parameter from units to pixels
|
|
AnishGulati |
1f6b9a |
and also take into consideration the time parameter
|
|
AnishGulati |
1f6b9a |
|
|
AnishGulati |
1f6b9a |
Args:
|
|
AnishGulati |
1f6b9a |
animated (lxml.etree._Element) : Stores animation which holds waypoints
|
|
AnishGulati |
1f6b9a |
i (int) : Iterator for animation
|
|
AnishGulati |
1f6b9a |
|
|
AnishGulati |
1f6b9a |
Returns:
|
|
AnishGulati |
1f6b9a |
(list) : [value, time] is returned
|
|
AnishGulati |
1f6b9a |
"""
|
|
AnishGulati |
1f6b9a |
pos = [float(animated[i][0].attrib["value"]) * settings.PIX_PER_UNIT,
|
|
AnishGulati |
1f6b9a |
get_frame(animated[i])]
|
|
AnishGulati |
1f6b9a |
return pos
|
|
AnishGulati |
1f6b9a |
|
|
AnishGulati |
1f6b9a |
|
|
AnishGulati |
1f6b9a |
def get_angle(theta):
|
|
AnishGulati |
1f6b9a |
"""
|
|
AnishGulati |
1f6b9a |
Converts the .sif angle into lottie angle
|
|
AnishGulati |
1f6b9a |
.sif uses positive x-axis as the start point and goes anticlockwise
|
|
AnishGulati |
1f6b9a |
lottie uses positive y-axis as the start point and goes clockwise
|
|
AnishGulati |
1f6b9a |
|
|
AnishGulati |
1f6b9a |
Args:
|
|
AnishGulati |
1f6b9a |
theta (float) : Stores Synfig format angle
|
|
AnishGulati |
1f6b9a |
|
|
AnishGulati |
1f6b9a |
Returns:
|
|
AnishGulati |
1f6b9a |
(int) : Lottie format angle
|
|
AnishGulati |
1f6b9a |
"""
|
|
AnishGulati |
1f6b9a |
theta = int(theta)
|
|
AnishGulati |
1f6b9a |
shift = -int(theta / 360)
|
|
AnishGulati |
1f6b9a |
theta = theta % 360
|
|
AnishGulati |
1f6b9a |
theta = (90 - theta) % 360
|
|
AnishGulati |
1f6b9a |
|
|
AnishGulati |
1f6b9a |
theta = theta + shift * 360
|
|
AnishGulati |
1f6b9a |
return theta
|
|
AnishGulati |
1f6b9a |
|
|
AnishGulati |
1f6b9a |
|
|
AnishGulati |
1f6b9a |
def is_animated(node):
|
|
AnishGulati |
1f6b9a |
"""
|
|
AnishGulati |
1f6b9a |
Tells whether a parater is animated or not
|
|
AnishGulati |
1f6b9a |
|
|
AnishGulati |
1f6b9a |
Args:
|
|
AnishGulati |
1f6b9a |
node (lxml.etree._Element) : Animation which stores waypoints
|
|
AnishGulati |
1f6b9a |
|
|
AnishGulati |
1f6b9a |
Returns:
|
|
AnishGulati |
1f6b9a |
(int) : Depending upon whether the parameter is animated, following
|
|
AnishGulati |
1f6b9a |
values are returned
|
|
AnishGulati |
1f6b9a |
0: If not animated
|
|
AnishGulati |
1f6b9a |
1: If only single waypoint is present
|
|
AnishGulati |
1f6b9a |
2: If more than one waypoint is present
|
|
AnishGulati |
1f6b9a |
"""
|
|
AnishGulati |
1f6b9a |
case = 0
|
|
AnishGulati |
1f6b9a |
if node.tag == "animated":
|
|
AnishGulati |
1f6b9a |
if len(node) == 1:
|
|
AnishGulati |
1f6b9a |
case = 1
|
|
AnishGulati |
1f6b9a |
else:
|
|
AnishGulati |
1f6b9a |
case = 2
|
|
AnishGulati |
1f6b9a |
else:
|
|
AnishGulati |
1f6b9a |
case = 0
|
|
AnishGulati |
1f6b9a |
return case
|
|
AnishGulati |
1f6b9a |
|
|
AnishGulati |
1f6b9a |
|
|
AnishGulati |
1f6b9a |
def clamp_col(color):
|
|
AnishGulati |
1f6b9a |
"""
|
|
AnishGulati |
1f6b9a |
This function converts the colors into int and takes them to the range of
|
|
AnishGulati |
1f6b9a |
0-255
|
|
AnishGulati |
1f6b9a |
|
|
AnishGulati |
1f6b9a |
Args:
|
|
AnishGulati |
1f6b9a |
color (float) : Synfig format color value
|
|
AnishGulati |
1f6b9a |
|
|
AnishGulati |
1f6b9a |
Returns:
|
|
AnishGulati |
1f6b9a |
(int) : Color value between 0-255
|
|
AnishGulati |
1f6b9a |
"""
|
|
AnishGulati |
1f6b9a |
color = color ** (1/settings.GAMMA)
|
|
AnishGulati |
1f6b9a |
color *= 255
|
|
AnishGulati |
1f6b9a |
color = int(color)
|
|
AnishGulati |
1f6b9a |
return max(0, min(color, 255))
|
|
AnishGulati |
1f6b9a |
|
|
AnishGulati |
1f6b9a |
|
|
AnishGulati |
1f6b9a |
def get_color_hex(node):
|
|
AnishGulati |
1f6b9a |
"""
|
|
AnishGulati |
1f6b9a |
Convert the <color></color> from rgba to hex format
|
|
AnishGulati |
1f6b9a |
|
|
AnishGulati |
1f6b9a |
Args:
|
|
AnishGulati |
1f6b9a |
node (lxml.etree._Element) : Synfig format color parameter
|
|
AnishGulati |
1f6b9a |
|
|
AnishGulati |
1f6b9a |
Returns:
|
|
AnishGulati |
1f6b9a |
(str) : hex format of color
|
|
AnishGulati |
1f6b9a |
"""
|
|
AnishGulati |
1f6b9a |
red, green, blue = 1, 0, 0
|
|
AnishGulati |
1f6b9a |
for col in node:
|
|
AnishGulati |
1f6b9a |
if col.tag == "r":
|
|
AnishGulati |
1f6b9a |
red = float(col.text)
|
|
AnishGulati |
1f6b9a |
elif col.tag == "g":
|
|
AnishGulati |
1f6b9a |
green = float(col.text)
|
|
AnishGulati |
1f6b9a |
elif col.tag == "b":
|
|
AnishGulati |
1f6b9a |
blue = float(col.text)
|
|
AnishGulati |
1f6b9a |
# Convert to 0-255 range
|
|
AnishGulati |
1f6b9a |
red, green, blue = clamp_col(red), clamp_col(green), clamp_col(blue)
|
|
AnishGulati |
1f6b9a |
|
|
AnishGulati |
1f6b9a |
# https://stackoverflow.com/questions/3380726/converting-a-rgb-color-tuple-to-a-six-digit-code-in-python/3380739#3380739
|
|
AnishGulati |
1f6b9a |
ret = "#{0:02x}{1:02x}{2:02x}".format(red, green, blue)
|
|
AnishGulati |
1f6b9a |
return ret
|
|
AnishGulati |
1f6b9a |
|
|
AnishGulati |
1f6b9a |
|
|
AnishGulati |
1f6b9a |
def get_frame(waypoint):
|
|
AnishGulati |
1f6b9a |
"""
|
|
AnishGulati |
1f6b9a |
Given a waypoint, it parses the time to frames
|
|
AnishGulati |
1f6b9a |
|
|
AnishGulati |
1f6b9a |
Args:
|
|
AnishGulati |
1f6b9a |
waypoint (lxml.etree._Element) : Synfig format waypoint
|
|
AnishGulati |
1f6b9a |
|
|
AnishGulati |
1f6b9a |
Returns:
|
|
AnishGulati |
1f6b9a |
(int) : the frame at which waypoint is present
|
|
AnishGulati |
1f6b9a |
"""
|
|
AnishGulati |
1f6b9a |
time = get_time(waypoint)
|
|
AnishGulati |
1f6b9a |
frame = time * settings.lottie_format["fr"]
|
|
AnishGulati |
1f6b9a |
frame = round(frame)
|
|
AnishGulati |
1f6b9a |
return frame
|
|
AnishGulati |
1f6b9a |
|
|
AnishGulati |
1f6b9a |
|
|
AnishGulati |
1f6b9a |
def get_time(waypoint):
|
|
AnishGulati |
1f6b9a |
"""
|
|
AnishGulati |
1f6b9a |
Given a waypoint, it parses the string time to float time
|
|
AnishGulati |
1f6b9a |
|
|
AnishGulati |
1f6b9a |
Args:
|
|
AnishGulati |
1f6b9a |
waypoint (lxml.etree._Element) : Synfig format waypoint
|
|
AnishGulati |
1f6b9a |
|
|
AnishGulati |
1f6b9a |
Returns:
|
|
AnishGulati |
1f6b9a |
(float) : the time in seconds at which the waypoint is present
|
|
AnishGulati |
1f6b9a |
"""
|
|
AnishGulati |
1f6b9a |
return parse_time(waypoint.attrib["time"])
|
|
AnishGulati |
1f6b9a |
|
|
AnishGulati |
1f6b9a |
|
|
AnishGulati |
1f6b9a |
def parse_time(time_in_str):
|
|
AnishGulati |
1f6b9a |
"""
|
|
AnishGulati |
1f6b9a |
Given a string, it parses time to float time
|
|
AnishGulati |
1f6b9a |
|
|
AnishGulati |
1f6b9a |
Args:
|
|
AnishGulati |
1f6b9a |
time_in_str (str) : Time in string format
|
|
AnishGulati |
1f6b9a |
|
|
AnishGulati |
1f6b9a |
Returns:
|
|
AnishGulati |
1f6b9a |
(float) : the time in seconds at represented by the string
|
|
AnishGulati |
1f6b9a |
"""
|
|
AnishGulati |
1f6b9a |
time = time_in_str.split(" ")
|
|
AnishGulati |
1f6b9a |
final = 0
|
|
AnishGulati |
1f6b9a |
for frame in time:
|
|
AnishGulati |
1f6b9a |
if frame[-1] == "h":
|
|
AnishGulati |
1f6b9a |
final += float(frame[:-1]) * 60 * 60
|
|
AnishGulati |
1f6b9a |
elif frame[-1] == "m":
|
|
AnishGulati |
1f6b9a |
final += float(frame[:-1]) * 60
|
|
AnishGulati |
1f6b9a |
elif frame[-1] == "s":
|
|
AnishGulati |
1f6b9a |
final += float(frame[:-1])
|
|
AnishGulati |
1f6b9a |
elif frame[-1] == "f": # This should never happen according to my code
|
|
AnishGulati |
1f6b9a |
raise ValueError("In waypoint, time is never expected in frames.")
|
|
AnishGulati |
1f6b9a |
return final
|
|
AnishGulati |
1f6b9a |
|
|
AnishGulati |
1f6b9a |
|
|
AnishGulati |
1f6b9a |
def get_vector(waypoint):
|
|
AnishGulati |
1f6b9a |
"""
|
|
AnishGulati |
1f6b9a |
Given a waypoint, it parses the string vector into Vector class defined in
|
|
luz.paz |
7040b8 |
this converter
|
|
AnishGulati |
1f6b9a |
|
|
AnishGulati |
1f6b9a |
Args:
|
|
AnishGulati |
1f6b9a |
waypoint (lxml.etree._Element) : Synfig format waypoint
|
|
AnishGulati |
1f6b9a |
|
|
AnishGulati |
1f6b9a |
Returns:
|
|
AnishGulati |
a3579e |
(common.Vector.Vector) : x and y axis values stores in Vector format
|
|
AnishGulati |
1f6b9a |
"""
|
|
AnishGulati |
1f6b9a |
# converting radius and angle to a vector
|
|
AnishGulati |
1f6b9a |
if waypoint.tag == "radial_composite":
|
|
AnishGulati |
1f6b9a |
for child in waypoint:
|
|
AnishGulati |
1f6b9a |
if child.tag == "radius":
|
|
AnishGulati |
1f6b9a |
radius = float(child[0].attrib["value"])
|
|
AnishGulati |
1f6b9a |
radius *= settings.PIX_PER_UNIT
|
|
AnishGulati |
1f6b9a |
elif child.tag == "theta":
|
|
AnishGulati |
1f6b9a |
angle = float(child[0].attrib["value"])
|
|
AnishGulati |
1f6b9a |
x, y = radial_to_tangent(radius, angle)
|
|
AnishGulati |
1f6b9a |
else:
|
|
AnishGulati |
1f6b9a |
x = float(waypoint[0][0].text)
|
|
AnishGulati |
1f6b9a |
y = float(waypoint[0][1].text)
|
|
AnishGulati |
1f6b9a |
return Vector(x, y)
|
|
AnishGulati |
1f6b9a |
|
|
AnishGulati |
1f6b9a |
|
|
AnishGulati |
1f6b9a |
def radial_to_tangent(radius, angle):
|
|
AnishGulati |
1f6b9a |
"""
|
|
AnishGulati |
1f6b9a |
Converts a tangent from radius and angle format to x, y axis co-ordinate
|
|
AnishGulati |
1f6b9a |
system
|
|
AnishGulati |
1f6b9a |
|
|
AnishGulati |
1f6b9a |
Args:
|
|
AnishGulati |
1f6b9a |
radius (float) : radius of a vector
|
|
AnishGulati |
1f6b9a |
angle (float) : angle in degrees
|
|
AnishGulati |
1f6b9a |
|
|
AnishGulati |
1f6b9a |
Returns:
|
|
AnishGulati |
1f6b9a |
(float) : The x-coordinate of the vector
|
|
AnishGulati |
1f6b9a |
(float) : The y-coordinate of the vector
|
|
AnishGulati |
1f6b9a |
"""
|
|
AnishGulati |
1f6b9a |
angle = math.radians(angle)
|
|
AnishGulati |
1f6b9a |
x = radius * math.cos(angle)
|
|
AnishGulati |
1f6b9a |
y = radius * math.sin(angle)
|
|
AnishGulati |
1f6b9a |
return x, y
|
|
AnishGulati |
1f6b9a |
|
|
AnishGulati |
1f6b9a |
|
|
AnishGulati |
1f6b9a |
def set_vector(waypoint, pos):
|
|
AnishGulati |
1f6b9a |
"""
|
|
AnishGulati |
1f6b9a |
Given a waypoint and pos(Vector), it set's the waypoint's vectors
|
|
AnishGulati |
1f6b9a |
|
|
AnishGulati |
1f6b9a |
Args:
|
|
AnishGulati |
1f6b9a |
waypoint (lxml.etree._Element) : Synfig format waypoint
|
|
AnishGulati |
1f6b9a |
|
|
AnishGulati |
1f6b9a |
Returns:
|
|
AnishGulati |
1f6b9a |
(None)
|
|
AnishGulati |
1f6b9a |
"""
|
|
AnishGulati |
1f6b9a |
waypoint[0][0].text = str(pos.val1)
|
|
AnishGulati |
1f6b9a |
waypoint[0][1].text = str(pos.val2)
|
|
AnishGulati |
1f6b9a |
|
|
AnishGulati |
1f6b9a |
|
|
AnishGulati |
1f6b9a |
def modify_final_dump(obj):
|
|
AnishGulati |
1f6b9a |
"""
|
|
AnishGulati |
1f6b9a |
This function will remove unwanted keys from the final dictionary and also
|
|
AnishGulati |
1f6b9a |
modify the floats according to our precision
|
|
AnishGulati |
1f6b9a |
|
|
AnishGulati |
1f6b9a |
Args:
|
|
AnishGulati |
1f6b9a |
obj (float | dict | list | tuple) : The object to be modified
|
|
AnishGulati |
1f6b9a |
|
|
AnishGulati |
1f6b9a |
Returns:
|
|
AnishGulati |
1f6b9a |
(float | dict | list) : Depending upon arguments, obj type is decided
|
|
AnishGulati |
1f6b9a |
"""
|
|
AnishGulati |
1f6b9a |
if isinstance(obj, float):
|
|
AnishGulati |
1f6b9a |
return round(obj, settings.FLOAT_PRECISION)
|
|
AnishGulati |
1f6b9a |
elif isinstance(obj, dict):
|
|
AnishGulati |
1f6b9a |
return dict((k, modify_final_dump(v)) for k, v in obj.items() if k not in ["synfig_i", "synfig_o"])
|
|
AnishGulati |
1f6b9a |
elif isinstance(obj, (list, tuple)):
|
|
AnishGulati |
1f6b9a |
return list(map(modify_final_dump, obj))
|
|
AnishGulati |
1f6b9a |
return obj
|