Files
blender-portable-repo/scripts/addons/contactsheet/checksqe.py
T
2026-03-17 14:58:51 -06:00

79 lines
2.4 KiB
Python

# SPDX-FileCopyrightText: 2021 Blender Studio Tools Authors
#
# SPDX-License-Identifier: GPL-3.0-or-later
from typing import Dict, List
import bpy
def _do_ranges_collide(range1: range, range2: range) -> bool:
"""Whether the two ranges collide with each other ."""
# Usual strip setup strip1(101, 120)|strip2(120, 130)|strip3(130, 140)
# first and last frame can be the same for each strip.
range2 = range(range2.start + 1, range2.stop - 1)
if not range1:
return True # Empty range is subset of anything.
if not range2:
return False # Non-empty range can't be subset of empty range.
if len(range1) > 1 and range1.step % range2.step:
return False # Must have a single value or integer multiple step.
if range(range1.start + 1, range1.stop - 1) == range2:
return True
if range2.start in range1 or range2[-1] in range1:
return True
return range1.start in range2 or range1[-1] in range2
def get_occupied_ranges(context: bpy.types.Context) -> Dict[str, List[range]]:
"""
Scans sequence editor and returns a dictionary. It contains a key for each channel
and a list of ranges with the occupied frame ranges as values.
"""
# {'1': [(101, 213), (300, 320)]}.
ranges: Dict[str, List[range]] = {}
# Populate ranges.
for strip in context.scene.sequence_editor.sequences_all:
ranges.setdefault(str(strip.channel), [])
ranges[str(strip.channel)].append(
range(strip.frame_final_start, strip.frame_final_end + 1)
)
# Sort ranges tuple list.
for channel in ranges:
liste = ranges[channel]
ranges[channel] = sorted(liste, key=lambda item: item.start)
return ranges
def get_occupied_ranges_for_strips(sequences: List["bpy.types.Strip"]) -> List[range]:
"""
Scans input list of sequences and returns a list of ranges that represent the occupied frame ranges.
"""
ranges: List[range] = []
# Populate ranges.
for strip in sequences:
ranges.append(range(strip.frame_final_start, strip.frame_final_end + 1))
# Sort ranges tuple list.
ranges.sort(key=lambda item: item.start)
return ranges
def is_range_occupied(range_to_check: range, occupied_ranges: List[range]) -> bool:
for r in occupied_ranges:
# Range(101, 150).
if _do_ranges_collide(range_to_check, r):
return True
continue
return False