DCC Integration¶
Each DCC is its own self-contained workspace package under packages/<dcc>/src/kpipe_<dcc>/,
following a three-layer pattern within that one package.
Layers¶
1. Launcher (packages/<dcc>/src/kpipe_<dcc>/launcher.py)¶
- Reads the DCC executable path from config
- Sets environment variables:
PYTHONPATH,OCIO,KPIPE_ENV, etc. - Spawns the DCC process
Run from the command line:
uv run kpipe launch blender
uv run kpipe launch nuke
uv run kpipe launch premiere
uv run kpipe launch tvpaint
uv run kpipe launch substance
uv run kpipe launch mrv2
All arguments after the DCC name are passed on to the DCC. kpipe launch does the
DCC-independent setup (logging via kpipe.init(), version banner, KPIPE_ROOT) and then
calls the launcher's launch(args: list[str]) -> int; the return value is the exit code.
Use kpipe -d launch <dcc> for debug logging.
2. Extension (sibling files in kpipe_<dcc>/)¶
Startup scripts loaded by the DCC when it launches, packaged alongside the launcher in the same directory. Responsibilities:
- Import and initialise the K-Pipe session
- Register DCC-specific actions into the action registry
- Add K-Pipe menus or panels to the DCC UI
Blender uses the Blender 4+ extension system (kpipe_blender/system/, containing both
the kpipe_blender extension and the integrated kpipe_asset_pipeline extension as
sibling installable extensions — required so Blender's local extension repository scan
sees both). Nuke uses a menu.py/init.py startup script pair, found by pointing
NUKE_PATH/NUKE_MENU_PATH at the package directory itself
(Path(__file__).resolve().parent from launcher.py, since launcher and extension files
are always siblings in this layout).
3. Session (kpipe.session, in packages/core/src/kpipe/session.py)¶
- Manages the active entity and task state
- Extensions register DCC-specific callbacks for open, save, and close events
- Handles versioned workfile naming on save
Adding a new DCC¶
- Create
packages/<dcc>/with asrc/kpipe_<dcc>/tree containinglauncher.pyplus the DCC's startup/extension scripts - Implement
launch(args: list[str]) -> intinlauncher.py(optionally decorated with@kpipe.cli.launch.launcher("<Display Name>")) and register it in thekpipe.cli.launchentry-point group inpackages/<dcc>/pyproject.toml([project.entry-points."kpipe.cli.launch"], e.g.<dcc> = "kpipe_<dcc>.launcher:launch"), which makes it available askpipe launch <dcc> - Add
packages/<dcc>to the rootpyproject.toml's[tool.uv.workspace] members - Add DCC path config key to your project bundle's
kpipe.toml
Opening a published mesh in Substance Painter¶
kpipe launch substance takes three arguments that belong together, used by LaunchDcc at the end of the blender_asset_fbx pipeline:
kpipe launch substance --kpipe-entity asset:Character:Doris --kpipe-task shading --kpipe-mesh Q:/.../doplay-Character_Doris-asset_fbx-v003.fbx
- No workfile for the task yet: a project is created from the mesh without a dialog, with the settings of
[dcc.substance.project], and saved as the first workfile as soon as Painter can save. - A workfile exists: the latest version of the main layer opens. If the mesh differs from the one stored in the project, including a re-publish to the same path, the artist can replace it. Replacing saves a new workfile version.
The task is set in the pipeline config, in LaunchDcc's args. Other arguments are passed on to Painter.
[dcc.substance.project] |
Default | Values |
|---|---|---|
normal_map_format |
"OpenGL" |
OpenGL, DirectX |
tangent_space_mode |
"PerFragment" |
PerFragment, PerVertex |
project_workflow |
"UVTile" |
UVTile, TextureSetPerUVTile, Default |
default_texture_resolution |
2048 |
Texture Set resolution |
import_cameras |
false |
Import cameras from the mesh |
template |
unset | Painter template file (template string) |
Every launch starts a new Painter instance and workfiles aren't locked, so a workfile can end up open in two instances.