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
characterentity kind and theplayandexpressionactions, 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.stagecompiler (cutan.compile), and the mouth and eye visuals of the stage runtime (cutan/runtime/visuals.js); - the lip-sync providers
offline,rhubarbandwhisper(cutan.audio); - locomotion, speech, blink and turn methods with their requirements and defaults, and the cut-out vocabulary;
- the
an character …andan impacts …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.stylesto list them (thecutan-styleskill 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 and cutan[faces] for the face locator; 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. 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.
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.
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 still work in an, with a MovedModuleWarning.
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.12
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | |
|---|---|---|---|
| cutan-0.0.12.tar.gz | 1.1 MB | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| cutan-0.0.12-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 1.4 MB
Release files / cutan-0.0.12.tar.gz
| Download URL | cutan-0.0.12.tar.gz |
|---|---|
| Size | 1.1 MB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
989e368b36efc6071809fba9996a98a57bfdac1e196052f7621246995bf5525b
|
|
BLAKE2b-256 checksum How to use checksums |
1dba630e14d5b96a26834909f2cfd59973206b0df6f1527dae01f2842d4e96a7
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
uv/0.12.23 {"installer":{"name":"uv","version":"0.12.23","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.12-py3-none-any.whl
| Download URL | cutan-0.0.12-py3-none-any.whl |
|---|---|
| Size | 363.1 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
5f207cf491a26a888109d4105a952638041f66701c07c8625bfa6d21347852e9
|
|
BLAKE2b-256 checksum How to use checksums |
debbf36009fd04e288c100ff15a9fa0350df2b126360ed193a80cf9573626738
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
uv/0.12.23 {"installer":{"name":"uv","version":"0.12.23","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}
|