Skip to content

Commit

Permalink
Range in parent for transitions (#184)
Browse files Browse the repository at this point in the history
* Fixed Transition support in otioview.

- Added range_in_parent and trimmed_range_in_parent to Transition.
- Added trim_child_range to Composition.
- Added range_in_parent to Item.
  • Loading branch information
jminor authored Nov 16, 2017
1 parent 22f20fd commit 9fc59a5
Show file tree
Hide file tree
Showing 5 changed files with 116 additions and 30 deletions.
37 changes: 31 additions & 6 deletions opentimelineio/core/composition.py
Original file line number Diff line number Diff line change
Expand Up @@ -206,9 +206,10 @@ def __deepcopy__(self, md):
return result

def _path_to_child(self, child):
if not isinstance(child, item.Item):
if not isinstance(child, composable.Composable):
raise TypeError(
"An object child of 'Item' is required, not type '{}'".format(
"An object child of 'Composable' is required,"
" not type '{}'".format(
type(child)
)
)
Expand Down Expand Up @@ -253,8 +254,6 @@ def range_of_child(self, child, reference_space=None):

parents = self._path_to_child(child)

result_range = child.source_range

current = child
result_range = None

Expand Down Expand Up @@ -339,8 +338,6 @@ def trimmed_range_of_child(self, child, reference_space=None):

parents = self._path_to_child(child)

result_range = child.source_range

current = child
result_range = None

Expand Down Expand Up @@ -383,6 +380,34 @@ def trimmed_range_of_child(self, child, reference_space=None):

return opentime.TimeRange(new_start_time, new_duration)

def trim_child_range(self, child_range):
if not self.source_range:
return child_range

# cropped out entirely
if (
self.source_range.start_time >= child_range.end_time_exclusive()
or self.source_range.end_time_exclusive() <= child_range.start_time
):
return None

if child_range.start_time < self.source_range.start_time:
child_range = opentime.range_from_start_end_time(
self.source_range.start_time,
child_range.end_time_exclusive()
)

if (
child_range.end_time_exclusive() >
self.source_range.end_time_exclusive()
):
child_range = opentime.range_from_start_end_time(
child_range.start_time,
self.source_range.end_time_exclusive()
)

return child_range

# @{ SerializableObject override.
def update(self, d):
"""Like the dictionary .update() method.
Expand Down
9 changes: 9 additions & 0 deletions opentimelineio/core/item.py
Original file line number Diff line number Diff line change
Expand Up @@ -118,6 +118,15 @@ def trimmed_range_in_parent(self):

return self.parent().trimmed_range_of_child(self)

def range_in_parent(self):
"""Find and return the timmed range of this item in the parent."""
if not self.parent():
raise exceptions.NotAChildError(
"No parent of {}, cannot compute range in parent.".format(self)
)

return self.parent().range_of_child(self)

def transformed_time(self, t, to_item):
"""Converts time t in the coordinate system of self to coordinate
system of to_item.
Expand Down
26 changes: 2 additions & 24 deletions opentimelineio/schema/track.py
Original file line number Diff line number Diff line change
Expand Up @@ -92,31 +92,9 @@ def range_of_child_at_index(self, index):
return opentime.TimeRange(start_time, child.duration())

def trimmed_range_of_child_at_index(self, index, reference_space=None):
range = self.range_of_child_at_index(index)
child_range = self.range_of_child_at_index(index)

if not self.source_range:
return range

# cropped out entirely
if (
self.source_range.start_time >= range.end_time_exclusive()
or self.source_range.end_time_exclusive() <= range.start_time
):
return None

if range.start_time < self.source_range.start_time:
range = opentime.range_from_start_end_time(
self.source_range.start_time,
range.end_time_exclusive()
)

if range.end_time_exclusive() > self.source_range.end_time_exclusive():
range = opentime.range_from_start_end_time(
range.start_time,
self.source_range.end_time_exclusive()
)

return range
return self.trim_child_range(child_range)

def available_range(self):
durations = []
Expand Down
19 changes: 19 additions & 0 deletions opentimelineio/schema/transition.py
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@
from .. import (
opentime,
core,
exceptions,
)


Expand Down Expand Up @@ -137,3 +138,21 @@ def overlapping():

def duration(self):
return self.in_offset + self.out_offset

def range_in_parent(self):
"""Find and return the range of this item in the parent."""
if not self.parent():
raise exceptions.NotAChildError(
"No parent of {}, cannot compute range in parent.".format(self)
)

return self.parent().range_of_child(self)

def trimmed_range_in_parent(self):
"""Find and return the timmed range of this item in the parent."""
if not self.parent():
raise exceptions.NotAChildError(
"No parent of {}, cannot compute range in parent.".format(self)
)

return self.parent().trimmed_range_of_child(self)
55 changes: 55 additions & 0 deletions tests/test_composition.py
Original file line number Diff line number Diff line change
Expand Up @@ -103,6 +103,61 @@ def test_repr(self):
")"
)

def test_trim_child_range(self):
for st in [
otio.schema.Track(name="foo"),
otio.schema.Stack(name="foo")
]:
st.source_range = otio.opentime.TimeRange(
start_time=otio.opentime.RationalTime(value=100, rate=24),
duration=otio.opentime.RationalTime(value=50, rate=24)
)
r = otio.opentime.TimeRange(
start_time=otio.opentime.RationalTime(value=110, rate=24),
duration=otio.opentime.RationalTime(value=30, rate=24)
)
self.assertEqual(st.trim_child_range(r), r)
r = otio.opentime.TimeRange(
start_time=otio.opentime.RationalTime(value=0, rate=24),
duration=otio.opentime.RationalTime(value=30, rate=24)
)
self.assertEqual(st.trim_child_range(r), None)
r = otio.opentime.TimeRange(
start_time=otio.opentime.RationalTime(value=1000, rate=24),
duration=otio.opentime.RationalTime(value=30, rate=24)
)
self.assertEqual(st.trim_child_range(r), None)
r = otio.opentime.TimeRange(
start_time=otio.opentime.RationalTime(value=90, rate=24),
duration=otio.opentime.RationalTime(value=30, rate=24)
)
self.assertEqual(
st.trim_child_range(r),
otio.opentime.TimeRange(
start_time=otio.opentime.RationalTime(value=100, rate=24),
duration=otio.opentime.RationalTime(value=20, rate=24)
)
)
r = otio.opentime.TimeRange(
start_time=otio.opentime.RationalTime(value=110, rate=24),
duration=otio.opentime.RationalTime(value=50, rate=24)
)
self.assertEqual(
st.trim_child_range(r),
otio.opentime.TimeRange(
start_time=otio.opentime.RationalTime(value=110, rate=24),
duration=otio.opentime.RationalTime(value=40, rate=24)
)
)
r = otio.opentime.TimeRange(
start_time=otio.opentime.RationalTime(value=90, rate=24),
duration=otio.opentime.RationalTime(value=1000, rate=24)
)
self.assertEqual(
st.trim_child_range(r),
st.source_range
)

def test_range_of_child(self):
st = otio.schema.Stack(name="foo", children=[
otio.schema.Clip(
Expand Down

0 comments on commit 9fc59a5

Please sign in to comment.