chore: checkpoint web Blender migration source, tools and docs
Some checks failed
M6 deployable RC / quick (push) Has been cancelled
M6 deployable RC / chromium (push) Has been cancelled
M6 deployable RC / release (push) Has been cancelled

Accumulated uncommitted work: GHOST Web backend, WebGL/GPU web layer,
web workflow engine and protocol, tooling, docs and task records.
Large generated evidence, user-testing archives, build snapshots and
imported test assets remain untracked.

Co-Authored-By: Claude Code <noreply@anthropic.com>
This commit is contained in:
mes123456
2026-11-10 11:18:01 +08:00
parent 122142c26c
commit f3e21c6b98
6887 changed files with 257154 additions and 12294 deletions

View File

@@ -0,0 +1,14 @@
# WEB Blender 功能模块使用说明书
- [正式 PDF](WEB_Blender_Function_User_Guide.pdf)
- [浏览器阅读版](说明书.html)
- [桌面与 Web 功能对照表](function-map.csv)
- [用户验证记录表](verification-checklist.csv)
- `samples/`:练习工程、资源和脚本。
- `screenshots/`:本轮操作截图及明确标记的局部裁剪。
- `source/`:可维护的模块内容、Markdown 和生成脚本。
按 M01–M03 开始,再通过目录进入具体功能。核对每章的验证范围与差异说明。
用户验证表初始为 NOT_RUN,避免把作者测试结果冒充用户自己的验收。
当前应用地址:http://127.0.0.1:5205/ 。
此说明书不宣称桌面全功能无差异。

View File

@@ -0,0 +1,443 @@
{
"document": "WEB Blender Function User Guide",
"version": "UM-20260916-R3",
"modules": 36,
"desktopParity": "NOT_ESTABLISHED",
"files": [
{
"path": "README.md",
"bytes": 725,
"sha256": "a68f6a8d75d85be2b90022822c4583c6d0bd7dd4315235882f8b27f14b369634"
},
{
"path": "WEB_Blender_Function_User_Guide.pdf",
"bytes": 8718825,
"sha256": "96020d2657c6d01b84aeb393cac35c7bb6d78471b1d9bf1ee32bc6831869cc51"
},
{
"path": "evidence-index.json",
"bytes": 20445,
"sha256": "a7c25dac7bcf2e427ce8b564bf7d55544384bbcc41f0eaacf75d9abe59f47077"
},
{
"path": "function-map.csv",
"bytes": 6226,
"sha256": "6b3d3fcb66a68946416de44e9f5b182bc5501ef3cce75caf90b83d23a6296724"
},
{
"path": "samples/01_move_object.py",
"bytes": 129,
"sha256": "9665a900cc8d75e40195cb4ecc219cf0bafdc7fb5f441f5df5fba8ffd4f386c8"
},
{
"path": "samples/02_quaternion.py",
"bytes": 186,
"sha256": "9f630249be62c704522162b1270626ce479eab59ec79073aa963ac0155a38527"
},
{
"path": "samples/03_axis_angle.py",
"bytes": 213,
"sha256": "272e50d36c9131de1edabe7d9f03d7696d6bebc17e161567925d8436d121b991"
},
{
"path": "samples/04_read_resource.py",
"bytes": 238,
"sha256": "367e0eeceb10817771dde6d89d05709c137e4fca796ae43f9826d6fbe9966adf"
},
{
"path": "samples/animation_scene.blend",
"bytes": 86768,
"sha256": "8bc730eb5df55d91246f0eade4f416cae6670dde1191b3dc340f283532a04f3d"
},
{
"path": "samples/attribute_scene.blend",
"bytes": 90108,
"sha256": "12fa75bb79f8c38e660d3d2a8fc9cc16dd3df4fc9208b0e2ad94fb1f8aa68f71"
},
{
"path": "samples/basic_scene.blend",
"bytes": 95608,
"sha256": "6fcc55bda74da8c95da96ba068b60339bf60ca44147ff8000fbb95d296db2a73"
},
{
"path": "samples/index.json",
"bytes": 4215,
"sha256": "00595432091636c6b76a31416e2c13fba6dcc57ce10555f8eaceecf0203cdc3d"
},
{
"path": "samples/mesh_editor_scene.blend",
"bytes": 92159,
"sha256": "5bb93920ec3bd8d113ebc6cf325d76a058abb0ac60b77c0f3ececc83c192c6cb"
},
{
"path": "samples/modifier_grease_pencil_scene.blend",
"bytes": 87788,
"sha256": "3a8525077807f9178dac3a5ba84b524e5f8e80874b15c54e2a6658ecb80315a3"
},
{
"path": "samples/modifier_stack_scene.blend",
"bytes": 92289,
"sha256": "e35b3e4eda35d67f1d90a52abdf9dc3b43a8c275a9e913df95241d797fa12854"
},
{
"path": "samples/nonmesh_scene.blend",
"bytes": 113991,
"sha256": "ae8ef85d606aa120ce6b7611fc03407fd80bb60311e94a6ef73f6384d0b6c8b4"
},
{
"path": "samples/parity_animation.blend",
"bytes": 90434,
"sha256": "377e8c6d09e9f563020b598dc123dc48334a39c6ac012d32d87c6c4fd778aae7"
},
{
"path": "samples/parity_scene.blend",
"bytes": 90044,
"sha256": "35c36777a9546a88de5ecb237808fb0519d7ddb2550608123ed629fb9a949416"
},
{
"path": "samples/pose_constraint_scene.blend",
"bytes": 89384,
"sha256": "39bfb2d9466cece01d7ddd822bb46407049d812cb66b07fb7852a2e14ed5c91e"
},
{
"path": "samples/resource_scene.blend",
"bytes": 90519,
"sha256": "8bf574ea102e8c983a89312d17d62cfa7ebcf700c1c625b581e7610e2a0a65f7"
},
{
"path": "samples/rotation-axis_angle.blend",
"bytes": 90015,
"sha256": "2c188fe457a68fdba7b2f2c360618350ab7c31827a443a944ce85fd60fea7826"
},
{
"path": "samples/rotation-parent.blend",
"bytes": 90181,
"sha256": "6bd20cb92da72daca4617d2ae10e5d5112058681fdbc512ad1c7619107c215b7"
},
{
"path": "samples/rotation-quaternion.blend",
"bytes": 90013,
"sha256": "a31107d5296ef7fbeda6a0ac7905edeacf8aa8b3ba2d5e96c755fd0c83f279e0"
},
{
"path": "samples/sequencer_scene.blend",
"bytes": 496033,
"sha256": "5f5212487bb6b5df62b5ca915c75133f1ca45678614712ea4c7d902d823cd90c"
},
{
"path": "samples/state.txt",
"bytes": 25,
"sha256": "346547a66c48c8f48e1bb5b850bb8ba31ecd837de16ee1481466d1657a16e35b"
},
{
"path": "samples/texture.png",
"bytes": 260,
"sha256": "2b0f5252b6c439373c57bdecdafb9f268f67a6aea63d44554de42c519d3a8410"
},
{
"path": "screenshots/M01-UJ-01-opened.png",
"bytes": 179686,
"sha256": "d75e4fe679299a348f30f97a4a34bc712c019ab20747af7593d12734fdff47ad"
},
{
"path": "screenshots/M02-UJ-20-keyboard-search-closed.png",
"bytes": 142065,
"sha256": "d7b4b997f24d38ffb5116429fa59ed45bd1d6f10b7ccfd4b8ac8cce3619a6910"
},
{
"path": "screenshots/M03-UJ-01-reopened.png",
"bytes": 179686,
"sha256": "d75e4fe679299a348f30f97a4a34bc712c019ab20747af7593d12734fdff47ad"
},
{
"path": "screenshots/M04-UT-270-quaternion-readout.png",
"bytes": 189866,
"sha256": "ac87dbfc5b7d33abff3ed1d64ccc923b412ce87a5961a0dce990d9739dd0d0f7"
},
{
"path": "screenshots/M05-UJ-02-rename-detail.png",
"bytes": 51635,
"sha256": "c754433d8410b0bcf046b6268d2b83f1ed4a73b6155ad1da3c4bb3edadf087d9"
},
{
"path": "screenshots/M05-UJ-02-rename.png",
"bytes": 202565,
"sha256": "cad4093d4c5bd156f38d3310ab170e96818e51e3d87c624b9be78142193a99f2"
},
{
"path": "screenshots/M06-UT-274-parent-readout.png",
"bytes": 191890,
"sha256": "63ced739d976e3ff9d4ccf68a083a103c18e976f0a014afee19ef24b4b9ac88b"
},
{
"path": "screenshots/M07-UJ-03-triangulated-detail.png",
"bytes": 53054,
"sha256": "af5d2019dea73390c5647d9071aa2f388025db726e622a062e47115d6c480fd2"
},
{
"path": "screenshots/M07-UJ-03-triangulated.png",
"bytes": 199856,
"sha256": "90d80372fea848e7d8ed99f004d5154befbf07eb285532b8a928c301373a03d9"
},
{
"path": "screenshots/M08-UJ-03-uv-projected-detail.png",
"bytes": 48492,
"sha256": "f94a847667d910dc40933a2d874bad76244bbb382cd38c7c160c9051f1d5aad7"
},
{
"path": "screenshots/M08-UJ-03-uv-projected.png",
"bytes": 192744,
"sha256": "1b05bcea85f5222fa4e9ff909ed3a0247c02100e5712b2b9d389ac56ba959822"
},
{
"path": "screenshots/M09-UJ-04-solidify-added-detail.png",
"bytes": 46143,
"sha256": "714d5c6bde47844002aa659334b935503460a4e9eb3e8303cf3c2754603cf0a1"
},
{
"path": "screenshots/M09-UJ-04-solidify-added.png",
"bytes": 179524,
"sha256": "38eb20078adfec0383c21a0fc0192fbc8164772b75911c5e96e2c56f2754033c"
},
{
"path": "screenshots/M10-UJ-05-cyclic-toggled-detail.png",
"bytes": 52738,
"sha256": "1b2849e94d739ecb074508c59c5f1df106e3ea94a980da08255e636e0e354aca"
},
{
"path": "screenshots/M10-UJ-05-cyclic-toggled.png",
"bytes": 225284,
"sha256": "6c90c359635873dc609deed37ed1e46fa9fde365ab340bf9a0ac6248ec9abbd5"
},
{
"path": "screenshots/M11-UJ-06-text-applied-detail.png",
"bytes": 53515,
"sha256": "bf018d2e3b31efbfd35aeabf7c55f91bfcdc1ce8ed2c855cf83e1c8d8f5aaf57"
},
{
"path": "screenshots/M11-UJ-06-text-applied.png",
"bytes": 218917,
"sha256": "d170a7b80dcae5c39c4dc3ee597b396e798321b7c4dcef758ed6403b37cbae18"
},
{
"path": "screenshots/M12-UJ-07-principled-applied-detail.png",
"bytes": 50329,
"sha256": "d11c58d0849effdc2167d292cf556523d0c5da18cf4b0d7f47ab70ca578c46ec"
},
{
"path": "screenshots/M12-UJ-07-principled-applied.png",
"bytes": 190105,
"sha256": "a6c13d4515816450ddc1b3095d56fae6fa8acfb230a7ee70eb4fa2f773f13a59"
},
{
"path": "screenshots/M13-UT-258-resource-bytes-persisted.png",
"bytes": 144812,
"sha256": "a547427a62e941c4b915f818f9827a218592e788f2b9bc0850daf97c86553ebc"
},
{
"path": "screenshots/M14-UJ-11-gamma-increased-detail.png",
"bytes": 55142,
"sha256": "449fbb0604bc2c29b7438b5abe7fa83719239b5ae10d148f28185cd1339c8938"
},
{
"path": "screenshots/M14-UJ-11-gamma-increased.png",
"bytes": 202754,
"sha256": "881ee98eacbfe3fbaf687b27741d8c170a62f50127bf2aed95b0ac4cc840b39e"
},
{
"path": "screenshots/M15-UJ-10-lens-increased-detail.png",
"bytes": 57463,
"sha256": "410db9f62c8109169cf3dc594b0618a7f39cae9f7de81a6725c43587129b1306"
},
{
"path": "screenshots/M15-UJ-10-lens-increased.png",
"bytes": 182065,
"sha256": "6c3bd1b06379914c3c5c275c74d0a0e19e64d1e3ddcba0bfdc51650a486d82fb"
},
{
"path": "screenshots/M16-UJ-12-marker-added-detail.png",
"bytes": 48452,
"sha256": "9fa0fc606760e632ed321a17cd8957f149ea62335327363ddce4de7d32622b7e"
},
{
"path": "screenshots/M16-UJ-12-marker-added.png",
"bytes": 184795,
"sha256": "2263ff275aa2bc24e19eca0ab7ca51dbceda00edddb613fa6e654ec7378e379b"
},
{
"path": "screenshots/M17-UJ-12-frame-three-detail.png",
"bytes": 48452,
"sha256": "9fa0fc606760e632ed321a17cd8957f149ea62335327363ddce4de7d32622b7e"
},
{
"path": "screenshots/M17-UJ-12-frame-three.png",
"bytes": 170004,
"sha256": "5af97c1302ea2a3876ffba43e2e35bb515c7525e1a5639c2d98a52635efe227f"
},
{
"path": "screenshots/M18-UJ-13-roll-changed-detail.png",
"bytes": 52263,
"sha256": "0baac195c51d0de483124ee2784a1f55bbe84ebe615af3c85ae495e2a2e5960c"
},
{
"path": "screenshots/M18-UJ-13-roll-changed.png",
"bytes": 182828,
"sha256": "7920d7f99edc085d55a5dd4202373d2449ebd2711c142494be093330e560aaa5"
},
{
"path": "screenshots/M19-UJ-08-sculpt-attributes-detail.png",
"bytes": 49464,
"sha256": "ed5f75d7bd576dba637b59b20d7e12cbe1bcf470eb9a4e75d92b6c297040f9a4"
},
{
"path": "screenshots/M19-UJ-08-sculpt-attributes.png",
"bytes": 197277,
"sha256": "cac57f19bad77670228bcc4c07d06f01c2334f07a1afb85cefb808924a2b44fe"
},
{
"path": "screenshots/M20-UJ-21-vertex-weight-applied-detail.png",
"bytes": 51414,
"sha256": "8a096f6507a8a7530db07721f0fc039625b15d4905cd643af439bb0dc48af135"
},
{
"path": "screenshots/M20-UJ-21-vertex-weight-applied.png",
"bytes": 241710,
"sha256": "70e23df97040234eda56f463ea9d60e5538effce7006c395993376dcef2d10fe"
},
{
"path": "screenshots/M21-UJ-17-layer-added-detail.png",
"bytes": 39666,
"sha256": "2fcbc1b392c7fbd41a5e6e16632fe4f368e5d44f69c6b7599c10a5252da3f3b8"
},
{
"path": "screenshots/M21-UJ-17-layer-added.png",
"bytes": 157384,
"sha256": "a09f3d761ab606f8543821fb6414b2311e03230bdd1a4d2accc333c3232d702a"
},
{
"path": "screenshots/M22-UJ-16-graph-visible-detail.png",
"bytes": 58586,
"sha256": "eb03bf099352dbacf004b3aca87ff7bf13d862650ff9b3e61f39f6bccf1e2aa1"
},
{
"path": "screenshots/M22-UJ-16-graph-visible.png",
"bytes": 210296,
"sha256": "c3ca6ac8f798f6e2c9ccf0e0e6d6a354eeb598460926cacfb070fb90e2125091"
},
{
"path": "screenshots/M23-UT-252-native-desktop.png",
"bytes": 759520,
"sha256": "43df0bbdd03a1ea74e59f6d2892d13e57400d87fa531a71a76cf96d53694e382"
},
{
"path": "screenshots/M24-UJ-14-mute-strip.png",
"bytes": 171412,
"sha256": "6173e6c7771ba717c223eab13f7dec9e7437fdb7e8a0ffdaa35f3a6bdea650ce"
},
{
"path": "screenshots/M25-UT-245-image-preview.png",
"bytes": 133799,
"sha256": "bbc48a954c261fafbc0dcb1cf1c0734fdaa0c7e9e7a4434eb26424ec821d6377"
},
{
"path": "screenshots/M26-UT-247-render-result.png",
"bytes": 130913,
"sha256": "9f9c18147618a5790381cbcf6f159512f220a8dbb7211ea3b92431dda89abc9c"
},
{
"path": "screenshots/M27-UT-250-continued-with-same-object-reference.png",
"bytes": 161185,
"sha256": "6664a803ed5f5257a6e2769e9ac174d104653d00b04b9cd16c2b66ad5136d45a"
},
{
"path": "screenshots/M28-UT-248-python-result.png",
"bytes": 145270,
"sha256": "d7c1c404b631588a0abed22e2bc352006ab511487a2f57dd2483e36cd7903d7b"
},
{
"path": "screenshots/M29-UT-252-native-desktop.png",
"bytes": 759520,
"sha256": "43df0bbdd03a1ea74e59f6d2892d13e57400d87fa531a71a76cf96d53694e382"
},
{
"path": "screenshots/M30-UJ-15-catalog-saved-detail.png",
"bytes": 55263,
"sha256": "8953d7a86c41f65ea2a7b0fb88f5e2636ca4fccbd6d4bc4e72d8ad02a75f092a"
},
{
"path": "screenshots/M30-UJ-15-catalog-saved.png",
"bytes": 202312,
"sha256": "4541701db387553ed10e95ccbb33fd55ab19e03dfab2c3459777650d88ca5a90"
},
{
"path": "screenshots/M31-UJ-09-mass-2-detail.png",
"bytes": 50676,
"sha256": "1718e40385af93e58f8932f5c18c275a0c827a831bf8754360d0c7b65c58969c"
},
{
"path": "screenshots/M31-UJ-09-mass-2.png",
"bytes": 199040,
"sha256": "4eb83a55ff6813ffbab4e6eb2b16f3956a350441e2e12934262d54ff6e2da2fa"
},
{
"path": "screenshots/M33-UJ-18-search-results.png",
"bytes": 181323,
"sha256": "014926742fa87b0461bf0b9b98f85b58a5ae439a3feb8bbae9123ee0b595c17f"
},
{
"path": "screenshots/M34-UJ-20-compact-layout.png",
"bytes": 142033,
"sha256": "1ef17d89acfa47b972b2c883b90037f1ebfac077b48b0232ec09d6e26c997961"
},
{
"path": "screenshots/M35-UT-245-image-preview.png",
"bytes": 133799,
"sha256": "bbc48a954c261fafbc0dcb1cf1c0734fdaa0c7e9e7a4434eb26424ec821d6377"
},
{
"path": "screenshots/M36-UT-275-kernel-exit-protected.png",
"bytes": 153850,
"sha256": "7cf7fa1db58ba57613ef9bcd00e8115b6619dc899b751c70922a1c97e2bced16"
},
{
"path": "source/build-handbook.py",
"bytes": 12519,
"sha256": "e5d0d589c062ad1819d811e64fdb0c0d4ddd6ba23fecdd04d14f940a28479734"
},
{
"path": "source/manual-source.md",
"bytes": 40848,
"sha256": "3f4c18e38d37b12da33b97a3871d19583bdf7b0a0a778098ec6fe588a73dc0bf"
},
{
"path": "source/modules.json",
"bytes": 55716,
"sha256": "f79033f34df13e09d8965209ee2795620b9e65c780fb5599b7b268570ad48abf"
},
{
"path": "source/modules.py",
"bytes": 40676,
"sha256": "1f39e6faf510d2ea5f824f11fdb1f4f33c29b33956400b1d9a646482d57c3074"
},
{
"path": "source/page08-preview.png",
"bytes": 119380,
"sha256": "a33c16eeb05e685b05f49f8e5cae9142463088bafa4cce706e68fa12dcb30ef1"
},
{
"path": "source/render-handbook.mjs",
"bytes": 2421,
"sha256": "2cfe9b5f4386ad5d55eafcd5616231792a334e38ac08c28d5ff225612821f9fc"
},
{
"path": "verification-checklist.csv",
"bytes": 9612,
"sha256": "1297f197b320b1d729838ac5c1349009fff6e151ce925b053cc83a29b1d89833"
},
{
"path": "说明书.html",
"bytes": 84637,
"sha256": "134f845140d3820ef6a2c3f955a536283c31937687dba4ed602151c9245413b3"
}
]
}

