You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
Every non-final stamp of an SDF relief/incise stroke is bounded 4×strength wide, so a 4-sample stroke dirties 53× the bricks of one stamp #672
On v0.120.1, one clay_layer_apply_stroke call with op RELIEF (INCISE behaves the same) authors one node per stamp. clay_layer_node_influence_bound reports those nodes as follows:
The last stamp is local: its x-extent is about 3× the brush radius on each side, under 1 world unit.
Every earlier stamp is widened by 4 × strength world units on each side, whatever the radius: +2.0 at strength 0.5, +4.0 at strength 1.0.
clay_brick_cache_mark_dirty_nodes follows those bounds. So a 4-sample stroke on a unit sphere dirties 2,548 bricks and the host re-meshes the whole sphere, while a single stamp dirties 48.
Repro
A document with one SDF layer holding a unit sphere.
One clay_layer_apply_stroke, op CLAY_OP_RELIEF (same with CLAY_OP_INCISE).
4 samples at x = 0, 0.03, 0.06, 0.09 (y = 0, z = 1), pressure 1.
Node ids from sizing with clay_stroke_resolve. For each authored node: clay_layer_node_influence_bound(doc, layer, node, low, high, &has, &infinite).
Stamp
x half-extent beyond its centre
last
about 3 × radius (0.36)
each earlier stamp
about 3 × radius + 4 × strength (+2.0 at strength 0.5)
Brick drain (clay_brick_cache_mark_dirty_nodes over the authored nodes, then take_dirty): 2,548 bricks for the stroke against 48 for one stamp.
Suspected cause
The #650 fix (PR #653, "Bound an edit by the smooth combines after it") dilates an edit's bound by the support of the smooth combines that follow it. For the non-final stamps of a stroke, the next stamp's relief amplitude (4 × strength) seems to be read as a blend support. Only the final stamp has no following combine, which fits the last stamp being the only local one.
Expected
Each stamp is bounded by its own reach (plus any genuine blend support), as a lone stamp is. The dirty region of a stroke should scale with the stroke's footprint, not with strength × stamp count.
Impact on hosts
This is the "cost scales with the edit, never with the sculpture" rule: every relief/incise stroke re-meshes most of a small form, and the dab latency budget is lost on larger ones. Hosts can't safely narrow the bound themselves, because that risks stale bricks.
Host evidence
ClaySpaceIOS pins this in Packages/ClayCoreKit/Tests/ClayCoreKitTests/StrokeInfluenceTripwire.swift (everyStampOfAStrokeIsBoundedByItsOwnReach). It's a known-issue test that flips when the engine fixes it; the branch will be linked once it's pushed. The app doesn't narrow the bound on its side meanwhile. Context: CyberdyneCorp/ClaySpaceIOS#3.
ClaySpaceIOS pins this with a known-issue test that will fail once it's fixed: StrokeInfluenceTripwire.swift (everyStampOfAStrokeIsBoundedByItsOwnReach). It's in CyberdyneCorp/ClaySpaceIOS#9.
Activity
leonardoaraujosantos commentedon Sep 30, 2026
ClaySpaceIOS pins this with a known-issue test that will fail once it's fixed: StrokeInfluenceTripwire.swift (
everyStampOfAStrokeIsBoundedByItsOwnReach). It's in CyberdyneCorp/ClaySpaceIOS#9.Test that every stamp of a relief stroke is bounded by its own reach (#…
Bound an edit to a relief or incise item by its own box (#672)
Record the ABI line after rebasing onto 0.123.0 (#672)
Merge pull request #683 from CyberdyneCorp/perf/672-relief-drag-reach