Coverage for lib/lottie/utils/tensor.py: 0%

62 statements  

« prev     ^ index     » next       coverage.py v7.2.2, created at 2023-03-20 16:17 +0100

1from .. import objects 

2 

3 

4class TensorSerializer: 

5 def process(self, animation: objects.Animation, flatten: bool = True): 

6 data = [] 

7 for layer in animation.layers: 

8 self.process_layer(layer, data) 

9 

10 if flatten: 

11 return self.flatten(data) 

12 

13 return data 

14 

15 def process_layer(self, layer, data): 

16 if not isinstance(layer, objects.ShapeLayer): 

17 return 

18 

19 self.process_shape_group(layer, data) 

20 

21 def process_shape(self, shape: objects.Path, data: dict): 

22 bez = shape.shape.get_value() 

23 if bez and len(bez.vertices) > 1: 

24 data["curves"].append(bez) 

25 

26 def process_styler(self, styler): 

27 return { 

28 "opacity": (styler.opacity.get_value() or 100) / 100, 

29 "color": 

30 styler.gradient.get_stops()[0][0] 

31 if isinstance(styler, objects.Gradient) 

32 else styler.color.get_value() 

33 } 

34 

35 def process_shape_group(self, group, data): 

36 shape_data = { 

37 "curves": [], 

38 "fill": None, 

39 "stroke": None 

40 } 

41 

42 for shape in group.shapes: 

43 if shape.hidden: 

44 continue 

45 

46 if isinstance(shape, objects.Group): 

47 child_data = self.process_shape_group(shape, data) 

48 shape_data["curves"] += child_data["curves"] 

49 elif isinstance(shape, objects.Path): 

50 self.process_shape(shape, shape_data) 

51 elif isinstance(shape, objects.Shape): 

52 self.process_shape(shape.to_bezier(), shape_data) 

53 elif isinstance(shape, (objects.Fill, objects.GradientFill)): 

54 shape_data["fill"] = self.process_styler(shape) 

55 elif isinstance(shape, objects.BaseStroke): 

56 shape_data["stroke"] = self.process_styler(shape) 

57 shape_data["stroke"]["width"] = shape.width.get_value() 

58 

59 if shape_data["curves"] and (shape_data["fill"] or shape_data["stroke"]): 

60 data.append(shape_data) 

61 

62 return shape_data 

63 

64 def flatten_color(self, data): 

65 if not data: 

66 return None 

67 return list(data["color"])[0:3] + [data["opacity"]] 

68 

69 def flatten(self, data): 

70 flattened = [] 

71 for item in data: 

72 base = { 

73 "fill": self.flatten_color(item["fill"]), 

74 "stroke": self.flatten_color(item["stroke"]), 

75 "stroke_width": item["stroke"]["width"] if item["stroke"] else 0, 

76 } 

77 base["color"] = base["fill"] or base["stroke"] 

78 

79 for curve in item["curves"]: 

80 points = [] 

81 for i in range(len(curve.vertices)): 

82 v = curve.vertices[i] 

83 points.append(list(v)) 

84 points.append(list(curve.out_tangents[i] + v)) 

85 next_i = (i+1) % len(curve.vertices) 

86 points.append(list(curve.in_tangents[next_i] + curve.vertices[next_i])) 

87 

88 if curve.closed: 

89 points.push(list(curve.vertices[0])) 

90 else: 

91 points.pop() 

92 points.pop() 

93 

94 flattened.append({ 

95 **base, 

96 "points": points, 

97 "closed": int(curve.closed) 

98 }) 

99 

100 return flattened