Skip to main content

cutan

Cut-out animation for an: rigged characters, faces and expressions, lip-sync, swap sets and views, impacts, and cut-out styles, as a genre package on the an core.

pip install "an[cutout]"      # an + the stage + cutan
an character new maya --offline

an finds cutan through the an.genres entry point and loads it with an.genres.load() (the CLI and an.load(project) do). The scene format, rendering and the asset library are an's; see its README.

What is here

cutan registers with the core:

  • the character entity kind and the play and expression actions, the [emotion] dialogue sugar and the semantic checks that go with them (cutan.genre, cutan.characters, cutan.expression);
  • the rig, face, viseme, blink, gaze and swap-pose compile passes over the an.stage compiler (cutan.compile), and the mouth and eye visuals of the stage runtime (cutan/runtime/visuals.js);
  • the lip-sync providers offline, rhubarb and whisper (cutan.audio);
  • locomotion, speech, blink and turn methods with their requirements and defaults, and the cut-out vocabulary;
  • the an character …, an impacts … and an projects … command namespaces;
  • carving parts out of photos and frames (cutan.carve, below);
  • the style lint (python -m cutan.verify.style VIDEO <style>) and the named style specs it measures against, shipped as package data: cutan.style_spec("south_park"), python -m cutan.styles to list them (the cutan-style skill applies one).

Carving parts from a photo or a frame

cutan.carve turns a photo or a video frame into a matted, cleaned, provenance-carrying cut-out part, and writes it as a library-ready prop folder. It needs OpenCV: pip install "cutan[carve]" (it installs opencv-python-headless; an environment that already has opencv-python or opencv-contrib-python works as it is, since all three provide the same cv2). Add cutan[rembg] for the neural matte, cutan[faces] for the face locator and cutan[superres] for super resolution; cutan.carve.check_requirements() lists what is installed.

from cutan.carve import carve, carve_head, frame_source, write_prop, grab_frame, Polygon, FlatColour

src = frame_source("https://www.youtube.com/watch?v=VIDEO_ID", t=34.5, license="all-rights-reserved")
frame = grab_frame("clip.mp4", 34.5)
lamp = carve(frame, point=(1060, 130), source=src)               # flat_colour: the cartoon-frame default
print(lamp.quality.warnings())                                    # backdrop left on the rim, glyphs attached, ...
write_prop(lamp, "assets/props/lamp")                             # prop.json + parts/body.png, source included
head = carve_head(frame, face=(830, 170, 930, 305), matte="rembg")  # neck cut, 512² canvas, face centre as origin

The matte is a strategy: flat_colour (the default), chroma, grabcut, polygon, focus, rembg, or any (rgb, hint) -> alpha callable. Two combine with & and |: Polygon(outline) & FlatColour() is a hand outline cleaned by a colour key. split_parts lifts moving parts off a carving, each with a pivot (clock hands off the face), and write_prop gives each part its own bone. A held prop names its points: write_prop(sabre, folder, landmarks={"grip": (x, y), "tip": (x, y)}) writes each as a slotless bone on the root, which an reads as the rig's named point (sabre@tip in a scene; grip is where the hold verbs take it by default). An object with states (a book closed, open, a page mid-turn; a lamp off and on) is one prop: write_prop(closed, folder, state="closed", states={"open": opened}) writes the drawings as the swap set state on the base slot, each anchored at its own carving's point (carve every state with point= at the same physical place: the hand, the hinge) and credited with its own source, and a scene swaps it with {kind: set, target: book/body, property: state, value: open}. Publishing the folder (an library publish <folder> prop.<name> --package cutan --origin carved) records the rights from the descriptor's own source; write_prop refuses a carving with no provenance (unless the pixels are yours: ours=True) and a source= that would loosen its licence without relicense=. Every coordinate is in the source's pixels, and a carving's recipe is its arguments by name, so carve(frame, **part.recipe) replays it: a batch of carves is a list of recipes.

