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

1from xml.dom import minidom 

2import enum 

3 

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 

11 

12 

13class SifAstComplex(SifAstNode, metaclass=SifNodeMeta): 

14 _nodes = [] 

15 

16 def __init__(self, **kw): 

17 for node in self._nodes: 

18 node.initialize_object(kw, self) 

19 

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 

27 

28 @classmethod 

29 def get_class_from_dom(cls, xml: minidom.Element, param: TypeDescriptor, registry: ObjectRegistry): 

30 return cls 

31 

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 

37 

38 

39class SifAstBoneLink(SifAstComplex): 

40 _tag = "bone_link" 

41 

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 ] 

51 

52 

53class SifAstBoneInfluence(SifAstComplex): 

54 _tag = "boneinfluence" 

55 

56 _nodes = [ 

57 # TODO bone_weight_list 

58 XmlAnimatable("link", "vector", NVector(0, 0)), 

59 ] 

60 

61 

62class SifSegCalcTangent(SifAstComplex): 

63 _tag = "segcalctangent" 

64 

65 _nodes = [ 

66 XmlSifElement("segment", Segment), 

67 XmlAnimatable("amount", "real", .5), 

68 ] 

69 

70 

71class SifSegCalcVertex(SifAstComplex): 

72 _tag = "segcalcvertex" 

73 

74 _nodes = [ 

75 XmlSifElement("segment", Segment), 

76 XmlAnimatable("amount", "real", .5), 

77 ] 

78 

79 

80class WeightedAverage(SifAstComplex): 

81 _tag = "weighted_average" 

82 

83 _nodes = [ 

84 XmlList(WeightedVector, "vectors", "entry"), 

85 ] 

86 

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 

91 

92 

93class SifAdd(SifAstComplex): 

94 _tag = "add" 

95 

96 _nodes = [ 

97 XmlAnimatable("lhs", "_recurse"), 

98 XmlAnimatable("rhs", "_recurse"), 

99 XmlAnimatable("scalar", "real", 1.), 

100 ] 

101 

102 

103class SifAnimatedFile(SifAstComplex): 

104 _tag = "animated_file" 

105 

106 _nodes = [ 

107 XmlAnimatable("filename", "string"), 

108 ] 

109 

110 

111class Accuracy(enum.Enum): 

112 Rough = 0 

113 Normal = 1 

114 Fine = 2 

115 Extreme = 3 

116 

117 

118class DerivativeOrder: 

119 FirstDerivative = 0 

120 SecondDerivative = 1 

121 

122 

123class SifDerivative(SifAstComplex): 

124 _tag = "derivative" 

125 

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 ] 

132 

133 

134class SifDynamic(SifAstComplex): 

135 _tag = "dynamic" 

136 

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 ] 

152 

153 

154class SifGreyed(SifAstComplex): 

155 _tag = "greyed" 

156 

157 _nodes = [ 

158 XmlAnimatable("link", "_recurse"), 

159 ] 

160 

161 

162class SifLinear(SifAstComplex): 

163 _tag = "linear" 

164 

165 _nodes = [ 

166 XmlAnimatable("slope", "vector", NVector(0, 0)), 

167 XmlAnimatable("offset", "vector", NVector(0, 0)), 

168 ] 

169 

170 

171class SifRadialComposite(SifAstComplex): 

172 _tag = "radial_composite" 

173 

174 _nodes = [ 

175 XmlAnimatable("radius", "real", 0.), 

176 XmlAnimatable("theta", "angle", 0.), 

177 ] 

178 

179 

180class SifComposite(SifAstComplex): 

181 _tag = "composite" 

182 

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 

189 

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 

194 

195 

196class SifVectorComposite(SifComposite): 

197 _type = "vector" 

198 

199 _nodes = [ 

200 XmlAnimatable("x", "real", 0.), 

201 XmlAnimatable("y", "real", 0.), 

202 ] 

203 

204 

205class SifRandom(SifAstComplex): 

206 _tag = "random" 

207 

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 ] 

216 

217 

218class SifReference(SifAstComplex): 

219 _tag = "link" 

220 

221 _nodes = [ 

222 XmlAnimatable("reference", "_recurse"), 

223 ] 

224 

225 

226class SifScale(SifAstComplex): 

227 _tag = "scale" 

228 

229 _nodes = [ 

230 XmlAnimatable("link", "_recurse"), 

231 XmlAnimatable("scalar", "real", 1.), 

232 ] 

233 

234 

235class SifStep(SifAstComplex): 

236 _tag = "step" 

237 

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 ] 

244 

245 

246class SifSubtract(SifAstComplex): 

247 _tag = "subtract" 

248 

249 _nodes = [ 

250 XmlAnimatable("lhs", "_recurse"), 

251 XmlAnimatable("rhs", "_recurse"), 

252 XmlAnimatable("scalar", "real", 1.), 

253 ] 

254 

255 

256class SifSwitch(SifAstComplex): 

257 _tag = "switch" 

258 

259 _nodes = [ 

260 XmlAnimatable("link_off", "_recurse"), 

261 XmlAnimatable("link_on", "_recurse"), 

262 XmlAnimatable("switch", "bool", False), 

263 ] 

264 

265 

266class SifTimedSwap(SifAstComplex): 

267 _tag = "timed_swap" 

268 

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 ] 

275 

276 

277class SifTimeLoop(SifAstComplex): 

278 _tag = "timeloop" 

279 

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 ] 

286 

287 

288class SifPower(SifAstComplex): 

289 _tag = "power" 

290 

291 _nodes = [ 

292 XmlAnimatable("base", "real", 1.), 

293 XmlAnimatable("power", "real", 1.), 

294 XmlAnimatable("epsilon", "real", 0.000001), 

295 XmlAnimatable("infinite", "real", 999999.), 

296 ] 

297 

298 

299class SifBlineCalcTangent(SifAstComplex): 

300 _tag = "blinecalctangent" 

301 

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 ] 

311 

312 

313class SifBlineCalcVertex(SifAstComplex): 

314 _tag = "blinecalcvertex" 

315 

316 _nodes = [ 

317 XmlSifElement("bline", Bline), 

318 XmlAnimatable("loop", "bool", False), 

319 XmlAnimatable("amount", "real", 0.5), 

320 XmlAnimatable("homogeneous", "bool", False), 

321 ]