v1.0.20 - viewport-relative retouch, bound to the darkroom image
Viewport-relative retouch
Placing a heal circle used to mean hand-computing a fraction of the whole frame while both the user and the model were looking at a zoomed crop. Three new tools work in the coordinates of what is actually on screen:
capture_viewport(viewport?, max_w?, max_h?, return_image?)- snapshot region plus render of themainorpreview2window, returns asnapshot_id.retouch_add_shape_in_viewport(...)- heal/clone circle placed in that snapshot's own pixels or 0..1 frame.retouch_update_shape_in_viewport(...)- move or resize an existing shape in place, keeping its formid.retouch_delete_shapes(formids, instance?)- batch cleanup.
coordinate_space is snapshot_normalized or snapshot_pixels (pixels of the returned render, not of the darktable window). The older viewport_* spellings remain as aliases.
Coordinate handling
Two stages sit behind these tools. The first is a plain affine remap from the captured region. The second matters more: darktable's masks are normalized against the pipe-input frame, not the processed frame get_viewport/get_preview report, and the two diverge as soon as orientation, crop, rotate or lens correction is active. A portrait raw alone is enough to put a neck target on the chest. The new dt.develop.backtransform_point binding (darktable-agentic 5.8.0+agentic.12) performs the same conversion the GUI drag path does, and every response reports input, display-frame and mask-frame values so a bad placement is debuggable.
Radius scales by the region's width only, never height and never an average, so circle size does not depend on the window's aspect ratio. Points outside the captured region are rejected rather than clamped.
Edits stay on the photo they were aimed at
Every darkroom binding resolves against darktable's global current image; there is no per-call image handle in the C API. A snapshot taken on one photo would happily write to whatever was open by the time the call landed. Reported from the field as an add that succeeded, a post-edit preview of an unrelated photo, and a delete that then failed with no darkroom image loaded.
- Snapshots record the image id at capture time.
- Mutating calls refuse a mismatch by id before writing anything.
- Previews report which photo they rendered, and shout when it is not the snapshot's.
- A darkroom-gone error now carries the live darkroom state instead of leaving the caller to guess.
Dependency fix
rawpy, Pillow and pyexiv2 moved from the [vision] extra into base dependencies. extract_previews and apply_ratings_batch are registered unconditionally, so they always failed at call time on a .deb deploy, whose venv is built from the base dependency set. The [vision] extra is gone.
Requirements
Needs darktable-agentic 5.8.0+agentic.12 or newer for the backtransform_point and retouch_update_shape Lua bindings.