A part carved from a low-resolution frame (a 360p scan, where a sabre's blade is 3 px wide) gets new pixels with superres=: carve(frame, crop=..., matte=..., superres="realesr-animevideov3") runs Real-ESRGAN for anime video (BSD-3, x4, cutan[superres]; its 2.5 MB ONNX model is downloaded once into ~/.cache/cutan/models, CUTAN_MODELS_DIR moves it, and checked by hash) on the crop in overlapping tiles before the matte, and the part keeps the 4x resolution. upscale= is different: it only mattes at a higher resolution and comes back to the source's. Coordinates (and detach, feather, pad) stay in the source's pixels, part.scale is the factor, and the recipe records the strategy with the model's sha256. superres="resample" interpolates instead (no new detail); any rgb -> rgb callable a whole factor larger is a strategy too.

The cut-out bench corpus (misc/bench/), examples/ and the demo gallery (misc/demos/) live here too; cutan.bench.run_bench() runs the corpus through an's bench runner.

Production packs from writers

skills/cutan-production-pack/ is an agent skill for people who write and direct but do not run cutan: uploaded to Claude.ai (zip the folder, or package it with the skill-creator skill), it has their Claude write a production pack: scene.md, a cast.sh of an character new commands, environments, props and their SVG drawings, and a PRODUCTION.md brief, in the formats this package reads. Its example pack (examples/the-umbrella/) is validated by tests/test_production_pack_skill.py, which also regenerates the skill's vocabulary, preset, rig-path and style tables from the code.

Receiving a pack:

python skills/cutan-production-pack/scripts/validate_pack.py <pack>   # cutan's own checks on a scratch project
an init <id> --id --genre cutout_animation                            # then copy the pack in, run cast.sh's lines
an validate <project> --strict-assets && an render <project>          # from the project root, and render

validate_pack.py runs only an character ... lines from cast.sh (no shell). Set the licence of the pack's own drawings (their source) before publishing a render.

Names that never change

Moving the code renamed nothing that is stored. Scenes keep renderer: cutout, the genre keeps its slug cutout_animation, character descriptors keep their document kind and version, and asset ids keep their character. prefix. These names are in cutan/__init__.py. The old an.characters, an.expression, an.impacts, an.audio.offline_lipsync-style import paths worked in an with a MovedModuleWarning and are removed there (an#321): import from cutan.

Where data lives

The genre's asset library and agent-made projects live under ~/.local/share/cutan by default. Set CUTAN_HOME to move them. The core's own library (voices, sounds, fonts) stays under an's root, and a project reads both as one search path.

Working on cutan

Read CLAUDE.md. In short: pip install -e . --no-deps next to an editable an, then pytest. The tests that render need a headless browser (playwright install chromium) and ffmpeg.

Metadata

Release files for cutan 0.0.100

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for cutan 0.0.100
File Size Uploaded Provenance Actions
cutan-0.0.100.tar.gz 1.4 MB Without provenance Details for cutan-0.0.100.tar.gz

Built distribution (wheel)

Table of built distributions (wheels) for cutan 0.0.100
File Interpreter ABI Platform Actions
cutan-0.0.100-py3-none-any.whl Python 3 none any Details for cutan-0.0.100-py3-none-any.whl

Total release size: 1.9 MB

Release files / cutan-0.0.100.tar.gz

Download URL cutan-0.0.100.tar.gz
Size 1.4 MB
Tags Source
SHA-256 checksum
How to use checksums
bce7339d2298b3b7db8120d450cbde195e99faa2ca0e261ebc61edb76d8825b2
BLAKE2b-256 checksum
How to use checksums
4cd0c6ec0fa3fef7107796e1244c63c3c17968b6f102ce400564f531c5ad6370
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via uv/0.13.6 {"installer":{"name":"uv","version":"0.13.6","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}

Release files / cutan-0.0.100-py3-none-any.whl

Download URL cutan-0.0.100-py3-none-any.whl
Size 532.8 kB
Tags Python 3
SHA-256 checksum
How to use checksums
23af04da93a27dbe4edc1bf6ba247acdadd619b643c8a868c2a4c0abf4b252ca
BLAKE2b-256 checksum
How to use checksums
013396d7a27e803df36a11acfcb87f9d5e06c4686366fc3423faf5c8864ad9c8
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via uv/0.13.6 {"installer":{"name":"uv","version":"0.13.6","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}

Security for cutan 0.0.100

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

No provenance found

None of the files in this release were uploaded with provenance metadata.

A note on package security

PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.

To learn more about protecting yourself from malicious actors, visit our package security documentation.

Release history Release notifications | RSS feed

This release

0.0.100 This release

2 release files No provenance

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page