129 lines
3.8 KiB
Python
129 lines
3.8 KiB
Python
# SPDX-FileCopyrightText: 2021 Blender Studio Tools Authors
|
|
#
|
|
# SPDX-License-Identifier: GPL-3.0-or-later
|
|
|
|
from __future__ import annotations
|
|
from typing import List
|
|
from pathlib import Path
|
|
|
|
import bpy
|
|
|
|
from .geo import Rectangle
|
|
|
|
|
|
class SequenceRect(Rectangle):
|
|
"""
|
|
Class that represents a Blender sequence strip as a rectangle. It
|
|
inherits from Rectangle class and implements the _ methods so the
|
|
Rectangle public interface works as excpected.
|
|
"""
|
|
|
|
valid_types: List[str] = ["MOVIE", "IMAGE"]
|
|
|
|
def __init__(self, sequence: "bpy.types.Strip"):
|
|
|
|
if sequence.type not in self.valid_types:
|
|
raise ValueError(
|
|
f"SequenceRect can only hold sequences of type {str(self.valid_types)}"
|
|
)
|
|
|
|
self._sequence: "bpy.types.Strip" = sequence
|
|
self._orig_x: int = sequence.transform.offset_x
|
|
self._orig_y: int = sequence.transform.offset_y
|
|
|
|
@property
|
|
def sequence(self) -> "bpy.types.Strip":
|
|
return self._sequence
|
|
|
|
def _get_orig_width(self) -> int:
|
|
return self.sequence.elements[0].orig_width
|
|
|
|
def _get_orig_height(self) -> int:
|
|
return self.sequence.elements[0].orig_height
|
|
|
|
# X.
|
|
def _get_x(self) -> int:
|
|
return (
|
|
self._canvas_x / 2 - (self.width / 2) + (self.sequence.transform.offset_x)
|
|
)
|
|
|
|
def _set_x(self, value: int) -> None:
|
|
# To origin.
|
|
self.sequence.transform.offset_x = -(self._canvas_x / 2) + (self.width / 2)
|
|
# Plus value.
|
|
self.sequence.transform.offset_x += value
|
|
|
|
# Y.
|
|
def _get_y(self) -> int:
|
|
return (
|
|
self._canvas_y / 2 - (self.height / 2) - (self.sequence.transform.offset_y)
|
|
)
|
|
|
|
def _set_y(self, value: int) -> None:
|
|
# Y in blender sqe goes up ^ + and down minus (confusing)
|
|
# to origin.
|
|
self.sequence.transform.offset_y = (self._canvas_y / 2) - (self.height / 2)
|
|
# Minus value.
|
|
self.sequence.transform.offset_y -= value
|
|
|
|
# Width.
|
|
def _get_width(self) -> int:
|
|
return self.orig_width * self.scale_x
|
|
|
|
def _set_width(self, value: int) -> None:
|
|
scale_fac = value / self.orig_width
|
|
self.scale_x = scale_fac
|
|
|
|
# Height.
|
|
def _get_height(self) -> int:
|
|
return self.orig_height * self.scale_y
|
|
|
|
def _set_height(self, value: int) -> None:
|
|
scale_fac = value / self.orig_height
|
|
self.scale_y = scale_fac
|
|
|
|
# Scale.
|
|
|
|
def _get_scale_x(self):
|
|
return self.sequence.transform.scale_x
|
|
|
|
def _get_scale_y(self):
|
|
return self.sequence.transform.scale_y
|
|
|
|
def _set_scale_x(self, factor: float) -> None:
|
|
self.sequence.transform.scale_x = float(factor)
|
|
|
|
def _set_scale_y(self, factor: float) -> None:
|
|
self.sequence.transform.scale_y = float(factor)
|
|
|
|
# Functions.
|
|
def copy(self) -> SequenceRect:
|
|
if self.sequence.type == "IMAGE":
|
|
strip = bpy.context.scene.sequence_editor.sequences.new_image(
|
|
self.sequence.name,
|
|
Path(self.sequence.directory)
|
|
.joinpath(self.sequence.elements[0].filename)
|
|
.as_posix(),
|
|
self.sequence.channel + 1,
|
|
self.sequence.frame_final_start,
|
|
)
|
|
elif self.sequence.type == "MOVIE":
|
|
strip = bpy.context.scene.sequence_editor.sequences.new_movie(
|
|
self.sequence.name,
|
|
self.sequence.file,
|
|
self.sequence.channel + 1,
|
|
self.sequence.frame_final_start,
|
|
)
|
|
|
|
sequence_rect = SequenceRect(strip)
|
|
sequence_rect.fit_to_rect(self)
|
|
return sequence_rect
|
|
|
|
@property
|
|
def _canvas_x(self):
|
|
return bpy.context.scene.render.resolution_x
|
|
|
|
@property
|
|
def _canvas_y(self):
|
|
return bpy.context.scene.render.resolution_y
|