View File

@@ -0,0 +1,463 @@
{
"createdAt": "2026-09-16T08:58:30.712828+00:00",
"testDirectory": "user-testing/WEB_Blender_Parity_Round3_20260916",
"images": [
{
"module": "M01",
"path": "screenshots/M01-UJ-01-opened.png",
"detail": null,
"source": "user-testing/WEB_Blender_Parity_Round3_20260916/user-journeys/2026-09-16T08-45-03-602Z/UJ-01/06-reopened.png",
"case": "UJ-01",
"label": "reopened",
"at": "2026-09-16T08:45:08.035Z",
"sha256": "d75e4fe679299a348f30f97a4a34bc712c019ab20747af7593d12734fdff47ad"
},
{
"module": "M02",
"path": "screenshots/M02-UJ-20-keyboard-search-closed.png",
"detail": null,
"source": "user-testing/WEB_Blender_Parity_Round3_20260916/user-journeys/2026-09-16T08-45-03-602Z/UJ-20/03-keyboard-search-closed.png",
"case": "UJ-20",
"label": "keyboard-search-closed",
"at": "2026-09-16T08:46:31.275Z",
"sha256": "d7b4b997f24d38ffb5116429fa59ed45bd1d6f10b7ccfd4b8ac8cce3619a6910"
},
{
"module": "M03",
"path": "screenshots/M03-UJ-01-reopened.png",
"detail": null,
"source": "user-testing/WEB_Blender_Parity_Round3_20260916/user-journeys/2026-09-16T08-45-03-602Z/UJ-01/06-reopened.png",
"case": "UJ-01",
"label": "reopened",
"at": "2026-09-16T08:45:08.035Z",
"sha256": "d75e4fe679299a348f30f97a4a34bc712c019ab20747af7593d12734fdff47ad"
},
{
"module": "M04",
"path": "screenshots/M04-UT-270-quaternion-readout.png",
"detail": null,
"source": "user-testing/WEB_Blender_Parity_Round3_20260916/native-tests/2026-09-16T08-39-24-229Z/UT-270/02-quaternion-readout.png",
"case": "UT-270",
"label": "quaternion-readout",
"at": "2026-09-16T08:42:31.790Z",
"sha256": "ac87dbfc5b7d33abff3ed1d64ccc923b412ce87a5961a0dce990d9739dd0d0f7"
},
{
"module": "M05",
"path": "screenshots/M05-UJ-02-rename.png",
"detail": "screenshots/M05-UJ-02-rename-detail.png",
"source": "user-testing/WEB_Blender_Parity_Round3_20260916/user-journeys/2026-09-16T08-45-03-602Z/UJ-02/03-rename.png",
"case": "UJ-02",
"label": "rename",
"at": "2026-09-16T08:45:10.991Z",
"sha256": "cad4093d4c5bd156f38d3310ab170e96818e51e3d87c624b9be78142193a99f2"
},
{
"module": "M06",
"path": "screenshots/M06-UT-274-parent-readout.png",
"detail": null,
"source": "user-testing/WEB_Blender_Parity_Round3_20260916/native-tests/2026-09-16T08-39-24-229Z/UT-274/02-parent-readout.png",
"case": "UT-274",
"label": "parent-readout",
"at": "2026-09-16T08:42:57.349Z",
"sha256": "63ced739d976e3ff9d4ccf68a083a103c18e976f0a014afee19ef24b4b9ac88b"
},
{
"module": "M07",
"path": "screenshots/M07-UJ-03-triangulated.png",
"detail": "screenshots/M07-UJ-03-triangulated-detail.png",
"source": "user-testing/WEB_Blender_Parity_Round3_20260916/user-journeys/2026-09-16T08-45-03-602Z/UJ-03/03-triangulated.png",
"case": "UJ-03",
"label": "triangulated",
"at": "2026-09-16T08:45:16.355Z",
"sha256": "90d80372fea848e7d8ed99f004d5154befbf07eb285532b8a928c301373a03d9"
},
{
"module": "M08",
"path": "screenshots/M08-UJ-03-uv-projected.png",
"detail": "screenshots/M08-UJ-03-uv-projected-detail.png",
"source": "user-testing/WEB_Blender_Parity_Round3_20260916/user-journeys/2026-09-16T08-45-03-602Z/UJ-03/04-uv-projected.png",
"case": "UJ-03",
"label": "uv-projected",
"at": "2026-09-16T08:45:16.820Z",
"sha256": "1b05bcea85f5222fa4e9ff909ed3a0247c02100e5712b2b9d389ac56ba959822"
},
{
"module": "M09",
"path": "screenshots/M09-UJ-04-solidify-added.png",
"detail": "screenshots/M09-UJ-04-solidify-added-detail.png",
"source": "user-testing/WEB_Blender_Parity_Round3_20260916/user-journeys/2026-09-16T08-45-03-602Z/UJ-04/04-solidify-added.png",
"case": "UJ-04",
"label": "solidify-added",
"at": "2026-09-16T08:45:21.672Z",
"sha256": "38eb20078adfec0383c21a0fc0192fbc8164772b75911c5e96e2c56f2754033c"
},
{
"module": "M10",
"path": "screenshots/M10-UJ-05-cyclic-toggled.png",
"detail": "screenshots/M10-UJ-05-cyclic-toggled-detail.png",
"source": "user-testing/WEB_Blender_Parity_Round3_20260916/user-journeys/2026-09-16T08-45-03-602Z/UJ-05/02-cyclic-toggled.png",
"case": "UJ-05",
"label": "cyclic-toggled",
"at": "2026-09-16T08:45:26.555Z",
"sha256": "6c90c359635873dc609deed37ed1e46fa9fde365ab340bf9a0ac6248ec9abbd5"
},
{
"module": "M11",
"path": "screenshots/M11-UJ-06-text-applied.png",
"detail": "screenshots/M11-UJ-06-text-applied-detail.png",
"source": "user-testing/WEB_Blender_Parity_Round3_20260916/user-journeys/2026-09-16T08-45-03-602Z/UJ-06/03-text-applied.png",
"case": "UJ-06",
"label": "text-applied",
"at": "2026-09-16T08:45:30.941Z",
"sha256": "d170a7b80dcae5c39c4dc3ee597b396e798321b7c4dcef758ed6403b37cbae18"
},
{
"module": "M12",
"path": "screenshots/M12-UJ-07-principled-applied.png",
"detail": "screenshots/M12-UJ-07-principled-applied-detail.png",
"source": "user-testing/WEB_Blender_Parity_Round3_20260916/user-journeys/2026-09-16T08-45-03-602Z/UJ-07/03-principled-applied.png",
"case": "UJ-07",
"label": "principled-applied",
"at": "2026-09-16T08:45:35.869Z",
"sha256": "a6c13d4515816450ddc1b3095d56fae6fa8acfb230a7ee70eb4fa2f773f13a59"
},
{
"module": "M13",
"path": "screenshots/M13-UT-258-resource-bytes-persisted.png",
"detail": null,
"source": "user-testing/WEB_Blender_Parity_Round3_20260916/native-tests/2026-09-16T08-39-24-229Z/UT-258/02-resource-bytes-persisted.png",
"case": "UT-258",
"label": "resource-bytes-persisted",
"at": "2026-09-16T08:40:54.455Z",
"sha256": "a547427a62e941c4b915f818f9827a218592e788f2b9bc0850daf97c86553ebc"
},
{
"module": "M14",
"path": "screenshots/M14-UJ-11-gamma-increased.png",
"detail": "screenshots/M14-UJ-11-gamma-increased-detail.png",
"source": "user-testing/WEB_Blender_Parity_Round3_20260916/user-journeys/2026-09-16T08-45-03-602Z/UJ-11/02-gamma-increased.png",
"case": "UJ-11",
"label": "gamma-increased",
"at": "2026-09-16T08:45:55.632Z",
"sha256": "881ee98eacbfe3fbaf687b27741d8c170a62f50127bf2aed95b0ac4cc840b39e"
},
{
"module": "M15",
"path": "screenshots/M15-UJ-10-lens-increased.png",
"detail": "screenshots/M15-UJ-10-lens-increased-detail.png",
"source": "user-testing/WEB_Blender_Parity_Round3_20260916/user-journeys/2026-09-16T08-45-03-602Z/UJ-10/02-lens-increased.png",
"case": "UJ-10",
"label": "lens-increased",
"at": "2026-09-16T08:45:51.152Z",
"sha256": "6c3bd1b06379914c3c5c275c74d0a0e19e64d1e3ddcba0bfdc51650a486d82fb"
},
{
"module": "M16",
"path": "screenshots/M16-UJ-12-marker-added.png",
"detail": "screenshots/M16-UJ-12-marker-added-detail.png",
"source": "user-testing/WEB_Blender_Parity_Round3_20260916/user-journeys/2026-09-16T08-45-03-602Z/UJ-12/04-marker-added.png",
"case": "UJ-12",
"label": "marker-added",
"at": "2026-09-16T08:46:00.465Z",
"sha256": "2263ff275aa2bc24e19eca0ab7ca51dbceda00edddb613fa6e654ec7378e379b"
},
{
"module": "M17",
"path": "screenshots/M17-UJ-12-frame-three.png",
"detail": "screenshots/M17-UJ-12-frame-three-detail.png",
"source": "user-testing/WEB_Blender_Parity_Round3_20260916/user-journeys/2026-09-16T08-45-03-602Z/UJ-12/02-frame-three.png",
"case": "UJ-12",
"label": "frame-three",
"at": "2026-09-16T08:45:59.925Z",
"sha256": "5af97c1302ea2a3876ffba43e2e35bb515c7525e1a5639c2d98a52635efe227f"
},
{
"module": "M18",
"path": "screenshots/M18-UJ-13-roll-changed.png",
"detail": "screenshots/M18-UJ-13-roll-changed-detail.png",
"source": "user-testing/WEB_Blender_Parity_Round3_20260916/user-journeys/2026-09-16T08-45-03-602Z/UJ-13/02-roll-changed.png",
"case": "UJ-13",
"label": "roll-changed",
"at": "2026-09-16T08:46:04.611Z",
"sha256": "7920d7f99edc085d55a5dd4202373d2449ebd2711c142494be093330e560aaa5"
},
{
"module": "M19",
"path": "screenshots/M19-UJ-08-sculpt-attributes.png",
"detail": "screenshots/M19-UJ-08-sculpt-attributes-detail.png",
"source": "user-testing/WEB_Blender_Parity_Round3_20260916/user-journeys/2026-09-16T08-45-03-602Z/UJ-08/02-sculpt-attributes.png",
"case": "UJ-08",
"label": "sculpt-attributes",
"at": "2026-09-16T08:45:41.503Z",
"sha256": "cac57f19bad77670228bcc4c07d06f01c2334f07a1afb85cefb808924a2b44fe"
},
{
"module": "M20",
"path": "screenshots/M20-UJ-21-vertex-weight-applied.png",
"detail": "screenshots/M20-UJ-21-vertex-weight-applied-detail.png",
"source": "user-testing/WEB_Blender_Parity_Round3_20260916/user-journeys/2026-09-16T08-50-12-365Z/UJ-21/03-vertex-weight-applied.png",
"case": "UJ-21",
"label": "vertex-weight-applied",
"at": "2026-09-16T08:50:16.205Z",
"sha256": "70e23df97040234eda56f463ea9d60e5538effce7006c395993376dcef2d10fe"
},
{
"module": "M21",
"path": "screenshots/M21-UJ-17-layer-added.png",
"detail": "screenshots/M21-UJ-17-layer-added-detail.png",
"source": "user-testing/WEB_Blender_Parity_Round3_20260916/user-journeys/2026-09-16T08-45-03-602Z/UJ-17/02-layer-added.png",
"case": "UJ-17",
"label": "layer-added",
"at": "2026-09-16T08:46:21.243Z",
"sha256": "a09f3d761ab606f8543821fb6414b2311e03230bdd1a4d2accc333c3232d702a"
},
{
"module": "M22",
"path": "screenshots/M22-UJ-16-graph-visible.png",
"detail": "screenshots/M22-UJ-16-graph-visible-detail.png",
"source": "user-testing/WEB_Blender_Parity_Round3_20260916/user-journeys/2026-09-16T08-45-03-602Z/UJ-16/03-graph-visible.png",
"case": "UJ-16",
"label": "graph-visible",
"at": "2026-09-16T08:46:17.105Z",
"sha256": "c3ca6ac8f798f6e2c9ccf0e0e6d6a354eeb598460926cacfb070fb90e2125091"
},
{
"module": "M23",
"path": "screenshots/M23-UT-252-native-desktop.png",
"detail": null,
"source": "user-testing/WEB_Blender_Parity_Round3_20260916/native-tests/2026-09-16T08-39-24-229Z/UT-252/02-native-desktop.png",
"case": "UT-252",
"label": "native-desktop",
"at": "2026-09-16T08:40:18.725Z",
"sha256": "43df0bbdd03a1ea74e59f6d2892d13e57400d87fa531a71a76cf96d53694e382"
},
{
"module": "M24",
"path": "screenshots/M24-UJ-14-mute-strip.png",
"detail": null,
"source": "user-testing/WEB_Blender_Parity_Round3_20260916/user-journeys/2026-09-16T08-45-03-602Z/UJ-14/04-mute-strip.png",
"case": "UJ-14",
"label": "mute-strip",
"at": "2026-09-16T08:46:08.810Z",
"sha256": "6173e6c7771ba717c223eab13f7dec9e7437fdb7e8a0ffdaa35f3a6bdea650ce"
},
{
"module": "M25",
"path": "screenshots/M25-UT-245-image-preview.png",
"detail": null,
"source": "user-testing/WEB_Blender_Parity_Round3_20260916/native-tests/2026-09-16T08-39-24-229Z/UT-245/03-image-preview.png",
"case": "UT-245",
"label": "image-preview",
"at": "2026-09-16T08:39:28.791Z",
"sha256": "bbc48a954c261fafbc0dcb1cf1c0734fdaa0c7e9e7a4434eb26424ec821d6377"
},
{
"module": "M26",
"path": "screenshots/M26-UT-247-render-result.png",
"detail": null,
"source": "user-testing/WEB_Blender_Parity_Round3_20260916/native-tests/2026-09-16T08-39-24-229Z/UT-247/02-render-result.png",
"case": "UT-247",
"label": "render-result",
"at": "2026-09-16T08:39:36.570Z",
"sha256": "9f9c18147618a5790381cbcf6f159512f220a8dbb7211ea3b92431dda89abc9c"
},
{
"module": "M27",
"path": "screenshots/M27-UT-250-continued-with-same-object-reference.png",
"detail": null,
"source": "user-testing/WEB_Blender_Parity_Round3_20260916/native-tests/2026-09-16T08-39-24-229Z/UT-250/06-continued-with-same-object-reference.png",
"case": "UT-250",
"label": "continued-with-same-object-reference",
"at": "2026-09-16T08:40:02.828Z",
"sha256": "6664a803ed5f5257a6e2769e9ac174d104653d00b04b9cd16c2b66ad5136d45a"
},
{
"module": "M28",
"path": "screenshots/M28-UT-248-python-result.png",
"detail": null,
"source": "user-testing/WEB_Blender_Parity_Round3_20260916/native-tests/2026-09-16T08-39-24-229Z/UT-248/02-python-result.png",
"case": "UT-248",
"label": "python-result",
"at": "2026-09-16T08:39:40.638Z",
"sha256": "d7c1c404b631588a0abed22e2bc352006ab511487a2f57dd2483e36cd7903d7b"
},
{
"module": "M29",
"path": "screenshots/M29-UT-252-native-desktop.png",
"detail": null,
"source": "user-testing/WEB_Blender_Parity_Round3_20260916/native-tests/2026-09-16T08-39-24-229Z/UT-252/02-native-desktop.png",
"case": "UT-252",
"label": "native-desktop",
"at": "2026-09-16T08:40:18.725Z",
"sha256": "43df0bbdd03a1ea74e59f6d2892d13e57400d87fa531a71a76cf96d53694e382"
},
{
"module": "M30",
"path": "screenshots/M30-UJ-15-catalog-saved.png",
"detail": "screenshots/M30-UJ-15-catalog-saved-detail.png",
"source": "user-testing/WEB_Blender_Parity_Round3_20260916/user-journeys/2026-09-16T08-45-03-602Z/UJ-15/03-catalog-saved.png",
"case": "UJ-15",
"label": "catalog-saved",
"at": "2026-09-16T08:46:12.925Z",
"sha256": "4541701db387553ed10e95ccbb33fd55ab19e03dfab2c3459777650d88ca5a90"
},
{
"module": "M31",
"path": "screenshots/M31-UJ-09-mass-2.png",
"detail": "screenshots/M31-UJ-09-mass-2-detail.png",
"source": "user-testing/WEB_Blender_Parity_Round3_20260916/user-journeys/2026-09-16T08-45-03-602Z/UJ-09/03-mass-2.png",
"case": "UJ-09",
"label": "mass-2",
"at": "2026-09-16T08:45:46.194Z",
"sha256": "4eb83a55ff6813ffbab4e6eb2b16f3956a350441e2e12934262d54ff6e2da2fa"
},
{
"module": "M33",
"path": "screenshots/M33-UJ-18-search-results.png",
"detail": null,
"source": "user-testing/WEB_Blender_Parity_Round3_20260916/user-journeys/2026-09-16T08-45-03-602Z/UJ-18/02-search-results.png",
"case": "UJ-18",
"label": "search-results",
"at": "2026-09-16T08:46:25.500Z",
"sha256": "014926742fa87b0461bf0b9b98f85b58a5ae439a3feb8bbae9123ee0b595c17f"
},
{
"module": "M34",
"path": "screenshots/M34-UJ-20-compact-layout.png",
"detail": null,
"source": "user-testing/WEB_Blender_Parity_Round3_20260916/user-journeys/2026-09-16T08-45-03-602Z/UJ-20/02-compact-layout.png",
"case": "UJ-20",
"label": "compact-layout",
"at": "2026-09-16T08:46:30.804Z",
"sha256": "1ef17d89acfa47b972b2c883b90037f1ebfac077b48b0232ec09d6e26c997961"
},
{
"module": "M35",
"path": "screenshots/M35-UT-245-image-preview.png",
"detail": null,
"source": "user-testing/WEB_Blender_Parity_Round3_20260916/native-tests/2026-09-16T08-39-24-229Z/UT-245/03-image-preview.png",
"case": "UT-245",
"label": "image-preview",
"at": "2026-09-16T08:39:28.791Z",
"sha256": "bbc48a954c261fafbc0dcb1cf1c0734fdaa0c7e9e7a4434eb26424ec821d6377"
},
{
"module": "M36",
"path": "screenshots/M36-UT-275-kernel-exit-protected.png",
"detail": null,
"source": "user-testing/WEB_Blender_Parity_Round3_20260916/native-tests/2026-09-16T08-39-24-229Z/UT-275/03-kernel-exit-protected.png",
"case": "UT-275",
"label": "kernel-exit-protected",
"at": "2026-09-16T08:43:06.120Z",
"sha256": "7cf7fa1db58ba57613ef9bcd00e8115b6619dc899b751c70922a1c97e2bced16"
}
],
"samples": {
"animation_scene.blend": {
"source": "tests/files/web/animation_scene.blend",
"sha256": "8bc730eb5df55d91246f0eade4f416cae6670dde1191b3dc340f283532a04f3d",
"bytes": 86768
},
"attribute_scene.blend": {
"source": "tests/files/web/attribute_scene.blend",
"sha256": "12fa75bb79f8c38e660d3d2a8fc9cc16dd3df4fc9208b0e2ad94fb1f8aa68f71",
"bytes": 90108
},
"basic_scene.blend": {
"source": "tests/files/web/basic_scene.blend",
"sha256": "6fcc55bda74da8c95da96ba068b60339bf60ca44147ff8000fbb95d296db2a73",
"bytes": 95608
},
"mesh_editor_scene.blend": {
"source": "tests/files/web/mesh_editor_scene.blend",
"sha256": "5bb93920ec3bd8d113ebc6cf325d76a058abb0ac60b77c0f3ececc83c192c6cb",
"bytes": 92159
},
"modifier_grease_pencil_scene.blend": {
"source": "tests/files/web/modifier_grease_pencil_scene.blend",
"sha256": "3a8525077807f9178dac3a5ba84b524e5f8e80874b15c54e2a6658ecb80315a3",
"bytes": 87788
},
"modifier_stack_scene.blend": {
"source": "tests/files/web/modifier_stack_scene.blend",
"sha256": "e35b3e4eda35d67f1d90a52abdf9dc3b43a8c275a9e913df95241d797fa12854",
"bytes": 92289
},
"nonmesh_scene.blend": {
"source": "tests/files/web/nonmesh_scene.blend",
"sha256": "ae8ef85d606aa120ce6b7611fc03407fd80bb60311e94a6ef73f6384d0b6c8b4",
"bytes": 113991
},
"parity_animation.blend": {
"source": "user-testing/WEB_Blender_Parity_Round3_20260916/fixtures/parity_animation.blend",
"sha256": "377e8c6d09e9f563020b598dc123dc48334a39c6ac012d32d87c6c4fd778aae7",
"bytes": 90434
},
"parity_scene.blend": {
"source": "user-testing/WEB_Blender_Parity_Round3_20260916/fixtures/parity_scene.blend",
"sha256": "35c36777a9546a88de5ecb237808fb0519d7ddb2550608123ed629fb9a949416",
"bytes": 90044
},
"pose_constraint_scene.blend": {
"source": "tests/files/web/pose_constraint_scene.blend",
"sha256": "39bfb2d9466cece01d7ddd822bb46407049d812cb66b07fb7852a2e14ed5c91e",
"bytes": 89384
},
"resource_scene.blend": {
"source": "user-testing/WEB_Blender_Parity_Round3_20260916/fixtures/resource_scene.blend",
"sha256": "8bf574ea102e8c983a89312d17d62cfa7ebcf700c1c625b581e7610e2a0a65f7",
"bytes": 90519
},
"rotation-axis_angle.blend": {
"source": "user-testing/WEB_Blender_Parity_Round3_20260916/fixtures/rotation-axis_angle.blend",
"sha256": "2c188fe457a68fdba7b2f2c360618350ab7c31827a443a944ce85fd60fea7826",
"bytes": 90015
},
"rotation-parent.blend": {
"source": "user-testing/WEB_Blender_Parity_Round3_20260916/fixtures/rotation-parent.blend",
"sha256": "6bd20cb92da72daca4617d2ae10e5d5112058681fdbc512ad1c7619107c215b7",
"bytes": 90181
},
"rotation-quaternion.blend": {
"source": "user-testing/WEB_Blender_Parity_Round3_20260916/fixtures/rotation-quaternion.blend",
"sha256": "a31107d5296ef7fbeda6a0ac7905edeacf8aa8b3ba2d5e96c755fd0c83f279e0",
"bytes": 90013
},
"sequencer_scene.blend": {
"source": "tests/files/web/sequencer_scene.blend",
"sha256": "5f5212487bb6b5df62b5ca915c75133f1ca45678614712ea4c7d902d823cd90c",
"bytes": 496033
},
"state.txt": {
"source": "user-testing/WEB_Blender_Parity_Round3_20260916/fixtures/state.txt",
"sha256": "346547a66c48c8f48e1bb5b850bb8ba31ecd837de16ee1481466d1657a16e35b",
"bytes": 25
},
"texture.png": {
"source": "user-testing/WEB_Blender_Parity_Round3_20260916/fixtures/texture.png",
"sha256": "2b0f5252b6c439373c57bdecdafb9f268f67a6aea63d44554de42c519d3a8410",
"bytes": 260
},
"04_read_resource.py": {
"source": "Handbook example",
"sha256": "367e0eeceb10817771dde6d89d05709c137e4fca796ae43f9826d6fbe9966adf",
"bytes": 238
},
"02_quaternion.py": {
"source": "Handbook example",
"sha256": "9f630249be62c704522162b1270626ce479eab59ec79073aa963ac0155a38527",
"bytes": 186
},
"03_axis_angle.py": {
"source": "Handbook example",
"sha256": "272e50d36c9131de1edabe7d9f03d7696d6bebc17e161567925d8436d121b991",
"bytes": 213
},
"01_move_object.py": {
"source": "Handbook example",
"sha256": "9665a900cc8d75e40195cb4ecc219cf0bafdc7fb5f441f5df5fba8ffd4f386c8",
"bytes": 129
}
}
}

