From ff791b15da178f81ba4e5f15a9d74a37b23b5c80 Mon Sep 17 00:00:00 2001 From: TMHSDigital <154358121+TMHSDigital@users.noreply.github.com> Date: Sat, 26 Sep 2026 14:09:28 -0400 Subject: [PATCH 1/2] docs(roadmap): restock the candidate pool with 25 subjects Twelve showcase props, each chosen for a contact or budget no shipped piece tests yet (flange-on-rail, pin-in-knuckle, belt-on-pulley, chain links, two-support span, coaxial basins), and thirteen API-contract examples covering traps AI code gets wrong (non-persistent handlers, link vs append, local vs world ray_cast, Non-Color normal maps, solidify even offset, FBX unit scale, collection instances). Co-Authored-By: Claude Opus 5.5 (1M context) Signed-off-by: TMHSDigital <154358121+TMHSDigital@users.noreply.github.com> --- ROADMAP.md | 25 +++++++++++++++++++++++++ 1 file changed, 25 insertions(+) diff --git a/ROADMAP.md b/ROADMAP.md index 4c6d54a..d0041fa 100644 --- a/ROADMAP.md +++ b/ROADMAP.md @@ -143,6 +143,31 @@ Not committed; target list for the next content version. (v0.3.0 shipped the smo - ~~Library ladder or book trolley with loose books as a game-prop showcase piece~~ **SHIPPED** (the trolley half) as `showcase/book-trolley/` — a double-sided library book truck on four swivel casters: arched end panels standing in skids, four sloped troughs each a tilted shelf and a backrest square to it, forty-seven spines-out hardbacks and two loose stacks on the deck; each trough book's fore-edge depth in its backrest is read off the mesh beside its shelf seat, `--off-back` and `--deep-back` exit 21 on it while every seat and the envelope still pass - Library rolling ladder (hooked top rollers riding a round rail, raked stiles, treads, floor wheels) as a game-prop showcase piece — the unbuilt half of the item above: a hook riding a round rail is a curved-on-curved contact that neither the trolley's flat backrests nor the yoke's hung ring exercise - Ox cart tongue or plough beam that hitches to the yoke's ring as a game-prop showcase piece — a hitch is a ring-on-hook contact the yoke's hung ring only tests against a fixed bar +- Mine cart on a rail segment as a game-prop showcase piece — flanged wheels seated on the railheads: every tread contact within a band of the rail top and every flange clearing the rail's inner face by a gauge band, so a cart riding up on a flange or dropping between the rails fails while seats and bbox still pass +- Hinged garden gate as a game-prop showcase piece — strap hinges whose knuckles sit coaxial on the post pintles: knuckle axis-to-pintle axis distance within a band and the swing arc clearing the latch post, a pin-in-knuckle contact no existing piece tests +- Mooring bollard with a coiled rope as a game-prop showcase piece — rope turns laid as stacked helices around the barrel: each turn resting on the one below (not interpenetrating, not floating), measured turn-to-turn off the mesh +- Ship's wheel as a game-prop showcase piece — spokes and handles by exact radial repetition: equal angular spacing, every spoke end seated in the rim, hub/rim concentric, handles on the computed radius +- Sawhorse pair carrying a plank as a game-prop showcase piece — splayed legs and a board spanning two supports: the plank's underside rests on both saddles within a band (a two-support span, not a single seat) and every foot lands on the floor +- Tiered stone fountain as a game-prop showcase piece — concentric basins on a column: every basin coaxial, each upper basin's lip overhanging the one below by a stated band so the overflow line lands inside the next basin +- Cannon on a wooden field carriage as a game-prop showcase piece — trunnions seated in the carriage's cap-square cradles: trunnion axis coaxial with both cradles and wheels resting on the ground at the axle's computed height +- Spinning wheel as a game-prop showcase piece — a drive band running from the wheel groove to the whorl: band path tangent to both pulleys within a band (a belt-on-pulley contact), treadle linkage reaching the crank +- Hanging tavern sign as a game-prop showcase piece — sign board hung from a wall bracket by chain: each link threaded through its neighbour without interpenetration and the board hanging plumb under the bracket hooks +- Tiered skep beehive on a stand as a game-prop showcase piece — coiled straw courses as stacked tori: each course seated on the one below, the dome closing on its axis +- Rowboat with oars in oarlocks as a game-prop showcase piece — oar shafts passing through the oarlock horns with clearance inside a band, hull resting on its keel line on a flat deck/floor +- Weathervane as a game-prop showcase piece — arrow and cardinal arms on a spindle: the arrow's pivot bore coaxial with the spindle and the arrow statically balanced (centroid on the pivot axis within a band) +- `persistent` app-handler witness — handlers registered without `@bpy.app.handlers.persistent` are dropped by `wm.read_homefile`/file load while persistent ones survive; assert the registered-handler set before and after a reload (silent loss AI code hits) +- Link vs append witness — `bpy.data.libraries.load(link=True)` yields a linked, non-editable datablock (`library` set, `is_editable` False) while append yields a local copy; write a temp .blend with `bpy.data.libraries.write`, then assert both paths +- Orphan purge witness — `bpy.data.orphans_purge(do_recursive=...)` removes exactly the zero-user datablocks computed independently beforehand, and `bpy.data.batch_remove` removes a given set in one call (counts closed-form) +- Local vs world ray-cast witness — `Object.ray_cast` takes object-local origin/direction while `Scene.ray_cast` takes world space; a transformed target hit at closed-form points both ways, and passing world coords to `Object.ray_cast` misses (the trap) +- `mathutils.bvhtree` witness — `BVHTree.FromObject` on evaluated geometry: `find_nearest` distances and `overlap` pairs match closed forms on a known arrangement +- Curves datablock witness — the modern `bpy.types.Curves` hair API (`add_curves`, `position` attribute, `curve_offset_data`) vs legacy particle hair: point and curve counts closed-form, every root on the emitter surface +- Non-Color normal-map witness — an image used as a normal map must be `colorspace_settings.name = 'Non-Color'`; a baked/sampled value round-trips only then, and sRGB shifts it by the transfer curve (a silent shading error AI code ships) +- Solidify even-thickness witness — `use_even_offset` keeps shell thickness constant at sharp corners, while without it the corner thins by 1/cos(θ/2): measured thickness at a known angle matches both closed forms +- Boolean solver witness — EXACT solver union/difference volumes match closed forms on overlapping primitives, and the result is manifold; FAST on coplanar faces is the documented failure case +- Lattice deform witness — a 2×2×2 lattice with one displaced point deforms interior verts by exact trilinear weights (`interpolation_type_u/v/w = 'KEY_LINEAR'`) +- FBX unit-scale witness — `export_scene.fbx` with `apply_unit_scale` / `apply_scale_options` changes exported coordinates by the closed-form ×100 cm factor; re-import restores metres only on the matching option +- Collection-instance witness — `instance_type = 'COLLECTION'` instances appear only in `depsgraph.object_instances` (never in `scene.objects`); instance world matrices match the closed-form offsets +- Asset-marking witness — `ID.asset_mark()`, `asset_data.tags` and catalog UUIDs written to `blender_assets.cats.txt`, re-read from a saved library file (check-only if no legible still) - ~~Small modular kit showcase on recognizable geometry (`modular-kit-snap` contract)~~ **SHIPPED** as `showcase/fence-kit/` — tiling post-and-rail section (AABB X is the tile width; does not re-witness the snap contract); `--skip-decimate` exits 9 on the LOD1 ratio band - ~~Custom ID-property delete witness~~ **SHIPPED** as `examples/cross-version-property-delete/` — IDs built via `bpy.data.objects.new` (not `active_object`); `property_unset` is TypeError and leaves the key; `del` removes it on 4.5 LTS and 5.x From 42a8eb9a0d0676b5b6922c8fe94b9bbcb3636c36 Mon Sep 17 00:00:00 2001 From: TMHSDigital <154358121+TMHSDigital@users.noreply.github.com> Date: Sat, 26 Sep 2026 14:27:47 -0400 Subject: [PATCH 2/2] docs(roadmap): add 16 flagship candidates Multi-part hero props (tower clock gear train, trebuchet, locomotive, windmill, carousel, sloop, chess set, dungeon kit) and multi-stage API contracts (GN simulation-zone ballistics, procedural buildings, road along a curve, L-system repeat zone, UDIM, ORM channel packing, Cryptomatte, planted-foot walk cycle), each anchored on one invariant measured off the result. Co-Authored-By: Claude Opus 5.5 (1M context) Signed-off-by: TMHSDigital <154358121+TMHSDigital@users.noreply.github.com> --- ROADMAP.md | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/ROADMAP.md b/ROADMAP.md index d0041fa..8f51d31 100644 --- a/ROADMAP.md +++ b/ROADMAP.md @@ -168,6 +168,22 @@ Not committed; target list for the next content version. (v0.3.0 shipped the smo - FBX unit-scale witness — `export_scene.fbx` with `apply_unit_scale` / `apply_scale_options` changes exported coordinates by the closed-form ×100 cm factor; re-import restores metres only on the matching option - Collection-instance witness — `instance_type = 'COLLECTION'` instances appear only in `depsgraph.object_instances` (never in `scene.objects`); instance world matrices match the closed-form offsets - Asset-marking witness — `ID.asset_mark()`, `asset_data.tags` and catalog UUIDs written to `blender_assets.cats.txt`, re-read from a saved library file (check-only if no legible still) +- **Flagship showcase: working clock-tower movement** — a tower clock with a visible gear train (great wheel, intermediate pinions, escape wheel, anchor and pendulum, dial motion works driving hour and minute hands): every meshing pair on its computed centre distance (pitch radii sum) with teeth interleaved not interpenetrating, train ratio hour:minute exactly 1:12 recomputed from tooth counts off the mesh, pendulum bob hanging plumb; `--wrong-ratio` / `--gear-clash` falsifiers +- **Flagship showcase: counterweight trebuchet** — A-frame, throwing arm on an axle, hinged counterweight box, sling and pouch, release pin: axle bore coaxial in both uprights, arm pivot on the axle, counterweight hanging plumb from its hinge, sling length within a band of the arm's short-side ratio, all four skids on the ground +- **Flagship showcase: steam locomotive (narrow-gauge)** — boiler barrel, smokebox, cab, drivers linked by coupling and connecting rods, valve gear: every driver on the rail at the axle's computed height, coupling-rod length equal to axle spacing so the rods stay parallel (a four-bar invariant measured off the mesh), crankpins at equal quartering angle +- **Flagship showcase: windmill with sail stocks and brake wheel** — tower cap, four lattice sails on a windshaft, brake wheel meshing the wallower: sails at exact 90° about the shaft axis, shaft tilt as a stated constant, brake-wheel/wallower centre distance from pitch radii +- **Flagship showcase: fairground carousel** — canopy, centre pole, crank rods, 12 horses on twisted brass poles in two rings: exact radial and angular spacing per ring, every pole plumb and passing through a horse's saddle bore, platform concentric with the canopy +- **Flagship showcase: pirate sloop** — lofted hull from stations, deck planking, mast, boom, gaff, shrouds and ratlines to chainplates, cannon ports: hull mirror-symmetric to the keel plane, every shroud terminating on its chainplate and masthead within a band, ratlines horizontal and evenly spaced +- **Flagship showcase: full chess set on a board** — 32 lathe-turned pieces (king to pawn, two woods) on an inlaid board: every piece centred on its square's computed centre, base seated on the board, lathe profiles revolved exactly (radii match profile closed form), 64 squares alternating by (file + rank) parity +- **Flagship showcase: modular dungeon kit** — floor, wall, corner, arch, stair and pillar tiles on a 2 m grid composed into a room: every open-edge boundary vert on the grid, zero gap/overlap at every joint, stair riser × count equal to one storey height, per-tile budgets plus a composed-room budget +- **Flagship example: GN simulation-zone ballistic fountain** — a Simulation Zone integrating particles under gravity: positions at frame N match the closed-form ballistic arc (p₀ + v₀t − ½gt²) per particle, determinism across re-bakes, and the 4.x vs 5.x bake/cache API paths documented; `--no-cache-reset` falsifier +- **Flagship example: GN procedural building generator** — one node tree with floor count, bay count and roof type as modifier inputs driving storeys, windows (instanced), cornices and a pitched or flat roof: window instance count = floors × bays × faces closed-form, storey heights exact, three buildings from the same tree side by side +- **Flagship example: GN road along a curve** — a Bezier path swept into a road with kerbs, lane markings and lamp posts instanced at equal arc-length spacing aligned to the tangent: post count = floor(length / spacing) + 1, every post perpendicular to the curve tangent within a band +- **Flagship example: L-system tree via GN repeat zone** — branching generated by a Repeat Zone: branch/leaf counts closed-form in the iteration depth, each child branch attached to its parent's tip, total height the closed-form series sum +- **Flagship example: UDIM texture set** — `Image.tiles.new` for 1001–1004, a UV layout spanning four tiles, per-tile bake/paint writes: tile numbers map to UV offsets exactly, each tile's pixels land only in its tile, `` filepath round-trips through save and reload +- **Flagship example: channel-packed ORM bake** — Cycles-bake AO, roughness and metallic of a prop into R/G/B of one Non-Color image: each channel matches its independently baked single-channel reference within a stated tolerance, and sRGB tagging is the falsifier +- **Flagship example: Cryptomatte ID witness** — a multi-object scene rendered with Cryptomatte passes to multilayer EXR: decoded object IDs (MurmurHash3 of the names) cover exactly each object's coverage mask, re-read with the stdlib-only EXR reader +- **Flagship example: walk cycle with planted feet** — slotted-action walk cycle on a leg rig with IK and NLA strip blending: planted-foot world position constant during each contact phase (foot slide below a band), stride length × cycles equals root travel, 4.5 vs 5.x channelbag paths - ~~Small modular kit showcase on recognizable geometry (`modular-kit-snap` contract)~~ **SHIPPED** as `showcase/fence-kit/` — tiling post-and-rail section (AABB X is the tile width; does not re-witness the snap contract); `--skip-decimate` exits 9 on the LOD1 ratio band - ~~Custom ID-property delete witness~~ **SHIPPED** as `examples/cross-version-property-delete/` — IDs built via `bpy.data.objects.new` (not `active_object`); `property_unset` is TypeError and leaves the key; `del` removes it on 4.5 LTS and 5.x