Skip to content

Clip class

Clip object class module.

Clip(clip_id: int, project: Project | None = None)

Bases: pytvpaint.utils.Removable, pytvpaint.utils.Renderable

A Clip is a container for layers and is part of a Scene.

Constructs a Clip from an existing TVPaint clip (giving its id).

Note

You should use Clip.new to create a new clip

Parameters:

Name Type Description Default
clip_id int

an existing clip id

required
project pytvpaint.project.Project | None

the project or the current one if None

None
Source code in pytvpaint/clip.py
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
def __init__(
    self,
    clip_id: int,
    project: Project | None = None,
) -> None:
    """Constructs a Clip from an existing TVPaint clip (giving its id).

    Note:
        You should use `Clip.new` to create a new clip

    Args:
        clip_id: an existing clip id
        project: the project or the current one if None
    """
    from pytvpaint.project import Project

    super().__init__()
    self._id = clip_id
    self._project = project or Project.current_project()
    self._data = george.tv_clip_info(self.id)

id: int property

The clip id.

project: Project property

The clip's project.

scene: Scene property writable

The clip's scene.

Raises:

Type Description
ValueError

if clip cannot be found in the project

camera: Camera property

The clip camera.

position: int property writable

The position of the clip in the scene.

Raises:

Type Description
ValueError

if clip cannot be found in the project

name: str property writable

The clip name.

duration: int property

The duration of the clip in frames. Takes into account the mark in/out of the clip.

is_selected: bool property writable

Returns True if the clip is selected.

is_visible: bool property writable

Returns True if the clip is visible.

color_index: int property writable

Get the clip color index.

action_text: str property writable

Get the action text of the clip.

dialog_text: str property writable

Get the dialog text of the clip.

note_text: str property writable

Get the note text of the clip.

current_frame: int property writable

Returns the current frame in the clip (timeline) relative to the project start frame.

layer_ids: Iterator[int] property

Iterator over the layer ids.

layers: Iterator[Layer] property

Iterator over the clip's layers.

layer_names: Iterator[str] property

Iterator over the clip's layer names.

current_layer: Layer property

Get the current layer in the clip.

Raises:

Type Description
ValueError

if clip cannot be found in the project

selected_layers: Iterator[Layer] property

Iterator over the selected layers.

visible_layers: Iterator[Layer] property

Iterator over the visible layers.

mark_in: int | None property writable

Get the mark in of the clip.

mark_out: int | None property writable

Get the mark out of the clip.

layer_colors: Iterator[LayerColor] property

Iterator over the layer colors.

bookmarks: Iterator[int] property

Iterator over the clip bookmarks.

sounds: Iterator[ClipSound] property

Iterates through the clip's soundtracks.

new(name: str, scene: Scene | None = None, project: Project | None = None) -> Clip classmethod

Creates a new clip.

Parameters:

Name Type Description Default
name str

the new clip name

required
scene pytvpaint.scene.Scene | None

the scene or the current one if None. Defaults to None.

None
project pytvpaint.project.Project | None

the project or the current one if None. Defaults to None.

None

Returns:

Name Type Description
Clip pytvpaint.clip.Clip

the newly created clip

Source code in pytvpaint/clip.py
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
@classmethod
def new(
    cls,
    name: str,
    scene: Scene | None = None,
    project: Project | None = None,
) -> Clip:
    """Creates a new clip.

    Args:
        name: the new clip name
        scene: the scene or the current one if None. Defaults to None.
        project: the project or the current one if None. Defaults to None.

    Returns:
        Clip: the newly created clip
    """
    from pytvpaint.project import Project

    project = project or Project.current_project()
    project.make_current()

    scene = scene or project.current_scene
    scene.make_current()

    name = utils.get_unique_name(project.clip_names, name)
    george.tv_clip_new(name)

    return Clip.current_clip()

refresh() -> None

Refreshes the clip data.

Source code in pytvpaint/clip.py
91
92
93
94
95
96
def refresh(self) -> None:
    """Refreshes the clip data."""
    super().refresh()
    if not self.refresh_on_call and self._data:
        return
    self._data = george.tv_clip_info(self._id)

make_current() -> None

Make the clip the current one.

Source code in pytvpaint/clip.py
 98
 99
100
101
102
def make_current(self) -> None:
    """Make the clip the current one."""
    if george.tv_clip_current_id() == self.id:
        return
    george.tv_clip_select(self.id)

start() -> int

The start frame of the clip.

