From 9b449186484c06afe9aae424f1a1cbd15dfd86d0 Mon Sep 17 00:00:00 2001 From: laluo <2135665716@qq.com> Date: Tue, 11 Aug 2026 09:50:40 +0800 Subject: [PATCH] =?UTF-8?q?docs:=20=E6=94=B6=E5=8F=A3R1=20Face=E9=98=B6?= =?UTF-8?q?=E6=AE=B5=E9=AA=8C=E6=94=B6=E5=8F=A3=E5=BE=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- README.md | 33 ++++++++++------ scripts/verify_face_ui_isolation_contract.py | 9 +++++ scripts/verify_first_level_acceptance_docs.py | 7 ++++ step_editor/window_actions.py | 38 ++++++++++++++----- 4 files changed, 66 insertions(+), 21 deletions(-) diff --git a/README.md b/README.md index 4e453e4..6fb2b9c 100644 --- a/README.md +++ b/README.md @@ -175,6 +175,12 @@ git diff --check - `[~]` 部分实现/进行中:已有识别、计划或部分模型编辑能力,但真实 STEP 上还需要继续补守门、补失败解释或补局部重建。 - `[ ]` 未实现:作为后续目标保留,当前不应在 UI 里伪装成可稳定修改。 +验收口径: + +- `[x]` 不是“所有 CAD 形态都能改”,而是“当前声明支持的模型范围已经有 UI/后端/回归测试闭环”。 +- R1 Face 是当前主线的第一阶段收口对象;孔、槽、凸台、圆角、壳体和 Edge 已有各自一级基线,但仍按模型工程师给出的真实 STEP 失败项继续补边界。 +- R8 的二级/三级传播、跨特征约束和特征组联动不算在 0~7 完成度里,不能拿它反向判定 R1 Face 没完成。 + ```text STEP/B-Rep 参数化编辑主线 ├── 0. 先让用户知道“能不能改” @@ -748,25 +754,30 @@ vertices: 3262 当前整体验证基线: - 2026-08-06,在 `pyocc` 环境下已通过 `python scripts\verify_first_level_edit_suites.py --stage face`,覆盖 Face 专项套件和 Face isolated worker。 +- 2026-08-11,在 `pyocc` 环境下已通过 `python scripts\verify_first_level_edit_suites.py --stage face`,覆盖 R1 Face 专项套件、Face isolated worker、保持关系隔离契约和 Face 阶段收口口径。 - 2026-08-06,在 `pyocc` 环境下已通过 `python scripts\verify_first_level_edit_suites.py --stage hole-slot`,覆盖孔/槽一级拓扑、局部重建和 isolated worker。 - 2026-08-06,在 `pyocc` 环境下已通过 `python scripts\verify_first_level_edit_suites.py --stage edge`,覆盖 Edge 一级拓扑、长度建模意图、坐标修改、圆角/倒角、椭圆 Edge 和 isolated worker。 - 2026-08-06,在 `pyocc` 环境下已通过 `python scripts\verify_first_level_edit_suites.py --stage boss --stage round-chamfer --stage shell --stage analytic`,覆盖凸台、圆角/倒角、壳体厚度和解析曲面。 - 2026-08-06,在 `pyocc` 环境下已通过 `python scripts\verify_first_level_edit_suites.py --quick`,覆盖 smoke test、属性表规格、参数表 UI、特征识别优先级、一级事实图、关联探测、显示网格预算和一级验收文档一致性。 -Face 阶段的当前验收口径: +Face 阶段的当前验收口径(R1 已收口): -- 当前阶段的 `一级关系` 定义为:选中 Face 本身、必要的同域/共面碎片 Face、这些 Face 的边界 Edge/Vertex,以及与该区域共享边的直接相邻 Face。只共享顶点的对象、相邻 Face 再连出去的 Face 都不作为当前阶段的自动传播范围。 -- 选中平面 Face 时,程序会生成 `一级关系` 事实包,记录当前 Face 区域数量、边界 Edge/Vertex 数量、共享边相邻 Face 数量,并明确二级、三级关系暂不自动传播;这些事实用于计划、校验和诊断,不再作为特征参数行显示。 -- `python scripts\verify_face_edit_suite.py` 必须通过,集中覆盖面内长度/面内宽度、中心、偏移、壳体厚度、拉伸/切除、局部变形禁用、目标值保护、属性回读、逻辑 Face ID 保持,以及 UI 里标题/复制 ID/按 ID 选择是否优先使用逻辑 Face ID。 +- 已验收:平面 Face 的 `面内长度`、`面内宽度`、`中心`、`偏移`,以及壳体厚度、圆柱端盖/圆柱侧面高度这类挂在 Face 入口上的高频编辑;支持 `局部重建`、`拉伸/切除`、`移动特征`、`缩放特征` 和受限的 `保持关系`。 +- 已验收:Face 的 `一级关系` 定义为选中 Face 本身、必要的同域/共面碎片 Face、这些 Face 的边界 Edge/Vertex,以及与该区域共享边的直接相邻 Face。只共享顶点的对象、相邻 Face 再连出去的 Face 都不作为 R1 自动传播范围。 +- 已验收:选中平面 Face 时,程序会生成 `一级关系` 事实包,记录当前 Face 区域、同域/共面碎片、一级平行/垂直关系、一级同轴圆柱事实、边界 Edge/Vertex、共享边相邻 Face,并明确二级、三级关系暂不自动传播;这些事实用于计划、校验和诊断,不再作为特征参数行显示。 +- 可用但受限:带内孔平面、曲面 Solid 上的平面、自由曲面、非矩形面、复杂端盖、接近切穿的内切等场景会按明确守门执行;能稳定改就走隔离/回滚,不能稳定改就提前 blocked 并说明原因。 +- 未实现/不承诺:原 CAD 历史恢复、任意复杂 Face 的通用局部重建、孔底/槽底/台阶等二级/三级传播、跨特征约束求解和特征组联动;这些属于 R8,不算 R1 未完成项。 +- `python scripts\verify_first_level_edit_suites.py --stage face` 必须通过,集中运行 R1 Face 专项套件和 Face isolated worker。 +- `python scripts\verify_face_edit_suite.py` 必须通过,集中覆盖面内长度/面内宽度、中心、偏移、保持关系、壳体厚度、拉伸/切除、局部变形禁用、目标值保护、属性回读、逻辑 Face ID 保持,以及 UI 里标题/复制 ID/按 ID 选择是否优先使用逻辑 Face ID。 - `python scripts\verify_property_editor_specs.py` 必须通过,确保平面 Face 的特征参数表使用 `面内长度`、`面内宽度`、`中心`、`偏移` 这些用户可理解的名称,且不把面积暴露成可编辑驱动参数,并递归检查提示文字里不再出现容易误解的旧词。 - `python scripts\verify_face_first_level_topology.py` 必须通过,确保普通正方体 Face 的一级关系能识别 4 条边界 Edge、4 个边界 Vertex、4 个共享边相邻 Face,并证明局部移动后目标 Face 的边界 Vertex 与共享边 Edge 已到新位置、一级侧面跟随重建、二级底面不跟随移动。 -- `python scripts\verify_cylindrical_first_level_topology.py` 必须通过,确保孔/槽类圆柱特征的计划层已经能识别圆柱侧壁、边界 Edge/Vertex、直接相邻 Face、底面/开口面/槽边界面,并明确二级、三级关系暂不自动传播。一级关系用于计划、校验和诊断,不再占用特征参数表;结果校验会拒绝虽然尺寸匹配但一级邻域明显弱于计划要求的圆柱结果。后续继续把这些一级关系用于更细的孔/槽实际重建策略。 -- `python scripts\verify_hole_slot_edit_suite.py` 必须通过,集中覆盖孔/槽一级拓扑、孔径/孔轴心/孔封堵、盲孔/盲槽深度、槽宽/槽深/弧长/弧角、长圆槽总长度/中心距、隔离执行、逻辑 Face ID 保持和属性表分组。 -- `python scripts\verify_boss_edit_suite.py` 必须通过,集中覆盖凸台一级拓扑、凸台直径/高度/轴心局部重建、圆 Edge 代理到凸台轴心移动,以及属性表分组。 -- `python scripts\verify_round_chamfer_edit_suite.py` 必须通过,集中覆盖新增圆角/倒角、已有圆角重建、简单等半径圆角链重建、四面连通链重建、结果反查、失败回滚和一级邻域守门。 -- `python scripts\verify_shell_edit_suite.py` 必须通过,集中覆盖壳体厚度的局部拉伸/切除、缩放特征语义、Face 一级关系计划字段和结果校验。 -- 对不能稳定做 `局部重建` 的 Face,要禁用该建模意图,并在提示中说明原因;不能让复杂内孔、曲面 Solid 或复杂边界静悄悄走高风险局部变形。 -- Face 一级关系闭环后,当前优先把槽/孔一级关系阶段补成独立闭环;槽/孔的一级邻域、局部重建和隔离执行稳定后,再继续推进 Edge 与其它特征阶段。 + +0~7 其它阶段的当前基线: + +- `python scripts\verify_first_level_edit_suites.py --stage hole-slot` 覆盖孔/槽一级拓扑、局部重建、隔离执行和属性表分组。孔组、阵列孔、多槽组联动仍属于 R8。 +- `python scripts\verify_first_level_edit_suites.py --stage edge` 覆盖 Edge 一级拓扑、长度建模意图、坐标修改、圆角/倒角、椭圆 Edge 和 isolated worker。任意曲线 Edge 通用约束编辑仍未开放。 +- `python scripts\verify_first_level_edit_suites.py --stage boss --stage round-chamfer --stage shell --stage analytic` 覆盖凸台、圆角/倒角、壳体厚度和解析曲面当前可用范围。复杂链式特征、通用抽壳历史恢复和跨特征传播仍不承诺。 +- R1 Face 收口后,下一步优先把 R2/R3 孔槽阶段也拆成“已验收 / 可用但受限 / 未实现”,再继续 Edge 与其它特征的同样收口。 ## 怎么使用 diff --git a/scripts/verify_face_ui_isolation_contract.py b/scripts/verify_face_ui_isolation_contract.py index 3c8daae..f109295 100644 --- a/scripts/verify_face_ui_isolation_contract.py +++ b/scripts/verify_face_ui_isolation_contract.py @@ -19,8 +19,10 @@ EXPECTED_FACE_ISOLATED_OPERATIONS = { "resize_face_area_local", "resize_face_area", "resize_face_size_local", + "resize_face_size_local_keep_relations", "resize_face_size_owning_scale", "move_face_center_local", + "move_face_center_local_keep_relations", "resize_shell_thickness", "resize_shell_thickness_owning_scale", "resize_cylindrical_height", @@ -127,9 +129,12 @@ PROPERTY_FACE_ACTION_TO_ISOLATED_OPERATION = { "move_selected_face_plane_position_local": "move_face_plane_offset_local", "resize_face_width_local": "resize_face_size_local", "resize_face_height_local": "resize_face_size_local", + "resize_face_width_keep_relations": "resize_face_size_local_keep_relations", + "resize_face_height_keep_relations": "resize_face_size_local_keep_relations", "resize_face_width_owning_scale": "resize_face_size_owning_scale", "resize_face_height_owning_scale": "resize_face_size_owning_scale", "move_selected_face_center_local": "move_face_center_local", + "move_selected_face_center_keep_relations": "move_face_center_local_keep_relations", "resize_shell_thickness": "resize_shell_thickness", "resize_shell_thickness_owning_scale": "resize_shell_thickness_owning_scale", "resize_cylinder_height": "resize_cylindrical_height", @@ -157,8 +162,12 @@ ACTION_IMPLEMENTATION_METHOD = { "push_pull_face_keep_relations": "_push_pull_face_action", "resize_face_width_local": "_resize_face_size_local", "resize_face_height_local": "_resize_face_size_local", + "resize_face_width_keep_relations": "_resize_face_size_local", + "resize_face_height_keep_relations": "_resize_face_size_local", "resize_face_width_owning_scale": "_resize_face_size_owning_scale", "resize_face_height_owning_scale": "_resize_face_size_owning_scale", + "move_selected_face_center_local": "_move_selected_face_center_local", + "move_selected_face_center_keep_relations": "_move_selected_face_center_local", "resize_torus_major_radius": "_resize_torus_radius", "resize_torus_minor_radius": "_resize_torus_radius", } diff --git a/scripts/verify_first_level_acceptance_docs.py b/scripts/verify_first_level_acceptance_docs.py index fb4ce23..69a3f5f 100644 --- a/scripts/verify_first_level_acceptance_docs.py +++ b/scripts/verify_first_level_acceptance_docs.py @@ -52,9 +52,16 @@ def _verify_readme_mentions(readme: str) -> None: "`[x]` 已实现", "`[~]` 部分实现/进行中", "`[ ]` 未实现", + "`[x]` 不是“所有 CAD 形态都能改”", + "R1 Face 是当前主线的第一阶段收口对象", + "R8 的二级/三级传播、跨特征约束和特征组联动不算在 0~7 完成度里", "STEP/B-Rep 参数化编辑主线", "[不能修改 -> 立即说明原因]", "[一级影响范围 -> 明确显示]", + "Face 阶段的当前验收口径(R1 已收口)", + "已验收:平面 Face 的 `面内长度`、`面内宽度`、`中心`、`偏移`", + "未实现/不承诺:原 CAD 历史恢复、任意复杂 Face 的通用局部重建", + "0~7 其它阶段的当前基线", "verify_first_level_edit_suites.py --quick", "verify_first_level_edit_suites.py --stage face", "verify_first_level_edit_suites.py --stage hole-slot", diff --git a/step_editor/window_actions.py b/step_editor/window_actions.py index 6eaead0..10d6460 100644 --- a/step_editor/window_actions.py +++ b/step_editor/window_actions.py @@ -5999,6 +5999,19 @@ class WindowActionMixin: return self.model.resize_face_size_local_keep_relations(face_id, target_size, axis_key) return self.model.resize_face_size_local(face_id, target_size, axis_key) + if keep_relations: + isolation = self._isolation_for_plan( + plan, + "resize_face_size_local_keep_relations", + [face_id, target_size, axis_key], + ) + else: + isolation = self._isolation_for_plan( + plan, + "resize_face_size_local", + [face_id, target_size, axis_key], + ) + self._run_edit_action( action, operation_name=f"修改{mode_label}", @@ -6044,11 +6057,7 @@ class WindowActionMixin: }, target_kind="face", target_id=face_id, - isolation=self._isolation_for_plan( - plan, - "resize_face_size_local_keep_relations" if keep_relations else "resize_face_size_local", - [face_id, target_size, axis_key], - ), + isolation=isolation, ) def _resize_face_size_owning_scale(self, axis: str) -> None: @@ -6453,6 +6462,19 @@ class WindowActionMixin: return self.model.move_face_center_local_keep_relations(face_id, target_center) return self.model.move_face_center_local(face_id, target_center) + if keep_relations: + isolation = self._isolation_for_plan( + plan, + "move_face_center_local_keep_relations", + [face_id, list(target_center)], + ) + else: + isolation = self._isolation_for_plan( + plan, + "move_face_center_local", + [face_id, list(target_center)], + ) + self._run_edit_action( action, operation_name=mode_label, @@ -6488,11 +6510,7 @@ class WindowActionMixin: }, target_kind="face", target_id=face_id, - isolation=self._isolation_for_plan( - plan, - "move_face_center_local_keep_relations" if keep_relations else "move_face_center_local", - [face_id, list(target_center)], - ), + isolation=isolation, ) def move_selected_axis_center_by_translation(self) -> None: