Coverage for lib/lottie/parsers/sif/ast_impl/nodes.py: 91%
125 statements
« prev ^ index » next coverage.py v7.2.2, created at 2023-03-20 16:17 +0100
« prev ^ index » next coverage.py v7.2.2, created at 2023-03-20 16:17 +0100
1from xml.dom import minidom
2import enum
4from lottie.nvector import NVector
5from lottie.parsers.sif.ast_impl.base import SifAstNode, TypeDescriptor, ObjectRegistry
6from lottie.parsers.sif.xml.animatable import XmlAnimatable
7from lottie.parsers.sif.xml.wrappers import XmlBoneReference, XmlSifElement, XmlList
8from lottie.parsers.sif.sif.nodes import Segment, WeightedVector, Bline
9from lottie.parsers.sif.sif.enums import Smooth
10from lottie.parsers.sif.sif.core import SifNodeMeta, FrameTime
13class SifAstComplex(SifAstNode, metaclass=SifNodeMeta):
14 _nodes = []
16 def __init__(self, **kw):
17 for node in self._nodes:
18 node.initialize_object(kw, self)
20 @classmethod
21 def from_dom(cls, xml: minidom.Element, param: TypeDescriptor, registry: ObjectRegistry):
22 outcls = cls.get_class_from_dom(xml, param, registry)
23 instance = outcls()
24 for node in outcls._nodes:
25 node.from_xml(instance, xml, registry)
26 return instance
28 @classmethod
29 def get_class_from_dom(cls, xml: minidom.Element, param: TypeDescriptor, registry: ObjectRegistry):
30 return cls
32 def to_dom(self, dom: minidom.Document, param: TypeDescriptor):
33 element = self._prepare_to_dom(dom, param)
34 for node in self._nodes:
35 node.to_xml(self, element, dom, param)
36 return element
39class SifAstBoneLink(SifAstComplex):
40 _tag = "bone_link"
42 _nodes = [
43 XmlBoneReference("bone"),
44 XmlAnimatable("base_value", "vector", NVector(0, 0)),
45 XmlAnimatable("translate", "bool", True),
46 XmlAnimatable("rotate", "bool", True),
47 XmlAnimatable("skew", "bool", True),
48 XmlAnimatable("scale_x", "bool", True),
49 XmlAnimatable("scale_y", "bool", True),
50 ]
53class SifAstBoneInfluence(SifAstComplex):
54 _tag = "boneinfluence"
56 _nodes = [
57 # TODO bone_weight_list
58 XmlAnimatable("link", "vector", NVector(0, 0)),
59 ]
62class SifSegCalcTangent(SifAstComplex):
63 _tag = "segcalctangent"
65 _nodes = [
66 XmlSifElement("segment", Segment),
67 XmlAnimatable("amount", "real", .5),
68 ]
71class SifSegCalcVertex(SifAstComplex):
72 _tag = "segcalcvertex"
74 _nodes = [
75 XmlSifElement("segment", Segment),
76 XmlAnimatable("amount", "real", .5),
77 ]
80class WeightedAverage(SifAstComplex):
81 _tag = "weighted_average"
83 _nodes = [
84 XmlList(WeightedVector, "vectors", "entry"),
85 ]
87 def _prepare_to_dom(self, dom: minidom.Document, param: TypeDescriptor):
88 element = dom.createElement(self._tag)
89 element.setAttribute("type", "weighted_vector")
90 return element
93class SifAdd(SifAstComplex):
94 _tag = "add"
96 _nodes = [
97 XmlAnimatable("lhs", "_recurse"),
98 XmlAnimatable("rhs", "_recurse"),
99 XmlAnimatable("scalar", "real", 1.),
100 ]
103class SifAnimatedFile(SifAstComplex):
104 _tag = "animated_file"
106 _nodes = [
107 XmlAnimatable("filename", "string"),
108 ]
111class Accuracy(enum.Enum):
112 Rough = 0
113 Normal = 1
114 Fine = 2
115 Extreme = 3
118class DerivativeOrder:
119 FirstDerivative = 0
120 SecondDerivative = 1
123class SifDerivative(SifAstComplex):
124 _tag = "derivative"
126 _nodes = [
127 XmlAnimatable("link", "_recurse"),
128 XmlAnimatable("interval", "real", 0.01),
129 XmlAnimatable("accuracy", "integer", Accuracy.Normal, Accuracy),
130 XmlAnimatable("order", "integer", DerivativeOrder.FirstDerivative, DerivativeOrder),
131 ]
134class SifDynamic(SifAstComplex):
135 _tag = "dynamic"
137 _nodes = [
138 XmlAnimatable("tip_static", "vector", NVector(0, 0)),
139 XmlAnimatable("origin", "vector", NVector(0, 0)),
140 XmlAnimatable("force", "vector", NVector(0, 0)),
141 XmlAnimatable("torque", "real", 0.),
142 XmlAnimatable("damping", "real", 0.4),
143 XmlAnimatable("friction", "real", 0.4),
144 XmlAnimatable("spring", "real", 30.),
145 XmlAnimatable("torsion", "real", 30.),
146 XmlAnimatable("mass", "real", 0.3),
147 XmlAnimatable("inertia", "real", 0.3),
148 XmlAnimatable("spring_rigid", "bool", False),
149 XmlAnimatable("torsion_rigid", "bool", False),
150 XmlAnimatable("origin_drags_tip", "bool", True),
151 ]
154class SifGreyed(SifAstComplex):
155 _tag = "greyed"
157 _nodes = [
158 XmlAnimatable("link", "_recurse"),
159 ]
162class SifLinear(SifAstComplex):
163 _tag = "linear"
165 _nodes = [
166 XmlAnimatable("slope", "vector", NVector(0, 0)),
167 XmlAnimatable("offset", "vector", NVector(0, 0)),
168 ]
171class SifRadialComposite(SifAstComplex):
172 _tag = "radial_composite"
174 _nodes = [
175 XmlAnimatable("radius", "real", 0.),
176 XmlAnimatable("theta", "angle", 0.),
177 ]
180class SifComposite(SifAstComplex):
181 _tag = "composite"
183 @classmethod
184 def get_class_from_dom(cls, xml: minidom.Element, param: TypeDescriptor, registry: ObjectRegistry):
185 type = xml.getAttribute("type")
186 if type == "vector":
187 return SifVectorComposite
188 return None
190 def _prepare_to_dom(self, dom: minidom.Document, param: TypeDescriptor):
191 element = dom.createElement("composite")
192 element.setAttribute("type", param.typename)
193 return element
196class SifVectorComposite(SifComposite):
197 _type = "vector"
199 _nodes = [
200 XmlAnimatable("x", "real", 0.),
201 XmlAnimatable("y", "real", 0.),
202 ]
205class SifRandom(SifAstComplex):
206 _tag = "random"
208 _nodes = [
209 XmlAnimatable("link", "_recurse"),
210 XmlAnimatable("radius", "real", 0.),
211 XmlAnimatable("seed", "integer", 0),
212 XmlAnimatable("speed", "real", 1.),
213 XmlAnimatable("smooth", "integer", Smooth.Cubic, Smooth),
214 XmlAnimatable("loop", "real", 0.),
215 ]
218class SifReference(SifAstComplex):
219 _tag = "link"
221 _nodes = [
222 XmlAnimatable("reference", "_recurse"),
223 ]
226class SifScale(SifAstComplex):
227 _tag = "scale"
229 _nodes = [
230 XmlAnimatable("link", "_recurse"),
231 XmlAnimatable("scalar", "real", 1.),
232 ]
235class SifStep(SifAstComplex):
236 _tag = "step"
238 _nodes = [
239 XmlAnimatable("link", "_recurse"),
240 XmlAnimatable("duration", "time", FrameTime(1, FrameTime.Unit.Seconds)),
241 XmlAnimatable("start_time", "time", FrameTime(0, FrameTime.Unit.Seconds)),
242 XmlAnimatable("intersection", "real", 0.5),
243 ]
246class SifSubtract(SifAstComplex):
247 _tag = "subtract"
249 _nodes = [
250 XmlAnimatable("lhs", "_recurse"),
251 XmlAnimatable("rhs", "_recurse"),
252 XmlAnimatable("scalar", "real", 1.),
253 ]
256class SifSwitch(SifAstComplex):
257 _tag = "switch"
259 _nodes = [
260 XmlAnimatable("link_off", "_recurse"),
261 XmlAnimatable("link_on", "_recurse"),
262 XmlAnimatable("switch", "bool", False),
263 ]
266class SifTimedSwap(SifAstComplex):
267 _tag = "timed_swap"
269 _nodes = [
270 XmlAnimatable("before", "_recurse"),
271 XmlAnimatable("after", "_recurse"),
272 XmlAnimatable("time", "time", FrameTime(0, FrameTime.Unit.Seconds)),
273 XmlAnimatable("length", "time", FrameTime(0, FrameTime.Unit.Seconds)),
274 ]
277class SifTimeLoop(SifAstComplex):
278 _tag = "timeloop"
280 _nodes = [
281 XmlAnimatable("link", "_recurse"),
282 XmlAnimatable("link_time", "time", FrameTime(0, FrameTime.Unit.Seconds)),
283 XmlAnimatable("local_time", "time", FrameTime(0, FrameTime.Unit.Seconds)),
284 XmlAnimatable("duration", "time", FrameTime(0, FrameTime.Unit.Seconds)),
285 ]
288class SifPower(SifAstComplex):
289 _tag = "power"
291 _nodes = [
292 XmlAnimatable("base", "real", 1.),
293 XmlAnimatable("power", "real", 1.),
294 XmlAnimatable("epsilon", "real", 0.000001),
295 XmlAnimatable("infinite", "real", 999999.),
296 ]
299class SifBlineCalcTangent(SifAstComplex):
300 _tag = "blinecalctangent"
302 _nodes = [
303 XmlSifElement("bline", Bline),
304 XmlAnimatable("loop", "bool", False),
305 XmlAnimatable("amount", "real", 0.5),
306 XmlAnimatable("offset", "angle", 0.),
307 XmlAnimatable("scale", "real", 1.),
308 XmlAnimatable("fixed_length", "bool", False),
309 XmlAnimatable("homogeneous", "bool", False),
310 ]
313class SifBlineCalcVertex(SifAstComplex):
314 _tag = "blinecalcvertex"
316 _nodes = [
317 XmlSifElement("bline", Bline),
318 XmlAnimatable("loop", "bool", False),
319 XmlAnimatable("amount", "real", 0.5),
320 XmlAnimatable("homogeneous", "bool", False),
321 ]