Source code in pytvpaint/clip.py
170
171
172
173
@refreshed_property
def start(self) -> int:
    """The start frame of the clip."""
    return self._data.first_frame + self.project.start_frame

end() -> int

The end frame of the clip.

Source code in pytvpaint/clip.py
175
176
177
178
@refreshed_property
def end(self) -> int:
    """The end frame of the clip."""
    return self._data.last_frame + self.project.start_frame

timeline_start() -> int

The start frame of the clip relative to the project's timeline.

Source code in pytvpaint/clip.py
185
186
187
188
189
190
191
192
193
194
195
196
197
198
@refreshed_property
def timeline_start(self) -> int:
    """The start frame of the clip relative to the project's timeline."""
    # get clip real start in project timeline
    clip_real_start = 0
    for clip in self.project.clips:
        if clip == self:
            break
        clip_start = clip.mark_in or clip.start
        clip_end = clip.mark_out or clip.end
        clip_duration = (clip_end - clip_start) + 1
        clip_real_start += clip_duration

    return clip_real_start + self.project.start_frame

timeline_end() -> int

The end frame of the clip relative to the project's timeline.

Source code in pytvpaint/clip.py
200
201
202
203
204
205
206
@refreshed_property
def timeline_end(self) -> int:
    """The end frame of the clip relative to the project's timeline."""
    clip_start = self.mark_in or self.start
    clip_end = self.mark_out or self.end
    clip_duration = clip_end - clip_start
    return self.timeline_start + clip_duration

frame_count() -> int

The clip's frame count.

Source code in pytvpaint/clip.py
208
209
210
211
@refreshed_property
def frame_count(self) -> int:
    """The clip's frame count."""
    return self._data.frame_count

is_current() -> bool

Returns True if the clip is the current one.

Source code in pytvpaint/clip.py
273
274
275
276
@refreshed_property
def is_current(self) -> bool:
    """Returns True if the clip is the current one."""
    return Clip.current_clip_id() == self.id

current_clip_id() -> int staticmethod

Returns the id of the current clip.

Source code in pytvpaint/clip.py
278
279
280
281
@staticmethod
def current_clip_id() -> int:
    """Returns the id of the current clip."""
    return george.tv_clip_current_id()

current_clip() -> Clip staticmethod

Returns the current clip object.

Source code in pytvpaint/clip.py
283
284
285
286
287
288
@staticmethod
def current_clip() -> Clip:
    """Returns the current clip object."""
    from pytvpaint.project import Project

    return Clip(Clip.current_clip_id(), Project.current_project())

duplicate() -> Clip

Duplicates the clip.

Note

a new unique name is choosen for the duplicated clip with get_unique_name.

Source code in pytvpaint/clip.py
302
303
304
305
306
307
308
309
310
311
312
@set_as_current
def duplicate(self) -> Clip:
    """Duplicates the clip.

    Note:
        a new unique name is choosen for the duplicated clip with `get_unique_name`.
    """
    george.tv_clip_duplicate(self.id)
    new_clip = self.project.current_clip
    new_clip.name = utils.get_unique_name(self.project.clip_names, new_clip.name)
    return new_clip

remove() -> None

Removes the clip.

Warning

the instance is not usable after that call because it's marked as removed.

Source code in pytvpaint/clip.py
314
315
316
317
318
319
320
321
def remove(self) -> None:
    """Removes the clip.

    Warning:
        the instance is not usable after that call because it's marked as removed.
    """
    george.tv_clip_close(self.id)
    self.mark_removed()

get_layer(by_id: int | None = None, by_name: str | None = None) -> Layer | None

Get a specific layer by id or name.

Source code in pytvpaint/clip.py
356
357
358
359
360
361
362
def get_layer(
    self,
    by_id: int | None = None,
    by_name: str | None = None,
) -> Layer | None:
    """Get a specific layer by id or name."""
    return utils.get_tvp_element(self.layers, by_id, by_name)

add_layer(layer_name: str) -> Layer

Add a new layer in the layer stack.

Source code in pytvpaint/clip.py
364
365
366
367
@set_as_current
def add_layer(self, layer_name: str) -> Layer:
    """Add a new layer in the layer stack."""
    return Layer.new(name=layer_name, clip=self)

load_media(media_path: Path, start_count: tuple[int, int] | None = None, stretch: bool = False, time_stretch: bool = False, preload: bool = False, with_name: str = '', field_order: george.FieldOrder = george.FieldOrder.LOWER) -> Layer

Loads a media (single frame, video, ...) into a new Layer in the clip.

