Skip to content

Commit 129c4bb

Browse files
Fix for find_children() with stacks #2 (#1766)
Signed-off-by: Darby Johnston <darbyjohnston@yahoo.com>
1 parent 987d00a commit 129c4bb

File tree

5 files changed

+108
-1
lines changed

5 files changed

+108
-1
lines changed

src/opentimelineio/composition.h

+1-1
Original file line numberDiff line numberDiff line change
@@ -101,7 +101,7 @@ class Composition : public Item
101101
bool shallow_search = false) const;
102102

103103
// Return all objects within the given search_range.
104-
std::vector<Retainer<Composable>> children_in_range(
104+
virtual std::vector<Retainer<Composable>> children_in_range(
105105
TimeRange const& search_range,
106106
ErrorStatus* error_status = nullptr) const;
107107

src/opentimelineio/stack.cpp

+20
Original file line numberDiff line numberDiff line change
@@ -79,6 +79,26 @@ Stack::range_of_all_children(ErrorStatus* error_status) const
7979
return result;
8080
}
8181

82+
std::vector<SerializableObject::Retainer<Composable>>
83+
Stack::children_in_range(
84+
TimeRange const& search_range,
85+
ErrorStatus* error_status) const
86+
{
87+
std::vector<SerializableObject::Retainer<Composable>> children;
88+
for (const auto& child : this->children())
89+
{
90+
if (const auto& item = dynamic_retainer_cast<Item>(child))
91+
{
92+
const auto range = item->trimmed_range_in_parent(error_status);
93+
if (range.has_value() && range.value().intersects(search_range))
94+
{
95+
children.push_back(child);
96+
}
97+
}
98+
}
99+
return children;
100+
}
101+
82102
TimeRange
83103
Stack::trimmed_range_of_child_at_index(int index, ErrorStatus* error_status)
84104
const

src/opentimelineio/stack.h

+4
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,10 @@ class Stack : public Composition
4040
std::map<Composable*, TimeRange>
4141
range_of_all_children(ErrorStatus* error_status = nullptr) const override;
4242

43+
std::vector<Retainer<Composable>> children_in_range(
44+
TimeRange const& search_range,
45+
ErrorStatus* error_status = nullptr) const override;
46+
4347
std::optional<IMATH_NAMESPACE::Box2d>
4448
available_image_bounds(ErrorStatus* error_status) const override;
4549

tests/test_track.cpp

+58
Original file line numberDiff line numberDiff line change
@@ -108,6 +108,64 @@ main(int argc, char** argv)
108108
assertEqual(result[1].value, cl1.value);
109109
});
110110

111+
tests.add_test(
112+
"test_find_children_stack", [] {
113+
using namespace otio;
114+
115+
SerializableObject::Retainer<Stack> stack = new Stack();
116+
SerializableObject::Retainer<Track> track = new Track;
117+
SerializableObject::Retainer<Clip> clip = new Clip;
118+
stack->append_child(track);
119+
track->append_child(clip);
120+
121+
// Simple find.
122+
clip->set_source_range(
123+
TimeRange(RationalTime(0.0, 24.0), RationalTime(3.0, 24.0)));
124+
otio::ErrorStatus err;
125+
auto items = stack->find_children(
126+
&err,
127+
TimeRange(RationalTime(0.0, 24.0), RationalTime(1.0, 24.0)));
128+
assertFalse(is_error(err));
129+
assertEqual(items.size(), 2);
130+
assertTrue(
131+
std::find(items.begin(), items.end(), track.value) != items.end());
132+
assertTrue(
133+
std::find(items.begin(), items.end(), clip.value) != items.end());
134+
135+
// Set a short source range on the track.
136+
track->set_source_range(
137+
TimeRange(RationalTime(0.0, 24.0), RationalTime(2.0, 24.0)));
138+
items = stack->find_children(
139+
&err,
140+
TimeRange(RationalTime(2.0, 24.0), RationalTime(1.0, 24.0)));
141+
assertFalse(is_error(err));
142+
assertEqual(items.size(), 0);
143+
144+
// Set a source range with a positive offset on the track.
145+
track->set_source_range(
146+
TimeRange(RationalTime(3.0, 24.0), RationalTime(3.0, 24.0)));
147+
items = stack->find_children(
148+
&err,
149+
TimeRange(RationalTime(2.0, 24.0), RationalTime(1.0, 24.0)));
150+
assertFalse(is_error(err));
151+
assertEqual(items.size(), 1);
152+
assertTrue(
153+
std::find(items.begin(), items.end(), track.value) != items.end());
154+
155+
// Set a source range with a negative offset on the track.
156+
track->set_source_range(
157+
TimeRange(RationalTime(-1.0, 24.0), RationalTime(3.0, 24.0)));
158+
items = stack->find_children(
159+
&err,
160+
TimeRange(RationalTime(1.0, 24.0), RationalTime(1.0, 24.0)));
161+
assertFalse(is_error(err));
162+
assertEqual(items.size(), 2);
163+
assertTrue(
164+
std::find(items.begin(), items.end(), track.value) != items.end());
165+
assertTrue(
166+
std::find(items.begin(), items.end(), clip.value) != items.end());
167+
});
168+
111169
tests.run(argc, argv);
112170
return 0;
113171
}

tests/test_track.py

+25
Original file line numberDiff line numberDiff line change
@@ -56,6 +56,31 @@ def test_find_children_shallow_search(self):
5656
self.assertEqual(result[0], cl0)
5757
self.assertEqual(result[1], cl1)
5858

59+
def test_find_children_stack(self):
60+
video_clip = otio.schema.Clip()
61+
video_clip.source_range = otio.opentime.TimeRange(
62+
otio.opentime.RationalTime(0.0, 30.0),
63+
otio.opentime.RationalTime(700.0, 30.0))
64+
audio_clip = otio.schema.Clip()
65+
audio_clip.source_range = otio.opentime.TimeRange(
66+
otio.opentime.RationalTime(0.0, 30.0),
67+
otio.opentime.RationalTime(704.0, 30.0))
68+
video_track = otio.schema.Track()
69+
audio_track = otio.schema.Track()
70+
stack = otio.schema.Stack()
71+
video_track.append(video_clip)
72+
audio_track.append(audio_clip)
73+
stack.append(video_track)
74+
stack.append(audio_track)
75+
76+
time = otio.opentime.RationalTime(703.0, 30.0)
77+
one_frame = otio.opentime.RationalTime(1.0, 30.0)
78+
range = otio.opentime.TimeRange(time, one_frame)
79+
items = stack.find_children(search_range=range)
80+
self.assertEqual(len(items), 2)
81+
self.assertTrue(audio_clip in items)
82+
self.assertTrue(audio_track in items)
83+
5984

6085
if __name__ == '__main__':
6186
unittest.main()

0 commit comments

Comments
 (0)