View File

@@ -0,0 +1,37 @@
模块,功能,桌面对应,Web 入口,范围,证据
M01,运行环境与样例准备,启动 Blender、打开工程,Chrome 浏览器;本机 Web 与原生 Blender 服务,本轮用户流程或原生对照实测,UJ-01
M02,界面、工作区与对象选择,Workspaces、Outliner、Properties,顶部工作区标签;右侧 Outliner,本轮用户流程或原生对照实测,"UJ-02,UJ-20"
M03,打开、保存、恢复、撤销与重做,File Open/Save、Undo/Redo,顶部打开/保存/恢复图标,Recent 列表,本轮用户流程或原生对照实测,"UJ-01,UJ-19"
M04,位置、缩放与全部旋转模式,Object Transform:Euler / Quaternion / Axis Angle,Properties > Transform;原生桌面;Python Console,本轮用户流程或原生对照实测,"UT-266,UT-270,UT-271,UT-272,UT-273,UT-274"
M05,对象创建、复制、重命名与删除,Add Object、Duplicate、Rename、Delete,Modeling 工具栏;Properties > Object & Hierarchy,本轮用户流程或原生对照实测,"UJ-01,UJ-02"
M06,集合、父子关系、原点与应用变换,Collections、Parenting、Origin、Apply Transform,Modeling 工具栏;Object & Hierarchy;原生桌面,部分入口确认;普通对象父级矩阵实测,UT-274
M07,网格编辑、选择与拓扑操作,Edit Mode、Vertex/Edge/Face、Triangulate,Modeling;模式按钮;网格工具栏,本轮用户流程或原生对照实测,UJ-03
M08,UV 投影与 UV 工作流,UV Editor、UV Projection / Unwrap,Properties > UV Projection;UV Editing 工作区,本轮用户流程或原生对照实测,UJ-03
M09,修改器参数与堆栈,Modifier Properties、Stack Ordering,Properties 中的 Modifier Stack,本轮用户流程或原生对照实测,UJ-04
M10,曲线、曲面与非网格对象,Curve / Surface / Metaball / Lattice,对应对象的 Properties;原生桌面,本轮用户流程或原生对照实测,UJ-05
M11,文本对象与字体,Text Object、Font Properties,文本对象的 Font body / Apply Text,本轮用户流程或原生对照实测,UJ-06
M12,材质与基础着色,Material Properties、Principled BSDF,材质属性面板;Shading,本轮用户流程或原生对照实测,UJ-07
M13,外部纹理、文件同步与项目资源,External Data、Pack Resources、Relative Paths,Scripting 或 Rendering 的 Resource files / Project folder,本轮用户流程或原生对照实测,"UT-254,UT-258,UT-259,UT-260,UT-261,UT-265"
M14,灯光、世界与色彩管理,Light、World、Color Management,Outliner 选择灯光;Scene Render 属性,本轮用户流程或原生对照实测,"UJ-10,UJ-11"
M15,相机与构图,Camera Properties、Active Camera,Camera 属性;原生桌面 Camera View,本轮用户流程或原生对照实测,UJ-10
M16,时间轴、关键帧与标记,Timeline、Insert Keyframe、Markers,底部时间轴与动画属性,本轮用户流程或原生对照实测,UJ-12
M17,曲线编辑器、驱动器与 NLA,Dope Sheet、Graph Editor、Drivers、NLA,Animation 工作区的现有入口;原生桌面,基础关键帧实测;完整编辑器路线待业务逐项验收,UJ-12
M18,骨架、姿态与约束,Armature Edit / Pose、Bone Roll、Constraints,骨架属性工作台;原生桌面,本轮用户流程或原生对照实测,UJ-13
M19,雕刻属性与面组,Sculpt Mode、Mask、Face Sets,Properties > Sculpt;原生桌面 Sculpt Mode,本轮用户流程或原生对照实测,UJ-08
M20,顶点颜色、权重与绘制属性,Color Attributes、Vertex Groups、Weight Paint,Edit Mode 顶点选择;Properties > Paint,本轮用户流程或原生对照实测,UJ-21
M21,Grease Pencil 图层与绘图数据,Grease Pencil Layers、Frames、Drawings,Grease Pencil 对象属性与编辑入口,本轮用户流程或原生对照实测,UJ-17
M22,几何节点与节点图,Geometry Nodes Editor,Properties > Geometry Graph;Geometry Nodes 工作区,本轮用户流程或原生对照实测,UJ-16
M23,合成器、遮罩与跟踪,Compositor、Mask Editor、Movie Clip Tracking,对应工作区;完整操作使用原生桌面,原生入口实测;本模块具体业务未全覆盖,UT-252
M24,视频序列与条带编辑,Video Sequencer、Strip Properties,Sequencer Strip Editing 工作区,本轮用户流程或原生对照实测,UJ-14
M25,真实图像渲染与 OpenEXR,Render Image、Cycles / Eevee / Workbench,Rendering > Render Frame,本轮用户流程或原生对照实测,"UT-245,UT-256"
M26,动画帧序列、MP4 与取消,Render Animation、Image Sequence、FFmpeg Output,Rendering > Start / End / Step / Render Animation,本轮用户流程或原生对照实测,"UT-246,UT-247,UT-257"
M27,持久 Python 控制台,Python Console、InteractiveConsole,Scripting > Python Console,本轮用户流程或原生对照实测,"UT-249,UT-250,UT-267,UT-268,UT-269"
M28,文本脚本与批处理,Text Editor、Run Script,Scripting > Text Editor,本轮用户流程或原生对照实测,UT-248
M29,真实原生桌面与交互式工具,Desktop Blender Editors、Modal Operators,F3 > Open Native Desktop Session,本轮用户流程或原生对照实测,"UT-252,UT-253"
M30,资产目录、链接库与追加,Asset Browser、Catalogs、Link / Append / Override,Properties > Asset Browser & Libraries,本轮用户流程或原生对照实测,UJ-15
M31,刚体与模拟工作流,Physics Properties、Rigid Body、Simulation Cache,Properties > Physics;原生桌面,本轮用户流程或原生对照实测,UJ-09
M32,体积数据与显示,Volume Objects、OpenVDB / NanoVDB,现有体积入口;原生桌面,引擎集合有覆盖;本章业务项目需单独验证,
M33,GLB 导出及其他交换格式,File Export / Import,顶部“导出 GLB”;F3 与当前格式入口,本轮用户流程或原生对照实测,UJ-18
M34,键盘、焦点与紧凑布局,Shortcuts、Focus、Editor Context,Web 输入框、搜索对话框与原生画面,本轮用户流程或原生对照实测,UJ-20
M35,一个可重复的建模到渲染练习,Modeling → Material → Camera → Render → Save,综合使用 Web、Scripting、Rendering,本轮用户流程或原生对照实测,"UT-248,UT-245,UT-252"
M36,错误恢复与用户验证记录,Reports、Undo、Recover、Reopen,状态栏、Python 输出、诊断导出、Recent,本轮用户流程或原生对照实测,"UJ-19,UT-251,UT-275,UT-276"
1 模块 功能 桌面对应 Web 入口 范围 证据
2 M01 运行环境与样例准备 启动 Blender、打开工程 Chrome 浏览器;本机 Web 与原生 Blender 服务 本轮用户流程或原生对照实测 UJ-01
3 M02 界面、工作区与对象选择 Workspaces、Outliner、Properties 顶部工作区标签;右侧 Outliner 本轮用户流程或原生对照实测 UJ-02,UJ-20
4 M03 打开、保存、恢复、撤销与重做 File Open/Save、Undo/Redo 顶部打开/保存/恢复图标,Recent 列表 本轮用户流程或原生对照实测 UJ-01,UJ-19
5 M04 位置、缩放与全部旋转模式 Object Transform:Euler / Quaternion / Axis Angle Properties > Transform;原生桌面;Python Console 本轮用户流程或原生对照实测 UT-266,UT-270,UT-271,UT-272,UT-273,UT-274
6 M05 对象创建、复制、重命名与删除 Add Object、Duplicate、Rename、Delete Modeling 工具栏;Properties > Object & Hierarchy 本轮用户流程或原生对照实测 UJ-01,UJ-02
7 M06 集合、父子关系、原点与应用变换 Collections、Parenting、Origin、Apply Transform Modeling 工具栏;Object & Hierarchy;原生桌面 部分入口确认;普通对象父级矩阵实测 UT-274
8 M07 网格编辑、选择与拓扑操作 Edit Mode、Vertex/Edge/Face、Triangulate Modeling;模式按钮;网格工具栏 本轮用户流程或原生对照实测 UJ-03
9 M08 UV 投影与 UV 工作流 UV Editor、UV Projection / Unwrap Properties > UV Projection;UV Editing 工作区 本轮用户流程或原生对照实测 UJ-03
10 M09 修改器参数与堆栈 Modifier Properties、Stack Ordering Properties 中的 Modifier Stack 本轮用户流程或原生对照实测 UJ-04
11 M10 曲线、曲面与非网格对象 Curve / Surface / Metaball / Lattice 对应对象的 Properties;原生桌面 本轮用户流程或原生对照实测 UJ-05
12 M11 文本对象与字体 Text Object、Font Properties 文本对象的 Font body / Apply Text 本轮用户流程或原生对照实测 UJ-06
13 M12 材质与基础着色 Material Properties、Principled BSDF 材质属性面板;Shading 本轮用户流程或原生对照实测 UJ-07
14 M13 外部纹理、文件同步与项目资源 External Data、Pack Resources、Relative Paths Scripting 或 Rendering 的 Resource files / Project folder 本轮用户流程或原生对照实测 UT-254,UT-258,UT-259,UT-260,UT-261,UT-265
15 M14 灯光、世界与色彩管理 Light、World、Color Management Outliner 选择灯光;Scene Render 属性 本轮用户流程或原生对照实测 UJ-10,UJ-11
16 M15 相机与构图 Camera Properties、Active Camera Camera 属性;原生桌面 Camera View 本轮用户流程或原生对照实测 UJ-10
17 M16 时间轴、关键帧与标记 Timeline、Insert Keyframe、Markers 底部时间轴与动画属性 本轮用户流程或原生对照实测 UJ-12
18 M17 曲线编辑器、驱动器与 NLA Dope Sheet、Graph Editor、Drivers、NLA Animation 工作区的现有入口;原生桌面 基础关键帧实测;完整编辑器路线待业务逐项验收 UJ-12
19 M18 骨架、姿态与约束 Armature Edit / Pose、Bone Roll、Constraints 骨架属性工作台;原生桌面 本轮用户流程或原生对照实测 UJ-13
20 M19 雕刻属性与面组 Sculpt Mode、Mask、Face Sets Properties > Sculpt;原生桌面 Sculpt Mode 本轮用户流程或原生对照实测 UJ-08
21 M20 顶点颜色、权重与绘制属性 Color Attributes、Vertex Groups、Weight Paint Edit Mode 顶点选择;Properties > Paint 本轮用户流程或原生对照实测 UJ-21
22 M21 Grease Pencil 图层与绘图数据 Grease Pencil Layers、Frames、Drawings Grease Pencil 对象属性与编辑入口 本轮用户流程或原生对照实测 UJ-17
23 M22 几何节点与节点图 Geometry Nodes Editor Properties > Geometry Graph;Geometry Nodes 工作区 本轮用户流程或原生对照实测 UJ-16
24 M23 合成器、遮罩与跟踪 Compositor、Mask Editor、Movie Clip Tracking 对应工作区;完整操作使用原生桌面 原生入口实测;本模块具体业务未全覆盖 UT-252
25 M24 视频序列与条带编辑 Video Sequencer、Strip Properties Sequencer Strip Editing 工作区 本轮用户流程或原生对照实测 UJ-14
26 M25 真实图像渲染与 OpenEXR Render Image、Cycles / Eevee / Workbench Rendering > Render Frame 本轮用户流程或原生对照实测 UT-245,UT-256
27 M26 动画帧序列、MP4 与取消 Render Animation、Image Sequence、FFmpeg Output Rendering > Start / End / Step / Render Animation 本轮用户流程或原生对照实测 UT-246,UT-247,UT-257
28 M27 持久 Python 控制台 Python Console、InteractiveConsole Scripting > Python Console 本轮用户流程或原生对照实测 UT-249,UT-250,UT-267,UT-268,UT-269
29 M28 文本脚本与批处理 Text Editor、Run Script Scripting > Text Editor 本轮用户流程或原生对照实测 UT-248
30 M29 真实原生桌面与交互式工具 Desktop Blender Editors、Modal Operators F3 > Open Native Desktop Session 本轮用户流程或原生对照实测 UT-252,UT-253
31 M30 资产目录、链接库与追加 Asset Browser、Catalogs、Link / Append / Override Properties > Asset Browser & Libraries 本轮用户流程或原生对照实测 UJ-15
32 M31 刚体与模拟工作流 Physics Properties、Rigid Body、Simulation Cache Properties > Physics;原生桌面 本轮用户流程或原生对照实测 UJ-09
33 M32 体积数据与显示 Volume Objects、OpenVDB / NanoVDB 现有体积入口;原生桌面 引擎集合有覆盖;本章业务项目需单独验证
34 M33 GLB 导出及其他交换格式 File Export / Import 顶部“导出 GLB”;F3 与当前格式入口 本轮用户流程或原生对照实测 UJ-18
35 M34 键盘、焦点与紧凑布局 Shortcuts、Focus、Editor Context Web 输入框、搜索对话框与原生画面 本轮用户流程或原生对照实测 UJ-20
36 M35 一个可重复的建模到渲染练习 Modeling → Material → Camera → Render → Save 综合使用 Web、Scripting、Rendering 本轮用户流程或原生对照实测 UT-248,UT-245,UT-252
37 M36 错误恢复与用户验证记录 Reports、Undo、Recover、Reopen 状态栏、Python 输出、诊断导出、Recent 本轮用户流程或原生对照实测 UJ-19,UT-251,UT-275,UT-276