Parameters:

Name Type Description Default
media_path pathlib.Path

the path of the media. If it's a file sequence, give the path of the first image.

required
start_count tuple[int, int] | None

the start and number of image of sequence to load. Defaults to None.

None
stretch bool

Stretch each image to the size of the layer. Defaults to None.

False
time_stretch bool

Once loaded, the layer will have a new number of image corresponding to the project framerate. Defaults to None.

False
preload bool

Load all the images in memory, no more reference on the files. Defaults to None.

False
with_name str

the name of the new layer

''
field_order pytvpaint.george.FieldOrder

the field order. Defaults to None.

pytvpaint.george.FieldOrder.LOWER

Returns:

Name Type Description
Layer pytvpaint.layer.Layer

the new layer created

Source code in pytvpaint/clip.py
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
@set_as_current
@george.undoable
def load_media(
    self,
    media_path: Path,
    start_count: tuple[int, int] | None = None,
    stretch: bool = False,
    time_stretch: bool = False,
    preload: bool = False,
    with_name: str = "",
    field_order: george.FieldOrder = george.FieldOrder.LOWER,
) -> Layer:
    """Loads a media (single frame, video, ...) into a new Layer in the clip.

    Args:
        media_path: the path of the media. If it's a file sequence, give the path of the first image.
        start_count: the start and number of image of sequence to load. 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.
        preload: Load all the images in memory, no more reference on the files. Defaults to None.
        with_name: the name of the new layer
        field_order: the field order. Defaults to None.

    Returns:
        Layer: the new layer created
    """
    media_path = Path(media_path)

    george.tv_load_sequence(
        media_path,
        start_count,
        field_order,
        stretch,
        time_stretch,
        preload,
    )

    new_layer = Layer.current_layer()
    new_layer.name = with_name or media_path.stem

    return new_layer

render(output_path: Path | str | FileSequence, start: int | None = None, end: int | None = None, use_camera: bool = False, layer_selection: list[Layer] | None = None, alpha_mode: george.AlphaSaveMode = george.AlphaSaveMode.PREMULTIPLY, background_mode: george.BackgroundMode | None = None, format_opts: list[str] | None = None) -> None

Render the clip to a single frame or frame sequence or movie.

Parameters:

Name Type Description Default
output_path pathlib.Path | str | fileseq.filesequence.FileSequence

a single file or file sequence pattern

required
start int | None

the start frame to render or the mark in or the clip's start if None. Defaults to None.

None
end int | None

the end frame to render or the mark out or the clip's end if None. Defaults to None.

None
use_camera bool

use the camera for rendering, otherwise render the whole canvas. Defaults to False.

False
layer_selection list[pytvpaint.layer.Layer] | None

list of layers to render, if None render all of them. Defaults to None.

None
alpha_mode pytvpaint.george.AlphaSaveMode

the alpha mode for rendering. Defaults to george.AlphaSaveMode.PREMULTIPLY.

pytvpaint.george.AlphaSaveMode.PREMULTIPLY
background_mode pytvpaint.george.BackgroundMode | None

the background mode for rendering. Defaults to None.

None
format_opts list[str] | None

custom format options. Defaults to None.

None

Raises:

Type Description
ValueError

if requested range (start-end) not in clip range/bounds

ValueError

if output is a movie, and it's duration is equal to 1 frame

FileNotFoundError

if the render failed and no files were found on disk or missing frames

Note

This functions uses the clip's range as a basis (start-end). This is different from a project range, which uses the project timeline. For more details on the differences in frame ranges and the timeline in TVPaint, please check the Usage/Rendering section of the documentation.

Warning

Even tough pytvpaint does a pretty good job of correcting the frame ranges for rendering, we're still encountering some weird edge cases where TVPaint will consider the range invalid for seemingly no reason.

