- update native web_engine sources and rebuilt wasm artifacts - add task cards, status notes and tooling scripts - add web e2e specs, tutorial UI sources and tutorial assets - sync golden task manifests and audit records Co-Authored-By: Claude Code <noreply@anthropic.com>
89 lines
28 KiB
Markdown
89 lines
28 KiB
Markdown
# WBV2-P1425-001 status
|
||
|
||
- task: `WBV2-P1425-001`; module: `OBJECT_ADD_ROUTE`; status: `in_progress`
|
||
- creation
|
||
- Add menu uses `web_blender.desktop_operator(native=true)` with revision/scene/area/mode/selection context.
|
||
- Mesh primitives incl. Circle/Grid/Monkey; NURBS curves/surfaces; non-mesh types and enum submenus; Empty display types; Grease Pencil line-art types; random hair; Edit-mode Add; generic F3; quick-toolbar primitives.
|
||
- hierarchy
|
||
- Commands/UI: `moveCollection` (including sibling ordering), `deleteCollection` (normal/recursive), `createCollection` child, `setActiveCollection`, `setScene`, `setSceneCollectionSettings`.
|
||
- Outliner collection drag/drop; Collection Properties delete/child/active/instance/up/down; per-ViewLayer exclude/holdout/indirectOnly/hide; topbar scene selector and scene delete; view layer add/remove; parent types and clear modes.
|
||
- modeling
|
||
- Mesh element selection bridge and post-operator readback; curve control-point selection bridge.
|
||
- Broad mesh/curve/UV operator coverage; selection-aware modal tools; UV projection/select/stitch/pack; vertex groups; shape keys; modifier Apply/Shape Key/Duplicate/Copy; object shading/convert/origin/transform/data/pivot/snap.
|
||
- Modifier whitelist expanded by 20 source-backed types: WeightedNormal, CorrectiveSmooth, LaplacianSmooth, Mask, NormalEdit, Skin, UVProject, UVWarp, Warp, DataTransfer, WeightVGEdit, WeightVGMix, WeightVGProximity, LaplacianDeform, ParticleInstance, Surface, MeshCache, MeshSequenceCache, Multires, Explode.
|
||
- implementation coverage: 486 operator units in five families have an implementation route (317 menu/modal, 26 typed command, 143 F3 operator palette). `MESH_OT_` 164/164, `OBJECT_OT_` 215/215, `CURVE_OT_` 51/51, `SURFACE_OT_` 6/6, `UV_OT_` 50/50 classified `WEB_MAIN` in the route catalog; behavioral evidence remains separate and `UNVERIFIED` for the broader catalog.
|
||
- artifacts: `implemented-routes.json`, `implemented-unit-bindings.json`, `implementation-summary.json`, `docs/plans/WEB_BLENDER_THREE_DOMAIN_VALIDATION_CHECKLIST.md`.
|
||
- build: WASM rebuilt with the project environment and absolute paths; runtime synced (wasm SHA-256 `8ec2268f73584215419b72292cda0bc8fb055a9e9044224722077bfe3f43987d`). Command registry check PASS (170 commands, 161 WEB_MAIN routes). Frontend incremental build passed with `WBV2_SKIP_TYPECHECK=1`.
|
||
- blockers fixed in this round:
|
||
- `editors/mesh` registers `mesh.convex_hull` under `WITH_BULLET`, but the Web `bf_bmesh` target omitted Bullet and therefore did not register the `convex_hull` BMO. Executing it ran a null operator type and crashed WASM (`table index is out of bounds`); SKIN used the same path. The WITH_WEB branch of `bmesh/CMakeLists.txt` now links `bf_intern_rigidbody` and `bf::dependencies::optional::bullet`.
|
||
- Speaker `distance_max` defaults to `FLT_MAX` in DNA while SceneIR budgets it to 1e9; the blend reader now clamps distance fields, and empty `actionSlotIdentifier` values (sound strips created by Speaker Add) are omitted instead of failing the schema.
|
||
- Add → 数据实例 now resolves the active object's data-block name and ID type from SceneIR before invoking `object.data_instance_add` (invoking it operand-less is correctly cancelled).
|
||
- Embedded the Essentials geometry-node bundles (`geometry_nodes_essentials`, `geometry_nodes_dynamics_assets`, `procedural_hair_node_assets` + catalog) under `/blender/datafiles/assets`. The browser asset index does not list packaged-FS files, so `add_essential_asset_modifier` now falls back to appending the requested NodeTree directly from the embedded .blend; hair curves Add completes with the Capture Rest Geometry and Hair Dynamics modifiers.
|
||
- Modifier parameter changes only wrote DNA and left the embedded Python depsgraph’s evaluated copy stale, so `object.modifier_apply` baked the previous level. Updated parameter publication now uses the concrete modifier RNA struct, full recalc flags (`GEOMETRY | SYNC_TO_EVAL | PARAMETERS`) and a notifier, re-tags after the SceneIR refresh, and the operator bootstrap re-syncs modifier RNA once before native execution. SUBSURF levels 2 evaluates 98 vertices, Apply bakes 98, and save/reopen keeps 98.
|
||
- Saving while an object was in Edit mode omitted the edit data (e.g. Armature edit-bones). The save export now calls `ED_editors_flush_edits` before serialization, matching desktop save; added/subdivided/duplicated bones and hair-curves modifiers persist across save/reopen.
|
||
- SceneIR published every Object in Main, so a newly created empty scene still listed the other scene’s objects and native operators failed with `OPERATOR_SELECTION_CONTEXT_UNAVAILABLE`. The reader now emits nodes only for objects reachable from the active scene’s master collection, and `setScene` also points every wmWindow at the selected scene. `scene.new` → switch → `scene.delete` now publishes 0 nodes for the empty scene, 3 for the original and returns to `Scene` after deletion.
|
||
- Library append read the source from memory but left a Library entry pointing at a browser locator; snapshot/save packing could not find that path and failed with `LIBRARY_DEPENDENCY_UNAVAILABLE`. The append path now retains the uploaded source bytes in `recovery_library_bytes` keyed by the missing-library path, so append, undo/redo, save and reopen work.
|
||
- Collection instances published only an EMPTY owner. The reader now emits `instanceCollectionId`, `SceneNodeIR` validates it, and the Three.js viewport recursively expands nested collection instances with composed matrices, respecting collection/member visibility and depth/cycle limits. Display copies share member geometry/materials; the viewport also draws camera frustums and empty axes, so instanced cameras and empties are visible. Picking reports the nearest instance owner, so nested instance contents select their own instance object. Save/reopen keeps the reference.
|
||
- `uv.select_overlap` now works on Web: the WASM call trapped with `'unreachable'` while constructing `blender::Array<ChangedInfo>` from its bitfield initializer. The local `ChangedInfo` array now uses `std::vector`, behavior-equivalent; the operator finishes and the 60-case matrix has no open operator failure.
|
||
- `object.shade_auto_smooth` now works on Web: the embedded Essentials bundle is not indexed by the asset system, so the operator cancelled with “No asset found … Smooth by Angle”. With `WITH_WEB` it fetches the bundle, suppresses the false asset report, direct-appends the NodeTree with `WM_file_append_datablock`, and validates it as the Smooth by Angle group.
|
||
- The full `mathutils` Python surface is available again on Web: the `MATH_WEB_CORE_ONLY` compile definition was removed from `bf_python_mathutils`, so `mathutils.geometry/interpolate/noise/bvhtree/kdtree` are registered. `uv.lightmap_pack` (`mathutils.geometry.box_pack_2d`) now finishes instead of raising `AttributeError`.
|
||
- Native canvas replacement no longer breaks GPU resources. The Web/native toggle destroys the old WebGL context, but a retained vert/index buffer from that context made the next modal frame throw “Blender WebGL2 drawing resource belongs to another canvas”. `WebGLObjects::require_owner` now drops the dead GL names and lets `bind()` re-create and re-upload from the retained CPU bytes, so the next canvas draws normally.
|
||
- Added a Web “调整上一步操作” panel for operators invoked through the native channel. It records the operator, schema and created objects; applying edits deletes the created objects and re-runs the operator with converted RNA values from the original context. Non-creating operators fall back to undo + re-invoke guarded by the history cursor. The panel’s “完整属性…” action opens the existing F3 operator form preselected with the recorded operator and values, so pointer, collection, nested-group, enum-set and matrix properties are editable in the same adjustment flow.
|
||
- operator sweep: `web/tests/e2e/wbv2-operator-sweep-production.spec.ts` invokes every registered operator in the native `mesh`/`object`/`uv`/`curve` families (167/250/55/51 identifiers extracted from the desktop registry `bpy.ops.*`) through `desktop_operator` with a fresh Main per case, classifies EXECUTED / CONTEXT_POLL / CONTEXT_CANCEL / CONTEXT_MESSAGE / ERROR / TIMEOUT / CRASH and writes `verification/operator-sweep-<family>.json` bound to the WASM hash. The mesh family sweep is running; results and any real failures will be recorded per family.
|
||
- verification PASS (Chromium, focused slices):
|
||
- `web/tests/e2e/wbv2-add-menu-native-production.spec.ts`: Add menu → native `mesh.primitive_monkey_add` → Main/SceneIR → Outliner shows Suzanne/Monkey.
|
||
- `web/tests/e2e/wbv2-three-domain-focused-production.spec.ts` creation: base 1 → create 2 → undo 3 → redo 4; saved 421,265 bytes; reopen revision 1 with `VerifyCube` present.
|
||
- hierarchy: create/move/active/delete revisions 3-6, undo 7, redo 8; saved 417,882 bytes; reopen revision 1 with `VerifyParent`.
|
||
- modeling: meshTriangulate 2, undo 3, redo 4; SUBSURF add 5, remove 6; saved 417,327 bytes; reopen revision 1.
|
||
- `web/tests/e2e/wbv2-mesh-native-operator-ui-production.spec.ts`: Web mode switch → Edit mode → meshSelection bridge → native `mesh.poke`; status `已执行:mesh.poke`.
|
||
- `web/tests/e2e/wbv2-modifier-matrix-production.spec.ts`: all 20 expanded modifier types add/evaluate/remove/save/reopen, every case `FINISHED` (including SKIN after the Bullet linkage fix).
|
||
- `web/tests/e2e/wbv2-convex-hull-native-production.spec.ts`: Edit mode → `mesh.select_all` → native `mesh.convex_hull` state `DONE`.
|
||
- `web/tests/e2e/wbv2-native-operator-matrix-production.spec.ts`: 60/60 mesh/UV/object operators `FINISHED` on WASM `8ec2268f`, including shade_auto_smooth, uv.lightmap_pack and uv.select_overlap after the asset, mathutils and overlap-container fixes. The receipt records the WASM SHA-256. UV-editor-only/cursor/active-face operators and no-op selection clears are documented as inapplicable to the detached Layout/VIEW_3D fixture, not counted. Earlier test-only failures were corrected against the native RNA registry (`mesh.vertices_smooth`, `object.hide_view_set` without `clear`, `mesh.unsubdivide` without `threshold`, etc.).
|
||
- `web/tests/e2e/wbv2-creation-object-types-production.spec.ts`: 29 creation/data cases on WASM `8ec2268f` — all six `SURFACE_OT_` primitives (surface, sphere, circle, curve, cylinder, torus), five curve primitives (Bezier, NURBS curve, NURBS path, Bezier circle, NURBS circle) and the mesh/text/armature/empty/camera/light/metaball/volume/lattice/GP/point cloud/hair curves/speaker/light probe/effector types each produced a SceneIR node; operand-less `object.data_instance_add` remains cancelled with no mutation. Receipt records the WASM SHA-256.
|
||
- `web/tests/e2e/wbv2-data-instance-add-production.spec.ts`: Outliner selection → Add → 数据实例 creates `Cube.001` through the native ID lookup.
|
||
- `web/tests/e2e/wbv2-hair-curves-add-production.spec.ts`: hair curves Add appends both embedded Essentials node groups; surface gains `Capture Rest Geometry`, Curves object gains `Hair Dynamics` and is parented to `BasicCube`.
|
||
- `web/tests/e2e/wbv2-modifier-parameters-apply-production.spec.ts`: SUBSURF levels 2 evaluates 98 vertices through `evaluateDepsgraph`, undo restores level 1 / 26 vertices, redo restores level 2 / 98, native `object.modifier_apply` bakes 98 and removes the modifier, save/reopen keeps 98.
|
||
- `web/tests/e2e/wbv2-modifier-apply-convert-production.spec.ts`: BEVEL width 0.1/segments 2 evaluates 56 vertices and `object.modifier_apply` bakes 56; SUBSURF level 2 followed by `object.convert(target=MESH)` bakes 98 and clears the stack.
|
||
- `web/tests/e2e/wbv2-curve-edit-operators-production.spec.ts`: Bezier create → Edit → 32 curve operators all `FINISHED` on WASM `1e6e7d3f` (added select more/less/next/previous/random/similar/linked, de_select_first/last, smooth radius/tilt/weight, spline_weight_set, shade smooth/flat, dissolve_verts, split, separate, hide, normals_make_consistent) and the receipt records the WASM SHA-256. `curve.select_nth`/`curve.select_row` are desktop-inapplicable to a default Bezier circle (same native errors: no active point / poll context incorrect) and are documented instead of counted. Fixed the menu enum value `AUTO` → `AUTOMATIC`.
|
||
- `web/tests/e2e/wbv2-convert-to-mesh-production.spec.ts`: Bezier (13 verts), NURBS surface (256 verts / 225 faces) and default Text (177 verts / 171 faces) all convert to `MESH` through `object.convert`.
|
||
- `web/tests/e2e/wbv2-armature-edit-production.spec.ts`: Armature create → Edit → primitive add (1→2 bones), subdivide (1→2), duplicate (1→2), calculate roll (count unchanged) all `FINISHED`; save while in Edit mode and reopen preserves the new bone count.
|
||
- `web/tests/e2e/wbv2-object-tools-production.spec.ts`: two shape keys, one vertex group, modifier copy (two SUBSURF entries) and SIMPLE_DEFORM apply-as-shape-key (2 keys, modifier kept).
|
||
- `web/tests/e2e/wbv2-hair-curves-add-production.spec.ts` now also saves and reopens: the Curves object keeps `Hair Dynamics`, its parent and the surface’s `Capture Rest Geometry`.
|
||
- `web/tests/e2e/wbv2-edit-mode-persistence-production.spec.ts`: `mesh.poke` in Edit mode grows the cube from 8 to 14 vertices, and save/reopen preserves 14.
|
||
- `web/tests/e2e/wbv2-scene-flow-production.spec.ts`: `scene.new` publishes 0 nodes for the empty scene, switching back publishes 3, switching to the empty scene publishes 0, and `scene.delete` returns to `Scene` with 3 nodes.
|
||
- `web/tests/e2e/wbv2-collection-instance-production.spec.ts`: the instance EMPTY publishes `instanceCollectionId: collection:Collection`; the Web `ViewportRenderer` creates 3 member display copies (mesh + light + camera frustum) for the 3-object collection and 1 base-scene helper; save/reopen keeps the reference.
|
||
- `web/tests/e2e/wbv2-nested-collection-instance-production.spec.ts`: a collection instance inside another collection instance expands recursively; the nested BasicCube clone reports `object:NestedInner` as its picking owner (not the outer `object:Collection`), and the nested instance contents render with composed matrices.
|
||
- `web/tests/e2e/wbv2-adjust-last-operation-production.spec.ts`: Add Circle → Web adjust panel → vertices 8 → apply replaces the original with one 8-vertex Circle; a second adjustment sets location X=3; “完整属性…” opens the preselected F3 form, sets vertices 12, and the final scene has one 12-vertex Circle at [3, 0, 0].
|
||
- `web/tests/e2e/modifier-stack-ui-production.spec.ts` (existing scenario suite, now unlocked): 8 cases — add/remove/move Bevel and parameters for Bevel/Array/Mirror/Solidify/Surf — pass with sequential single-writer clients, invalid-command rejection, undo/redo, save/reopen and replay; native Blender readback confirms both the modified stack and untouched objects.
|
||
- Unlocked existing production scenarios (17 tests): `rig-pose-authoring-native` bones/pose with native golden readback and independent replay; `mesh-main-reader-production`; `light-subtypes-reader-production`; `nonmesh-main-reader-production`; `native-main-lifecycle`; `nla-evaluation-golden`; `library-append-main` (append/undo/redo/save/reopen against the desktop canonical report); `rna-datablock-reflection-native` (native datablock reflection survives reopen; zero-user orphan IDs are excluded because desktop save prunes them).
|
||
- Combined verification: 22 focused three-domain tests + 17 unlocked existing scenarios, all passing with bounded parallelism on the current WASM.
|
||
- Re-run on WASM `8ec2268f`: 22 focused production scenarios pass — three-domain creation/hierarchy/modeling (3), creation/operator slices (10), hierarchy/persistence/collection/adjust (7), native operator matrix (60/60 operators), 32 curve operators, the native modal scenario and the `?ui=web` object-editor scenario. Receipts were regenerated against this hash.
|
||
- `web/tests/e2e/object-hierarchy-production.spec.ts` now passes against the production build served by `tools/web/deployment-http-server.mjs` with `?ui=web` (`web/playwright.deployment-local.config.ts`): parent/unparent UI, collection lifecycle, negatives, undo/redo, save/reopen and native golden readback. `web/dist` was rebuilt from the current sources/WASM before the run.
|
||
- `web/tests/e2e/modeling-native-modal-production.spec.ts` now passes on the current WASM: translate cancel restores Main and history, translate/rotate/scale modals, Edit-mode projected-vertex click plus modal transform, undo/redo, save/reopen and Properties readback — across the Web-tools/native-canvas toggles before and after save. The scenario takes ~56s with SwiftShader, so the spec now sets its own 300s budget instead of the 30s default. Receipt: `verification/native-modal-production.json` plus its `native-modal-artifacts/`.
|
||
- `web/tests/e2e/object-editor-ui-production.spec.ts` now passes on `?ui=web` against `web/dist`: clear location/rotation/scale, create CAMERA/LIGHT/EMPTY/ARMATURE, selection, collection viewport/render toggles, undo/redo, negative no-mutation, save/reopen and an independent determinism run; the native desktop readback agrees on every checkpoint. The previous `selected` mismatch was not a save-path difference: with the native build, `Collection.hide_viewport = True` deselects the object and showing the collection again keeps it deselected, so the Web-saved `selected=false` matches desktop. The test checkpoint now records the Outliner activation state that `Select Active` is undone to, and the reopen step no longer re-clicks the Outliner row (which had masked the selection stored in the file).
|
||
- receipts: `tests/golden/WBV2-P1425-001/verification/{add-menu-native-production,create-production,hierarchy-production,modeling-production,mesh-native-operator-ui-production,modifier-matrix-production,convex-hull-native-production,native-operator-matrix-production,creation-object-types-production,data-instance-add-production,hair-curves-add-production,modifier-parameters-apply-production,modifier-apply-convert-production,curve-edit-operators-production,convert-to-mesh-production,armature-edit-production,object-tools-production,edit-mode-persistence-production,scene-flow-production,collection-instance-production,nested-collection-instance-production,adjust-last-operation-production,object-editor-positive,object-editor-negative,object-editor-undo_redo,object-editor-save_reopen,object-editor-determinism,native-modal-production}.json`.
|
||
- retained verification blockers (not claimed as passed):
|
||
- Scenario-style specs that create several `WebEngineClient`s must terminate each client before opening the next; the unlocked suites now do this on `?engine=manual` and pass. Specs that still drive the app page remain subject to the single-writer contract.
|
||
- resolved in this round: `object-editor-ui-production.spec.ts` passes on `?ui=web` with the deployment server and native readback. Desktop Blender deselects objects when their Collection is hidden and does not restore the selection when it is shown, so the Web-saved `selected=false` is correct; the stale expectation and two harness assumptions (undo baseline, post-open re-selection) were corrected.
|
||
- resolved in this round: `modeling-native-modal-production.spec.ts` passes after `WebGLObjects` re-homes retained CPU bytes onto the replacement canvas; no GPU canvas detach remains.
|
||
- resolved in this round: Web-only Edit-mode switch and `mesh.poke` pass after passing `selectedObjects`/`activeObject`/`baseRevision`, detaching the GPU surface on the Web-tools toggle, and importing `bpy` inside the selection helpers; verified by `wbv2-mesh-native-operator-ui-production.spec.ts`.
|
||
- remaining: broader per-operator behavioral evidence for the 486 routes; Ocean/OpenVDB modifiers cannot be enabled because the Web build has `WITH_FFTW3=OFF` and `WITH_OPENVDB=OFF`, and no WASM FFTW/OpenVDB libraries or sources are available locally. Full desktop parity is not claimed.
|
||
- 2026-11-10 operator-family sweep and Web fixes (WASM `33db5f5e`):
|
||
- `web/tests/e2e/wbv2-operator-sweep-production.spec.ts` invokes every live registered operator in the mesh/object/uv/curve families (167/250/55/51) through `desktop_operator` with a fresh Main per case; each family receipt in `verification/operator-sweep-<family>.json` records the per-operator outcome plus the WASM SHA-256. Final counts: mesh 136 EXECUTED, object 104, uv 32, curve 43 (315/523). Remaining outcomes are MODAL (PASS_THROUGH), CONTEXT_POLL/CANCEL/MESSAGE matching a native poll/report for the detached Layout/VIEW_3D fixture, or ADDON_MISSING for `uv.export_layout` (the bundled `io_mesh_uv_layout` addon is not loaded). Zero CRASH, zero TIMEOUT, zero core OPERATOR_MISSING; the classifier separates native Blender RuntimeError reports from WASM traps.
|
||
- Freestyle mesh-data operators now exist on Web. `WITH_FREESTYLE=OFF` compiled out `mesh.mark_freestyle_edge/face` although the Web menu exposed them, so clicking always failed with `get_rna_type(...) not found`. The registration and the two exec functions are now guarded by `WITH_FREESTYLE || WITH_WEB` in `mesh_ops.cc`, `editmesh_tools.cc` and `mesh_intern.hh`; they only write the `freestyle_edge`/`freestyle_face` boolean attributes and need no Freestyle renderer. Both FINISHED in the 62-case matrix.
|
||
- `object.quick_explode` now works. The EXPLODE modifier's dynamic `vertex_group` string has no fixed RNA buffer, so the accessor generator emitted `maxLength=-1` and the editor-workflow validator rejected the whole snapshot (`EDITOR_LAYOUT_INVALID: Invalid modifier string resource metadata`). `extract_modifier_accessors.py` now clamps a missing declared maxlength to 63; Quick Explode FINISHED with ParticleSystem + Explode modifiers on the object.
|
||
- Geometry Nodes modifier inputs are editable from Python again. `node_socket.cc` wrapped all 19 `make_geometry_nodes_input_srna` registrations in `#ifndef WITH_WEB`, so every NodesModifier input item exposed only `rna_type`/`name` (`object.quick_fur` failed at `inputs.Input_12.value`). Removing those guards restores `value`/`type`/`attribute_name`/`layer_name` on boolean, float, object, material, geometry, menu and collection inputs; verified with a temporary Chromium probe (Input_12/15/20/22 expose `value`), probe removed.
|
||
- Menu wiring: `mesh.spin`/`mesh.screw` now pass `axis=[0,0,1]` (EXEC without a view axis reported `Invalid/unset axis`), `mesh.rip` routes through `queueLocalDesktopOperator` so the native invoke runs, and the curve menu's `curve.spin` was removed because its poll (`ED_operator_editsurf`) only accepts an edited surface object.
|
||
- The modifier-stack UI test was retargeted from the legacy `.modifier-stack-authoring` panel (not rendered in the current Web tools layout) to the live `[data-modifier-row]` properties panel and its desktop labels (`Amount`/`Segments`, `Solidify` option id). This was a stale test selector, not a product regression. Focused regression on `33db5f5e`: 38/38 tests passed with 4 workers (three-domain chains, 62-case operator matrix, modifier-stack UI/native scenarios, creation/adjust/data-instance/hair-curves/modifier-apply/convert/armature/object-tools/edit-persistence/scene/collection, native modal, rig, readers, NLA, library append, RNA reflection).
|
||
- Open gaps (not claimed): `object.quick_fur` still fails because the linked procedural-hair node group evaluates to non-curves (`Evaluated geometry from modifier does not contain curves`) and the Web RNA Main-access guard then invalidates the Python callback (`Main changed during Python property conversion or callback`); QuadriFlow remesh (`WITH_QUADRIFLOW=OFF`), OpenVDB voxel remesh (`WITH_OPENVDB=OFF`), Mantaflow fluid quick effects (`WITH_MOD_FLUID=OFF`) and Ocean bake (`WITH_FFTW3=OFF`) remain build-flag gaps; `object.lightprobe_cache_bake` hits the browser draw-manager single-canvas guard; `uv.export_layout` needs the unloaded bundled addon. The changed spin/screw/rip menu wiring was verified through the same native operator channel, not by clicking the production menu.
|
||
- Receipts on `33db5f5e`: `verification/operator-sweep-{mesh,object,uv,curve}.json`, `native-operator-matrix-production.json` (62/62), `creation-object-types-production.json` (29/29), `curve-edit-operators-production.json` (32/32), `object-editor-*.json` (5), plus the production hierarchy timestamped receipt.
|
||
- 2026-11-10 late round (WASM `dc7a76eb`): further modeling gaps closed:
|
||
- Quick Fur and geometry-node assets now evaluate. `WEB_headless_node_system_init()` registered only a small geometry-node subset and no zone types, so the bundled procedural-hair groups loaded Capture Attribute / Separate Components / Input Radius as `NodeUndefined` and the node-tree updater called through a null zone vtable (`RuntimeError: null function`). The Web `bf_nodes` source set now includes `intern/node_register.cc` and the engine calls the desktop `register_nodes()` once. The hair groups load with zero undefined nodes; `object.quick_fur` creates 1212 points across 101 curves with Generate applied and Set Profile/Interpolate/Noise/Frizz/Hair Dynamics kept.
|
||
- Temporary `G_MAIN` swaps during library append/link no longer poison an in-flight Python callback. `RNAMainAccessScope::restore_after_temporary_main_swap` / `restore_context_after_temporary_main_swap` revive suspended scopes when the same Main is swapped back (genuine replacement/clear still invalidates); `BKE_blender_globals_main_swap` and the Web context refresh call the restore after rebinding. Quick Fur's nested `modifier_apply` now completes instead of failing with `Main changed during Python property conversion or callback`.
|
||
- QuadriFlow remesh is enabled (`WITH_QUADRIFLOW=ON`): `object.quadriflow_remesh` finishes with “QuadriFlow: Remeshing completed” and remeshes the 8-vertex test cube to 3954 vertices.
|
||
- Mantaflow fluid is enabled (`WITH_MOD_FLUID=ON`). `MOD_fluid.cc` forced the Fluid modifier's RNA `srna` to `nullptr` under `WITH_WEB`, so `rna_Modifier_refine` dereferenced null when a Fluid modifier was converted to Python. The real `&RNA_FluidModifier` is restored (and the matching Cloth `nullptr` is fixed). `object.quick_liquid` creates a Liquid Domain with Fluid modifiers plus a Liquid Particle System; `object.quick_smoke` creates a Smoke Domain with Fluid modifiers; a Cloth modifier exposes its settings without crashing.
|
||
- `uv.export_layout` is available: the Python bootstrap registers the bundled `io_mesh_uv_layout` addon when the session starts (retry-safe). The operator poll passes for a UV-mapped active mesh and an SVG export writes 1288 bytes to `/browser/uv_layout.svg`.
|
||
- Final sweep on `dc7a76eb`: mesh 136/167, object 108/250, uv 32/55, curve 43/51 EXECUTED (319/523); zero CRASH/TIMEOUT/core OPERATOR_MISSING. `object.quick_fur`, `quick_explode`, `quick_liquid`, `quick_smoke` and `quadriflow_remesh` are EXECUTED; `uv.export_layout` is registered (native context message for the empty-filepath sweep invocation instead of ADDON_MISSING).
|
||
- remaining (not claimed): OpenVDB voxel remesh (`WITH_OPENVDB=OFF`; `.deps/native/openvdb` contains only `include/` and native `lib/*.so`, no OpenVDB source or wasm OpenVDB/Boost/TBB/blosc artifacts); Ocean bake (`WITH_FFTW3=OFF`; `.deps/native/fftw3` is native only, no WASM FFTW sources/libs); light-probe cache bake runs the EEVEE lightbake job, which calls DRW_gpu_context_create; the headless manual host has no active GPU context, so it reports 'Browser draw manager must be created once per WM canvas'. A canvas-attached UI session is not yet verified, and this is render-engine behavior outside the three modeling domains. The non-executed sweep operators are modal/context classes matching desktop semantics. Full desktop parity remains NOT_CLAIMED pending user acceptance and WASM ports of OpenVDB/FFTW3.
|
||
- next action: port OpenVDB and FFTW3 to WASM to close voxel remesh and ocean bake; keep the documented gaps explicit; full desktop parity remains NOT_CLAIMED pending user acceptance.
|