View File

@@ -0,0 +1,5 @@
import bpy
obj = bpy.data.objects['ParityCube']
obj.location = (2.0, -1.0, 0.5)
print('MOVE_OK', obj.name, tuple(obj.location))

View File

@@ -0,0 +1,6 @@
import bpy
obj = bpy.data.objects['ParityCube']
obj.rotation_mode = 'QUATERNION'
obj.rotation_quaternion = (2.0, 0.0, 0.0, 2.0)
print('QUATERNION_WXYZ', tuple(obj.rotation_quaternion))

View File

@@ -0,0 +1,7 @@
import bpy
import math
obj = bpy.data.objects['ParityCube']
obj.rotation_mode = 'AXIS_ANGLE'
obj.rotation_axis_angle = (math.pi / 3, 0.0, 1.0, 0.0)
print('ANGLE_RADIANS_AXIS_XYZ', tuple(obj.rotation_axis_angle))

View File

@@ -0,0 +1,7 @@
import bpy
from pathlib import Path
image = bpy.data.images['ExternalParityImage']
path = Path(bpy.path.abspath(image.filepath)).parent / 'state.txt'
print('IMAGE_SIZE', list(image.size))
print('RESOURCE_TEXT', path.read_text().strip())

View File

@@ -0,0 +1,107 @@
{
"animation_scene.blend": {
"source": "tests/files/web/animation_scene.blend",
"sha256": "8bc730eb5df55d91246f0eade4f416cae6670dde1191b3dc340f283532a04f3d",
"bytes": 86768
},
"attribute_scene.blend": {
"source": "tests/files/web/attribute_scene.blend",
"sha256": "12fa75bb79f8c38e660d3d2a8fc9cc16dd3df4fc9208b0e2ad94fb1f8aa68f71",
"bytes": 90108
},
"basic_scene.blend": {
"source": "tests/files/web/basic_scene.blend",
"sha256": "6fcc55bda74da8c95da96ba068b60339bf60ca44147ff8000fbb95d296db2a73",
"bytes": 95608
},
"mesh_editor_scene.blend": {
"source": "tests/files/web/mesh_editor_scene.blend",
"sha256": "5bb93920ec3bd8d113ebc6cf325d76a058abb0ac60b77c0f3ececc83c192c6cb",
"bytes": 92159
},
"modifier_grease_pencil_scene.blend": {
"source": "tests/files/web/modifier_grease_pencil_scene.blend",
"sha256": "3a8525077807f9178dac3a5ba84b524e5f8e80874b15c54e2a6658ecb80315a3",
"bytes": 87788
},
"modifier_stack_scene.blend": {
"source": "tests/files/web/modifier_stack_scene.blend",
"sha256": "e35b3e4eda35d67f1d90a52abdf9dc3b43a8c275a9e913df95241d797fa12854",
"bytes": 92289
},
"nonmesh_scene.blend": {
"source": "tests/files/web/nonmesh_scene.blend",
"sha256": "ae8ef85d606aa120ce6b7611fc03407fd80bb60311e94a6ef73f6384d0b6c8b4",
"bytes": 113991
},
"parity_animation.blend": {
"source": "user-testing/WEB_Blender_Parity_Round3_20260916/fixtures/parity_animation.blend",
"sha256": "377e8c6d09e9f563020b598dc123dc48334a39c6ac012d32d87c6c4fd778aae7",
"bytes": 90434
},
"parity_scene.blend": {
"source": "user-testing/WEB_Blender_Parity_Round3_20260916/fixtures/parity_scene.blend",
"sha256": "35c36777a9546a88de5ecb237808fb0519d7ddb2550608123ed629fb9a949416",
"bytes": 90044
},
"pose_constraint_scene.blend": {
"source": "tests/files/web/pose_constraint_scene.blend",
"sha256": "39bfb2d9466cece01d7ddd822bb46407049d812cb66b07fb7852a2e14ed5c91e",
"bytes": 89384
},
"resource_scene.blend": {
"source": "user-testing/WEB_Blender_Parity_Round3_20260916/fixtures/resource_scene.blend",
"sha256": "8bf574ea102e8c983a89312d17d62cfa7ebcf700c1c625b581e7610e2a0a65f7",
"bytes": 90519
},
"rotation-axis_angle.blend": {
"source": "user-testing/WEB_Blender_Parity_Round3_20260916/fixtures/rotation-axis_angle.blend",
"sha256": "2c188fe457a68fdba7b2f2c360618350ab7c31827a443a944ce85fd60fea7826",
"bytes": 90015
},
"rotation-parent.blend": {
"source": "user-testing/WEB_Blender_Parity_Round3_20260916/fixtures/rotation-parent.blend",
"sha256": "6bd20cb92da72daca4617d2ae10e5d5112058681fdbc512ad1c7619107c215b7",
"bytes": 90181
},
"rotation-quaternion.blend": {
"source": "user-testing/WEB_Blender_Parity_Round3_20260916/fixtures/rotation-quaternion.blend",
"sha256": "a31107d5296ef7fbeda6a0ac7905edeacf8aa8b3ba2d5e96c755fd0c83f279e0",
"bytes": 90013
},
"sequencer_scene.blend": {
"source": "tests/files/web/sequencer_scene.blend",
"sha256": "5f5212487bb6b5df62b5ca915c75133f1ca45678614712ea4c7d902d823cd90c",
"bytes": 496033
},
"state.txt": {
"source": "user-testing/WEB_Blender_Parity_Round3_20260916/fixtures/state.txt",
"sha256": "346547a66c48c8f48e1bb5b850bb8ba31ecd837de16ee1481466d1657a16e35b",
"bytes": 25
},
"texture.png": {
"source": "user-testing/WEB_Blender_Parity_Round3_20260916/fixtures/texture.png",
"sha256": "2b0f5252b6c439373c57bdecdafb9f268f67a6aea63d44554de42c519d3a8410",
"bytes": 260
},
"04_read_resource.py": {
"source": "Handbook example",
"sha256": "367e0eeceb10817771dde6d89d05709c137e4fca796ae43f9826d6fbe9966adf",
"bytes": 238
},
"02_quaternion.py": {
"source": "Handbook example",
"sha256": "9f630249be62c704522162b1270626ce479eab59ec79073aa963ac0155a38527",
"bytes": 186
},
"03_axis_angle.py": {
"source": "Handbook example",
"sha256": "272e50d36c9131de1edabe7d9f03d7696d6bebc17e161567925d8436d121b991",
"bytes": 213
},
"01_move_object.py": {
"source": "Handbook example",
"sha256": "9665a900cc8d75e40195cb4ecc219cf0bafdc7fb5f441f5df5fba8ffd4f386c8",
"bytes": 129
}
}

View File

@@ -0,0 +1 @@
RESOURCE_ROUND2_ORIGINAL

Binary file not shown.

After

Width:  |  Height:  |  Size: 260 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 176 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 139 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 176 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 185 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 50 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 198 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 187 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 52 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 195 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 47 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 188 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 45 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 175 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 52 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 220 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 52 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 214 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 49 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 186 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 141 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 54 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 198 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 56 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 178 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 47 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 180 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 47 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 166 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 51 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 178 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 48 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 193 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 50 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 236 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 39 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 154 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 57 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 205 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 742 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 167 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 131 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 128 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 157 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 142 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 742 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 54 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 198 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 50 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 194 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 177 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 139 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 131 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 150 KiB

View File

