Coverage for lib/lottie/parsers/sif/sif/nodes.py: 90%
426 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
1import enum
2from lottie.parsers.sif.sif.core import SifNodeMeta, FrameTime
3from lottie.parsers.sif.sif.enums import Smooth
4from lottie.parsers.sif.xml.utils import *
5from lottie.parsers.sif.xml.core_nodes import *
6from lottie.parsers.sif.xml.animatable import *
7from lottie.parsers.sif.xml.wrappers import *
10class SifNode(metaclass=SifNodeMeta):
11 def __init__(self, **kw):
12 for node in self._nodes:
13 node.initialize_object(kw, self)
15 def __setattr__(self, name, value):
16 if name in self._nodemap:
17 value = self._nodemap[name].clean(value)
18 return super().__setattr__(name, value)
20 @staticmethod
21 def static_from_dom(cls, xml: minidom.Element, registry: ObjectRegistry):
22 instance = cls()
23 for node in cls._nodes:
24 node.from_xml(instance, xml, registry)
25 return instance
27 @classmethod
28 def from_dom(cls, xml: minidom.Element, registry: ObjectRegistry):
29 return SifNode.static_from_dom(cls, xml, registry)
31 def to_dom(self, dom: minidom.Document):
32 element = dom.createElement(self._tag)
33 for node in self._nodes:
34 node.to_xml(self, element, dom)
35 return element
38class AbstractTransform(SifNode):
39 _nodes = [
40 XmlFixedAttribute("type", "transformation")
41 ]
43 @classmethod
44 def from_dom(cls, xml: minidom.Element, registry: ObjectRegistry):
45 if xml.tagName == "bone_link": 45 ↛ 46line 45 didn't jump to line 46, because the condition on line 45 was never true
46 return SifNode.static_from_dom(BoneLinkTransform, xml, registry)
48 if xml.tagName != "composite": 48 ↛ 49line 48 didn't jump to line 49, because the condition on line 48 was never true
49 raise ValueError("Invalid transform element: %s" % xml.tagName)
50 return SifNode.static_from_dom(SifTransform, xml, registry)
53class SifTransform(AbstractTransform):
54 _tag = "composite"
56 _nodes = [
57 XmlAnimatable("offset", "vector", NVector(0, 0)),
58 XmlAnimatable("angle", "angle", 0.),
59 XmlAnimatable("skew_angle", "angle", 0.),
60 XmlAnimatable("scale", "vector", NVector(1, 1)),
61 ]
64class BlinePoint(SifNode):
65 _tag = "composite"
67 _nodes = [
68 XmlFixedAttribute("type", "bline_point"),
69 XmlAnimatable("point", "vector", NVector(0, 0)),
70 XmlAnimatable("width", "real", 1.),
71 XmlAnimatable("origin", "real", .5),
72 XmlAnimatable("split", "bool", False),
73 XmlAnimatable("t1", "vector"),
74 XmlAnimatable("t2", "vector"),
75 XmlAnimatable("split_radius", "bool", True),
76 XmlAnimatable("split_angle", "bool", False),
77 ]
80class Bline(SifNode):
81 _nodes = [
82 XmlAttribute("loop", bool_str, False),
83 XmlFixedAttribute("type", "bline_point"),
84 XmlList(BlinePoint, "points", "entry"),
85 ]
88class BlendMethod(enum.Enum):
89 Composite = 0
90 Straight = 1
91 Onto = 13
92 StraightOnto = 21
93 Behind = 12
94 Screen = 16
95 Overlay = 20
96 HardLight = 17
97 Multiply = 6
98 Divide = 7
99 Add = 4
100 Subtract = 5
101 Difference = 18
102 Lighten = 2
103 Darken = 3
104 Color = 8
105 Hue = 9
106 Saturation = 10
107 Luminosity = 11
108 AlphaOver = 19
109 AlphaBrighten = 14
110 AlphaDarken = 15
111 Alpha = 23
114class BlurType(enum.Enum):
115 Box = 0
116 FastGaussian = 1
117 CrossHatch = 2
118 Gaussian = 3
119 Disc = 4
122class WindingStyle(enum.Enum):
123 NonZero = 0
124 EvenOdd = 1
127class Def(SifNode):
128 _nodes = [
129 XmlAttribute("guid", str),
130 XmlAttribute("id", str),
131 ]
132 _subclasses = None
134 @classmethod
135 def from_dom(cls, xml: minidom.Element, registry: ObjectRegistry):
136 actual_class = cls
137 if cls == Def:
138 actual_class = Def.def_types()[xml.tagName]
140 obj = SifNode.static_from_dom(actual_class, xml, registry)
141 if obj.id:
142 registry.register_as(obj, obj.id)
143 if obj.guid:
144 registry.register(obj)
145 return obj
147 @staticmethod
148 def tags():
149 return list(Def.def_types().keys())
151 @staticmethod
152 def def_types():
153 if Def._subclasses is None: 153 ↛ 156line 153 didn't jump to line 156, because the condition on line 153 was never false
154 Def._subclasses = {}
155 Def._gather_def_types(Def)
156 return Def._subclasses
158 @staticmethod
159 def _gather_def_types(cls):
160 for subcls in cls.__subclasses__():
161 Def._subclasses[subcls._tag] = subcls
162 Def._gather_def_types(subcls)
165class Duplicate(Def):
166 _nodes = [
167 XmlFixedAttribute("type", "real"),
168 XmlAnimatable("from", "real", 1.),
169 XmlAnimatable("to", "real", 1.),
170 XmlAnimatable("step", "real", 1.),
171 ]
173 @property
174 def from_(self):
175 return getattr(self, "from")
177 @from_.setter
178 def from_(self, value):
179 setattr(self, "from", value)
182class ExportedValue(Def):
183 def __init__(self, id, value, typename):
184 self.id = id
185 self.value = value
186 self.type = TypeDescriptor(typename)
188 def to_dom(self, dom: minidom.Document):
189 element = self.value.to_dom(dom, self.type)
190 element.setAttribute("id", self.id)
191 return element
194class Layer(SifNode):
195 _types = None
197 _version = "0.1"
198 _layer_type = None
200 _nodes = [
201 XmlAttribute("type", str),
202 XmlAttribute("active", bool_str, True),
203 XmlAttribute("version", str),
204 XmlAttribute("exclude_from_rendering", bool_str, False),
205 XmlAttribute("desc", str, ""),
206 ]
208 def __init__(self, **kw):
209 kw.setdefault("version", self._version)
210 super().__init__(**kw)
211 self.type = self._layer_type
213 def __repr__(self):
214 return "<%s.%s %r>" % (__name__, self.__class__.__name__, self.desc or self.type)
216 def to_dom(self, dom: minidom.Document):
217 element = dom.createElement("layer")
218 for node in self._nodes:
219 node.to_xml(self, element, dom)
220 return element
222 @classmethod
223 def from_dom(cls, xml: minidom.Element, registry: ObjectRegistry):
224 actual_class = cls
225 if cls == Layer: 225 ↛ 229line 225 didn't jump to line 229, because the condition on line 225 was never false
226 type = xml.getAttribute("type")
227 actual_class = Layer.layer_types().get(type, Layer)
229 return SifNode.static_from_dom(actual_class, xml, registry)
231 @staticmethod
232 def layer_types():
233 if Layer._types is None:
234 Layer._types = {}
235 Layer._gather_layer_types(Layer)
236 return Layer._types
238 @staticmethod
239 def _gather_layer_types(cls):
240 for subcls in cls.__subclasses__():
241 if subcls._layer_type:
242 Layer._types[subcls._layer_type] = subcls
243 Layer._gather_layer_types(subcls)
246class DrawableLayer(Layer):
247 _nodes = [
248 XmlParam("z_depth", "real", 0.),
249 XmlParam("amount", "real", 1.),
250 XmlParam("blend_method", "integer", BlendMethod.Composite, BlendMethod, static=True),
251 ]
254class GroupLayerBase(DrawableLayer):
255 _nodes = [
256 XmlParam("origin", "vector", NVector(0, 0)),
257 XmlParamSif("transformation", AbstractTransform, SifTransform),
258 XmlWrapperParam("canvas", XmlWrapper("canvas", XmlList(Layer))),
260 XmlParam("time_dilation", "real", 1.),
261 XmlParam("time_offset", "time", FrameTime(0, FrameTime.Unit.Frame)),
262 XmlParam("children_lock", "bool", False, static=True),
263 XmlParam("outline_grow", "real", 0.),
264 ]
266 def add_layer(self, layer: Layer):
267 self.layers.append(layer)
268 return layer
271class FilterGroupLayer(GroupLayerBase):
272 _layer_type = "filter_group"
274 _nodes = [
275 ]
278class GroupLayer(GroupLayerBase):
279 _layer_type = "group"
280 _version = "0.3"
282 _nodes = [
283 XmlParam("z_range", "bool", False, static=True),
284 XmlParam("z_range_position", "real", 0.),
285 XmlParam("z_range_depth", "real", 0.),
286 XmlParam("z_range_blur", "real", 0.),
287 ]
290class SwitchLayer(GroupLayerBase):
291 _layer_type = "switch"
293 _nodes = [
294 XmlParam("layer_name", "string"),
295 XmlParam("layer_depth", "integer", -1),
296 ]
299class RectangleLayer(DrawableLayer):
300 _layer_type = "rectangle"
302 _nodes = [
303 XmlParam("color", "color", NVector(0, 0, 0, 1)),
304 XmlParam("point1", "vector", NVector(0, 0)),
305 XmlParam("point2", "vector", NVector(0, 0)),
306 XmlParam("expand", "real", 0.),
307 XmlParam("invert", "bool", False),
308 XmlParam("feather_x", "real", 0.),
309 XmlParam("feather_y", "real", 0.),
310 XmlParam("bevel", "real", 0.),
311 XmlParam("bevCircle", "bool", True),
312 ]
315class CircleLayer(DrawableLayer):
316 _layer_type = "circle"
318 _nodes = [
319 XmlParam("color", "color", NVector(0, 0, 0, 1)),
320 XmlParam("radius", "real", 0.),
321 XmlParam("feather", "real", 0.),
322 XmlParam("origin", "vector", NVector(0, 0)),
323 XmlParam("invert", "bool", False),
324 ]
327class SimpleCircleLayer(DrawableLayer):
328 _layer_type = "simple_circle"
330 _nodes = [
331 XmlParam("color", "color", NVector(0, 0, 0, 1)),
332 XmlParam("radius", "real", 0.),
333 XmlParam("center", "vector", NVector(0, 0)),
334 ]
337class ComplexShape(DrawableLayer):
338 _nodes = [
339 XmlParam("color", "color", NVector(0, 0, 0, 1)),
340 XmlParam("origin", "vector", NVector(0, 0)),
341 XmlParam("invert", "bool", False),
342 XmlParam("antialias", "bool", True),
343 XmlParam("feather", "real", 0.),
344 XmlParam("blurtype", "integer", BlurType.FastGaussian, BlurType),
345 XmlParam("winding_style", "integer", WindingStyle.NonZero, WindingStyle),
346 ]
349class StarLayer(ComplexShape):
350 _layer_type = "star"
352 _nodes = [
353 XmlParam("radius1", "real", 0.),
354 XmlParam("radius2", "real", 0.),
355 XmlParam("angle", "angle", 0.),
356 XmlParam("points", "integer", 5),
357 XmlParam("regular_polygon", "bool", False),
358 ]
361class LineCap(enum.Enum):
362 Rounded = 1
363 Squared = 2
364 Peak = 3
365 Flat = 4
366 InnerRounded = 5
367 OffPeak = 6
370class CuspStyle(enum.Enum):
371 Miter = 0
372 Round = 1
373 Bevel = 2
376class AbstractOutline(ComplexShape):
377 _nodes = [
378 XmlParam("width", "real", 0.1),
379 XmlParam("expand", "real", 0.),
380 XmlParamSif("bline", Bline),
381 ]
384class OutlineLayer(AbstractOutline):
385 _layer_type = "outline"
387 _nodes = [
388 XmlParam("sharp_cusps", "bool", True),
389 XmlParam("round_tip[0]", "bool", True),
390 XmlParam("round_tip[1]", "bool", True),
391 XmlParam("homogeneous_width", "bool", True),
392 ]
394 @property
395 def start_tip(self):
396 return LineCap.Rounded if self.round_tip_0 else LineCap.Flat
398 @property
399 def end_tip(self):
400 return LineCap.Rounded if self.round_tip_1 else LineCap.Flat
402 @property
403 def cusp_type(self):
404 return CuspStyle.Miter if self.sharp_cusps else CuspStyle.Round
407class AdvancedOutlineLayer(AbstractOutline):
408 _layer_type = "advanced_outline"
410 _nodes = [
411 XmlParam("start_tip", "integer", LineCap.Rounded, LineCap),
412 XmlParam("end_tip", "integer", LineCap.Rounded, LineCap),
413 XmlParam("cusp_type", "integer", CuspStyle.Miter, CuspStyle),
414 XmlParam("smoothness", "real", 1.),
415 XmlParam("homogeneous", "bool", False),
416 # TODO wplist
417 ]
420class PolygonLayer(ComplexShape):
421 _layer_type = "polygon"
423 _nodes = [
424 XmlDynamicListParam("vector_list", "vector", "points"),
425 ]
428class RegionLayer(ComplexShape):
429 _layer_type = "region"
431 _nodes = [
432 XmlParamSif("bline", Bline),
433 ]
436class FontStyle(enum.Enum):
437 Normal = 0
438 Oblique = 1
439 Italic = 2
442class TextLayer(DrawableLayer):
443 _layer_type = "text"
445 _nodes = [
446 XmlParam("text", "string"),
447 XmlParam("color", "color", NVector(0, 0, 0, 1)),
448 XmlParam("family", "string"),
449 XmlParam("style", "integer", FontStyle.Normal, FontStyle),
450 XmlParam("weight", "integer", 400),
451 XmlParam("compress", "real", 1.),
452 XmlParam("vcompress", "real", 1.),
453 XmlParam("size", "vector", NVector(1, 1)),
454 XmlParam("orient", "vector", NVector(.5, .5)),
455 XmlParam("origin", "vector", NVector(0, 0)),
456 XmlParam("use_kerning", "bool", False),
457 XmlParam("grid_fit", "bool", False),
458 XmlParam("invert", "bool", False),
459 ]
462class TransformDown(Layer):
463 pass
466class TranslateLayer(TransformDown):
467 _layer_type = "translate"
469 _nodes = [
470 XmlParam("origin", "vector", NVector(0, 0)),
471 ]
474class RotateLayer(TransformDown):
475 _layer_type = "rotate"
477 _nodes = [
478 XmlParam("origin", "vector", NVector(0, 0)),
479 XmlParam("amount", "angle", 0.),
480 ]
483class ScaleLayer(TransformDown):
484 _layer_type = "zoom"
486 _nodes = [
487 XmlParam("center", "vector", NVector(0, 0)),
488 XmlParam("amount", "real", 0.),
489 ]
492class GradientLayer(DrawableLayer):
493 _nodes = [
494 XmlParam("gradient", "gradient", []),
495 XmlParam("loop", "bool", False),
496 XmlParam("zigzag", "bool", False),
497 ]
500class RadialGradient(GradientLayer):
501 _layer_type = "radial_gradient"
503 _nodes = [
504 XmlParam("center", "vector", NVector(0, 0)),
505 XmlParam("radius", "real", 1),
506 ]
509class LinearGradient(GradientLayer):
510 _layer_type = "linear_gradient"
512 _nodes = [
513 XmlParam("p1", "vector", NVector(0, 0)),
514 XmlParam("p2", "vector", NVector(0, 0)),
515 ]
518class ConicalLinearGradient(DrawableLayer):
519 _layer_type = "conical_gradient"
521 _nodes = [
522 XmlParam("gradient", "gradient", []),
523 XmlParam("symmetric", "bool", False),
524 XmlParam("center", "vector", NVector(0, 0)),
525 XmlParam("angle", "angle", 0.),
526 ]
529class CurveGradient(GradientLayer):
530 _layer_type = "curve_gradient"
532 _nodes = [
533 XmlParam("origin", "vector", NVector(0, 0)),
534 XmlParam("width", "real", 0.0833333358),
535 XmlParamSif("bline", Bline),
536 XmlParam("perpendicular", "bool", False),
537 XmlParam("fast", "bool", True),
538 ]
541class NoiseLayer(DrawableLayer):
542 _layer_type = "noise"
544 _nodes = [
545 XmlParam("gradient", "gradient", []),
546 XmlParam("seed", "integer", 0),
547 XmlParam("size", "vector", NVector(1, 1)),
548 XmlParam("smooth", "integer", Smooth.Cosine, Smooth),
549 XmlParam("detail", "integer", 4),
550 XmlParam("speed", "integer", 0.),
551 XmlParam("turbulent", "bool", False),
552 XmlParam("do_alpha", "bool", False),
553 XmlParam("super_sample", "bool", False),
554 ]
557class SpiralGradient(DrawableLayer):
558 _layer_type = "spiral_gradient"
560 _nodes = [
561 XmlParam("gradient", "gradient", []),
562 XmlParam("center", "vector", NVector(0, 0)),
563 XmlParam("radius", "real", 0.5),
564 XmlParam("angle", "real", 0),
565 XmlParam("clockwise", "bool", False),
566 ]
569class BoneRoot(SifNode):
570 _tag = "bone_root"
572 _nodes = [
573 XmlFixedAttribute("type", "bone_object"),
574 XmlAttribute("guid", str)
575 ]
577 @classmethod
578 def from_dom(cls, xml: minidom.Element, registry: ObjectRegistry):
579 if xml.tagName == "bone_root":
580 val = SifNode.static_from_dom(BoneRoot, xml, registry)
581 else:
582 val = SifNode.static_from_dom(Bone, xml, registry)
583 registry.register(val)
584 return val
586 def __repr__(self):
587 return "<%s %r>" % (self.__class__.__name__, self.guid)
590class Bone(BoneRoot):
591 _tag = "bone"
593 _nodes = [
594 XmlWrapper("name", XmlSimpleElement("string", att_name="name")),
595 XmlBoneReference("parent"),
596 XmlAnimatable("origin", "vector", NVector(0, 0)),
597 XmlAnimatable("angle", "angle", 0.),
598 XmlAnimatable("scalelx", "real", 1.),
599 XmlAnimatable("width", "real", .1),
600 XmlAnimatable("scalex", "real", 1.),
601 XmlAnimatable("tipwidth", "real", .1),
602 XmlAnimatable("bone_depth", "real", 0.),
603 XmlAnimatable("length", "real", 1.),
604 ]
607class BoneLinkTransform(AbstractTransform):
608 _tag = "bone_link"
610 _nodes = [
611 XmlBoneReference("bone"),
612 XmlSifElement("base_value", SifTransform),
613 XmlAnimatable("translate", "bool", True),
614 XmlAnimatable("rotate", "bool", True),
615 XmlAnimatable("skew", "bool", True),
616 XmlAnimatable("scale_x", "bool", True),
617 XmlAnimatable("scale_y", "bool", True),
618 ]
621class SkeletonLayer(Layer):
622 _layer_type = "skeleton"
624 _nodes = [
625 XmlParam("z_depth", "real", 0.),
626 XmlParam("amount", "real", 1.),
627 XmlParam("name", "string"),
628 XmlStaticListParam("bones", "bone_object")
629 ]
632class SubsamplingType(enum.Enum):
633 Constant = 0
634 Linear = 1
635 Hyperbolic = 2
638class MotionBlurLayer(Layer):
639 _layer_type = "MotionBlur"
641 _nodes = [
642 XmlParam("aperture", "time", FrameTime(1, FrameTime.Unit.Seconds)),
643 XmlParam("subsamples_factor", "real", 1.),
644 XmlParam("subsampling_type", "integer", SubsamplingType.Hyperbolic, SubsamplingType),
645 XmlParam("subsample_start", "real", 0.),
646 XmlParam("subsample_end", "real", 1.),
647 ]
650class BlurLayer(DrawableLayer):
651 _layer_type = "blur"
653 _nodes = [
654 XmlParam("size", "vector", NVector(1, 1)),
655 XmlParam("type", "integer", BlurType.FastGaussian, BlurType),
656 ]
659class RadialBlurLayer(DrawableLayer):
660 _layer_type = "radial_blur"
662 _nodes = [
663 XmlParam("origin", "vector", NVector(0, 0)),
664 XmlParam("size", "real", .2),
665 XmlParam("fade_out", "bool", False),
666 ]
669class CurveWarpLayer(Layer):
670 _layer_type = "curve_warp"
672 _nodes = [
673 XmlParam("origin", "vector", NVector(0, 0)),
674 XmlParam("perp_width", "real", 1.),
675 XmlParam("start_point", "vector", NVector(0, 0)),
676 XmlParam("end_point", "vector", NVector(0, 0)),
677 XmlParamSif("bline", Bline),
678 XmlParam("fast", "bool", True),
679 ]
682class InsideOutLayer(Layer):
683 _layer_type = "inside_out"
685 _nodes = [
686 XmlParam("origin", "vector", NVector(0, 0)),
687 ]
690class NoiseDistortLayer(DrawableLayer):
691 _layer_type = "noise_distort"
693 _nodes = [
694 XmlParam("displacement", "vector", NVector(0.25, 0.25)),
695 XmlParam("size", "vector", NVector(1, 1)),
696 XmlParam("seed", "integer", 0),
697 XmlParam("smooth", "integer", Smooth.Cosine, Smooth),
698 XmlParam("detail", "integer", 4),
699 XmlParam("speed", "real", 0.),
700 XmlParam("turbulent", "bool", False),
701 ]
704class SkeletonDeformationLayer(DrawableLayer):
705 _layer_type = "skeleton_deformation"
707 _nodes = [
708 XmlParam("displacement", "vector", NVector(0.25, 0.25)),
709 XmlParam("point1", "vector", NVector(0, 0)),
710 XmlParam("point2", "vector", NVector(0, 0)),
711 XmlParam("x_subdivisions", "integer", 32),
712 XmlParam("y_subdivisions", "integer", 32),
713 # TODO bones (pair_bone_object_bone_object)
714 ]
717class DistortType(enum.Enum):
718 Spherize = 0
719 VerticalBar = 1
720 HorizontalBar = 2
723class SpherizeLayer(Layer):
724 _layer_type = "spherize"
726 _nodes = [
727 XmlParam("center", "vector", NVector(0., 0.)),
728 XmlParam("radius", "real", 1.),
729 XmlParam("amount", "real", 1.),
730 XmlParam("clip", "bool", False),
731 XmlParam("type", "integer", DistortType.Spherize, DistortType),
732 ]
735class StretchLayer(Layer):
736 _layer_type = "stretch"
738 _nodes = [
739 XmlParam("amount", "vector", NVector(1., 1.)),
740 XmlParam("center", "vector", NVector(0., 0.)),
741 ]
744class TwirlLayer(Layer):
745 _layer_type = "twirl"
747 _nodes = [
748 XmlParam("center", "vector", NVector(0., 0.)),
749 XmlParam("radius", "real", 1.),
750 XmlParam("rotations", "real", 0.),
751 XmlParam("distort_inside", "bool", True),
752 XmlParam("distort_outside", "bool", False),
753 ]
756class WarpLayer(Layer):
757 _layer_type = "warp"
759 _nodes = [
760 XmlParam("src_tl", "vector", NVector(0., 0.)),
761 XmlParam("src_br", "vector", NVector(0., 0.)),
762 XmlParam("dest_tl", "vector", NVector(0., 0.)),
763 XmlParam("dest_tr", "vector", NVector(0., 0.)),
764 XmlParam("dest_bl", "vector", NVector(0., 0.)),
765 XmlParam("dest_br", "vector", NVector(0., 0.)),
766 XmlParam("clip", "bool", True),
767 XmlParam("interpolation", "integer", Smooth.Cubic, Smooth),
768 ]
771class MetaballsLayer(DrawableLayer):
772 _layer_type = "metaballs"
774 _nodes = [
775 XmlParam("gradient", "gradient", []),
776 XmlDynamicListParam("centers", "vector"),
777 XmlDynamicListParam("radii", "real"),
778 XmlDynamicListParam("weights", "real"),
779 XmlParam("threshold", "real", 0.),
780 XmlParam("threshold1", "real", 1.),
781 XmlParam("positive", "bool", False),
782 ]
785class ClampLayer(Layer):
786 _layer_type = "clamp"
788 _nodes = [
789 XmlParam("invert_negative", "bool", False),
790 XmlParam("clamp_ceiling", "bool", False),
791 XmlParam("ceiling", "real", 1.),
792 XmlParam("floor", "real", 0.),
793 ]
796class ColorCorrectLayer(Layer):
797 _layer_type = "colorcorrect"
799 _nodes = [
800 XmlParam("hue_adjust", "angle", 0.),
801 XmlParam("brightness", "real", 0.),
802 XmlParam("contrast", "real", 1.),
803 XmlParam("exposure", "real", 0.),
804 XmlParam("gamma", "real", 1.),
805 ]
808class HalftoneType(enum.Enum):
809 Symmetric = 0
810 LightOnDark = 2
811 Diamond = 3
812 Stripe = 4
815class Halftone2Layer(DrawableLayer):
816 _layer_type = "halftone2"
818 _nodes = [
819 XmlParam("origin", "vector", NVector(0, 0)),
820 XmlParam("angle", "angle", 0.),
821 XmlParam("size", "vector", NVector(0.25, 0.25)),
822 XmlParam("color_light", "color", NVector(1, 1, 1, 1)),
823 XmlParam("color_dark", "color", NVector(0, 0, 0, 1)),
824 XmlParam("type", "integer", HalftoneType.Symmetric, HalftoneType),
825 ]
828class Halftone3Layer(DrawableLayer):
829 _layer_type = "halftone3"
831 _nodes = [
832 XmlParam("origin", "vector", NVector(0, 0)),
833 XmlParam("size", "vector", NVector(0.25, 0.25)),
834 XmlParam("type", "integer", HalftoneType.Symmetric, HalftoneType),
835 XmlParam("subtractive", "bool", True),
837 XmlParam("color[0]", "color", NVector(0, 1, 1, 1)),
838 XmlParam("tone[0].origin", "vector", NVector(0, 0)),
839 XmlParam("tone[0].angle", "angle", 0.),
841 XmlParam("color[1]", "color", NVector(1, 0, 1, 1)),
842 XmlParam("tone[1].origin", "vector", NVector(0, 0)),
843 XmlParam("tone[1].angle", "angle", 30.),
845 XmlParam("color[2]", "color", NVector(1, 1, 0, 1)),
846 XmlParam("tone[2].origin", "vector", NVector(0, 0)),
847 XmlParam("tone[2].angle", "angle", 60.),
848 ]
851class LumakeyLayer(DrawableLayer):
852 _layer_type = "lumakey"
854 _nodes = [
855 ]
858class JuliaLayer(DrawableLayer):
859 _layer_type = "julia"
861 _nodes = [
862 XmlParam("icolor", "color", NVector(0, 0, 0, 1)),
863 XmlParam("ocolor", "color", NVector(0, 0, 0, 1)),
864 XmlParam("color_shift", "real", 0.),
865 XmlParam("iterations", "integer", 32),
866 XmlParam("seed", "vector", NVector(0, 0)),
867 XmlParam("bailout", "real", 2.),
868 XmlParam("distort_inside", "bool", True),
869 XmlParam("shade_inside", "bool", True),
870 XmlParam("solid_inside", "bool", False),
871 XmlParam("invert_inside", "bool", False),
872 XmlParam("color_inside", "bool", True),
873 XmlParam("distort_outside", "bool", True),
874 XmlParam("shade_outside", "bool", True),
875 XmlParam("solid_outside", "bool", False),
876 XmlParam("invert_outside", "bool", False),
877 XmlParam("color_outside", "bool", False),
878 XmlParam("color_cycle", "bool", False),
879 XmlParam("smooth_outside", "bool", True),
880 XmlParam("broken", "bool", False),
881 ]
884class MandelbrotLayer(Layer):
885 _layer_type = "mandelbrot"
887 _nodes = [
888 XmlParam("iterations", "integer", 32),
889 XmlParam("bailout", "real", 2.),
890 XmlParam("broken", "bool", False),
891 XmlParam("distort_inside", "bool", True),
892 XmlParam("shade_inside", "bool", True),
893 XmlParam("solid_inside", "bool", False),
894 XmlParam("invert_inside", "bool", False),
895 XmlParam("distort_outside", "bool", True),
896 XmlParam("shade_outside", "bool", True),
897 XmlParam("solid_outside", "bool", False),
898 XmlParam("invert_outside", "bool", False),
899 XmlParam("smooth_outside", "bool", True),
901 XmlParam("gradient_inside", "gradient", []),
902 XmlParam("gradient_offset_inside", "real", 0.),
903 XmlParam("gradient_loop_inside", "bool", True),
905 XmlParam("gradient_outside", "gradient", []),
906 XmlParam("gradient_offset_outside", "real", 0.),
907 XmlParam("gradient_loop_outside", "bool", True),
908 XmlParam("gradient_scale_outside", "real", 1.),
909 ]
912class CheckerboardLayer(DrawableLayer):
913 _layer_type = "checker_board"
915 _nodes = [
916 XmlParam("color", "color", NVector(0, 0, 0, 1)),
917 XmlParam("origin", "vector", NVector(0, 0)),
918 XmlParam("size", "vector", NVector(0.25, 0.25)),
919 XmlParam("antialias", "bool", True),
920 ]
923class SolidColorLayer(DrawableLayer):
924 _layer_type = "SolidColor"
926 _nodes = [
927 XmlParam("color", "color", NVector(0, 0, 0, 1)),
928 ]
931class DuplicateLayer(DrawableLayer):
932 _layer_type = "duplicate"
934 _nodes = [
935 XmlParam("index", "real"),
936 ]
939class ImportedImageLayer(DrawableLayer):
940 _layer_type = "import"
942 _nodes = [
943 XmlParam("tl", "vector", NVector(0, 0)),
944 XmlParam("br", "vector", NVector(0, 0)),
945 XmlParam("c", "integer", Smooth.Linear, Smooth),
946 XmlParam("gamma_adjust", "real", 1.),
947 XmlParam("filename", "string"),
948 XmlParam("time_offset", "time", FrameTime(0, FrameTime.Unit.Frame)),
949 ]
952class PlantLayer(DrawableLayer):
953 _layer_type = "plant"
955 _nodes = [
956 XmlParamSif("bline", Bline),
957 XmlParam("origin", "vector", NVector(0, 0)),
958 XmlParam("gradient", "gradient", []),
959 XmlParam("split_angle", "angle", 10.),
960 XmlParam("gravity", "vector", NVector(0, -.1)),
961 XmlParam("velocity", "real", .3),
962 XmlParam("perp_velocity", "real", 0.),
963 XmlParam("size", "real", 0.015),
964 XmlParam("size_as_alpha", "bool", False),
965 XmlParam("reverse", "bool", True),
966 XmlParam("step", "real", 0.01),
967 XmlParam("seed", "integer", 0),
968 XmlParam("splits", "integer", 5),
969 XmlParam("sprouts", "integer", 5),
970 XmlParam("random_factor", "real", 0.2),
971 XmlParam("drag", "real", 0.1),
972 XmlParam("use_width", "bool", True),
973 ]
976class SoundLayer(Layer):
977 _layer_type = "sound"
979 _nodes = [
980 XmlParam("z_depth", "real", 0.),
981 XmlParam("filename", "string"),
982 XmlParam("delay", "time", FrameTime(0, FrameTime.Unit.Seconds)),
983 XmlParam("volume", "real", 1.),
984 ]
987class SuperSampleLayer(Layer):
988 _layer_type = "super_sample"
990 _nodes = [
991 XmlParam("width", "integer", 2),
992 XmlParam("height", "integer", 2),
993 XmlParam("scanline", "bool", False),
994 XmlParam("alpha_aware", "bool", True),
995 ]
998class XorPatternLayer(DrawableLayer):
999 _layer_type = "xor_pattern"
1001 _nodes = [
1002 XmlParam("origin", "vecor", NVector(0, 0)),
1003 XmlParam("size", "vecor", NVector(0.25, 0.25)),
1004 ]
1007class BevelLayer(DrawableLayer):
1008 _layer_type = "bevel"
1010 _nodes = [
1011 XmlParam("type", "integer", BlurType.FastGaussian, BlurType),
1012 XmlParam("color1", "color", NVector(1, 1, 1, 1)),
1013 XmlParam("color2", "color", NVector(0, 0, 0, 1)),
1014 XmlParam("angle", "angle", 135.),
1015 XmlParam("depth", "real", .2),
1016 XmlParam("softness", "real", .1),
1017 XmlParam("use_luma", "bool", False),
1018 XmlParam("solid", "bool", False),
1019 ]
1022class ShadeLayer(DrawableLayer):
1023 _layer_type = "shade"
1025 _nodes = [
1026 XmlParam("type", "integer", BlurType.FastGaussian, BlurType),
1027 XmlParam("color", "color", NVector(1, 1, 1, 1)),
1028 XmlParam("origin", "vector", NVector(0, 0)),
1029 XmlParam("size", "vector", NVector(0.1, 0.1)),
1030 XmlParam("invert", "bool", False),
1031 ]
1034class FreeTimeLayer(Layer):
1035 _layer_type = "freetime"
1037 _nodes = [
1038 XmlParam("z_depth", "real", 0.),
1039 XmlParam("time", "time", FrameTime(0, FrameTime.Unit.Seconds)),
1040 ]
1043class StroboscopeLayer(Layer):
1044 _layer_type = "stroboscope"
1046 _nodes = [
1047 XmlParam("z_depth", "real", 0.),
1048 XmlParam("frequency", "real", 2.),
1049 ]
1052class TimeLoopLayer(Layer):
1053 _layer_type = "timeloop"
1055 _nodes = [
1056 XmlParam("z_depth", "real", 0.),
1057 XmlParam("link_time", "time", FrameTime(0, FrameTime.Unit.Seconds), static=True),
1058 XmlParam("local_time", "time", FrameTime(0, FrameTime.Unit.Seconds), static=True),
1059 XmlParam("duration", "time", FrameTime(0, FrameTime.Unit.Seconds), static=True),
1060 XmlParam("only_for_positive_duration", "bool", False, static=True),
1061 XmlParam("symmetrical", "bool", True, static=True),
1062 ]
1065class Keyframe(SifNode):
1066 _nodes = [
1067 XmlAttribute("active", bool_str, True),
1068 XmlAttribute("time", FrameTime, FrameTime(0, FrameTime.Unit.Frame)),
1069 ]
1072class Canvas(SifNode, ObjectRegistry):
1073 _nodes = [
1074 XmlAttribute("version"),
1075 XmlAttribute("width", float, 512),
1076 XmlAttribute("height", float, 512),
1077 XmlAttribute("xres", float, 2834.645752),
1078 XmlAttribute("yres", float, 2834.645752),
1079 XmlAttribute("gamma-r", float, 1.),
1080 XmlAttribute("gamma-g", float, 1.),
1081 XmlAttribute("gamma-b", float, 1.),
1082 XmlAttribute("view-box", NVector),
1083 XmlAttribute("antialias", bool, True),
1084 XmlAttribute("fps", float, 60),
1085 XmlAttribute("begin-time", FrameTime, FrameTime(0, FrameTime.Unit.Frame)),
1086 XmlAttribute("end-time", FrameTime, FrameTime(3, FrameTime.Unit.Seconds)),
1087 XmlAttribute("bgcolor", NVector, NVector(0, 0, 0, 0)),
1088 XmlSimpleElement("name"),
1089 XmlMeta("background_first_color", NVector, NVector(0.88, 0.88, 0.88)),
1090 XmlMeta("background_rendering", bool, False),
1091 XmlMeta("background_second_color", NVector, NVector(0.65, 0.65, 0.65)),
1092 XmlMeta("background_size", NVector, NVector(15, 15)),
1093 XmlMeta("grid_color", NVector, NVector(0.62, 0.62, 0.62)),
1094 XmlMeta("grid_show", bool, False),
1095 XmlMeta("grid_size", NVector, NVector(0.25, 0.25)),
1096 XmlMeta("grid_snap", bool, False),
1097 XmlMeta("guide_color", NVector, NVector(0.4, 0.4, 1)),
1098 XmlMeta("guide_show", bool, True),
1099 XmlMeta("guide_snap", bool, False),
1100 XmlMeta("jack_offset", float, 0),
1101 XmlMeta("onion_skin", bool, False),
1102 XmlMeta("onion_skin_future", int, 0),
1103 XmlMeta("onion_skin_past", int, 1),
1104 XmlList(Keyframe),
1105 XmlWrapper("defs", XmlList(Def, "defs", None, Def.tags())),
1106 XmlWrapper("bones", XmlList(BoneRoot, "bones", None, {"bone", "bone_root"})),
1107 XmlList(Layer),
1108 ]
1110 def __init__(self, **kw):
1111 SifNode.__init__(self, **kw)
1112 ObjectRegistry.__init__(self)
1114 def to_xml(self):
1115 dom = minidom.Document()
1116 dom.appendChild(self.to_dom(dom))
1117 return dom
1119 @classmethod
1120 def from_xml_file(cls, xml):
1121 if isinstance(xml, str): 1121 ↛ 1124line 1121 didn't jump to line 1124, because the condition on line 1121 was never false
1122 with open(xml, "r") as file:
1123 return cls.from_xml(minidom.parse(file))
1124 return cls.from_xml(minidom.parse(xml))
1126 @classmethod
1127 def from_xml_string(cls, xml):
1128 return cls.from_xml(minidom.parseString(xml))
1130 @classmethod
1131 def from_xml(cls, xml: minidom.Document):
1132 obj = cls.from_dom(xml.documentElement, None)
1133 xml.unlink()
1134 return obj
1136 @classmethod
1137 def from_dom(cls, xml: minidom.Element, registry: ObjectRegistry = None):
1138 instance = cls()
1139 for node in cls._nodes:
1140 node.from_xml(instance, xml, instance)
1141 return instance
1143 def time_to_frames(self, time: FrameTime):
1144 if time.unit == FrameTime.Unit.Frame:
1145 return time.value
1146 elif time.unit == FrameTime.Unit.Seconds:
1147 return time.value * self.fps
1149 def add_layer(self, layer: Layer):
1150 self.layers.append(layer)
1151 return layer
1153 def make_color(self, r, g, b, a=1):
1154 """
1155 Applies Gamma to the rgb values
1156 """
1157 return NVector(
1158 r ** self.gamma_r,
1159 g ** self.gamma_g,
1160 b ** self.gamma_b,
1161 a
1162 )
1165class Segment(SifNode):
1166 _nodes = [
1167 XmlAnimatable("p1", "vector"),
1168 XmlAnimatable("t1", "vector"),
1169 XmlAnimatable("p2", "vector"),
1170 XmlAnimatable("t2", "vector")
1171 ]
1174class WeightedVector(SifNode):
1175 _tag = "weighted_vector"
1177 _nodes = [
1178 XmlAnimatable("weight", "real", 1.),
1179 XmlAnimatable("value", "vector"),
1180 ]