Skip to content

Commit

Permalink
UPDATE default values and fix misc small bugs
Browse files Browse the repository at this point in the history
* Changed Signatures for functions :
  * grg_clip.tv_load_sequence
  * grg_clip.tv_sound_clip_adjust
  * grg_layer.tv_load_image
  * grg_project.tv_load_project
  * grg_project.tv_project_save_sequence
  * grg_project.tv_frame_rate_project_set
  * grg_project.tv_sound_project_adjust
  • Loading branch information
rlahmidi committed May 28, 2024
1 parent 1b08186 commit 4cc5ea5
Show file tree
Hide file tree
Showing 9 changed files with 66 additions and 62 deletions.
4 changes: 2 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@

**PyTVPaint** is a type-safe Python library that wraps the George programming language commands in order to interact with the 2D animation software TVPaint.

It communicates through WebSocket to a [custom C++ plugin](https://github.com/brunchstudio/tvpaint-rpc) running in an opened TVPaint instance.
It communicates through WebSocket to a [custom C++ plugin](https://github.com/brunchstudio/tvpaint-rpc) running in an open TVPaint instance.

You can check the [documentation](https://brunchstudio.github.io/pytvpaint/) for more details.

Expand All @@ -29,7 +29,7 @@ You can check the [documentation](https://brunchstudio.github.io/pytvpaint/) for
Install the package with Pip:

```console
pip install pytvpaint
pip install pytvpaint
```

## Simple example
Expand Down
61 changes: 32 additions & 29 deletions pytvpaint/george/grg_clip.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,6 @@
args_dict_to_list,
tv_parse_dict,
tv_parse_list,
validate_args_list,
)
from pytvpaint.george.exceptions import NoObjectWithIdError
from pytvpaint.george.grg_base import (
Expand Down Expand Up @@ -219,18 +218,18 @@ def tv_load_sequence(
seq_path: Path | str,
offset_count: tuple[int, int] | None = None,
field_order: FieldOrder | None = None,
stretch: bool | None = None,
time_stretch: bool | None = None,
preload: bool | None = None,
stretch: bool = False,
time_stretch: bool = False,
preload: bool = False,
) -> int:
"""Load a sequence of images or movie in a new layer.
Args:
seq_path: the first file of the sequence to load
offset_count: the start and number of image of sequence to load. Defaults to None.
offset_count: the start and number of images in the sequence to load. Defaults to None.
field_order: the field order. Defaults to None.
stretch: Stretch each image to the size of the layer. Defaults to None.
time_stretch: Once loaded, the layer will have a new number of image corresponding to the project framerate. Defaults to None.
time_stretch: Once loaded, the layer will have a new number of images corresponding to the project framerate. Defaults to None.
preload: Load all the images in memory, no more reference on the files. Defaults to None.
Raises:
Expand All @@ -245,27 +244,24 @@ def tv_load_sequence(
if not seq_path.exists():
raise FileNotFoundError(f"File not found at: {seq_path.as_posix()}")

args: list[int | str | None] = [field_order.value if field_order else None]
args: list[int | str] = [seq_path.as_posix()]
if offset_count and len(offset_count) == 2:
args.extend(offset_count)
if field_order:
args.append(field_order.value)

if offset_count is not None:
offset, count = offset_count
args.insert(0, count)
args.insert(0, offset)

# Filter None inline arguments
args = [a for a in args if a is not None]

args += args_dict_to_list(
{
"stretch": stretch,
"timestretch": time_stretch,
"preload": preload,
}
)
extra_args = [
(stretch, "stretch"),
(time_stretch, "timestretch"),
(preload, "preload"),
]
for param, param_name in extra_args:
if not param:
continue
args.append(param_name)

result = send_cmd(
"tv_LoadSequence",
seq_path.as_posix(),
*args,
error_values=[-1],
)
Expand Down Expand Up @@ -646,15 +642,22 @@ def tv_sound_clip_adjust(
color_index: int | None = None,
) -> None:
"""Change a soundtracks settings."""
cur_options = tv_sound_clip_info(tv_clip_current_id(), track_index)
args: list[int | float | None] = []

optional_args = [
int(mute) if mute is not None else None,
volume,
offset,
(fade_in_start, fade_in_stop, fade_out_start, fade_out_stop),
color_index,
(int(mute) if mute is not None else None, int(cur_options.mute)),
(volume, cur_options.volume),
(offset, cur_options.offset),
(fade_in_start, cur_options.fade_in_start),
(fade_in_stop, cur_options.fade_in_stop),
(fade_out_start, cur_options.fade_out_start),
(fade_out_stop, cur_options.fade_out_stop),
]
for arg, default_value in optional_args:
args.append(arg if arg is not None else default_value)

args = validate_args_list(optional_args)
args.append(color_index)
send_cmd("tv_SoundClipAdjust", track_index, *args, error_values=[-2, -3])


Expand Down
2 changes: 1 addition & 1 deletion pytvpaint/george/grg_layer.py
Original file line number Diff line number Diff line change
Expand Up @@ -1213,7 +1213,7 @@ def tv_save_image(export_path: Path | str) -> None:


@try_cmd(exception_msg="Invalid image format")
def tv_load_image(img_path: Path | str, stretch: bool | None = None) -> None:
def tv_load_image(img_path: Path | str, stretch: bool = False) -> None:
"""Load an image in the current image layer.
Raises:
Expand Down
38 changes: 18 additions & 20 deletions pytvpaint/george/grg_project.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,6 @@
from pytvpaint.george.client.parse import (
tv_cast_to_type,
tv_parse_list,
validate_args_list,
)
from pytvpaint.george.exceptions import NoObjectWithIdError
from pytvpaint.george.grg_base import (
Expand Down Expand Up @@ -127,7 +126,7 @@ def tv_project_new(


@try_cmd(exception_msg="Invalid format")
def tv_load_project(project_path: Path | str, silent: bool | None = None) -> str:
def tv_load_project(project_path: Path | str, silent: bool = False) -> str:
"""Load a file as a project if possible or open Import panel.
Raises:
Expand All @@ -141,7 +140,7 @@ def tv_load_project(project_path: Path | str, silent: bool | None = None) -> str

args: list[Any] = [project_path.as_posix()]

if silent is not None:
if silent:
args.extend(["silent", int(silent)])

return send_cmd("tv_LoadProject", *args, error_values=[-1])
Expand Down Expand Up @@ -255,7 +254,7 @@ def tv_get_field() -> FieldOrder:

def tv_project_save_sequence(
export_path: Path | str,
use_camera: bool | None = None,
use_camera: bool = False,
start: int | None = None,
end: int | None = None,
) -> None:
Expand Down Expand Up @@ -314,9 +313,7 @@ def tv_frame_rate_set(
send_cmd("tv_FrameRate", *args)


def tv_frame_rate_project_set(
frame_rate: float, time_stretch: bool | None = None
) -> None:
def tv_frame_rate_project_set(frame_rate: float, time_stretch: bool = False) -> None:
"""Set the framerate of the current project."""
args: list[Any] = [frame_rate]
if time_stretch:
Expand Down Expand Up @@ -427,22 +424,23 @@ def tv_sound_project_adjust(
color_index: int | None = None,
) -> None:
"""Change the current project's soundtrack settings."""
cur_options = tv_sound_project_info(tv_project_current_id(), track_index)
args: list[int | float | None] = []

optional_args = [
int(mute) if mute is not None else None,
volume,
offset,
(fade_in_start, fade_in_stop, fade_out_start, fade_out_stop),
color_index,
(int(mute) if mute is not None else None, int(cur_options.mute)),
(volume, cur_options.volume),
(offset, cur_options.offset),
(fade_in_start, cur_options.fade_in_start),
(fade_in_stop, cur_options.fade_in_stop),
(fade_out_start, cur_options.fade_out_start),
(fade_out_stop, cur_options.fade_out_stop),
]
for arg, default_value in optional_args:
args.append(arg if arg is not None else default_value)

args = validate_args_list(optional_args)

send_cmd(
"tv_SoundProjectAdjust",
track_index,
*args,
error_values=[-2, -3],
)
args.append(color_index)
send_cmd("tv_SoundProjectAdjust", track_index, *args, error_values=[-2, -3])


@try_cmd(
Expand Down
2 changes: 2 additions & 0 deletions pytvpaint/layer.py
Original file line number Diff line number Diff line change
Expand Up @@ -785,6 +785,8 @@ def new_background_layer(
Returns:
Layer: the new animation layer
"""
from pytvpaint.clip import Clip

clip = clip or Clip.current_clip()
layer = cls.new(name, clip, color)
layer.pre_behavior = george.LayerBehavior.HOLD
Expand Down
3 changes: 2 additions & 1 deletion tests/george/test_grg_camera.py
Original file line number Diff line number Diff line change
Expand Up @@ -99,7 +99,8 @@ def test_tv_camera_insert_point(test_project: TVPProject) -> None:
assert tv_camera_interpolation(0.0) == point


def test_tv_camera_remove_point() -> None:
def test_tv_camera_remove_point(test_project: TVPProject) -> None:
# Note : leave `test_project` in test args otherwise test won't work
tv_camera_insert_point(0, 50, 25, 0, 0.0)
tv_camera_remove_point(0)

Expand Down
12 changes: 6 additions & 6 deletions tests/george/test_grg_clip.py
Original file line number Diff line number Diff line change
Expand Up @@ -249,17 +249,17 @@ def test_tv_last_image(test_clip: TVPClip) -> None:

@pytest.mark.parametrize("offset_count", [None, *itertools.product([0, 1], [0, 1])])
@pytest.mark.parametrize("field_order", [None, *FieldOrder])
@pytest.mark.parametrize("stretch", [None, False, True])
@pytest.mark.parametrize("time_stretch", [None, False, True])
@pytest.mark.parametrize("preload", [None, False, True])
@pytest.mark.parametrize("stretch", [False, True])
@pytest.mark.parametrize("time_stretch", [False, True])
@pytest.mark.parametrize("preload", [False, True])
def test_tv_load_sequence(
ppm_sequence: list[Path],
test_clip: TVPClip,
offset_count: tuple[int, int] | None,
field_order: FieldOrder | None,
stretch: bool | None,
time_stretch: bool | None,
preload: bool | None,
stretch: bool,
time_stretch: bool,
preload: bool,
) -> None:
total_images = len(ppm_sequence)
first_image = ppm_sequence[0]
Expand Down
2 changes: 1 addition & 1 deletion tests/george/test_grg_layer.py
Original file line number Diff line number Diff line change
Expand Up @@ -927,7 +927,7 @@ def test_tv_load_image(
test_clip: TVPClip,
test_layer: TVPLayer,
ppm_sequence: list[Path],
stretch: bool | None,
stretch: bool,
) -> None:
tv_load_image(ppm_sequence[0], stretch)
# Verify that there's an instance frame
Expand Down
4 changes: 2 additions & 2 deletions tests/george/test_grg_project.py
Original file line number Diff line number Diff line change
Expand Up @@ -301,13 +301,13 @@ def test_tv_get_field(test_project: TVPProject) -> None:
assert tv_get_field() == test_project.field_order


@pytest.mark.parametrize("use_camera", [None, False, True])
@pytest.mark.parametrize("use_camera", [False, True])
@pytest.mark.parametrize("start, end", [(None, None), (0, 5), (0, 0), (0, 1), (2, 5)])
def test_tv_project_save_sequence(
test_project: TVPProject,
tmp_path: Path,
ppm_sequence: list[Path],
use_camera: bool | None,
use_camera: bool,
start: int | None,
end: int | None,
) -> None:
Expand Down

0 comments on commit 4cc5ea5

Please sign in to comment.