@@ -0,0 +1,109 @@
#!/usr/bin/env python3
"""Create a self-contained handbook with actual screenshots and editable source."""
import csv
import hashlib
import html
import json
from datetime import datetime, timezone
from pathlib import Path
import shutil
from PIL import Image
from modules import MODULES
BASE=Path(__file__).resolve().parents[1]
ROOT=BASE.parents[1]
TEST=ROOT/'user-testing/WEB_Blender_Parity_Round3_20260916'
E=html.escape
def read(path):return json.loads(path.read_text())
def sha(path):return hashlib.sha256(path.read_bytes()).hexdigest()
results={}
for category in ('native-tests','user-journeys'):
for file in sorted((TEST/category).glob('*/summary.json')):
for row in read(file):results[row['id']]={**row,'directory':file.parent}
def picture(module):
if not module['image']:return None
case,label=module['image'];entry=results.get(case)
if not entry or entry['status']!='PASS':raise RuntimeError('Missing current evidence: '+case)
steps=[step for step in entry['steps'] if label in step['label']]
if not steps:raise RuntimeError('Missing image step: '+case+' '+label)
step=steps[-1];src=TEST/step['png'] if 'png' in step else entry['directory']/case/step['file']
target=BASE/'screenshots'/f'{module["id"]}-{case}-{label}.png';shutil.copy2(src,target)
image=Image.open(target);image.verify()
detail=None
if case.startswith('UJ-') and module['id'] not in ('M01','M02','M03','M24','M33','M34'):
with Image.open(target) as original:
if original.width>=1500:
detail=target.with_name(target.stem+'-detail.png')
original.crop((int(original.width*.80),45,original.width,original.height-25)).save(detail)
return {'path':str(target.relative_to(BASE)),'detail':str(detail.relative_to(BASE)) if detail else None,
'source':str(src.relative_to(ROOT)),'case':case,'label':step['label'],'at':step['at'],'sha256':sha(target)}
samples={}
sample_names={module['sample'] for module in MODULES}|{'parity_animation.blend','texture.png','state.txt','rotation-axis_angle.blend','rotation-parent.blend'}
for name in sorted(sample_names):
candidates=[TEST/'fixtures'/name,ROOT/'tests/files/web'/name]
src=next((p for p in candidates if p.exists()),None)
if src is None:raise RuntimeError('Missing sample: '+name)
target=BASE/'samples'/name;shutil.copy2(src,target)
samples[name]={'source':str(src.relative_to(ROOT)),'sha256':sha(target),'bytes':target.stat().st_size}
for p in (BASE/'samples').glob('*.py'):samples[p.name]={'source':'Handbook example','sha256':sha(p),'bytes':p.stat().st_size}
(BASE/'samples/index.json').write_text(json.dumps(samples,ensure_ascii=False,indent=2))
css='''<style>@page{size:A4;margin:16mm 15mm 18mm}*{box-sizing:border-box}body{font:10.5pt "Noto Sans CJK SC",sans-serif;line-height:1.75;color:#26342f}h1{font-size:27pt;line-height:1.4}h2{font-size:19pt;line-height:1.5;margin:0 0 10px}h3{font-size:13pt;margin:18px 0 7px;break-after:avoid}h4{font-size:11pt;break-after:avoid}section{break-before:page}a{color:#166556;text-decoration:none}table{width:100%;border-collapse:collapse;font-size:8.5pt}th,td{border:1px solid #afc4bc;padding:6px;vertical-align:top;overflow-wrap:anywhere}th{background:#e9f1ee}tr,figure{break-inside:avoid}ul,ol{padding-left:23px}li{margin:7px 0}p{margin:9px 0}figure{margin:16px 0}figure img{display:block;max-width:100%;max-height:440px;object-fit:contain;border:1px solid #c8d1cc;margin:auto}figure.detail img{max-height:570px;max-width:75%}figcaption{font-size:8pt;color:#53635c;margin-top:5px;overflow-wrap:anywhere}.info{background:#edf3f0;border-left:3px solid #448575;padding:10px;margin:12px 0}.meta{font-size:9pt;color:#4c655a}.toc{columns:2;column-gap:24px}.toc p{break-inside:avoid;font-size:10pt}pre{font:8.5pt "Noto Sans Mono CJK SC",monospace;white-space:pre-wrap;overflow-wrap:anywhere;padding:10px;background:#f1f5f3}code{overflow-wrap:anywhere}footer{font-size:8pt}.no-break{break-inside:avoid}</style>'''
parts=['<!doctype html><html lang="zh-CN"><meta charset="utf-8"><title>WEB Blender 功能模块使用说明书</title>'+css+'<body>',
'<h1>WEB Blender<br>功能模块使用说明书</h1><p>桌面 Blender 对照版 · UM-20260916-R3</p><p>适用:本机 Blender 5.2.0 LTS 与本项目 Web 构件。中文版。</p>',
'<div class="info">这是一份日常使用与用户验证手册,按 36 个功能模块组织。它说明当前软件可用的操作路线,并明确区分已实测、入口已确认及仍待业务验证的内容。它不是桌面全功能一致性证书。</div>',
'<h3>开始使用</h3><ol><li>阅读 M01–M03,打开 samples/basic_scene.blend 并完成一次保存重开。</li><li>通过目录定位工作模块,按“逐步操作”执行。</li><li>用章末核对项验证结果;发生问题按 M36 记录和恢复。</li></ol>',
'<h3>本目录内容</h3><p>WEB_Blender_Function_User_Guide.pdf 为正式 PDF;说明书.html 可在浏览器阅读;screenshots/ 保存本轮原图与明确标记的裁剪图;samples/ 保存练习工程和脚本;verification-checklist.csv 用于后续验证记录;source/ 为可维护的说明书源文件。</p>',
'<h3>三个执行入口</h3><p>Web 编辑器负责当前已移植的浏览器操作;原生批处理用于真实渲染和一次性脚本;原生桌面面板承载真实 Blender 窗口与交互式工具。相同工作区名称并不自动意味着控件、上下文和快捷键全部相同。</p>',
'<section id="contents"><h2>使用目录</h2><div class="toc">'+''.join(f'<p><a href="#{m["id"]}">{m["id"]} {E(m["title"])}</a></p>' for m in MODULES)+'</div></section>',
'<section><h2>桌面与 Web 功能对照</h2><table><tr><th>模块</th><th>桌面对应</th><th>当前 Web 入口</th><th>证据范围</th></tr>'+''.join(f'<tr><td>{m["id"]} {E(m["title"])}</td><td>{E(m["desktop"])}</td><td>{E(m["entry"])}</td><td>{E(m["coverage"])}</td></tr>' for m in MODULES)+'</table></section>']
images=[];records=[];markdown=['# WEB Blender 功能模块使用说明书\n\nUM-20260916-R3\n']
for module in MODULES:
id=module['id'];image=picture(module)
for case in module['evidence']:
if results.get(case,{}).get('status')!='PASS':raise RuntimeError('Missing module evidence: '+id+' '+case)
parts.append(f'<section id="{id}"><h2>{id} {E(module["title"])}</h2><p class="meta">桌面对应:{E(module["desktop"])}<br>Web 入口:{E(module["entry"])}<br>练习文件:samples/{E(module["sample"])}<br>验证范围:{E(module["coverage"])}</p>')
markdown.append(f'\n## {id} {module["title"]}\n\n桌面对应:{module["desktop"]}\n\nWeb 入口:{module["entry"]}\n\n练习文件:samples/{module["sample"]}\n')
for title,steps in module['workflows']:
parts.append('<h3>'+E(title)+'</h3><ol>'+''.join('<li>'+E(s)+'</li>' for s in steps)+'</ol>')
markdown.append('\n### '+title+'\n\n'+'\n'.join(f'{i}. {s}' for i,s in enumerate(steps,1))+'\n')
parts.append('<h3>完成后的核对</h3><ul>'+''.join('<li>'+E(c)+'</li>' for c in module['checks'])+'</ul>')
if module['limits']:parts.append('<h3>与桌面的差异及使用范围</h3><ul>'+''.join('<li>'+E(c)+'</li>' for c in module['limits'])+'</ul>')
if image:
images.append({'module':id,**image})
parts.append(f'<figure><img src="{image["path"]}"><figcaption>本轮实拍:{image["case"]} / {E(image["label"])},{E(image["at"])}。PNG 原图位于 {image["path"]}。跨模块引用原生桌面入口图时,不代表本模块所有动作均已完成。</figcaption></figure>')
if image['detail']:parts.append(f'<figure class="detail"><img src="{image["detail"]}"><figcaption>同一操作截图的右侧属性区域裁剪,未修改界面内容。</figcaption></figure>')
parts.append('<p class="meta">核对记录:日期 ______ 软件版本 ______ 结果 ______ 问题编号 ______<br>关联证据:'+E(', '.join(module['evidence']) or '见自动化测试集合;业务用例待补充')+'</p></section>')
markdown.append('\n核对:\n'+'\n'.join('- '+c for c in module['checks'])+'\n\n边界:\n'+'\n'.join('- '+c for c in module['limits'])+'\n')
for i,check in enumerate(module['checks'],1):records.append([id,module['title'],f'{id}-V{i:02d}',check,module['sample'],'NOT_RUN','','','',''])
parts.append('<section><h2>附录 A:可直接使用的脚本</h2><p>samples/01–04 为练习脚本。先打开所需样例,再通过 Scripting 的 Open .py 加载。四元数和轴角脚本使用 parity_scene.blend;资源脚本使用 resource_scene.blend,并先同步 texture.png 与 state.txt。</p>')
for file in sorted((BASE/'samples').glob('*.py')):parts.append('<h3>'+E(file.name)+'</h3><pre>'+E(file.read_text())+'</pre>')
parts.append('</section><section><h2>附录 B:用户验证方法</h2><ol><li>使用未修改的练习输入,记录软件版本、浏览器、日期和模块编号。</li><li>按章内顺序操作,保存关键步骤 PNG、输出文件和诊断。</li><li>核对实际值、撤销/重做和保存重开结果;必要时用桌面 Blender 独立打开文件。</li><li>填写 verification-checklist.csv。PASS 表示该项满足判据;FAIL 表示不满足;BLOCKED 表示缺前提;NOT_RUN 表示未执行。</li><li>修改软件版本后重新验证关键业务,不直接沿用旧版本通过记录。</li></ol><p>测试次数和通过数量不等于桌面全功能覆盖。使用说明书后续应随着功能变化更新;截图和样例哈希见 evidence-index.json 与 delivery-manifest.json。</p></section>')
parts.append('<section><h2>附录 C:版本、来源与仍有差异的功能</h2><p>用户可从本轮测试目录查看完整 244 文件集合、32 个原生对照及实际用户流程。本说明书只引用当前测试目录中有完成记录的截图。部分章节提供的是已确认原生入口的操作路线,章节中另行说明其未覆盖业务。</p><p>源码依据包括本机 Blender _console_python.py 的交互控制台、blenkernel/object.cc 的 BKE_object_to_mat4、makesrna/rna_object.cc 的旋转属性,以及 bpath.cc / packedFile.cc 的资源路径和打包语义。</p><p>仍有差异:批处理脚本异常回写策略、完整桌面 UI/上下文同步、Web 紧凑编辑器的完整工具集、任意插件、复杂链接资源与模拟缓存、全部设备输入和所有渲染组合。具体工程必须另行验证,不能将本手册作为无例外等价声明。</p></section></body></html>')
(BASE/'说明书.html').write_text(''.join(parts));(BASE/'source/manual-source.md').write_text('\n'.join(markdown))
(BASE/'source/modules.json').write_text(json.dumps(MODULES,ensure_ascii=False,indent=2))
(BASE/'evidence-index.json').write_text(json.dumps({'createdAt':datetime.now(timezone.utc).isoformat(),'testDirectory':str(TEST.relative_to(ROOT)),'images':images,'samples':samples},ensure_ascii=False,indent=2))
with (BASE/'verification-checklist.csv').open('w',encoding='utf-8-sig',newline='') as f:
writer=csv.writer(f);writer.writerow(['模块','功能','验证项','判据','样例','结果','软件版本','日期','实际结果','问题编号']);writer.writerows(records)
with (BASE/'function-map.csv').open('w',encoding='utf-8-sig',newline='') as f:
writer=csv.writer(f);writer.writerow(['模块','功能','桌面对应','Web 入口','范围','证据'])
writer.writerows([[m['id'],m['title'],m['desktop'],m['entry'],m['coverage'],','.join(m['evidence'])] for m in MODULES])
(BASE/'README.md').write_text('''# WEB Blender 功能模块使用说明书
- [正式 PDF](WEB_Blender_Function_User_Guide.pdf)
- [浏览器阅读版](说明书.html)
- [桌面与 Web 功能对照表](function-map.csv)
- [用户验证记录表](verification-checklist.csv)
- `samples/`:练习工程、资源和脚本。
- `screenshots/`:本轮操作截图及明确标记的局部裁剪。
- `source/`:可维护的模块内容、Markdown 和生成脚本。
按 M01–M03 开始,再通过目录进入具体功能。核对每章的验证范围与差异说明。
用户验证表初始为 NOT_RUN,避免把作者测试结果冒充用户自己的验收。
当前应用地址:http://127.0.0.1:5205/ 。
此说明书不宣称桌面全功能无差异。
''')
print(json.dumps({'modules':len(MODULES),'steps':sum(len(s) for m in MODULES for _,s in m['workflows']),'verificationItems':len(records),'contextScreenshots':len(images),'samples':len(samples)},ensure_ascii=False))

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,215 @@
"""Chinese, workflow-oriented handbook content; evidence links are resolved by the builder."""
MODULES=[]
def M(number,title,desktop,entry,sample,evidence,workflows,checks,limits=(),image=None,coverage='本轮用户流程或原生对照实测'):
MODULES.append(dict(id=f'M{number:02d}',title=title,desktop=desktop,entry=entry,sample=sample,evidence=evidence,
workflows=workflows,checks=checks,limits=list(limits),image=image,coverage=coverage))
M(1,'运行环境与样例准备','启动 Blender、打开工程','Chrome 浏览器;本机 Web 与原生 Blender 服务','basic_scene.blend',['UJ-01'],[
('首次进入',['打开 http://127.0.0.1:5205/,等待底部 Engine 显示 ready。','使用本说明书 samples/ 中的练习文件副本;不要直接覆盖唯一的生产工程。','确认页面具有顶部工作区、Outliner、3D Viewport、Properties 和底部状态栏。','点击顶部“打开 .blend”图标,选择 basic_scene.blend;等待 SceneIR 状态和三个对象出现。']),
('服务与数据准备',['需要重新启动本轮服务时,在项目根目录运行:node user-testing/WEB_Blender_Parity_Round3_20260916/scripts/serve.mjs。','WASM 浏览器编辑和原生桌面/渲染服务是不同执行入口。要使用 Cycles、原生 Python 或原生桌面,必须保留本机服务运行。','外部纹理、字体、视频或缓存按 M13 的资源同步流程提供;仅有 .blend 不保证包含所有文件。'])],
['页面可打开样例;Outliner 出现 BasicCube、BasicCamera 和 BasicArea。','原生功能前先确认服务可用,普通页面显示不等于原生服务已就绪。'],
['本轮验证范围为本机 Chromium;其他浏览器、远程部署与全部平台差异不在本手册的通过声明内。','不要用 file:// 双击应用 index.html 启动软件。'],('UJ-01','opened'))
M(2,'界面、工作区与对象选择','Workspaces、Outliner、Properties','顶部工作区标签;右侧 Outliner','basic_scene.blend',['UJ-02','UJ-20'],[
('定位编辑对象',['打开样例,在 Outliner 单击 BasicCube。','确认高亮行和 Properties 名称都是 BasicCube,避免修改相机或灯光。','通过顶部 Layout、Modeling、UV Editing、Shading、Animation、Rendering、Scripting 等标签切换任务区域。','需要下方属性时滚动 Properties 内部区域;不要把滚动页面和滚动属性面板混淆。']),
('查找命令',['点击顶部 F3 / 操作搜索按钮;搜索命令名称。','阅读搜索结果中的执行路线和参数表单,选择确实适合当前对象类型、模式和编辑器的操作。','按 Escape 或关闭按钮退出搜索,确认焦点回到原界面。'])],
['切换工作区后项目对象仍在;选中对象与属性名称一致。','搜索关闭后可以继续选择和编辑。'],
['工作区名称相同不代表全部桌面编辑器控件已经移植。遇到缺失的编辑器操作,使用 M29 的原生桌面入口。'],('UJ-20','keyboard-search-closed'))
M(3,'打开、保存、恢复、撤销与重做','File Open/Save、Undo/Redo','顶部打开/保存/恢复图标,Recent 列表','basic_scene.blend',['UJ-01','UJ-19'],[
('打开与保存',['打开 .blend 后等待读取进度结束,确认对象数量。','执行一次明确的编辑,例如添加立方体;观察“未保存”状态。','点击“保存项目”,确认浏览器下载完成并记住下载目录。','需要长期保留时保留下载的 .blend,以及尚未打包的配套外部资源。','重新选择刚下载的文件,检查新增对象和属性仍存在。']),
('撤销与恢复',['点击“撤销”观察上一项编辑消失;点击“重做”确认恢复。','页面刷新后从 Recent 选择保存过的项目,或点击“恢复项目”。','确认恢复后的对象与保存修订一致;浏览器站点数据被清除时,应改用下载的 .blend。','打开损坏文件若失败,保留当前场景,使用诊断导出记录错误,再打开正确文件。'])],
['新增对象经保存、重新打开仍存在。','撤销和重做各一次后结果可预测,恢复不丢失已经提交的修改。'],
['下载文件和浏览器本地存储是两种不同的保留方式。更换端口、浏览器配置或清除站点数据会影响本地恢复。'],('UJ-01','reopened'))
M(4,'位置、缩放与全部旋转模式','Object Transform:Euler / Quaternion / Axis Angle','Properties > Transform;原生桌面;Python Console','rotation-quaternion.blend',['UT-266','UT-270','UT-271','UT-272','UT-273','UT-274'],[
('查看真实变换',['打开 rotation-quaternion.blend 并选中 ParityCube。','在 Transform 查看位置和缩放;四元数模式下逐项查看 W、X、Y、Z。','打开 rotation-axis_angle.blend,查看 Angle 与 Axis X/Y/Z;Angle 显示角度,Python 属性中存放弧度。','不要用四元数分量代替 Euler 角。样例中原始四元数可以不是单位长度,Blender 在构造旋转矩阵时归一化。']),
('按桌面方式精确编辑',['需要数值变换时,打开 M29 的原生桌面,选择目标对象。','把指针置于原生 3D 视图,按 G、X、1、Enter,沿 X 轴移动 1 个单位。','旋转使用 R 和轴限制,缩放使用 S;确认后点击 Apply to Web Scene。','返回 Web 的 Transform 核对数值,再保存项目。','有父级或增量变换时区分通道数值与最终世界位置;不要仅凭位置输入值推断视口中的世界位置。'])],
['UT-270–274 的矩阵参考可用于比较四元数、轴角、六种 Euler 顺序、增量与普通对象父级。','变换后撤销、重做、保存重开仍显示正确值。'],
['紧凑 Transform 面板主要提供读数。完整旋转模式编辑请用原生桌面或明确的 bpy 属性命令。','Web 快捷键和工具不保证逐键等同桌面模态工具;精确 G/R/S 工作流优先在原生桌面内完成。','骨骼父级、约束驱动和全部复杂求值组合尚未逐项覆盖。'],('UT-270','quaternion-readout'))
M(5,'对象创建、复制、重命名与删除','Add Object、Duplicate、Rename、Delete','Modeling 工具栏;Properties > Object & Hierarchy','basic_scene.blend',['UJ-01','UJ-02'],[
('创建与命名',['打开样例,点击“添加立方体”,核对对象数由 3 变为 4。','在 Outliner 选择新对象;在“对象名称”字段输入可识别名称。','点击“重命名”,等待 Outliner 与属性名称同步。']),
('复制与清理',['选择 BasicCube,点击“复制对象”。','确认复制品有独立的对象条目,再重命名以便区分。','仅选择要清理的复制品,点击“删除对象”。','撤销确认该对象可恢复;重做再次删除,最后保存并重开。'])],
['对象数的增减与操作一致;保存后的名称正确。','删除前确认活动对象,避免误删相机或灯光。'],
['Linked Duplicate 共享数据与普通复制的语义不同,使用前应确认是否需要共享网格;本章主要实测普通复制。'],('UJ-02','rename'))
M(6,'集合、父子关系、原点与应用变换','Collections、Parenting、Origin、Apply Transform','Modeling 工具栏;Object & Hierarchy;原生桌面','rotation-parent.blend',['UT-274'],[
('整理层级',['在 Modeling 点击 New Collection 建立集合。','选中对象,在 Object & Hierarchy 的 Collection 下拉框选择目标集合。','建立父子关系前明确活动对象和另一个选中对象,确认当前工具栏 Parent 所用的父子顺序;不确定时进入原生桌面按桌面方式设置。','使用 Unparent 后核对对象世界位置;复杂层级先保存副本。']),
('原点和变换',['选择单个对象,记录位置、旋转和缩放。','按需求使用“应用变换”或“原点到几何体”;这是改变对象数据或变换关系,不只是切换显示。','核对视口、对象通道及保存后的结果,再决定是否继续后续建模。'])],
['rotation-parent.blend 的局部/世界矩阵与桌面参考一致。','实际业务工程要分别验证集合成员、父子名称和世界位置。'],
['本轮专门覆盖普通对象父级逆矩阵读取;本章其余层级操作来自现有入口,不能推断所有约束、骨骼父级都完全一致。'],('UT-274','parent-readout'),'部分入口确认;普通对象父级矩阵实测')
M(7,'网格编辑、选择与拓扑操作','Edit Mode、Vertex/Edge/Face、Triangulate','Modeling;模式按钮;网格工具栏','mesh_editor_scene.blend',['UJ-03'],[
('编辑网格',['打开样例并选中 BasicCube。','点击 Object Mode 切换到编辑模式,选择 3 Face 面选择。','点击 Select All,确认有面被选中。','点击 TRIANGULATE,观察面结构与统计值变化。','需要其他拓扑操作时保持正确选择域;操作按钮不可用时先检查对象类型和选择。']),
('确认与回退',['撤销一次,检查拓扑恢复;重做恢复三角化。','保存项目并重开,重新选择对象检查面数量。','复杂挤出、倒角或依赖视口鼠标位置的工具,可在原生桌面用 Edit Mode 的标准模态操作完成,再回写。'])],
['选择域、选中数量和执行对象对应。','拓扑变化经过撤销、保存和重开仍可确认。'],
['不要把桌面所有网格工具都视为已在 Web 工具栏实现。工具缺失或上下文要求不满足时,应切换真实原生桌面。'],('UJ-03','triangulated'))
M(8,'UV 投影与 UV 工作流','UV Editor、UV Projection / Unwrap','Properties > UV Projection;UV Editing 工作区','mesh_editor_scene.blend',['UJ-03'],[
('立方体投影',['完成网格面选择,保留至少一个选中的面。','滚动到 UV Projection 区域,在 UV projection method 选择 CUBE。','点击 Project UV,等待场景修订更新。','切换 UV Editing 检查当前 UV 相关状态;需要逐点 UV 编辑时进入原生桌面的 UV Editor。','保存 .blend,并在桌面 UV Editor 中核对 UV 层和投影结果。'])],
['投影作用于选中的正确网格和面。','保存重开后 UV 数据仍存在;需要逐点对照时用桌面 UV Editor 检查。'],
['当前 Web UV 工作流是有限操作集,不等于桌面 UV Editor 所有选取、拼接、松弛和排布工具。'],('UJ-03','uv-projected'))
M(9,'修改器参数与堆栈','Modifier Properties、Stack Ordering','Properties 中的 Modifier Stack','modifier_stack_scene.blend',['UJ-04'],[
('修改已有参数',['选择 StackTarget,在堆栈中找到 Stack Bevel。','在 width 输入 0.35,并按 Enter 提交。','等待字段保持为 0.35,核对视口或状态变化。']),
('新增与管理',['在 Modifier type 输入 SOLIDIFY,点击对应 Add 按钮。','确认新修改器出现在目标对象的堆栈内。','调整可用的顺序和启用状态时,每次观察最终效果;不同顺序可能得到不同结果。','撤销和重做,再保存重开确认堆栈与参数。'])],
['参数值和修改器顺序保存后仍正确。','找不到修改器或参数时,不应以相近名称或预览效果替代桌面功能。'],
['存在修改器数据读写支持,不代表所有修改器的完整交互参数和求值组合都已覆盖。'],('UJ-04','solidify-added'))
M(10,'曲线、曲面与非网格对象','Curve / Surface / Metaball / Lattice','对应对象的 Properties;原生桌面','nonmesh_scene.blend',['UJ-05'],[
('曲线闭合',['打开 nonmesh_scene.blend 并选择 WebCurveObject。','找到 Curve cyclic U,记录原值后切换复选框。','观察曲线闭合状态,撤销和重做各一次。','保存重开,重新选择 WebCurveObject 确认 cyclic U 保留。']),
('其他非网格对象',['先在 Outliner 确认对象确为曲面、代谢球或晶格,避免把网格工具用于非网格数据。','使用界面已显示的该类型属性;如需桌面编辑模式完整控制点工具,进入原生桌面。','提交前确认活动对象与模式,完成后 Apply to Web Scene 并保存。'])],
['曲线闭合属性经保存重开保留。','复杂非网格编辑应核对控制点数、类型及最终形状。'],
['本章直接实测曲线闭合;曲面、代谢球和晶格所有编辑动作尚未逐项做用户验收。'],('UJ-05','cyclic-toggled'))
M(11,'文本对象与字体','Text Object、Font Properties','文本对象的 Font body / Apply Text','nonmesh_scene.blend',['UJ-06'],[
('修改正文',['打开样例并选中 WebFontObject。','在 Font body 中输入 WEB Blender User Test,点击 Apply Text。','观察文字对象或状态更新;仅修改输入框但未提交不能视为已保存。','保存并重新打开项目,在桌面检查文本数据 body 一致。']),
('使用外部字体',['准备具有合法使用权的字体文件,并使用已有字体导入入口或原生桌面的 Font 属性加载。','外部字体需要与工程一起打包或作为资源同步;不要仅记录本机绝对路径。','保存后在另一环境打开,检查字形是否仍正确。'])],
['正文保持为输入内容,桌面读回一致。','外部字体工程需额外检查字体资源是否可用。'],
['本轮用户流程验证正文持久化;所有字族、排版、国际文字与字体授权流程未逐项覆盖。'],('UJ-06','text-applied'))
M(12,'材质与基础着色','Material Properties、Principled BSDF','材质属性面板;Shading','attribute_scene.blend',['UJ-07'],[
('调整粗糙度',['打开 attribute_scene.blend 并选择 AttributeMeshObject。','找到“材质粗糙度”,输入 0.42。','点击“应用 Principled”,等待提交完成。','保存并重新打开,核对粗糙度字段仍为 0.42。']),
('判断外观',['Web 视口用于编辑预览;确认最终外观时使用 Rendering 的原生渲染。','节点类型、纹理连接、透明或复杂着色不明确时,使用原生桌面 Shader Editor 核对。','将修改前后的同参数最终渲染图作为视觉比较依据。'])],
['数据参数经保存重开不变。','最终外观比较必须固定引擎、灯光、相机和色彩管理。'],
['Three.js 预览不能当作完整 Cycles/Eevee 材质一致性的证明。'],('UJ-07','principled-applied'))
M(13,'外部纹理、文件同步与项目资源','External Data、Pack Resources、Relative Paths','Scripting 或 Rendering 的 Resource files / Project folder','resource_scene.blend',['UT-254','UT-258','UT-259','UT-260','UT-261','UT-265'],[
('同步练习资源',['打开 resource_scene.blend,切换 Scripting。','在 Resource files 同时选择 texture.png 和 state.txt。','按文件名确认列表顺序,Project path 分别填写 textures/texture.png 和 textures/state.txt。','若 .blend 中使用其他原始绝对路径,在 Original Blender path 填入那个精确路径,不能只填文件名。','点击 Sync Resources,等待 2 files synchronized。','在 Text Editor 执行:import bpy;print(list(bpy.data.images["ExternalParityImage"].size))。应成功得到 [8, 8]。']),
('刷新、清理和交付',['刷新页面并重新打开同一项目,不重新上传,检查资源仍可供原生命令使用。','服务重启或临时令牌过期时会尝试从同一浏览器的保存副本恢复。','要移除本项目保存的资源副本,点击 Clear Resources;这不会删除已嵌入 .blend 的贴图。','原生结果若提供 resources.zip,请与下载的 .blend 一起保存;视频、序列和部分缓存不能靠普通打包完全嵌入。'])],
['外部纹理尺寸和路径正确;同一项目刷新后仍可读取。','交付到其他设备时,同时检查 .blend 与外部文件的相对位置。'],
['资源保存受浏览器 origin、配置、配额和清理操作影响;不等于桌面无限文件系统。','当前项目 ID 沿用规范化文件名,同名文件视为同一项目;不同工程应命名区分或先清除资源。','256 MiB / 4096 文件上限仍存在;复杂 UDIM、链接库与模拟缓存组合未全覆盖。'],('UT-258','resource-bytes-persisted'))
M(14,'灯光、世界与色彩管理','Light、World、Color Management','Outliner 选择灯光;Scene Render 属性','basic_scene.blend',['UJ-10','UJ-11'],[
('灯光能量',['选中 BasicArea,确认属性显示灯光对象。','点击 Light 面板的“增加能量”,等待读数变化。','使用原生渲染判断照明变化,不只依赖视口材质预览。']),
('场景色彩',['选择场景相关属性,找到 Scene Render。','点击“增加 Gamma”,确认 Gamma 变为 1.10;需要时调整曝光或 View Transform。','保存重开,核对色彩管理参数。','世界背景或复杂环境节点需要完整编辑时,在原生桌面 World / Shader Editor 设置后回写。'])],
['相同相机与引擎下比较灯光和色彩变化。','保存后 Gamma 等参数不回到原值。'],
['世界节点、所有灯光子类型及全部颜色管理选项不因本章样例通过而自动视为完全一致。'],('UJ-11','gamma-increased'))
M(15,'相机与构图','Camera Properties、Active Camera','Camera 属性;原生桌面 Camera View','basic_scene.blend',['UJ-10'],[
('编辑焦距',['在 Outliner 选中 BasicCamera。','找到 Camera 面板,点击“增加焦距”,检查焦距读数由 50 增到 55。','切换到灯光编辑后再选回相机,确认没有误把活动对象改成其他对象。','保存并用桌面打开文件,核对相机焦距。']),
('确认实际渲染相机',['使用 parity_scene.blend 练习渲染,它包含已配置的相机。','若业务工程有多个相机,在原生桌面设置活动相机并核对相机视图。','执行 Render Frame 确认最终构图;编辑视口的观察角度不等于渲染相机。'])],
['相机焦距保存后为预期值;灯光编辑不会覆盖相机属性。','渲染构图与活动相机一致。'],[],('UJ-10','lens-increased'))
M(16,'时间轴、关键帧与标记','Timeline、Insert Keyframe、Markers','底部时间轴与动画属性','animation_scene.blend',['UJ-12'],[
('插入位置关键帧',['打开 animation_scene.blend,选择 AnimatedObject。','在“当前帧”输入 3,移开焦点提交。','点击“插入位置关键帧”,等待场景修订更新。','切换到其他帧观察动画数据;不要只凭对象仍在同一位置判断是否插帧成功。']),
('添加标记',['在 Marker name 输入 User Marker,点击 Add Marker。','核对标记名称和对应帧。','撤销、重做,再保存重开;标记名称应保留。'])],
['关键帧写入正确对象和通道。','保存重开后标记仍为 User Marker。'],
['完整曲线编辑、驱动器和 NLA 的交互工作流见 M17;并非所有桌面动画控件都在紧凑时间轴内。'],('UJ-12','marker-added'))
M(17,'曲线编辑器、驱动器与 NLA','Dope Sheet、Graph Editor、Drivers、NLA','Animation 工作区的现有入口;原生桌面','animation_scene.blend',['UJ-12'],[
('使用完整桌面动画编辑器',['先保存工程,按 M29 连接原生桌面。','在原生窗口切换 Animation 工作区,或通过编辑器类型选择 Graph Editor / Dope Sheet / NLA Editor。','选中目标对象,再选动画通道或 Action;核对帧范围与活动 Action。','按业务需要移动关键帧、调整插值或条带;完成后退出正在运行的模态工具。','点击 Apply to Web Scene,回到 Web 检查帧范围,保存并在桌面读回。'])],
['验证时记录对象、Action、通道、帧、插值和条带范围,不只记录视口外观。'],
['本章提供真实原生桌面的操作路线。所有驱动器表达式、NLA 混合组合和 Web 编辑器交互未逐项验收。'],('UJ-12','frame-three'),'基础关键帧实测;完整编辑器路线待业务逐项验收')
M(18,'骨架、姿态与约束','Armature Edit / Pose、Bone Roll、Constraints','骨架属性工作台;原生桌面','pose_constraint_scene.blend',['UJ-13'],[
('编辑骨骼属性',['打开样例,选择 PoseConstraintArmatureObject。','在 Active armature bone 选择 Auxiliary。','点击 Rotate Bone Roll,再点击 Enable X Mirror。','观察当前骨骼属性,撤销和重做后保存。']),
('复杂姿态操作',['需要完整姿态工具或约束参数时,连接原生桌面,确认选中骨架并进入 Pose Mode。','选中具体骨骼后调整变换或约束;不要在网格对象上寻找骨骼属性。','退出工具后回写 Web 场景,保存 .blend;桌面核对骨骼名称、姿态和约束目标。'])],
['滚转和镜像状态保存后保持。','约束验证应记录目标、影响值、空间和结果。'],
['骨骼父级、全部约束求值和完整权重变形组合没有由本章一次操作证明一致。'],('UJ-13','roll-changed'))
M(19,'雕刻属性与面组','Sculpt Mode、Mask、Face Sets','Properties > Sculpt;原生桌面 Sculpt Mode','basic_scene.blend',['UJ-08'],[
('设置遮罩与面组',['打开样例,选择 BasicCube,滚动到 Sculpt 区域。','在 Sculpt active face set 填入 2,根据需要调整 Sculpt mask。','点击 Apply Sculpt Attributes,等待场景提交。','撤销、重做,再保存重开。']),
('完整笔刷操作',['实际雕刻笔刷工作请在原生桌面进入 Sculpt Mode,确认活动网格、笔刷和遮罩。','完成一段笔划后退出工具,Apply to Web Scene,再保存。','记录笔刷、强度、半径、对称轴和模型密度,便于业务复测。'])],
['面组和遮罩属性保留,且作用于正确网格。'],
['属性写入通过不等于所有桌面笔刷、动态拓扑和多分辨率工作流已移植到 Web 编辑器。'],('UJ-08','sculpt-attributes'))
M(20,'顶点颜色、权重与绘制属性','Color Attributes、Vertex Groups、Weight Paint','Edit Mode 顶点选择;Properties > Paint','mesh_editor_scene.blend',['UJ-21'],[
('设置顶点颜色',['选择 BasicCube,进入 Edit Mode,点击 1 Vertex,再点击 Select All。','在 Paint 的 Vertex color 选择目标颜色。','点击 Apply Color,确认出现 WebPaintColor POINT。','属性颜色需要对应材质节点消费才会影响最终着色;不要把属性存在等同于材质已连接。']),
('设置顶点组权重',['在 Vertex group 输入 GuideWeights,调整 Weight。','需要保持单独数值时取消 Normalize weights;需要规范化时启用它并理解各组权重会重新分配。','点击 Apply Weight,确认 GuideWeights 组存在。','保存并重新打开,检查颜色属性和顶点组仍存在。'])],
['没有选中顶点时按钮不应执行写入。','保存后 WebPaintColor 和 GuideWeights 保留。'],
['Texture Paint 的完整图像笔刷、UV 贴图绘制与所有权重笔刷仍应通过原生桌面并另行业务验证。'],('UJ-21','vertex-weight-applied'))
M(21,'Grease Pencil 图层与绘图数据','Grease Pencil Layers、Frames、Drawings','Grease Pencil 对象属性与编辑入口','modifier_grease_pencil_scene.blend',['UJ-17'],[
('新增图层',['打开样例,选择 GreasePencilObject。','在 Grease Pencil new layer name 输入 User Layer。','点击 Add Layer,确认图层条目出现。','撤销、重做并保存,重新打开后检查图层名称。']),
('绘制与逐帧检查',['进行实际笔划、帧和选区操作前确认当前图层及帧。','完整桌面绘图工具可在原生桌面中使用;结束工具后回写并保存。','验证时记录图层、帧和笔划数量,区分选择变化与数据变化。'])],
['User Layer 保存后存在于正确的 Grease Pencil 数据中。'],
['新增图层不代表所有二维画布、笔刷、修改器与逐帧动画组合已完全对齐。'],('UJ-17','layer-added'))
M(22,'几何节点与节点图','Geometry Nodes Editor','Properties > Geometry Graph;Geometry Nodes 工作区','basic_scene.blend',['UJ-16'],[
('创建节点图',['选择 BasicCube,滚动到 Geometry Graph / geometry node authoring 区域。','点击创建 Geometry 图的按钮,确认存在 Group Input、Group Output。','使用当前节点类型列表和输入/输出选择器建立所需连接。','点击“提交 Geometry 图”,等待提交成功后保存。']),
('验证节点结果',['先检查节点名称、插槽类型与链接方向,再观察几何结果。','复杂节点或界面未提供的插槽,使用原生桌面的 Geometry Nodes Editor。','保存重开,并在桌面确认节点图和对象修改器的关联。'])],
['节点图可以创建、保存和重新读取。','业务验证应记录节点类型、默认值、链接和求值结果。'],
['有限节点图通过不代表桌面全部节点、字段语义和模拟区域完整可用。'],('UJ-16','graph-visible'))
M(23,'合成器、遮罩与跟踪','Compositor、Mask Editor、Movie Clip Tracking','对应工作区;完整操作使用原生桌面','parity_scene.blend',['UT-252'],[
('合成与遮罩路线',['保存工程后连接原生桌面。','在原生窗口选择 Compositing,开启节点并确认 Render Layers 到 Composite 的连接。','按业务需要添加节点、编辑参数和链接,再执行真实渲染检查输出。','需要 Mask 或 Movie Clip Editor 时切换原生编辑器类型,先加载或同步实际素材。','完成后 Apply to Web Scene,保存 .blend 与相关素材。'])],
['以最终输出图像和节点/遮罩/跟踪数据共同验收,不能只看工作区标签。'],
['原生会话入口经过验证,但本轮没有逐项完成复杂合成、跟踪解算或遮罩编辑的人机验收。','React 工作区中的有限控件不等于完整桌面编辑器;本章是明确的原生操作路线。'],('UT-252','native-desktop'),'原生入口实测;本模块具体业务未全覆盖')
M(24,'视频序列与条带编辑','Video Sequencer、Strip Properties','Sequencer Strip Editing 工作区','sequencer_scene.blend',['UJ-14'],[
('移动与静音',['打开 sequencer_scene.blend,在 Sequencer strip 选择 WebImage · IMAGE。','记录 Start 原值,点击 Move +1,应变为 13。','勾选 Muted,确认条带静音状态。','撤销、重做、保存并重开,核对条带名称、起止范围及静音值。']),
('使用外部视频和声音',['按 M13 同步媒体文件,保持目录和文件名。','检查浏览器预览与原生渲染的解码能力;浏览器不能预览某格式不等于 Blender 不能读取。','输出成片使用 M26 的 MP4 或帧序列路线,并实际播放下载产物。'])],
['条带范围与静音状态保存后正确。','外部媒体需随工程交付;缺失媒体不能作为正常空画面验收。'],
['全部特效、转场、代理、声音混合及长片工程组合尚未覆盖。'],('UJ-14','mute-strip'))
M(25,'真实图像渲染与 OpenEXR','Render Image、Cycles / Eevee / Workbench','Rendering > Render Frame','parity_scene.blend',['UT-245','UT-256'],[
('输出 PNG',['打开 parity_scene.blend,切换 Rendering。','在 Engine 选择 CYCLES,在 Format 选择 PNG。','检查场景与帧;练习样例已配置相机、灯光和 96×96 输出。','点击 Render Frame,等待 SUCCEEDED。','检查图像不是空白,点击 frame-*.png 下载并保存。']),
('输出 OpenEXR',['将 Format 改为 OPEN_EXR / OpenEXR,再执行 Render Frame。','下载 frame-*.exr;浏览器没有 EXR 预览不代表文件无效。','用桌面 Blender Image Editor 打开下载文件,检查尺寸和通道。','比较渲染时固定 .blend、引擎、采样、分辨率、色彩管理和帧。'])],
['练习 PNG 与同构件桌面 Cycles 独立渲染平均像素误差为 0;该结论只针对所测样例。','EXR 可在桌面读取,样例为 96×96、4 通道。'],
['完整 Eevee、GPU/CUDA 与所有生产场景尚未由该小样例验证。','原生服务停止或渲染失败时不能把旧预览当作新产物。'],('UT-245','image-preview'))
M(26,'动画帧序列、MP4 与取消','Render Animation、Image Sequence、FFmpeg Output','Rendering > Start / End / Step / Render Animation','parity_animation.blend',['UT-246','UT-247','UT-257'],[
('输出两帧动画',['打开 parity_animation.blend,选择 CYCLES。','设置 Start=1、End=2、Step=1,Format=PNG。','点击 Render Animation,等待两张帧图与 animation-frames.zip。','下载 ZIP 并逐帧检查,立方体位置应变化。']),
('输出 MP4',['Format 改为 MP4 / H.264,保持帧范围,点击 Render Animation。','下载 animation*.mp4 并播放;本练习应为 2 帧、24 fps。','需要停止时点击 Cancel,等待按钮恢复可用;不要保存取消后迟到或旧的结果链接。'])],
['帧数、范围、时间变化与业务需求一致。','取消后不发布新产物,当前场景保持可编辑。'],
['长片、全部编码器、音视频混合、全部帧率与大分辨率组合仍需业务专项验证。'],('UT-247','render-result'))
M(27,'持久 Python 控制台','Python Console、InteractiveConsole','Scripting > Python Console','parity_scene.blend',['UT-249','UT-250','UT-267','UT-268','UT-269'],[
('连接并连续执行',['切换 Scripting,在 Python Console 点击 Connect,等待 READY。','输入 counter = 40,点击 Execute。多行编辑时使用 Shift+Enter 换行。','下一次执行 counter += 2,然后 print(counter),应输出 42。','可使用 bpy、C、D、Vector、sin、pi 等桌面控制台常用默认名称;表达式结果可通过 _ 读取。']),
('理解异常与继续操作',['运行时若出现普通 Python 异常,界面显示 PYTHON_ERROR,但会话保持 READY,可以继续执行。','异常前已完成的 bpy 修改会保留并回写;局部变量和对象引用也保留。异常不是自动回滚。','语法错误不会执行该段代码;修正语法后直接 Execute。','SystemExit 和 KeyboardInterrupt 会显示错误并允许继续输入;不要把它们当作关闭服务的方法。']),
('会话与 Web 编辑的关系',['在 Web 侧另做修改、撤销或重做后,旧原生会话可能过期。点击 Reset Session 以当前场景重新连接。','出现 SOURCE_CHANGED / RESET_REQUIRED 时,保存当前 Web 场景并重新 Connect,不能强行提交旧会话。','用完点击 Disconnect / Stop,释放原生会话资源。'])],
['counter 跨命令保留;普通异常后可以继续访问同一个对象引用。','场景外部修改时旧会话不会覆盖最新 Web 场景。'],
['原生进程退出、传输失败、输出超限或结果保存失败仍会重置会话,见 M36。','刷新页面或 Reset Session 不是保留 Python 局部变量的操作。'],('UT-250','continued-with-same-object-reference'))
M(28,'文本脚本与批处理','Text Editor、Run Script','Scripting > Text Editor','parity_scene.blend',['UT-248'],[
('运行脚本',['在 Python script source 输入:import bpy;bpy.data.objects["ParityCube"].location.x = 2;print("SCRIPT_OK"),每句独立成行。','确认 Name 为要使用的脚本名,点击 Run Script。','等待 SCRIPT_OK 与 SUCCEEDED,检查目标对象位置。','保存 .blend,再用撤销和重做确认这次提交可以回退。']),
('脚本文件与错误',['可在 Open .py 选择脚本文件,检查内容后执行。','Run Script 为一次性批处理;需要跨命令变量时使用 M27 的持久控制台。','批处理失败时查看输出与诊断,修正后重新运行;不要假设失败前的修改已写回 Web。'])],
['成功执行后对象 X=2,保存后桌面读回正确。','运行前明确所用对象名称与上下文。'],
['批处理采用成功后回写策略;其异常语义仍不同于桌面 Text Editor 中已经修改当前场景的行为。','只在受信任的本机环境运行需要的脚本。文件写入和外部访问受原生任务隔离边界约束。'],('UT-248','python-result'))
M(29,'真实原生桌面与交互式工具','Desktop Blender Editors、Modal Operators','F3 > Open Native Desktop Session','parity_scene.blend',['UT-252','UT-253'],[
('连接真实桌面',['打开工程,在 Web Outliner 选择要编辑的对象。','点击 F3 / 操作搜索,搜索 Open Native Desktop Session 并执行。','在 Native Blender Desktop 对话框点击 Connect,等待 READY 和真实 Blender 画面。','在原生画面中确认活动对象;鼠标指针所在编辑器决定多数桌面快捷键的上下文。']),
('模态编辑与回写',['在原生 3D Viewport 选中 ParityCube,按 G、X、1、Enter。','取消工具可按 Escape 或点击 Cancel Tool;未完成工具时不要提交。','点击 Apply to Web Scene,等待 READY。','关闭原生对话框,在 Web 核对 Transform,再点击保存项目下载 .blend。','结束后 Disconnect / Stop;浏览器中的保存文件才是交付文件,不依赖临时原生工作目录。'])],
['确认移动后 X=1;取消移动后 X 保持原值。','每次提交都作用于开始会话时的同一项目修订。'],
['这是原生 Blender 交互面板,尚未把全部桌面布局和导航状态同步为 React 编辑器状态。','同时存在会话数和超时边界;中文输入法、剪贴板、复杂设备输入等没有完整桌面等价保证。'],('UT-252','native-desktop'))
M(30,'资产目录、链接库与追加','Asset Browser、Catalogs、Link / Append / Override','Properties > Asset Browser & Libraries','basic_scene.blend',['UJ-15'],[
('标记资产与目录',['选中 BasicCube,滚动到 Asset Browser & Libraries。','Catalog ID 输入 user-test-assets,Catalog name 输入 User Assets。','点击 Mark Asset,再点击 Save Catalog。','确认未保存状态被正确标记,保存重开并核对目录与资产信息。']),
('链接与追加的前提',['链接与普通追加有不同的数据所有权:链接数据可能禁止直接修改。','Web 的 Append to Main 入口需要 Source .blend 和对应 Binding JSON;没有有效绑定文件时不要任意构造或跳过检查。','需要完整文件浏览器方式的 Link/Append 时,进入原生桌面,确保源文件可在任务资源中访问,再按桌面 File 菜单操作。','完成后核对库路径、对象归属和是否需要 Override,并交付配套库文件。'])],
['资产标记和目录经保存重开保留。','业务链接工程应额外验证依赖链和重新加载。'],
['本章直接实测资产目录;任意链接库、嵌套依赖和完整 Override 操作尚未全覆盖。'],('UJ-15','catalog-saved'))
M(31,'刚体与模拟工作流','Physics Properties、Rigid Body、Simulation Cache','Properties > Physics;原生桌面','basic_scene.blend',['UJ-09'],[
('刚体参数',['选择 BasicCube,滚动到 Physics。','在 Physics system 选择 RIGID_BODY,点击 Add。','在 RIGID_BODY Mass 输入 2,移开焦点提交。','确认读数为 2,保存重开;无效范围输入不应破坏现有有效数据。']),
('其他模拟系统',['完整模拟设置或烘焙请使用原生桌面并先保存工程副本。','明确模拟类型、碰撞对象、时间范围、缓存路径及是否需要外部资源。','烘焙后检查缓存是否随工程保存;在新会话或新环境重新载入验证。'])],
['刚体质量与系统类型经保存保留。','模拟是否可重现必须通过播放、输出帧和缓存重新加载判断。'],
['建立刚体或读取模拟设置不等于所有物理求解器和外部缓存已完整移植。'],('UJ-09','mass-2'))
M(32,'体积数据与显示','Volume Objects、OpenVDB / NanoVDB','现有体积入口;原生桌面','parity_scene.blend',[],[
('使用体积项目',['准备包含体积对象和完整外部网格文件的工程;先在桌面确认输入本身可用。','在 Web 打开工程,按 M13 同步相关文件和相对路径。','核对体积名称、帧号、显示状态及实际视口内容;切换帧时确认不是重复旧帧。','最终外观通过原生渲染对照,保存工程并验证资源仍可定位。'])],
['体积资源加载、页反馈、恢复和渲染由原自动化集合提供有限覆盖。','实际业务样例须记录网格名称、分辨率、范围、帧序列和内存用量。'],
['本轮没有为任意生产体积项目提供完整用户步骤实测截图;不能从自动化小样例推广到所有格式、压缩和缓存组合。'],None,'引擎集合有覆盖;本章业务项目需单独验证')
M(33,'GLB 导出及其他交换格式','File Export / Import','顶部“导出 GLB”;F3 与当前格式入口','basic_scene.blend',['UJ-18'],[
('导出 GLB',['打开样例并确认场景内容。','点击“导出 GLB”,等待下载完成。','保留导出诊断或损失说明;交换格式不保证完整保留 Blender 的所有数据。','在目标软件或桌面 Blender 中重新导入 GLB,检查几何、对象数量、变换和材质。']),
('选择其他格式',['使用前先确认该格式的导入/导出入口实际可用及限制说明。','需要桌面插件或当前 Web 不支持的选项时,使用原生桌面的对应导入导出功能。','对关键工程始终同时保留原始 .blend。'])],
['下载文件非空且目标软件可读取。','业务验收应检查具体可接受的数据损失。'],
['格式名称出现在目录中不代表全部选项、材质和动画数据都可无损转换。'],('UJ-18','search-results'))
M(34,'键盘、焦点与紧凑布局','Shortcuts、Focus、Editor Context','Web 输入框、搜索对话框与原生画面','basic_scene.blend',['UJ-20'],[
('键盘使用',['使用 F3 打开搜索,输入关键词;用 Escape 关闭。','输入数值或脚本时确认焦点位于目标输入框,避免快捷键作用到视口。','缩小窗口后检查主要按钮仍可访问;必要时滚动对应面板。','原生快捷键需要原生画面获得焦点且鼠标位于正确编辑器,见 M29。'])],
['对话框关闭后焦点可返回,继续编辑不应误触其他工具。'],
['本轮有 960×844 紧凑布局流程;不代表所有手机、触控、IME 或辅助技术组合已完成验证。'],('UJ-20','compact-layout'))
M(35,'一个可重复的建模到渲染练习','Modeling → Material → Camera → Render → Save','综合使用 Web、Scripting、Rendering','parity_scene.blend',['UT-248','UT-245','UT-252'],[
('完整练习',['打开 parity_scene.blend,保留原样例副本。','选中 ParityCube,按 M29 在原生桌面做一次移动并 Apply to Web Scene;或者用 M28 的脚本明确设置位置。','核对 Transform,不用视口观察角度替代相机构图。','按需调整已提供的材质和灯光参数,保存一个新的 .blend。','进入 Rendering,选择 CYCLES、PNG、帧 1,执行 Render Frame。','下载渲染图,确认主体、光照和构图;再重新打开保存的 .blend,重复同参数渲染作比较。','记录所用样例、参数、结果文件和任何差异。'])],
['数据修改、保存文件和最终图片三者一致。','场景与资源可从保存结果恢复,不依赖当前浏览器中的临时预览。'],
['这个综合练习由已测步骤组成;用户自己的复杂组合仍需要逐项验证。'],('UT-245','image-preview'))
M(36,'错误恢复与用户验证记录','Reports、Undo、Recover、Reopen','状态栏、Python 输出、诊断导出、Recent','parity_scene.blend',['UJ-19','UT-251','UT-275','UT-276'],[
('识别错误类型',['普通控制台 PYTHON_ERROR:检查已执行修改,修正代码继续;需要回退时先在 Web 撤销,再 Reset Session。','RESET_REQUIRED、进程退出或输出超限:当前 Web 场景受保护,重新 Connect 后继续。','SOURCE_CHANGED:保留最新 Web 编辑,放弃旧会话的过期提交并重连。','RESOURCE_HASH_MISMATCH 或缺失资源:清除损坏副本,按正确路径重新同步;不要把旧结果当作本次输出。']),
('记录并复测',['发现问题时先保存当前可用工程副本和必要资源。','记录模块编号、输入文件、对象、模式、操作顺序、预期与实际结果。','保存 PNG 和诊断文件;如果有下载产物,附上原文件而非只附截图。','用同一输入重做步骤,确认是否稳定复现。','按 verification-checklist.csv 填写 PASS、FAIL、BLOCKED 或 NOT_RUN;不把没做过的操作记为通过。'])],
['修复后需重新执行实际失败步骤,再保存并重新打开验证。','原生崩溃和输出超限不会把未确认修改覆盖到 Web 场景。'],
['本手册不是全功能等价证书。无法从现有证据证明的功能仍按未验证处理。'],('UT-275','kernel-exit-protected'))

