/usr/share/pyshared/pgm/timing/modifier.py is in python-pgm 0.3.12-2build2.
This file is owned by root:root, with mode 0o644.
The actual contents of the file can be viewed below.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 | # -*- mode: python; coding: utf-8 -*-
#
# Pigment Python tools
#
# Copyright © 2006, 2007, 2008 Fluendo Embedded S.L.
#
# This library is free software; you can redistribute it and/or
# modify it under the terms of the GNU Lesser General Public
# License as published by the Free Software Foundation; either
# version 2 of the License, or (at your option) any later version.
#
# This library is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
# Lesser General Public License for more details.
#
# You should have received a copy of the GNU Lesser General Public
# License along with this library; if not, write to the
# Free Software Foundation, Inc., 59 Temple Place - Suite 330,
# Boston, MA 02111-1307, USA.
# TODO: - Spline interpolation
"""
"""
from pgm.utils import classinit, maths
from pgm.timing import keyframe
# Interpolation constants
LINEAR, SPLINE = 0, 1
ABSOLUTE, RELATIVE = 0, 1
class Modifier(object):
"""
"""
# Allows property fget/fset/fdel/doc overriding
__metaclass__ = classinit.ClassInitMeta
__classinit__ = classinit.build_properties
def __init__(self, obj=[], prop=None, timeline=[], interpolation=LINEAR,
operation=ABSOLUTE):
self._lerp = None
self._operation = operation
self._prop_initial_values = []
self.obj = obj
self.prop = prop
self.timeline = timeline
self.interpolation = interpolation
def __repr__(self):
string = {LINEAR:'LINEAR', SPLINE:'SPLINE'}
return "<modifier.Modifier(obj=%r, prop=%r, timeline=%r, " \
"interpolation=%s)>" % (self._obj, self._prop, self._timeline,
string[self._interpolation])
# Property definitions
def obj__get(self):
"""The list of objects"""
return self._obj
def obj__set(self, obj):
if isinstance(obj, (list, tuple)):
try:
obj_type = type(obj[0])
for i in obj[1:]:
pass
## if (not issubclass(obj_type, type(i))) or (not issubclass(type(i),obj_type)):
## error = 'Mismatching types in the list (%r vs %r)'
## raise TypeError, error % (type(i), obj_type)
# obj is an empty list
except IndexError:
self._obj = []
# All the objects in the list are of the same type
else:
self._obj = list(obj)
else:
raise TypeError, 'Modifier.obj__set(): obj must be list or tuple'
self._obj = []
def prop__get(self):
"""The property of the object class"""
return self._prop
def prop__set(self, prop):
# Check if prop is in the namespace of the obj class
try:
attrib = getattr(self._obj[0], prop)
self._prop = prop
# Store a pointer to the adapted lerp func
if isinstance(attrib, (list, tuple)):
self._lerp = maths.lerp_seq
else:
self._lerp = maths.lerp
if self._operation == RELATIVE:
self._save_property_initial_value()
except TypeError:
raise TypeError, 'Modifier.prop__set(): prop must be string'
self._prop = None
except IndexError:
raise TypeError, 'Modifier.prop__set(): obj list is empty'
self._prop = None
except AttributeError:
raise TypeError, 'Modifier.prop__set(): No attribute %s in %r' \
% (prop, self._obj[0])
self._prop = None
def timeline__get(self):
"""The timeline (list of keyframes) to interpolate"""
return self._timeline
def timeline__set(self, timeline):
if isinstance(timeline, (list, tuple)):
try:
for i in timeline:
if not isinstance(i, keyframe.KeyFrame):
raise TypeError, 'Not a keyframe.KeyFrame object'
# obj is an empty list
except IndexError:
self._timeline = []
# All the objects in the list are KeyFrame
# FIXME: A sort on the KeyFrame.time parameter is needed
# here because we can't assume the user give us a
# sorted list.
else:
self._timeline = timeline
else:
raise TypeError, 'Modifier.timeline__set(): ' \
'timeline must be list or tuple'
self._timeline = []
if len(self._timeline) < 2:
raise TypeError, 'timeline must at least contain 2 KeyFrame'
def interpolation__get(self):
"""The interpolation type"""
return self._interpolation
def interpolation__set(self, interpolation):
if interpolation == LINEAR or interpolation == SPLINE:
self._interpolation = interpolation
else:
print 'Modifier.interpolation__set():' \
'Bad interpolation type, reseting to LINEAR.'
self._interpolation = LINEAR
def _save_property_initial_value(self):
"""
"""
for obj in self._obj:
value = obj.__getattribute__(self._prop)
self._prop_initial_values.append(value)
# Public methods
def next_keyframe_index(self, factor):
"""
Return the index of the next KeyFrame that will be reached in the
timeline starting from time factor.
"""
# We assume here that self._timeline is sorted.
timeline_len = len(self._timeline)
i = 0
while self._timeline[i].time < factor:
i += 1
# The user gives us a partial timeline finishing before 1.0.
if i >= timeline_len:
return -1
return i
def update(self, factor):
"""
"""
i = self.next_keyframe_index(factor)
if i == -1:
return
# Expand the factor from the time range
# [self._timeline[i-1].time, self._timeline[i].time]
# to the range [0, 1].
new_factor = (factor - self._timeline[i-1].time) \
/ (self._timeline[i].time - \
self._timeline[i-1].time)
# Linearly interpolate the new_factor between the KeyFrame values.
value = self._lerp(self._timeline[i-1].value,
self._timeline[i].value, new_factor)
# Let's modify the objects.
rank = 0
for obj in self._obj:
if self._operation != RELATIVE:
#print 'setting', self._prop, value
obj.__setattr__(self._prop, value)
else:
initial_value = self._prop_initial_values[rank]
if isinstance(initial_value, (list, tuple)):
relative_value = tuple(map(lambda x,y: x+y,
initial_value, value))
else:
relative_value = initial_value + value
#print 'setting', self._prop, relative_value
obj.__setattr__(self._prop, relative_value)
rank += 1
|