- 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>
28 KiB
28 KiB
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.
- Add menu uses
- hierarchy
- Commands/UI:
moveCollection(including sibling ordering),deleteCollection(normal/recursive),createCollectionchild,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.
- Commands/UI:
- 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 classifiedWEB_MAINin the route catalog; behavioral evidence remains separate andUNVERIFIEDfor 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 withWBV2_SKIP_TYPECHECK=1. - blockers fixed in this round:
editors/meshregistersmesh.convex_hullunderWITH_BULLET, but the Webbf_bmeshtarget omitted Bullet and therefore did not register theconvex_hullBMO. 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 ofbmesh/CMakeLists.txtnow linksbf_intern_rigidbodyandbf::dependencies::optional::bullet.- Speaker
distance_maxdefaults toFLT_MAXin DNA while SceneIR budgets it to 1e9; the blend reader now clamps distance fields, and emptyactionSlotIdentifiervalues (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, soadd_essential_asset_modifiernow 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_applybaked 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_editsbefore 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, andsetScenealso points every wmWindow at the selected scene.scene.new→ switch →scene.deletenow publishes 0 nodes for the empty scene, 3 for the original and returns toSceneafter 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 inrecovery_library_byteskeyed 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,SceneNodeIRvalidates 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_overlapnow works on Web: the WASM call trapped with'unreachable'while constructingblender::Array<ChangedInfo>from its bitfield initializer. The localChangedInfoarray now usesstd::vector, behavior-equivalent; the operator finishes and the 60-case matrix has no open operator failure.object.shade_auto_smoothnow 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”. WithWITH_WEBit fetches the bundle, suppresses the false asset report, direct-appends the NodeTree withWM_file_append_datablock, and validates it as the Smooth by Angle group.- The full
mathutilsPython surface is available again on Web: theMATH_WEB_CORE_ONLYcompile definition was removed frombf_python_mathutils, somathutils.geometry/interpolate/noise/bvhtree/kdtreeare registered.uv.lightmap_pack(mathutils.geometry.box_pack_2d) now finishes instead of raisingAttributeError. - 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_ownernow drops the dead GL names and letsbind()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.tsinvokes every registered operator in the nativemesh/object/uv/curvefamilies (167/250/55/51 identifiers extracted from the desktop registrybpy.ops.*) throughdesktop_operatorwith a fresh Main per case, classifies EXECUTED / CONTEXT_POLL / CONTEXT_CANCEL / CONTEXT_MESSAGE / ERROR / TIMEOUT / CRASH and writesverification/operator-sweep-<family>.jsonbound 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 → nativemesh.primitive_monkey_add→ Main/SceneIR → Outliner shows Suzanne/Monkey.web/tests/e2e/wbv2-three-domain-focused-production.spec.tscreation: base 1 → create 2 → undo 3 → redo 4; saved 421,265 bytes; reopen revision 1 withVerifyCubepresent.- 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 → nativemesh.poke; status已执行:mesh.poke.web/tests/e2e/wbv2-modifier-matrix-production.spec.ts: all 20 expanded modifier types add/evaluate/remove/save/reopen, every caseFINISHED(including SKIN after the Bullet linkage fix).web/tests/e2e/wbv2-convex-hull-native-production.spec.ts: Edit mode →mesh.select_all→ nativemesh.convex_hullstateDONE.web/tests/e2e/wbv2-native-operator-matrix-production.spec.ts: 60/60 mesh/UV/object operatorsFINISHEDon WASM8ec2268f, 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_setwithoutclear,mesh.unsubdividewithoutthreshold, etc.).web/tests/e2e/wbv2-creation-object-types-production.spec.ts: 29 creation/data cases on WASM8ec2268f— all sixSURFACE_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-lessobject.data_instance_addremains cancelled with no mutation. Receipt records the WASM SHA-256.web/tests/e2e/wbv2-data-instance-add-production.spec.ts: Outliner selection → Add → 数据实例 createsCube.001through the native ID lookup.web/tests/e2e/wbv2-hair-curves-add-production.spec.ts: hair curves Add appends both embedded Essentials node groups; surface gainsCapture Rest Geometry, Curves object gainsHair Dynamicsand is parented toBasicCube.web/tests/e2e/wbv2-modifier-parameters-apply-production.spec.ts: SUBSURF levels 2 evaluates 98 vertices throughevaluateDepsgraph, undo restores level 1 / 26 vertices, redo restores level 2 / 98, nativeobject.modifier_applybakes 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 andobject.modifier_applybakes 56; SUBSURF level 2 followed byobject.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 allFINISHEDon WASM1e6e7d3f(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_roware 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 valueAUTO→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 toMESHthroughobject.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) allFINISHED; 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.tsnow also saves and reopens: the Curves object keepsHair Dynamics, its parent and the surface’sCapture Rest Geometry.web/tests/e2e/wbv2-edit-mode-persistence-production.spec.ts:mesh.pokein 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.newpublishes 0 nodes for the empty scene, switching back publishes 3, switching to the empty scene publishes 0, andscene.deletereturns toScenewith 3 nodes.web/tests/e2e/wbv2-collection-instance-production.spec.ts: the instance EMPTY publishesinstanceCollectionId: collection:Collection; the WebViewportRenderercreates 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 reportsobject:NestedInneras its picking owner (not the outerobject: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-nativebones/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=webobject-editor scenario. Receipts were regenerated against this hash. web/tests/e2e/object-hierarchy-production.spec.tsnow passes against the production build served bytools/web/deployment-http-server.mjswith?ui=web(web/playwright.deployment-local.config.ts): parent/unparent UI, collection lifecycle, negatives, undo/redo, save/reopen and native golden readback.web/distwas rebuilt from the current sources/WASM before the run.web/tests/e2e/modeling-native-modal-production.spec.tsnow 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.jsonplus itsnative-modal-artifacts/.web/tests/e2e/object-editor-ui-production.spec.tsnow passes on?ui=webagainstweb/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 previousselectedmismatch was not a save-path difference: with the native build,Collection.hide_viewport = Truedeselects the object and showing the collection again keeps it deselected, so the Web-savedselected=falsematches desktop. The test checkpoint now records the Outliner activation state thatSelect Activeis 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
WebEngineClients must terminate each client before opening the next; the unlocked suites now do this on?engine=manualand pass. Specs that still drive the app page remain subject to the single-writer contract. - resolved in this round:
object-editor-ui-production.spec.tspasses on?ui=webwith 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-savedselected=falseis 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.tspasses afterWebGLObjectsre-homes retained CPU bytes onto the replacement canvas; no GPU canvas detach remains. - resolved in this round: Web-only Edit-mode switch and
mesh.pokepass after passingselectedObjects/activeObject/baseRevision, detaching the GPU surface on the Web-tools toggle, and importingbpyinside the selection helpers; verified bywbv2-mesh-native-operator-ui-production.spec.ts.
- Scenario-style specs that create several
- remaining: broader per-operator behavioral evidence for the 486 routes; Ocean/OpenVDB modifiers cannot be enabled because the Web build has
WITH_FFTW3=OFFandWITH_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.tsinvokes every live registered operator in the mesh/object/uv/curve families (167/250/55/51) throughdesktop_operatorwith a fresh Main per case; each family receipt inverification/operator-sweep-<family>.jsonrecords 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 foruv.export_layout(the bundledio_mesh_uv_layoutaddon 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=OFFcompiled outmesh.mark_freestyle_edge/facealthough the Web menu exposed them, so clicking always failed withget_rna_type(...) not found. The registration and the two exec functions are now guarded byWITH_FREESTYLE || WITH_WEBinmesh_ops.cc,editmesh_tools.ccandmesh_intern.hh; they only write thefreestyle_edge/freestyle_faceboolean attributes and need no Freestyle renderer. Both FINISHED in the 62-case matrix. object.quick_explodenow works. The EXPLODE modifier's dynamicvertex_groupstring has no fixed RNA buffer, so the accessor generator emittedmaxLength=-1and the editor-workflow validator rejected the whole snapshot (EDITOR_LAYOUT_INVALID: Invalid modifier string resource metadata).extract_modifier_accessors.pynow 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.ccwrapped all 19make_geometry_nodes_input_srnaregistrations in#ifndef WITH_WEB, so every NodesModifier input item exposed onlyrna_type/name(object.quick_furfailed atinputs.Input_12.value). Removing those guards restoresvalue/type/attribute_name/layer_nameon boolean, float, object, material, geometry, menu and collection inputs; verified with a temporary Chromium probe (Input_12/15/20/22 exposevalue), probe removed. - Menu wiring:
mesh.spin/mesh.screwnow passaxis=[0,0,1](EXEC without a view axis reportedInvalid/unset axis),mesh.riproutes throughqueueLocalDesktopOperatorso the native invoke runs, and the curve menu'scurve.spinwas 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-authoringpanel (not rendered in the current Web tools layout) to the live[data-modifier-row]properties panel and its desktop labels (Amount/Segments,Solidifyoption id). This was a stale test selector, not a product regression. Focused regression on33db5f5e: 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_furstill 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_bakehits the browser draw-manager single-canvas guard;uv.export_layoutneeds 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 asNodeUndefinedand the node-tree updater called through a null zone vtable (RuntimeError: null function). The Webbf_nodessource set now includesintern/node_register.ccand the engine calls the desktopregister_nodes()once. The hair groups load with zero undefined nodes;object.quick_furcreates 1212 points across 101 curves with Generate applied and Set Profile/Interpolate/Noise/Frizz/Hair Dynamics kept. - Temporary
G_MAINswaps during library append/link no longer poison an in-flight Python callback.RNAMainAccessScope::restore_after_temporary_main_swap/restore_context_after_temporary_main_swaprevive suspended scopes when the same Main is swapped back (genuine replacement/clear still invalidates);BKE_blender_globals_main_swapand the Web context refresh call the restore after rebinding. Quick Fur's nestedmodifier_applynow completes instead of failing withMain changed during Python property conversion or callback. - QuadriFlow remesh is enabled (
WITH_QUADRIFLOW=ON):object.quadriflow_remeshfinishes with “QuadriFlow: Remeshing completed” and remeshes the 8-vertex test cube to 3954 vertices. - Mantaflow fluid is enabled (
WITH_MOD_FLUID=ON).MOD_fluid.ccforced the Fluid modifier's RNAsrnatonullptrunderWITH_WEB, sorna_Modifier_refinedereferenced null when a Fluid modifier was converted to Python. The real&RNA_FluidModifieris restored (and the matching Clothnullptris fixed).object.quick_liquidcreates a Liquid Domain with Fluid modifiers plus a Liquid Particle System;object.quick_smokecreates a Smoke Domain with Fluid modifiers; a Cloth modifier exposes its settings without crashing. uv.export_layoutis available: the Python bootstrap registers the bundledio_mesh_uv_layoutaddon 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_smokeandquadriflow_remeshare EXECUTED;uv.export_layoutis registered (native context message for the empty-filepath sweep invocation instead of ADDON_MISSING).
- Quick Fur and geometry-node assets now evaluate.
- remaining (not claimed): OpenVDB voxel remesh (
WITH_OPENVDB=OFF;.deps/native/openvdbcontains onlyinclude/and nativelib/*.so, no OpenVDB source or wasm OpenVDB/Boost/TBB/blosc artifacts); Ocean bake (WITH_FFTW3=OFF;.deps/native/fftw3is 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.