Binary file not shown.

After

Width:  |  Height:  |  Size: 117 KiB

View File

@@ -0,0 +1,14 @@
import fs from 'node:fs';import path from 'node:path';import {fileURLToPath,pathToFileURL} from 'node:url';import {createRequire} from 'node:module';import {execFileSync} from 'node:child_process';import crypto from 'node:crypto';
const base=path.resolve(path.dirname(fileURLToPath(import.meta.url)),'..'),root=path.resolve(base,'../..');
const {chromium}=createRequire(path.join(root,'web/package.json'))('playwright');
const browser=await chromium.launch({executablePath:'/usr/bin/google-chrome',args:['--no-sandbox','--allow-file-access-from-files']});
try{const page=await browser.newPage();await page.goto(pathToFileURL(path.join(base,'说明书.html')).href);await page.evaluate(()=>document.fonts.ready);
const broken=await page.evaluate(()=>[...document.images].filter(image=>!image.complete||image.naturalWidth===0).map(image=>image.src));if(broken.length)throw new Error('Missing handbook images: '+JSON.stringify(broken));
await page.pdf({path:path.join(base,'WEB_Blender_Function_User_Guide.pdf'),format:'A4',printBackground:true,preferCSSPageSize:true,tagged:true,outline:true,displayHeaderFooter:true,headerTemplate:'<div></div>',footerTemplate:'<div style="font-size:8px;margin:0 40px;width:100%">WEB Blender · UM-20260916-R3 <span style="float:right"><span class="pageNumber"></span> / <span class="totalPages"></span></span></div>'});
}finally{await browser.close();}
const text=execFileSync('pdftotext',['-layout',path.join(base,'WEB_Blender_Function_User_Guide.pdf'),'-'],{encoding:'utf8',maxBuffer:8*1024*1024});
for(let i=1;i<=36;i++){const id='M'+String(i).padStart(2,'0');if(!text.includes(id))throw new Error('Missing PDF module: '+id);}
const walk=dir=>fs.readdirSync(dir,{withFileTypes:true}).flatMap(item=>item.isDirectory()?walk(path.join(dir,item.name)):[path.join(dir,item.name)]);
const files=walk(base).filter(file=>!file.endsWith('delivery-manifest.json')&&!file.includes('/__pycache__/'));
const manifest={document:'WEB Blender Function User Guide',version:'UM-20260916-R3',modules:36,desktopParity:'NOT_ESTABLISHED',files:files.map(file=>({path:path.relative(base,file),bytes:fs.statSync(file).size,sha256:crypto.createHash('sha256').update(fs.readFileSync(file)).digest('hex')}))};
fs.writeFileSync(path.join(base,'delivery-manifest.json'),JSON.stringify(manifest,null,2)+'\n');console.log(JSON.stringify({pdf:'WEB_Blender_Function_User_Guide.pdf',modules:36,files:files.length}));

View File

@@ -0,0 +1,68 @@
模块,功能,验证项,判据,样例,结果,软件版本,日期,实际结果,问题编号
M01,运行环境与样例准备,M01-V01,页面可打开样例;Outliner 出现 BasicCube、BasicCamera 和 BasicArea。,basic_scene.blend,NOT_RUN,,,,
M01,运行环境与样例准备,M01-V02,原生功能前先确认服务可用,普通页面显示不等于原生服务已就绪。,basic_scene.blend,NOT_RUN,,,,
M02,界面、工作区与对象选择,M02-V01,切换工作区后项目对象仍在;选中对象与属性名称一致。,basic_scene.blend,NOT_RUN,,,,
M02,界面、工作区与对象选择,M02-V02,搜索关闭后可以继续选择和编辑。,basic_scene.blend,NOT_RUN,,,,
M03,打开、保存、恢复、撤销与重做,M03-V01,新增对象经保存、重新打开仍存在。,basic_scene.blend,NOT_RUN,,,,
M03,打开、保存、恢复、撤销与重做,M03-V02,撤销和重做各一次后结果可预测,恢复不丢失已经提交的修改。,basic_scene.blend,NOT_RUN,,,,
M04,位置、缩放与全部旋转模式,M04-V01,UT-270–274 的矩阵参考可用于比较四元数、轴角、六种 Euler 顺序、增量与普通对象父级。,rotation-quaternion.blend,NOT_RUN,,,,
M04,位置、缩放与全部旋转模式,M04-V02,变换后撤销、重做、保存重开仍显示正确值。,rotation-quaternion.blend,NOT_RUN,,,,
M05,对象创建、复制、重命名与删除,M05-V01,对象数的增减与操作一致;保存后的名称正确。,basic_scene.blend,NOT_RUN,,,,
M05,对象创建、复制、重命名与删除,M05-V02,删除前确认活动对象,避免误删相机或灯光。,basic_scene.blend,NOT_RUN,,,,
M06,集合、父子关系、原点与应用变换,M06-V01,rotation-parent.blend 的局部/世界矩阵与桌面参考一致。,rotation-parent.blend,NOT_RUN,,,,
M06,集合、父子关系、原点与应用变换,M06-V02,实际业务工程要分别验证集合成员、父子名称和世界位置。,rotation-parent.blend,NOT_RUN,,,,
M07,网格编辑、选择与拓扑操作,M07-V01,选择域、选中数量和执行对象对应。,mesh_editor_scene.blend,NOT_RUN,,,,
M07,网格编辑、选择与拓扑操作,M07-V02,拓扑变化经过撤销、保存和重开仍可确认。,mesh_editor_scene.blend,NOT_RUN,,,,
M08,UV 投影与 UV 工作流,M08-V01,投影作用于选中的正确网格和面。,mesh_editor_scene.blend,NOT_RUN,,,,
M08,UV 投影与 UV 工作流,M08-V02,保存重开后 UV 数据仍存在;需要逐点对照时用桌面 UV Editor 检查。,mesh_editor_scene.blend,NOT_RUN,,,,
M09,修改器参数与堆栈,M09-V01,参数值和修改器顺序保存后仍正确。,modifier_stack_scene.blend,NOT_RUN,,,,
M09,修改器参数与堆栈,M09-V02,找不到修改器或参数时,不应以相近名称或预览效果替代桌面功能。,modifier_stack_scene.blend,NOT_RUN,,,,
M10,曲线、曲面与非网格对象,M10-V01,曲线闭合属性经保存重开保留。,nonmesh_scene.blend,NOT_RUN,,,,
M10,曲线、曲面与非网格对象,M10-V02,复杂非网格编辑应核对控制点数、类型及最终形状。,nonmesh_scene.blend,NOT_RUN,,,,
M11,文本对象与字体,M11-V01,正文保持为输入内容,桌面读回一致。,nonmesh_scene.blend,NOT_RUN,,,,
M11,文本对象与字体,M11-V02,外部字体工程需额外检查字体资源是否可用。,nonmesh_scene.blend,NOT_RUN,,,,
M12,材质与基础着色,M12-V01,数据参数经保存重开不变。,attribute_scene.blend,NOT_RUN,,,,
M12,材质与基础着色,M12-V02,最终外观比较必须固定引擎、灯光、相机和色彩管理。,attribute_scene.blend,NOT_RUN,,,,
M13,外部纹理、文件同步与项目资源,M13-V01,外部纹理尺寸和路径正确;同一项目刷新后仍可读取。,resource_scene.blend,NOT_RUN,,,,
M13,外部纹理、文件同步与项目资源,M13-V02,交付到其他设备时,同时检查 .blend 与外部文件的相对位置。,resource_scene.blend,NOT_RUN,,,,
M14,灯光、世界与色彩管理,M14-V01,相同相机与引擎下比较灯光和色彩变化。,basic_scene.blend,NOT_RUN,,,,
M14,灯光、世界与色彩管理,M14-V02,保存后 Gamma 等参数不回到原值。,basic_scene.blend,NOT_RUN,,,,
M15,相机与构图,M15-V01,相机焦距保存后为预期值;灯光编辑不会覆盖相机属性。,basic_scene.blend,NOT_RUN,,,,
M15,相机与构图,M15-V02,渲染构图与活动相机一致。,basic_scene.blend,NOT_RUN,,,,
M16,时间轴、关键帧与标记,M16-V01,关键帧写入正确对象和通道。,animation_scene.blend,NOT_RUN,,,,
M16,时间轴、关键帧与标记,M16-V02,保存重开后标记仍为 User Marker。,animation_scene.blend,NOT_RUN,,,,
M17,曲线编辑器、驱动器与 NLA,M17-V01,验证时记录对象、Action、通道、帧、插值和条带范围,不只记录视口外观。,animation_scene.blend,NOT_RUN,,,,
M18,骨架、姿态与约束,M18-V01,滚转和镜像状态保存后保持。,pose_constraint_scene.blend,NOT_RUN,,,,
M18,骨架、姿态与约束,M18-V02,约束验证应记录目标、影响值、空间和结果。,pose_constraint_scene.blend,NOT_RUN,,,,
M19,雕刻属性与面组,M19-V01,面组和遮罩属性保留,且作用于正确网格。,basic_scene.blend,NOT_RUN,,,,
M20,顶点颜色、权重与绘制属性,M20-V01,没有选中顶点时按钮不应执行写入。,mesh_editor_scene.blend,NOT_RUN,,,,
M20,顶点颜色、权重与绘制属性,M20-V02,保存后 WebPaintColor 和 GuideWeights 保留。,mesh_editor_scene.blend,NOT_RUN,,,,
M21,Grease Pencil 图层与绘图数据,M21-V01,User Layer 保存后存在于正确的 Grease Pencil 数据中。,modifier_grease_pencil_scene.blend,NOT_RUN,,,,
M22,几何节点与节点图,M22-V01,节点图可以创建、保存和重新读取。,basic_scene.blend,NOT_RUN,,,,
M22,几何节点与节点图,M22-V02,业务验证应记录节点类型、默认值、链接和求值结果。,basic_scene.blend,NOT_RUN,,,,
M23,合成器、遮罩与跟踪,M23-V01,以最终输出图像和节点/遮罩/跟踪数据共同验收,不能只看工作区标签。,parity_scene.blend,NOT_RUN,,,,
M24,视频序列与条带编辑,M24-V01,条带范围与静音状态保存后正确。,sequencer_scene.blend,NOT_RUN,,,,
M24,视频序列与条带编辑,M24-V02,外部媒体需随工程交付;缺失媒体不能作为正常空画面验收。,sequencer_scene.blend,NOT_RUN,,,,
M25,真实图像渲染与 OpenEXR,M25-V01,练习 PNG 与同构件桌面 Cycles 独立渲染平均像素误差为 0;该结论只针对所测样例。,parity_scene.blend,NOT_RUN,,,,
M25,真实图像渲染与 OpenEXR,M25-V02,EXR 可在桌面读取,样例为 96×96、4 通道。,parity_scene.blend,NOT_RUN,,,,
M26,动画帧序列、MP4 与取消,M26-V01,帧数、范围、时间变化与业务需求一致。,parity_animation.blend,NOT_RUN,,,,
M26,动画帧序列、MP4 与取消,M26-V02,取消后不发布新产物,当前场景保持可编辑。,parity_animation.blend,NOT_RUN,,,,
M27,持久 Python 控制台,M27-V01,counter 跨命令保留;普通异常后可以继续访问同一个对象引用。,parity_scene.blend,NOT_RUN,,,,
M27,持久 Python 控制台,M27-V02,场景外部修改时旧会话不会覆盖最新 Web 场景。,parity_scene.blend,NOT_RUN,,,,
M28,文本脚本与批处理,M28-V01,成功执行后对象 X=2,保存后桌面读回正确。,parity_scene.blend,NOT_RUN,,,,
M28,文本脚本与批处理,M28-V02,运行前明确所用对象名称与上下文。,parity_scene.blend,NOT_RUN,,,,
M29,真实原生桌面与交互式工具,M29-V01,确认移动后 X=1;取消移动后 X 保持原值。,parity_scene.blend,NOT_RUN,,,,
M29,真实原生桌面与交互式工具,M29-V02,每次提交都作用于开始会话时的同一项目修订。,parity_scene.blend,NOT_RUN,,,,
M30,资产目录、链接库与追加,M30-V01,资产标记和目录经保存重开保留。,basic_scene.blend,NOT_RUN,,,,
M30,资产目录、链接库与追加,M30-V02,业务链接工程应额外验证依赖链和重新加载。,basic_scene.blend,NOT_RUN,,,,
M31,刚体与模拟工作流,M31-V01,刚体质量与系统类型经保存保留。,basic_scene.blend,NOT_RUN,,,,
M31,刚体与模拟工作流,M31-V02,模拟是否可重现必须通过播放、输出帧和缓存重新加载判断。,basic_scene.blend,NOT_RUN,,,,
M32,体积数据与显示,M32-V01,体积资源加载、页反馈、恢复和渲染由原自动化集合提供有限覆盖。,parity_scene.blend,NOT_RUN,,,,
M32,体积数据与显示,M32-V02,实际业务样例须记录网格名称、分辨率、范围、帧序列和内存用量。,parity_scene.blend,NOT_RUN,,,,
M33,GLB 导出及其他交换格式,M33-V01,下载文件非空且目标软件可读取。,basic_scene.blend,NOT_RUN,,,,
M33,GLB 导出及其他交换格式,M33-V02,业务验收应检查具体可接受的数据损失。,basic_scene.blend,NOT_RUN,,,,
M34,键盘、焦点与紧凑布局,M34-V01,对话框关闭后焦点可返回,继续编辑不应误触其他工具。,basic_scene.blend,NOT_RUN,,,,
M35,一个可重复的建模到渲染练习,M35-V01,数据修改、保存文件和最终图片三者一致。,parity_scene.blend,NOT_RUN,,,,
M35,一个可重复的建模到渲染练习,M35-V02,场景与资源可从保存结果恢复,不依赖当前浏览器中的临时预览。,parity_scene.blend,NOT_RUN,,,,
M36,错误恢复与用户验证记录,M36-V01,修复后需重新执行实际失败步骤,再保存并重新打开验证。,parity_scene.blend,NOT_RUN,,,,
M36,错误恢复与用户验证记录,M36-V02,原生崩溃和输出超限不会把未确认修改覆盖到 Web 场景。,parity_scene.blend,NOT_RUN,,,,
1 模块 功能 验证项 判据 样例 结果 软件版本 日期 实际结果 问题编号
2 M01 运行环境与样例准备 M01-V01 页面可打开样例;Outliner 出现 BasicCube、BasicCamera 和 BasicArea。 basic_scene.blend NOT_RUN
3 M01 运行环境与样例准备 M01-V02 原生功能前先确认服务可用,普通页面显示不等于原生服务已就绪。 basic_scene.blend NOT_RUN
4 M02 界面、工作区与对象选择 M02-V01 切换工作区后项目对象仍在;选中对象与属性名称一致。 basic_scene.blend NOT_RUN
5 M02 界面、工作区与对象选择 M02-V02 搜索关闭后可以继续选择和编辑。 basic_scene.blend NOT_RUN
6 M03 打开、保存、恢复、撤销与重做 M03-V01 新增对象经保存、重新打开仍存在。 basic_scene.blend NOT_RUN
7 M03 打开、保存、恢复、撤销与重做 M03-V02 撤销和重做各一次后结果可预测,恢复不丢失已经提交的修改。 basic_scene.blend NOT_RUN
8 M04 位置、缩放与全部旋转模式 M04-V01 UT-270–274 的矩阵参考可用于比较四元数、轴角、六种 Euler 顺序、增量与普通对象父级。 rotation-quaternion.blend NOT_RUN
9 M04 位置、缩放与全部旋转模式 M04-V02 变换后撤销、重做、保存重开仍显示正确值。 rotation-quaternion.blend NOT_RUN
10 M05 对象创建、复制、重命名与删除 M05-V01 对象数的增减与操作一致;保存后的名称正确。 basic_scene.blend NOT_RUN
11 M05 对象创建、复制、重命名与删除 M05-V02 删除前确认活动对象,避免误删相机或灯光。 basic_scene.blend NOT_RUN
12 M06 集合、父子关系、原点与应用变换 M06-V01 rotation-parent.blend 的局部/世界矩阵与桌面参考一致。 rotation-parent.blend NOT_RUN
13 M06 集合、父子关系、原点与应用变换 M06-V02 实际业务工程要分别验证集合成员、父子名称和世界位置。 rotation-parent.blend NOT_RUN
14 M07 网格编辑、选择与拓扑操作 M07-V01 选择域、选中数量和执行对象对应。 mesh_editor_scene.blend NOT_RUN
15 M07 网格编辑、选择与拓扑操作 M07-V02 拓扑变化经过撤销、保存和重开仍可确认。 mesh_editor_scene.blend NOT_RUN
16 M08 UV 投影与 UV 工作流 M08-V01 投影作用于选中的正确网格和面。 mesh_editor_scene.blend NOT_RUN
17 M08 UV 投影与 UV 工作流 M08-V02 保存重开后 UV 数据仍存在;需要逐点对照时用桌面 UV Editor 检查。 mesh_editor_scene.blend NOT_RUN
18 M09 修改器参数与堆栈 M09-V01 参数值和修改器顺序保存后仍正确。 modifier_stack_scene.blend NOT_RUN
19 M09 修改器参数与堆栈 M09-V02 找不到修改器或参数时,不应以相近名称或预览效果替代桌面功能。 modifier_stack_scene.blend NOT_RUN
20 M10 曲线、曲面与非网格对象 M10-V01 曲线闭合属性经保存重开保留。 nonmesh_scene.blend NOT_RUN
21 M10 曲线、曲面与非网格对象 M10-V02 复杂非网格编辑应核对控制点数、类型及最终形状。 nonmesh_scene.blend NOT_RUN
22 M11 文本对象与字体 M11-V01 正文保持为输入内容,桌面读回一致。 nonmesh_scene.blend NOT_RUN
23 M11 文本对象与字体 M11-V02 外部字体工程需额外检查字体资源是否可用。 nonmesh_scene.blend NOT_RUN
24 M12 材质与基础着色 M12-V01 数据参数经保存重开不变。 attribute_scene.blend NOT_RUN
25 M12 材质与基础着色 M12-V02 最终外观比较必须固定引擎、灯光、相机和色彩管理。 attribute_scene.blend NOT_RUN
26 M13 外部纹理、文件同步与项目资源 M13-V01 外部纹理尺寸和路径正确;同一项目刷新后仍可读取。 resource_scene.blend NOT_RUN
27 M13 外部纹理、文件同步与项目资源 M13-V02 交付到其他设备时,同时检查 .blend 与外部文件的相对位置。 resource_scene.blend NOT_RUN
28 M14 灯光、世界与色彩管理 M14-V01 相同相机与引擎下比较灯光和色彩变化。 basic_scene.blend NOT_RUN
29 M14 灯光、世界与色彩管理 M14-V02 保存后 Gamma 等参数不回到原值。 basic_scene.blend NOT_RUN
30 M15 相机与构图 M15-V01 相机焦距保存后为预期值;灯光编辑不会覆盖相机属性。 basic_scene.blend NOT_RUN
31 M15 相机与构图 M15-V02 渲染构图与活动相机一致。 basic_scene.blend NOT_RUN
32 M16 时间轴、关键帧与标记 M16-V01 关键帧写入正确对象和通道。 animation_scene.blend NOT_RUN
33 M16 时间轴、关键帧与标记 M16-V02 保存重开后标记仍为 User Marker。 animation_scene.blend NOT_RUN
34 M17 曲线编辑器、驱动器与 NLA M17-V01 验证时记录对象、Action、通道、帧、插值和条带范围,不只记录视口外观。 animation_scene.blend NOT_RUN
35 M18 骨架、姿态与约束 M18-V01 滚转和镜像状态保存后保持。 pose_constraint_scene.blend NOT_RUN
36 M18 骨架、姿态与约束 M18-V02 约束验证应记录目标、影响值、空间和结果。 pose_constraint_scene.blend NOT_RUN
37 M19 雕刻属性与面组 M19-V01 面组和遮罩属性保留,且作用于正确网格。 basic_scene.blend NOT_RUN
38 M20 顶点颜色、权重与绘制属性 M20-V01 没有选中顶点时按钮不应执行写入。 mesh_editor_scene.blend NOT_RUN
39 M20 顶点颜色、权重与绘制属性 M20-V02 保存后 WebPaintColor 和 GuideWeights 保留。 mesh_editor_scene.blend NOT_RUN
40 M21 Grease Pencil 图层与绘图数据 M21-V01 User Layer 保存后存在于正确的 Grease Pencil 数据中。 modifier_grease_pencil_scene.blend NOT_RUN
41 M22 几何节点与节点图 M22-V01 节点图可以创建、保存和重新读取。 basic_scene.blend NOT_RUN
42 M22 几何节点与节点图 M22-V02 业务验证应记录节点类型、默认值、链接和求值结果。 basic_scene.blend NOT_RUN
43 M23 合成器、遮罩与跟踪 M23-V01 以最终输出图像和节点/遮罩/跟踪数据共同验收,不能只看工作区标签。 parity_scene.blend NOT_RUN
44 M24 视频序列与条带编辑 M24-V01 条带范围与静音状态保存后正确。 sequencer_scene.blend NOT_RUN
45 M24 视频序列与条带编辑 M24-V02 外部媒体需随工程交付;缺失媒体不能作为正常空画面验收。 sequencer_scene.blend NOT_RUN
46 M25 真实图像渲染与 OpenEXR M25-V01 练习 PNG 与同构件桌面 Cycles 独立渲染平均像素误差为 0;该结论只针对所测样例。 parity_scene.blend NOT_RUN
47 M25 真实图像渲染与 OpenEXR M25-V02 EXR 可在桌面读取,样例为 96×96、4 通道。 parity_scene.blend NOT_RUN
48 M26 动画帧序列、MP4 与取消 M26-V01 帧数、范围、时间变化与业务需求一致。 parity_animation.blend NOT_RUN
49 M26 动画帧序列、MP4 与取消 M26-V02 取消后不发布新产物,当前场景保持可编辑。 parity_animation.blend NOT_RUN
50 M27 持久 Python 控制台 M27-V01 counter 跨命令保留;普通异常后可以继续访问同一个对象引用。 parity_scene.blend NOT_RUN
51 M27 持久 Python 控制台 M27-V02 场景外部修改时旧会话不会覆盖最新 Web 场景。 parity_scene.blend NOT_RUN
52 M28 文本脚本与批处理 M28-V01 成功执行后对象 X=2,保存后桌面读回正确。 parity_scene.blend NOT_RUN
53 M28 文本脚本与批处理 M28-V02 运行前明确所用对象名称与上下文。 parity_scene.blend NOT_RUN
54 M29 真实原生桌面与交互式工具 M29-V01 确认移动后 X=1;取消移动后 X 保持原值。 parity_scene.blend NOT_RUN
55 M29 真实原生桌面与交互式工具 M29-V02 每次提交都作用于开始会话时的同一项目修订。 parity_scene.blend NOT_RUN
56 M30 资产目录、链接库与追加 M30-V01 资产标记和目录经保存重开保留。 basic_scene.blend NOT_RUN
57 M30 资产目录、链接库与追加 M30-V02 业务链接工程应额外验证依赖链和重新加载。 basic_scene.blend NOT_RUN
58 M31 刚体与模拟工作流 M31-V01 刚体质量与系统类型经保存保留。 basic_scene.blend NOT_RUN
59 M31 刚体与模拟工作流 M31-V02 模拟是否可重现必须通过播放、输出帧和缓存重新加载判断。 basic_scene.blend NOT_RUN
60 M32 体积数据与显示 M32-V01 体积资源加载、页反馈、恢复和渲染由原自动化集合提供有限覆盖。 parity_scene.blend NOT_RUN
61 M32 体积数据与显示 M32-V02 实际业务样例须记录网格名称、分辨率、范围、帧序列和内存用量。 parity_scene.blend NOT_RUN
62 M33 GLB 导出及其他交换格式 M33-V01 下载文件非空且目标软件可读取。 basic_scene.blend NOT_RUN
63 M33 GLB 导出及其他交换格式 M33-V02 业务验收应检查具体可接受的数据损失。 basic_scene.blend NOT_RUN
64 M34 键盘、焦点与紧凑布局 M34-V01 对话框关闭后焦点可返回,继续编辑不应误触其他工具。 basic_scene.blend NOT_RUN
65 M35 一个可重复的建模到渲染练习 M35-V01 数据修改、保存文件和最终图片三者一致。 parity_scene.blend NOT_RUN
66 M35 一个可重复的建模到渲染练习 M35-V02 场景与资源可从保存结果恢复,不依赖当前浏览器中的临时预览。 parity_scene.blend NOT_RUN
67 M36 错误恢复与用户验证记录 M36-V01 修复后需重新执行实际失败步骤,再保存并重新打开验证。 parity_scene.blend NOT_RUN
68 M36 错误恢复与用户验证记录 M36-V02 原生崩溃和输出超限不会把未确认修改覆盖到 Web 场景。 parity_scene.blend NOT_RUN

