diff --git a/sg_otio/cut_diff.py b/sg_otio/cut_diff.py index ca9246a..87c01e1 100644 --- a/sg_otio/cut_diff.py +++ b/sg_otio/cut_diff.py @@ -505,19 +505,20 @@ def _check_and_set_rescan(self): # some entries might be flagged as "Need rescan", even if there are no # cut changes. if ( - self.sg_shot_head_in is not None # Report rescan only if value is set on the Shot + self.sg_shot_head_in is not None # Report extended only if value is set on the Shot and self.head_duration is not None and self.head_duration.to_frames() < 0 ): self._diff_type = _DIFF_TYPES.EXTENDED if ( - self.sg_shot_tail_out is not None # Report rescan only if value is set on the Shot + self.sg_shot_tail_out is not None # Report extended only if value is set on the Shot and self.tail_duration is not None and self.tail_duration.to_frames() < 0 ): self._diff_type = _DIFF_TYPES.EXTENDED + sg_settings = SGSettings() # We use cut in and cut out values which accurately report changes since # they are not based on Shot values. if ( @@ -528,10 +529,19 @@ def _check_and_set_rescan(self): if self._diff_type != _DIFF_TYPES.EXTENDED: self._diff_type = _DIFF_TYPES.CUT_CHANGE diff = (self.cut_in - self.old_cut_in).to_frames() - if diff > 0: - self._cut_changes_reasons.append("Head extended %d frs" % diff) + if sg_settings.default_head_duration: + # Report handle changes if handles are in use + if diff > 0: + # More frames in the handle + self._cut_changes_reasons.append("Head handle extended %d frs" % diff) + else: + # Less frames in the handle + self._cut_changes_reasons.append("Head handle trimmed %d frs" % -diff) else: - self._cut_changes_reasons.append("Head trimmed %d frs" % -diff) + if diff > 0: + self._cut_changes_reasons.append("In trimmed %d frs" % diff) + else: + self._cut_changes_reasons.append("In extended %d frs" % -diff) if ( self.old_cut_out is not None @@ -541,7 +551,16 @@ def _check_and_set_rescan(self): if self._diff_type != _DIFF_TYPES.EXTENDED: self._diff_type = _DIFF_TYPES.CUT_CHANGE diff = (self.cut_out - self.old_cut_out).to_frames() - if diff > 0: - self._cut_changes_reasons.append("Tail trimmed %d frs" % diff) + if sg_settings.default_head_duration: + # Report handle changes if handles are in use + if diff > 0: + # Less frames in the handle + self._cut_changes_reasons.append("Tail handle trimmed %d frs" % diff) + else: + # More frames in the handle + self._cut_changes_reasons.append("Tail handle extended %d frs" % -diff) else: - self._cut_changes_reasons.append("Tail extended %d frs" % -diff) + if diff > 0: + self._cut_changes_reasons.append("Out extended %d frs" % diff) + else: + self._cut_changes_reasons.append("Out trimmed %d frs" % -diff) diff --git a/sg_otio/track_diff.py b/sg_otio/track_diff.py index 0a3324c..c9defd9 100644 --- a/sg_otio/track_diff.py +++ b/sg_otio/track_diff.py @@ -887,7 +887,7 @@ def write_csv_report(self, csv_path, title, sg_links=None): data_row = [ cut_order, cut_diff.diff_type.name, - shot_name, + cut_diff.shot_name, duration, start, end, @@ -917,7 +917,7 @@ def write_csv_report(self, csv_path, title, sg_links=None): data_row = [ cut_order, cut_diff.diff_type.name, - shot_name, + cut_diff.shot_name, duration, start, end, diff --git a/tests/test_cut_diff.py b/tests/test_cut_diff.py index 5426fd0..7319048 100644 --- a/tests/test_cut_diff.py +++ b/tests/test_cut_diff.py @@ -78,7 +78,7 @@ def _add_sg_cut_data(self): self.add_to_sg_mock_db(self.sg_sequences) self._sg_entities_to_delete.extend(self.sg_sequences) self.sg_shots = [{ - "code": "shot_6666", + "code": "SHOT_6666", "project": self.mock_project, "type": "Shot", "sg_sequence": self.sg_sequences[0], @@ -92,7 +92,7 @@ def _add_sg_cut_data(self): "id": 6667, "sg_status_list": None, }, { - "code": "shot_6668", + "code": "SHOT_6668", "project": self.mock_project, "type": "Shot", "sg_sequence": self.sg_sequences[0], @@ -960,7 +960,7 @@ def test_cut_differences(self): cut_diff.compute_head_tail_values() cut_diff._check_and_set_changes() self.assertEqual(cut_diff.diff_type, _DIFF_TYPES.CUT_CHANGE) - self.assertEqual(cut_diff.reasons, ["Tail trimmed 10 frs"]) + self.assertEqual(cut_diff.reasons, ["Tail handle trimmed 10 frs"]) clip.source_range = TimeRange( RationalTime(100, 24), RationalTime(20, 24), # duration, 20 frames. @@ -968,7 +968,7 @@ def test_cut_differences(self): cut_diff.compute_head_tail_values() cut_diff._check_and_set_changes() self.assertEqual(cut_diff.diff_type, _DIFF_TYPES.CUT_CHANGE) - self.assertEqual(cut_diff.reasons, ["Head trimmed 10 frs"]) + self.assertEqual(cut_diff.reasons, ["Head handle trimmed 10 frs"]) clip.source_range = TimeRange( RationalTime(111, 24), RationalTime(8, 24), # duration, 8 frames. @@ -976,9 +976,44 @@ def test_cut_differences(self): cut_diff.compute_head_tail_values() cut_diff._check_and_set_changes() self.assertEqual(cut_diff.diff_type, _DIFF_TYPES.CUT_CHANGE) - self.assertEqual(cut_diff.reasons, ["Head extended 1 frs", "Tail extended 1 frs"]) + self.assertEqual(cut_diff.reasons, ["Head handle extended 1 frs", "Tail handle extended 1 frs"]) - # Check rescan are correctly detected. + # Without handles extended/trimmed are reported + # for in and out points. + settings = SGSettings() + head_duration = settings.default_head_duration + tail_duration = settings.default_tail_duration + settings.default_head_duration = 0 + settings.default_tail_duration = 0 + clip.source_range = TimeRange( + RationalTime(110, 24), + RationalTime(20, 24), # duration, 20 frames. + ) + cut_diff.compute_head_tail_values() + cut_diff._check_and_set_changes() + self.assertEqual(cut_diff.diff_type, _DIFF_TYPES.CUT_CHANGE) + self.assertEqual(cut_diff.reasons, ["Out extended 10 frs"]) + clip.source_range = TimeRange( + RationalTime(100, 24), + RationalTime(20, 24), # duration, 20 frames. + ) + cut_diff.compute_head_tail_values() + cut_diff._check_and_set_changes() + self.assertEqual(cut_diff.diff_type, _DIFF_TYPES.CUT_CHANGE) + self.assertEqual(cut_diff.reasons, ["In extended 10 frs"]) + clip.source_range = TimeRange( + RationalTime(111, 24), + RationalTime(8, 24), # duration, 8 frames. + ) + cut_diff.compute_head_tail_values() + cut_diff._check_and_set_changes() + self.assertEqual(cut_diff.diff_type, _DIFF_TYPES.CUT_CHANGE) + self.assertEqual(cut_diff.reasons, ["In trimmed 1 frs", "Out trimmed 1 frs"]) + + settings.default_head_duration = head_duration + settings.default_tail_duration = tail_duration + + # Check "extended" are correctly detected. # So far values coming from the Shot should be None self.assertIsNone(cut_diff.sg_shot_head_in) self.assertIsNone(cut_diff.old_head_duration)