Source code in pytvpaint/clip.py
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
@set_as_current
def render(
    self,
    output_path: Path | str | FileSequence,
    start: int | None = None,
    end: int | None = None,
    use_camera: bool = False,
    layer_selection: list[Layer] | None = None,
    alpha_mode: george.AlphaSaveMode = george.AlphaSaveMode.PREMULTIPLY,
    background_mode: george.BackgroundMode | None = None,
    format_opts: list[str] | None = None,
) -> None:
    """Render the clip to a single frame or frame sequence or movie.

    Args:
        output_path: a single file or file sequence pattern
        start: the start frame to render or the mark in or the clip's start if None. Defaults to None.
        end: the end frame to render or the mark out or the clip's end if None. Defaults to None.
        use_camera: use the camera for rendering, otherwise render the whole canvas. Defaults to False.
        layer_selection: list of layers to render, if None render all of them. Defaults to None.
        alpha_mode: the alpha mode for rendering. Defaults to george.AlphaSaveMode.PREMULTIPLY.
        background_mode: the background mode for rendering. Defaults to None.
        format_opts: custom format options. Defaults to None.

    Raises:
        ValueError: if requested range (start-end) not in clip range/bounds
        ValueError: if output is a movie, and it's duration is equal to 1 frame
        FileNotFoundError: if the render failed and no files were found on disk or missing frames

    Note:
        This functions uses the clip's range as a basis (start-end). This  is different from a project range, which
        uses the project timeline. For more details on the differences in frame ranges and the timeline in TVPaint,
        please check the `Usage/Rendering` section of the documentation.

    Warning:
        Even tough pytvpaint does a pretty good job of correcting the frame ranges for rendering, we're still
        encountering some weird edge cases where TVPaint will consider the range invalid for seemingly no reason.
    """
    default_start = self.mark_in or self.start
    default_end = self.mark_out or self.end

    self._render(
        output_path,
        default_start,
        default_end,
        start,
        end,
        use_camera,
        layer_selection=layer_selection,
        alpha_mode=alpha_mode,
        background_mode=background_mode,
        format_opts=format_opts,
    )

export_tvp(export_path: Path | str) -> None

Exports the clip in .tvp format which can be imported as a project in TVPaint.

Raises:

Type Description
ValueError

if output extension is not (.tvp)

FileNotFoundError

if the render failed and no files were found on disk

Source code in pytvpaint/clip.py
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
@set_as_current
def export_tvp(self, export_path: Path | str) -> None:
    """Exports the clip in .tvp format which can be imported as a project in TVPaint.

    Raises:
        ValueError: if output extension is not (.tvp)
        FileNotFoundError: if the render failed and no files were found on disk
    """
    export_path = Path(export_path)

    if export_path.suffix != ".tvp":
        raise ValueError("The file extension must be .tvp")

    export_path.parent.mkdir(exist_ok=True, parents=True)
    george.tv_save_clip(export_path)

    if not export_path.exists():
        raise FileNotFoundError(
            f"Could not find output at : {export_path.as_posix()}"
        )

export_json(export_path: Path | str, save_format: george.SaveFormat, folder_pattern: str = '[%3li] %ln', file_pattern: str = '[%3ii] %ln', layer_selection: list[Layer] | None = None, alpha_mode: george.AlphaSaveMode = george.AlphaSaveMode.PREMULTIPLY, background_mode: george.BackgroundMode | None = None, format_opts: list[str] | None = None, all_images: bool = False, ignore_duplicates: bool = False) -> None

Exports the instances (or all the images) of layers in the clip and a JSON file describing the structure of that clip.

Parameters:

Name Type Description Default
export_path pathlib.Path | str

the JSON export path

required
save_format pytvpaint.george.SaveFormat

file format to use for rendering

required
folder_pattern str

the folder name pattern (%li: layer index, %ln: layer name, %fi: file index (added in 11.0.8)). Defaults to None.

'[%3li] %ln'
file_pattern str

the file name pattern (%li: layer index, %ln: layer name, %ii: image index, %in: image name, %fi: file index (added in 11.0.8)). Defaults to None.

'[%3ii] %ln'
layer_selection list[pytvpaint.layer.Layer] | None

list of layers to render or all if None. Defaults to None.

None
alpha_mode pytvpaint.george.AlphaSaveMode

the export alpha mode. Defaults to george.AlphaSaveMode.PREMULTIPLY.

pytvpaint.george.AlphaSaveMode.PREMULTIPLY
background_mode pytvpaint.george.BackgroundMode | None

the export background mode. Defaults to None.

None
format_opts list[str] | None

custom format options. Defaults to None.

None
all_images bool

export all images (not only the instances). Defaults to False.

False
ignore_duplicates bool

Ignore duplicates images. Defaults to None.

False

Raises:

Type Description
FileNotFoundError

if the export failed and no files were found on disk

Source code in pytvpaint/clip.py
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
@set_as_current
def export_json(
    self,
    export_path: Path | str,
    save_format: george.SaveFormat,
    folder_pattern: str = r"[%3li] %ln",
    file_pattern: str = r"[%3ii] %ln",
    layer_selection: list[Layer] | None = None,
    alpha_mode: george.AlphaSaveMode = george.AlphaSaveMode.PREMULTIPLY,
    background_mode: george.BackgroundMode | None = None,
    format_opts: list[str] | None = None,
    all_images: bool = False,
    ignore_duplicates: bool = False,
) -> None:
    """Exports the instances (or all the images) of layers in the clip and a JSON file describing the structure of that clip.

    Args:
        export_path: the JSON export path
        save_format: file format to use for rendering
        folder_pattern: the folder name pattern (%li: layer index, %ln: layer name, %fi: file index (added in 11.0.8)). Defaults to None.
        file_pattern: the file name pattern (%li: layer index, %ln: layer name, %ii: image index, %in: image name, %fi: file index (added in 11.0.8)). Defaults to None.
        layer_selection: list of layers to render or all if None. Defaults to None.
        alpha_mode: the export alpha mode. Defaults to george.AlphaSaveMode.PREMULTIPLY.
        background_mode: the export background mode. Defaults to None.
        format_opts: custom format options. Defaults to None.
        all_images: export all images (not only the instances). Defaults to False.
        ignore_duplicates: Ignore duplicates images. Defaults to None.

    Raises:
        FileNotFoundError: if the export failed and no files were found on disk
    """
    export_path = Path(export_path)
    export_path.parent.mkdir(exist_ok=True, parents=True)

    fill_background = bool(
        background_mode not in [None, george.BackgroundMode.NONE]
    )

    with utils.render_context(
        alpha_mode, background_mode, save_format, format_opts, layer_selection
    ):
        george.tv_clip_save_structure_json(
            export_path,
            save_format,
            fill_background=fill_background,
            folder_pattern=folder_pattern,
            file_pattern=file_pattern,
            visible_layers_only=True,
            all_images=all_images,
            ignore_duplicates=ignore_duplicates,
        )

    if not export_path.exists():
        raise FileNotFoundError(
            f"Could not find output at : {export_path.as_posix()}"
        )

export_psd(export_path: Path | str, mode: george.PSDSaveMode, start: int | None = None, end: int | None = None, layer_selection: list[Layer] | None = None, alpha_mode: george.AlphaSaveMode = george.AlphaSaveMode.PREMULTIPLY, background_mode: george.BackgroundMode | None = None, format_opts: list[str] | None = None) -> None

Save the current clip as a PSD.

Parameters:

Name Type Description Default
export_path pathlib.Path | str

the PSD save path

required
mode pytvpaint.george.PSDSaveMode

whether to save all the images, only the instances or inside the markin

required
start int | None

the start frame. Defaults to None.

None
end int | None

the end frame. Defaults to None.

None
layer_selection list[pytvpaint.layer.Layer] | None

layers to render. Defaults to None (render all the layers).

None
alpha_mode pytvpaint.george.AlphaSaveMode

the alpha save mode. Defaults to george.AlphaSaveMode.PREMULTIPLY.

pytvpaint.george.AlphaSaveMode.PREMULTIPLY
background_mode pytvpaint.george.BackgroundMode | None

the export background mode. Defaults to None.

None
format_opts list[str] | None

custom format options. Defaults to None.

None

Raises:

Type Description
FileNotFoundError

if the export failed and no files were found on disk

Source code in pytvpaint/clip.py
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
@set_as_current
def export_psd(
    self,
    export_path: Path | str,
    mode: george.PSDSaveMode,
    start: int | None = None,
    end: int | None = None,
    layer_selection: list[Layer] | None = None,
    alpha_mode: george.AlphaSaveMode = george.AlphaSaveMode.PREMULTIPLY,
    background_mode: george.BackgroundMode | None = None,
    format_opts: list[str] | None = None,
) -> None:
    """Save the current clip as a PSD.

    Args:
        export_path: the PSD save path
        mode: whether to save all the images, only the instances or inside the markin
        start: the start frame. Defaults to None.
        end: the end frame. Defaults to None.
        layer_selection: layers to render. Defaults to None (render all the layers).
        alpha_mode: the alpha save mode. Defaults to george.AlphaSaveMode.PREMULTIPLY.
        background_mode: the export background mode. Defaults to None.
        format_opts: custom format options. Defaults to None.

    Raises:
        FileNotFoundError: if the export failed and no files were found on disk
    """
    start = start or self.mark_in or self.start
    end = end or self.mark_out or self.end

    export_path = Path(export_path)
    image = start if mode == george.PSDSaveMode.IMAGE else None

    with utils.render_context(
        alpha_mode,
        background_mode,
        george.SaveFormat.PSD,
        format_opts,
        layer_selection,
    ):
        george.tv_clip_save_structure_psd(
            export_path,
            mode,
            image=image,
            mark_in=start,
            mark_out=end,
        )

    if mode == george.PSDSaveMode.MARKIN:
        # raises error if sequence not found
        check_path = export_path.with_suffix(f".#{export_path.suffix}").as_posix()
        assert FileSequence.findSequenceOnDisk(check_path)
    else:
        if not export_path.exists():
            raise FileNotFoundError(
                f"Could not find output at : {export_path.as_posix()}"
            )

export_csv(export_path: Path | str, save_format: george.SaveFormat, all_images: bool = False, exposure_label: str = '', layer_selection: list[Layer] | None = None, alpha_mode: george.AlphaSaveMode = george.AlphaSaveMode.PREMULTIPLY, background_mode: george.BackgroundMode | None = None, format_opts: list[str] | None = None) -> None

Save the current clip as a CSV.

Parameters:

Name Type Description Default
export_path pathlib.Path | str

the .csv export path

required
save_format pytvpaint.george.SaveFormat

file format to use for rendering

required
all_images bool

export all images or only instances. Defaults to None.

False
exposure_label str

give a label when the image is an exposure. Defaults to None.

''
layer_selection list[pytvpaint.layer.Layer] | None

layers to render. Defaults to None (render all the layers).

None
alpha_mode pytvpaint.george.AlphaSaveMode

the alpha save mode. Defaults to george.AlphaSaveMode.PREMULTIPLY.

pytvpaint.george.AlphaSaveMode.PREMULTIPLY
background_mode pytvpaint.george.BackgroundMode | None

the export background mode. Defaults to None.

None
format_opts list[str] | None

custom format options. Defaults to None.

None

Raises:

Type Description
ValueError

if the extension is not .csv

FileNotFoundError

if the render failed and no files were found on disk

Source code in pytvpaint/clip.py
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
@set_as_current
def export_csv(
    self,
    export_path: Path | str,
    save_format: george.SaveFormat,
    all_images: bool = False,
    exposure_label: str = "",
    layer_selection: list[Layer] | None = None,
    alpha_mode: george.AlphaSaveMode = george.AlphaSaveMode.PREMULTIPLY,
    background_mode: george.BackgroundMode | None = None,
    format_opts: list[str] | None = None,
) -> None:
    """Save the current clip as a CSV.

    Args:
        export_path: the .csv export path
        save_format: file format to use for rendering
        all_images: export all images or only instances. Defaults to None.
        exposure_label: give a label when the image is an exposure. Defaults to None.
        layer_selection: layers to render. Defaults to None (render all the layers).
        alpha_mode: the alpha save mode. Defaults to george.AlphaSaveMode.PREMULTIPLY.
        background_mode: the export background mode. Defaults to None.
        format_opts: custom format options. Defaults to None.

    Raises:
        ValueError: if the extension is not .csv
        FileNotFoundError: if the render failed and no files were found on disk
    """
    export_path = Path(export_path)

    if export_path.suffix != ".csv":
        raise ValueError("Export path must have .csv extension")

    with utils.render_context(
        alpha_mode, background_mode, save_format, format_opts, layer_selection
    ):
        george.tv_clip_save_structure_csv(export_path, all_images, exposure_label)

    if not export_path.exists():
        raise FileNotFoundError(
            f"Could not find output at : {export_path.as_posix()}"
        )

export_sprites(export_path: Path | str, layout: george.SpriteLayout | None = None, space: int = 0, layer_selection: list[Layer] | None = None, alpha_mode: george.AlphaSaveMode = george.AlphaSaveMode.PREMULTIPLY, background_mode: george.BackgroundMode | None = None, format_opts: list[str] | None = None) -> None

Save the current clip as sprites in one image.

Parameters:

Name Type Description Default
export_path pathlib.Path | str

description

required
layout pytvpaint.george.SpriteLayout | None

the sprite layout. Defaults to None.

None
space int

the space between each sprite in the image. Defaults to None.

0
layer_selection list[pytvpaint.layer.Layer] | None

layers to render. Defaults to None (render all the layers).

None
alpha_mode pytvpaint.george.AlphaSaveMode

the alpha save mode. Defaults to george.AlphaSaveMode.PREMULTIPLY.

pytvpaint.george.AlphaSaveMode.PREMULTIPLY
background_mode pytvpaint.george.BackgroundMode | None

the export background mode. Defaults to None.

None
format_opts list[str] | None

custom format options. Defaults to None.

None

Raises:

Type Description
FileNotFoundError

if the export failed and no files were found on disk

Source code in pytvpaint/clip.py
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
@set_as_current
def export_sprites(
    self,
    export_path: Path | str,
    layout: george.SpriteLayout | None = None,
    space: int = 0,
    layer_selection: list[Layer] | None = None,
    alpha_mode: george.AlphaSaveMode = george.AlphaSaveMode.PREMULTIPLY,
    background_mode: george.BackgroundMode | None = None,
    format_opts: list[str] | None = None,
) -> None:
    """Save the current clip as sprites in one image.

    Args:
        export_path (Path | str): _description_
        layout: the sprite layout. Defaults to None.
        space: the space between each sprite in the image. Defaults to None.
        layer_selection: layers to render. Defaults to None (render all the layers).
        alpha_mode: the alpha save mode. Defaults to george.AlphaSaveMode.PREMULTIPLY.
        background_mode: the export background mode. Defaults to None.
        format_opts: custom format options. Defaults to None.

    Raises:
        FileNotFoundError: if the export failed and no files were found on disk
    """
    export_path = Path(export_path)
    save_format = george.SaveFormat.from_extension(export_path.suffix)

    with utils.render_context(
        alpha_mode, background_mode, save_format, format_opts, layer_selection
    ):
        george.tv_clip_save_structure_sprite(export_path, layout, space)

    if not export_path.exists():
        raise FileNotFoundError(
            f"Could not find output at : {export_path.as_posix()}"
        )

export_flix(export_path: Path | str, start: int | None = None, end: int | None = None, import_parameters: str = '', file_parameters: str = '', send: bool = False, layer_selection: list[Layer] | None = None, alpha_mode: george.AlphaSaveMode = george.AlphaSaveMode.PREMULTIPLY, background_mode: george.BackgroundMode | None = None, format_opts: list[str] | None = None) -> None

Save the current clip for Flix.

Parameters:

Name Type Description Default
export_path pathlib.Path | str

the .xml export path

required
start int | None

the start frame. Defaults to None.

None
end int | None

the end frame. Defaults to None.

None
import_parameters str

the attribute(s) of the global tag (waitForSource/...). Defaults to None.

''
file_parameters str

the attribute(s) of each (file) tag (dialogue/...). Defaults to None.

''
send bool

open a browser with the prefilled url. Defaults to None.

False
layer_selection list[pytvpaint.layer.Layer] | None

layers to render. Defaults to None (render all the layers).

None
alpha_mode pytvpaint.george.AlphaSaveMode

the alpha save mode. Defaults to george.AlphaSaveMode.PREMULTIPLY.

pytvpaint.george.AlphaSaveMode.PREMULTIPLY
background_mode pytvpaint.george.BackgroundMode | None

the export background mode. Defaults to None.

None
format_opts list[str] | None

custom format options. Defaults to None.

None

Raises:

Type Description
ValueError

if the extension is not .xml

FileNotFoundError

if the export failed and no files were found on disk

Source code in pytvpaint/clip.py
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
@set_as_current
def export_flix(
    self,
    export_path: Path | str,
    start: int | None = None,
    end: int | None = None,
    import_parameters: str = "",
    file_parameters: str = "",
    send: bool = False,
    layer_selection: list[Layer] | None = None,
    alpha_mode: george.AlphaSaveMode = george.AlphaSaveMode.PREMULTIPLY,
    background_mode: george.BackgroundMode | None = None,
    format_opts: list[str] | None = None,
) -> None:
    """Save the current clip for Flix.

    Args:
        export_path: the .xml export path
        start: the start frame. Defaults to None.
        end: the end frame. Defaults to None.
        import_parameters: the attribute(s) of the global <flixImport> tag (waitForSource/...). Defaults to None.
        file_parameters: the attribute(s) of each <image> (file) tag (dialogue/...). Defaults to None.
        send: open a browser with the prefilled url. Defaults to None.
        layer_selection: layers to render. Defaults to None (render all the layers).
        alpha_mode: the alpha save mode. Defaults to george.AlphaSaveMode.PREMULTIPLY.
        background_mode: the export background mode. Defaults to None.
        format_opts: custom format options. Defaults to None.

    Raises:
        ValueError: if the extension is not .xml
        FileNotFoundError: if the export failed and no files were found on disk
    """
    export_path = Path(export_path)

    if export_path.suffix != ".xml":
        raise ValueError("Export path must have .xml extension")

    original_file = self.project.path
    import_parameters = (
        import_parameters
        or 'waitForSource="1" multipleSetups="1" replaceSelection="0"'
    )

    # The project needs to be saved
    self.project.save()

    # save alpha mode and save format values
    with utils.render_context(
        alpha_mode, background_mode, None, format_opts, layer_selection
    ):
        george.tv_clip_save_structure_flix(
            export_path,
            start,
            end,
            import_parameters,
            file_parameters,
            send,
            original_file,
        )

    if not export_path.exists():
        raise FileNotFoundError(
            f"Could not find output at : {export_path.as_posix()}"
        )