File diff suppressed because one or more lines are too long

View File

@@ -0,0 +1,7 @@
# 菜单、界面与功能对照
[PDF](WEB_Blender_Desktop_Menus.pdf)
[浏览器版](manual.html)
截图在 screenshots/,明确列出的未完成范围见最后一章。

View File

@@ -0,0 +1,99 @@
{
"files": [
{
"path": "user-manual/WEB_Blender_Desktop_Menus_20260916/README.md",
"bytes": 175,
"sha256": "6b63ea6b8d8f0604669dbf51e4b284caff1a82980a0c8d4330034b5fc3bd5ab4"
},
{
"path": "user-manual/WEB_Blender_Desktop_Menus_20260916/WEB_Blender_Desktop_Menus.pdf",
"bytes": 2077057,
"sha256": "0f699bff2e400e71bdceea46f8a723f6d2e45c3fe67dedb7916032b6da2a7c14"
},
{
"path": "user-manual/WEB_Blender_Desktop_Menus_20260916/evidence-index.json",
"bytes": 2360,
"sha256": "3b2bb363ef581a5b49c0fcd0d744f1d56c90ad337fc53b41c915a2e0e7fad86e"
},
{
"path": "user-manual/WEB_Blender_Desktop_Menus_20260916/manual.html",
"bytes": 10635,
"sha256": "04d9404a80108d4dae44deb53c29e184227bb79f889a7dee792633450e82a290"
},
{
"path": "user-manual/WEB_Blender_Desktop_Menus_20260916/screenshots/01-MENU-01.png",
"bytes": 184001,
"sha256": "910a279c59847edcf9a19324780ef70302249db5448c113058647b8e84d4c666"
},
{
"path": "user-manual/WEB_Blender_Desktop_Menus_20260916/screenshots/02-MENU-15.png",
"bytes": 194861,
"sha256": "9b355fd084443277d652ed9f6449273f41bea6313c0224d3859fa8faa1110979"
},
{
"path": "user-manual/WEB_Blender_Desktop_Menus_20260916/screenshots/03-MENU-05.png",
"bytes": 184064,
"sha256": "27e9951c641029892b8d6d5fcdfb7f8bf4651aa225bc240ac97ec7eb5d3d36f1"
},
{
"path": "user-manual/WEB_Blender_Desktop_Menus_20260916/screenshots/04-MENU-02.png",
"bytes": 169411,
"sha256": "7c541a0cb2446ce83c0fcdeb38f9219753c58a2e50b02a892a368f7b478c293e"
},
{
"path": "user-manual/WEB_Blender_Desktop_Menus_20260916/screenshots/05-MENU-04.png",
"bytes": 181001,
"sha256": "ca004be47bcddf4266296846b8c567dad576ab463e2628c4de9748ccf5704f90"
},
{
"path": "user-manual/WEB_Blender_Desktop_Menus_20260916/screenshots/06-MENU-03.png",
"bytes": 180738,
"sha256": "6afa2ddc29e762f05112a1d04a634ef72313d2531e14813a73c4d70e9bc57163"
},
{
"path": "user-manual/WEB_Blender_Desktop_Menus_20260916/screenshots/07-MENU-07.png",
"bytes": 129883,
"sha256": "28a162cd642198a88e8ff672ed45f894f5aec6916bd810fed564becb4247adf0"
},
{
"path": "user-manual/WEB_Blender_Desktop_Menus_20260916/screenshots/08-MENU-08.png",
"bytes": 137943,
"sha256": "a0bd6dda1e0fad3c5fe38637a7de711530387186cabd177018f4ce1c272751ad"
},
{
"path": "user-manual/WEB_Blender_Desktop_Menus_20260916/screenshots/09-MENU-10.png",
"bytes": 184001,
"sha256": "910a279c59847edcf9a19324780ef70302249db5448c113058647b8e84d4c666"
},
{
"path": "user-manual/WEB_Blender_Desktop_Menus_20260916/screenshots/10-MENU-12.png",
"bytes": 198474,
"sha256": "56f97a1963d44275ba47e4dae77a554bd20f222053994809908255658905b271"
},
{
"path": "user-manual/WEB_Blender_Desktop_Menus_20260916/screenshots/11-MENU-17.png",
"bytes": 87359,
"sha256": "68ce0be1feac57bc81211e25fb366386a5461bfe2a64163a0090a423d016a5e6"
},
{
"path": "user-manual/WEB_Blender_Desktop_Menus_20260916/source/build.py",
"bytes": 9967,
"sha256": "2cda7c44ade1d27010b793b99d89449e0b8c238c6082068d123132d2d3057c72"
},
{
"path": "user-manual/WEB_Blender_Desktop_Menus_20260916/source/cover-preview.png",
"bytes": 61790,
"sha256": "fb961aff7df9f8a7b37764ef7cad6db34fefe2db742e8adedc4058189786ff7a"
},
{
"path": "user-manual/WEB_Blender_Desktop_Menus_20260916/source/render.mjs",
"bytes": 930,
"sha256": "255e0bdeccab50d5667d0c1c383d16fcbc1b714a8c06165ac414196cb04b90a0"
},
{
"path": "user-manual/WEB_Blender_Desktop_Menus_20260916/source/\u64cd\u4f5c\u8bf4\u660e.md",
"bytes": 6084,
"sha256": "aeb2b12e479ac1675abfbd10a901c6ecc019af46ec5dffbcb2279f1ba9c9e801"
}
]
}

View File

@@ -0,0 +1,68 @@
[
{
"chapter": 1,
"case": "MENU-01",
"source": "user-testing/WEB_Blender_Desktop_Menus_20260916/runs/2026-09-16T16-13-46-733Z/MENU-01/01-header.png",
"file": "screenshots/01-MENU-01.png"
},
{
"chapter": 2,
"case": "MENU-15",
"source": "user-testing/WEB_Blender_Desktop_Menus_20260916/runs/2026-09-16T16-13-46-733Z/MENU-15/01-factory-general.png",
"file": "screenshots/02-MENU-15.png"
},
{
"chapter": 3,
"case": "MENU-05",
"source": "user-testing/WEB_Blender_Desktop_Menus_20260916/runs/2026-09-16T16-13-46-733Z/MENU-05/01-save-as.png",
"file": "screenshots/03-MENU-05.png"
},
{
"chapter": 4,
"case": "MENU-02",
"source": "user-testing/WEB_Blender_Desktop_Menus_20260916/runs/2026-09-16T16-13-46-733Z/MENU-02/02-cube-added.png",
"file": "screenshots/04-MENU-02.png"
},
{
"chapter": 5,
"case": "MENU-04",
"source": "user-testing/WEB_Blender_Desktop_Menus_20260916/runs/2026-09-16T16-13-46-733Z/MENU-04/01-edit-triangulated.png",
"file": "screenshots/05-MENU-04.png"
},
{
"chapter": 6,
"case": "MENU-03",
"source": "user-testing/WEB_Blender_Desktop_Menus_20260916/runs/2026-09-16T16-13-46-733Z/MENU-03/01-renamed.png",
"file": "screenshots/06-MENU-03.png"
},
{
"chapter": 7,
"case": "MENU-07",
"source": "user-testing/WEB_Blender_Desktop_Menus_20260916/runs/2026-09-16T16-13-46-733Z/MENU-07/01-render-result.png",
"file": "screenshots/07-MENU-07.png"
},
{
"chapter": 8,
"case": "MENU-08",
"source": "user-testing/WEB_Blender_Desktop_Menus_20260916/runs/2026-09-16T16-13-46-733Z/MENU-08/01-front-framed.png",
"file": "screenshots/08-MENU-08.png"
},
{
"chapter": 9,
"case": "MENU-10",
"source": "user-testing/WEB_Blender_Desktop_Menus_20260916/runs/2026-09-16T16-13-46-733Z/MENU-10/01-workspace-cycle.png",
"file": "screenshots/09-MENU-10.png"
},
{
"chapter": 10,
"case": "MENU-12",
"source": "user-testing/WEB_Blender_Desktop_Menus_20260916/runs/2026-09-16T16-13-46-733Z/MENU-12/02-explicit-unavailable.png",
"file": "screenshots/10-MENU-12.png"
},
{
"chapter": 11,
"case": "MENU-17",
"source": "user-testing/WEB_Blender_Desktop_Menus_20260916/runs/2026-09-16T16-13-46-733Z/MENU-17/01-compact-menu.png",
"file": "screenshots/11-MENU-17.png"
}
]

File diff suppressed because one or more lines are too long

Binary file not shown.

After

Width:  |  Height:  |  Size: 180 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 190 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 180 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 165 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 177 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 176 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 127 KiB

Some files were not shown because too many files have changed in this diff Show More