feat: 完善Face保持关系守门与大模型预判
This commit is contained in:
+16
-1
@@ -729,6 +729,14 @@ class StepModel(FeatureMixin, ExportMixin, TransformMixin, OperationMixin, Polyd
|
||||
center=_tuple_or_none(info.get("area_center")),
|
||||
)
|
||||
)
|
||||
try:
|
||||
info.update(self.face_first_level_topology(face_id))
|
||||
info.update(self.face_first_level_facts(face_id, scope="face"))
|
||||
except Exception as exc:
|
||||
info.setdefault("topology_relation_status", "unavailable")
|
||||
info.setdefault("topology_relation_message", str(exc))
|
||||
info.setdefault("first_level_planar_relation_status", "unavailable")
|
||||
info.setdefault("first_level_planar_relation_summary", str(exc))
|
||||
elif surface_type == GeomAbs_Cylinder:
|
||||
cyl = surf.Cylinder()
|
||||
axis = cyl.Axis()
|
||||
@@ -1737,6 +1745,12 @@ class StepModel(FeatureMixin, ExportMixin, TransformMixin, OperationMixin, Polyd
|
||||
) -> dict[str, object]:
|
||||
if info.get("surface") != "plane":
|
||||
return {}
|
||||
boundary_edge_ids = self._face_boundary_edge_ids(face_id)
|
||||
inner_boundary_wires = int(info.get("inner_boundary_wires", 0) or 0)
|
||||
if inner_boundary_wires > 1:
|
||||
return {}
|
||||
if inner_boundary_wires == 1 and len(boundary_edge_ids) < 6:
|
||||
return {}
|
||||
if str(prismatic_info.get("prismatic_feature_semantics") or "") in {"additive-boss", "subtractive-pocket"}:
|
||||
return {}
|
||||
try:
|
||||
@@ -1748,7 +1762,6 @@ class StepModel(FeatureMixin, ExportMixin, TransformMixin, OperationMixin, Polyd
|
||||
except Exception:
|
||||
return {}
|
||||
|
||||
boundary_edge_ids = self._face_boundary_edge_ids(face_id)
|
||||
adjacent_face_ids = sorted(set(self._adjacent_face_ids_for_edges(boundary_edge_ids, face_id)) - {face_id})
|
||||
if len(adjacent_face_ids) < 6:
|
||||
return {}
|
||||
@@ -2340,6 +2353,8 @@ class StepModel(FeatureMixin, ExportMixin, TransformMixin, OperationMixin, Polyd
|
||||
shell_info: dict[str, object],
|
||||
prismatic_info: dict[str, object],
|
||||
) -> dict[str, object]:
|
||||
if bool(info.get("has_inner_boundaries")) or int(info.get("inner_boundary_wires", 0) or 0) > 0:
|
||||
return {}
|
||||
try:
|
||||
solid_id = int(info.get("solid_id", -1))
|
||||
except (TypeError, ValueError):
|
||||
|
||||
@@ -369,6 +369,19 @@ class OperationMixin:
|
||||
return plan
|
||||
|
||||
def _multistep_prismatic_plan_blocker(self, face_id: int, operation_label: str) -> str:
|
||||
try:
|
||||
quick_info = self.quick_face_info(face_id)
|
||||
except Exception:
|
||||
quick_info = {}
|
||||
if quick_info:
|
||||
if str(quick_info.get("surface") or "") != "plane":
|
||||
return ""
|
||||
inner_boundary_wires = int(quick_info.get("inner_boundary_wires", 0) or 0)
|
||||
boundary_edges = int(quick_info.get("boundary_edges", 0) or 0)
|
||||
if inner_boundary_wires > 1:
|
||||
return ""
|
||||
if inner_boundary_wires == 1 and boundary_edges < 6:
|
||||
return ""
|
||||
try:
|
||||
feature = self.feature_info(face_id)
|
||||
except Exception:
|
||||
|
||||
@@ -2466,13 +2466,37 @@ class WindowStateMixin:
|
||||
root_specs: list[dict[str, object]],
|
||||
action_info: dict[str, object],
|
||||
) -> list[dict[str, object]]:
|
||||
root_rows = self._feature_property_specs(root_specs, action_info)
|
||||
associated = action_info.get("associated_feature_infos")
|
||||
if not isinstance(associated, (list, tuple)) or not associated:
|
||||
return root_rows
|
||||
def no_editable_feature_dimensions_spec() -> dict[str, object]:
|
||||
reason = str(
|
||||
action_info.get("freeform_face_blockers")
|
||||
or action_info.get("recognition_blockers")
|
||||
or action_info.get("local_face_deform_blocker")
|
||||
or action_info.get("feature_edit_actions")
|
||||
or "当前识别结果没有稳定可修改参数;详细原因请看诊断信息。"
|
||||
).strip()
|
||||
if not reason:
|
||||
reason = "当前识别结果没有稳定可修改参数;详细原因请看诊断信息。"
|
||||
return {
|
||||
"key": "no_editable_feature_dimensions",
|
||||
"label": "可修改参数",
|
||||
"current_text": "当前无可修改参数",
|
||||
"current_raw": "",
|
||||
"target_text": "",
|
||||
"editable": False,
|
||||
"enabled": False,
|
||||
"status_text": "不可修改",
|
||||
"disabled_tip": reason,
|
||||
"span_value_columns": True,
|
||||
"parameter_role": "empty_state",
|
||||
}
|
||||
|
||||
root_rows = self._feature_property_specs(root_specs, action_info)
|
||||
root_dimensions = [dict(spec) for spec in root_rows if spec.get("parameter_role") == "dimension"]
|
||||
related_rows: list[dict[str, object]] = []
|
||||
associated = action_info.get("associated_feature_infos")
|
||||
if not isinstance(associated, (list, tuple)) or not associated:
|
||||
return root_dimensions or [no_editable_feature_dimensions_spec()]
|
||||
|
||||
for index, related_info in enumerate(associated, start=1):
|
||||
if not isinstance(related_info, dict):
|
||||
continue
|
||||
@@ -2492,7 +2516,8 @@ class WindowStateMixin:
|
||||
related["association_index"] = index
|
||||
related_rows.append(related)
|
||||
|
||||
return root_dimensions + related_rows
|
||||
rows = root_dimensions + related_rows
|
||||
return rows or [no_editable_feature_dimensions_spec()]
|
||||
|
||||
def _ordered_property_info_items(self, info: dict[str, object]) -> list[tuple[str, object]]:
|
||||
items = self._ordered_info_items(info)
|
||||
@@ -3572,6 +3597,43 @@ class WindowStateMixin:
|
||||
+ plane_origin[1] * plane_direction[1]
|
||||
+ plane_origin[2] * plane_direction[2]
|
||||
)
|
||||
keep_relation_fields_present = any(
|
||||
key in action_info
|
||||
for key in (
|
||||
"first_level_planar_relation_status",
|
||||
"first_level_planar_relation_count",
|
||||
"first_level_planar_relation_angled_count",
|
||||
"first_level_planar_relation_non_planar_face_ids",
|
||||
"first_level_adjacent_surface_types",
|
||||
)
|
||||
)
|
||||
keep_relation_enabled = current_plane_position is not None
|
||||
keep_relation_disabled_tip = "当前平面缺少稳定移动方向或基准点,不能保持一级平面关系。"
|
||||
if keep_relation_enabled and keep_relation_fields_present:
|
||||
relation_status = str(action_info.get("first_level_planar_relation_status") or "")
|
||||
relation_count = _int_or_none(action_info.get("first_level_planar_relation_count")) or 0
|
||||
angled_count = _int_or_none(action_info.get("first_level_planar_relation_angled_count")) or 0
|
||||
non_planar_face_ids = _int_values(action_info.get("first_level_planar_relation_non_planar_face_ids"))
|
||||
adjacent_surfaces = tuple(action_info.get("first_level_adjacent_surface_types") or ())
|
||||
non_plane_adjacent_surfaces = tuple(
|
||||
item
|
||||
for item in adjacent_surfaces
|
||||
if isinstance(item, (tuple, list))
|
||||
and len(item) >= 2
|
||||
and str(item[1]) != "plane"
|
||||
)
|
||||
if non_planar_face_ids or non_plane_adjacent_surfaces:
|
||||
keep_relation_enabled = False
|
||||
keep_relation_disabled_tip = "一级相邻 Face 中包含非平面/曲面,当前“保持关系”只支持平面邻域。"
|
||||
elif angled_count > 0:
|
||||
keep_relation_enabled = False
|
||||
keep_relation_disabled_tip = "一级相邻平面中存在斜交关系,当前“保持关系”只支持平行/垂直。"
|
||||
elif relation_status != "ready":
|
||||
keep_relation_enabled = False
|
||||
keep_relation_disabled_tip = "当前一级平面关系还不可验证,不能使用“保持关系”。"
|
||||
elif relation_count <= 0:
|
||||
keep_relation_enabled = False
|
||||
keep_relation_disabled_tip = "当前一级邻域没有识别到可保持的平行/垂直平面关系。"
|
||||
add_scoped_spec(
|
||||
key="face_target_normal_position",
|
||||
label="偏移",
|
||||
@@ -3598,12 +3660,12 @@ class WindowStateMixin:
|
||||
"label": "保持关系",
|
||||
"action": "push_pull_face_keep_relations",
|
||||
"target_attr": "offset_input",
|
||||
"enabled": current_plane_position is not None,
|
||||
"enabled": keep_relation_enabled,
|
||||
"enabled_tip": (
|
||||
"输入偏移的目标位置;程序会沿当前 Face 法向拉伸/切除,"
|
||||
"并要求一级相邻平面的平行/垂直关系可验证。"
|
||||
),
|
||||
"disabled_tip": "当前平面缺少稳定移动方向或基准点,不能保持一级平面关系。",
|
||||
"disabled_tip": keep_relation_disabled_tip,
|
||||
"range_hint": (
|
||||
"这是带约束守门的拉伸/切除:只支持直接相邻平面关系清楚、且关系为平行/垂直的一级邻域;"
|
||||
"遇到非平面相邻面、斜交关系或复杂多边界慢计划会直接阻止。"
|
||||
|
||||
Reference in New Issue
Block a user