set_layer_color(layer_color: LayerColor) -> None

Set the layer color at the provided index.

Parameters:

Name Type Description Default
layer_color pytvpaint.layer.LayerColor

the layer color instance.

required
Source code in pytvpaint/clip.py
846
847
848
849
850
851
852
853
854
def set_layer_color(self, layer_color: LayerColor) -> None:
    """Set the layer color at the provided index.

    Args:
        layer_color: the layer color instance.
    """
    george.tv_layer_color_set_color(
        self.id, layer_color.index, layer_color.color, layer_color.name
    )

get_layer_color(by_index: int | None = None, by_name: str | None = None) -> LayerColor | None

Get a layer color by index or name.

Raises:

Type Description
ValueError

if none of the arguments by_index and by_name where provided

Source code in pytvpaint/clip.py
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
def get_layer_color(
    self,
    by_index: int | None = None,
    by_name: str | None = None,
) -> LayerColor | None:
    """Get a layer color by index or name.

    Raises:
        ValueError: if none of the arguments `by_index` and `by_name` where provided
    """
    if not by_index and by_name:
        raise ValueError(
            "At least one value (by_index or by_name) must be provided"
        )

    if by_index is not None:
        return next(c for i, c in enumerate(self.layer_colors) if i == by_index)

    try:
        return next(c for c in self.layer_colors if c.name == by_name)
    except StopIteration:
        return None

add_bookmark(frame: int) -> None

Add a bookmark at that frame.

Source code in pytvpaint/clip.py
888
889
890
def add_bookmark(self, frame: int) -> None:
    """Add a bookmark at that frame."""
    george.tv_bookmark_set(frame - self.project.start_frame)

remove_bookmark(frame: int) -> None

Remove a bookmark at that frame.

Source code in pytvpaint/clip.py
892
893
894
def remove_bookmark(self, frame: int) -> None:
    """Remove a bookmark at that frame."""
    george.tv_bookmark_clear(frame - self.project.start_frame)

clear_bookmarks() -> None

Remove all the bookmarks.

Source code in pytvpaint/clip.py
896
897
898
899
900
def clear_bookmarks(self) -> None:
    """Remove all the bookmarks."""
    bookmarks = list(self.bookmarks)
    for frame in bookmarks:
        self.remove_bookmark(frame)

go_to_previous_bookmark() -> None

Go to the previous bookmarks frame.

Source code in pytvpaint/clip.py
902
903
904
905
@set_as_current
def go_to_previous_bookmark(self) -> None:
    """Go to the previous bookmarks frame."""
    george.tv_bookmark_prev()

go_to_next_bookmark() -> None

Go to the next bookmarks frame.

Source code in pytvpaint/clip.py
907
908
909
910
@set_as_current
def go_to_next_bookmark(self) -> None:
    """Go to the next bookmarks frame."""
    george.tv_bookmark_next()

get_sound(by_id: int | None = None, by_path: Path | str | None = None) -> ClipSound | None

Get a clip sound by id or by path.

Raises:

Type Description
ValueError

if sound object could not be found in clip

Source code in pytvpaint/clip.py
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
def get_sound(
    self,
    by_id: int | None = None,
    by_path: Path | str | None = None,
) -> ClipSound | None:
    """Get a clip sound by id or by path.

    Raises:
        ValueError: if sound object could not be found in clip
    """
    for sound in self.sounds:
        if (by_id and sound.id == by_id) or (by_path and sound.path == by_path):
            return sound

    return None

add_sound(sound_path: Path | str) -> ClipSound

Adds a new clip soundtrack.

Source code in pytvpaint/clip.py
938
939
940
def add_sound(self, sound_path: Path | str) -> ClipSound:
    """Adds a new clip soundtrack."""
    return ClipSound.new(sound_path, parent=self)