feat: 完善 Face 一级关系编辑和稳定性校验
This commit is contained in:
+236
-33
@@ -30,6 +30,7 @@ PROPERTY_ACTION_COLUMN = 4
|
||||
|
||||
FEATURE_EDIT_SEMANTICS_KEYS = {
|
||||
"face_first_level_topology",
|
||||
"cylindrical_feature_first_level_topology",
|
||||
"slot_edit_semantics",
|
||||
"hole_edit_semantics",
|
||||
"boss_edit_semantics",
|
||||
@@ -160,6 +161,26 @@ class WindowStateMixin:
|
||||
enriched["pick_position"] = pick_position
|
||||
return enriched
|
||||
|
||||
def _first_level_fact_selection_fields(self, face_id: int, scope: str = "auto") -> dict[str, object]:
|
||||
if self.model is None:
|
||||
return {}
|
||||
try:
|
||||
return self.model.face_first_level_facts(face_id, scope=scope)
|
||||
except Exception as exc:
|
||||
return {
|
||||
"first_level_fact_model": "STEP/B-Rep first-level fact graph",
|
||||
"first_level_fact_status": "unavailable",
|
||||
"first_level_fact_relation_depth": 1,
|
||||
"first_level_fact_scope": scope,
|
||||
"first_level_fact_subject_face_ids": (face_id,),
|
||||
"first_level_fact_subject_face_count": 1,
|
||||
"first_level_fact_boundary_edge_count": 0,
|
||||
"first_level_fact_boundary_vertex_count": 0,
|
||||
"first_level_fact_adjacent_face_count": 0,
|
||||
"first_level_fact_ignored_relation_depths": ("second-level", "third-level", "deeper"),
|
||||
"first_level_fact_summary": f"当前 Face 的一级事实图暂时无法生成:{exc}",
|
||||
}
|
||||
|
||||
def _face_first_level_selection_fields(self, face_id: int) -> dict[str, object]:
|
||||
if self.model is None:
|
||||
return {}
|
||||
@@ -198,6 +219,70 @@ class WindowStateMixin:
|
||||
"first_level_face_ids": topology.get("first_level_face_ids", (face_id,)),
|
||||
"first_level_face_count": topology.get("first_level_face_count", 1),
|
||||
"first_level_topology_note": topology.get("first_level_topology_note", ""),
|
||||
**self._first_level_fact_selection_fields(face_id, scope="face"),
|
||||
}
|
||||
|
||||
def _cylindrical_first_level_selection_fields(self, face_id: int) -> dict[str, object]:
|
||||
if self.model is None:
|
||||
return {}
|
||||
try:
|
||||
topology = self.model.cylindrical_feature_first_level_topology(face_id)
|
||||
except Exception as exc:
|
||||
return {
|
||||
"topology_relation_depth": 1,
|
||||
"topology_relation_model": "STEP/B-Rep cylindrical-feature shared-edge first-level",
|
||||
"topology_relation_status": "unavailable",
|
||||
"topology_relation_message": str(exc),
|
||||
"topology_ignored_relation_depths": ("second-level", "third-level", "deeper"),
|
||||
"topology_ignored_relation_note": "当前阶段只传播一级关系;二级、三级拓扑暂不自动递归编辑。",
|
||||
"cylindrical_feature_side_face_count": 1,
|
||||
"cylindrical_feature_boundary_edge_count": 0,
|
||||
"cylindrical_feature_boundary_vertex_count": 0,
|
||||
"cylindrical_feature_adjacent_face_count": 0,
|
||||
"cylindrical_feature_end_face_count": 0,
|
||||
"cylindrical_feature_bottom_face_count": 0,
|
||||
"cylindrical_feature_opening_face_count": 0,
|
||||
"cylindrical_feature_slot_boundary_face_count": 0,
|
||||
"first_level_topology_note": f"当前圆柱特征的一级关系暂时无法确认:{exc}",
|
||||
}
|
||||
return {
|
||||
"topology_relation_depth": topology.get("topology_relation_depth", 1),
|
||||
"topology_relation_model": topology.get("topology_relation_model"),
|
||||
"topology_relation_scope": topology.get("topology_relation_scope"),
|
||||
"topology_relation_boundary": topology.get("topology_relation_boundary"),
|
||||
"topology_relation_status": "ready",
|
||||
"topology_ignored_relation_depths": topology.get("topology_ignored_relation_depths", ()),
|
||||
"topology_ignored_relation_note": topology.get("topology_ignored_relation_note", ""),
|
||||
"first_level_boundary_edge_ids": topology.get("cylindrical_feature_boundary_edge_ids", ()),
|
||||
"first_level_boundary_edge_count": topology.get("cylindrical_feature_boundary_edge_count", 0),
|
||||
"first_level_boundary_vertex_count": topology.get("cylindrical_feature_boundary_vertex_count", 0),
|
||||
"first_level_adjacent_face_ids": topology.get("cylindrical_feature_adjacent_face_ids", ()),
|
||||
"first_level_adjacent_face_count": topology.get("cylindrical_feature_adjacent_face_count", 0),
|
||||
"first_level_face_ids": topology.get("cylindrical_feature_first_level_face_ids", (face_id,)),
|
||||
"first_level_face_count": topology.get("cylindrical_feature_first_level_face_count", 1),
|
||||
"first_level_topology_note": topology.get("first_level_topology_note", ""),
|
||||
"cylindrical_feature_side_face_ids": topology.get("cylindrical_feature_side_face_ids", (face_id,)),
|
||||
"cylindrical_feature_side_face_count": topology.get("cylindrical_feature_side_face_count", 1),
|
||||
"cylindrical_feature_boundary_edge_ids": topology.get("cylindrical_feature_boundary_edge_ids", ()),
|
||||
"cylindrical_feature_boundary_edge_count": topology.get("cylindrical_feature_boundary_edge_count", 0),
|
||||
"cylindrical_feature_boundary_vertex_count": topology.get("cylindrical_feature_boundary_vertex_count", 0),
|
||||
"cylindrical_feature_adjacent_face_ids": topology.get("cylindrical_feature_adjacent_face_ids", ()),
|
||||
"cylindrical_feature_adjacent_face_count": topology.get("cylindrical_feature_adjacent_face_count", 0),
|
||||
"cylindrical_feature_end_face_ids": topology.get("cylindrical_feature_end_face_ids", ()),
|
||||
"cylindrical_feature_end_face_count": topology.get("cylindrical_feature_end_face_count", 0),
|
||||
"cylindrical_feature_bottom_face_ids": topology.get("cylindrical_feature_bottom_face_ids", ()),
|
||||
"cylindrical_feature_bottom_face_count": topology.get("cylindrical_feature_bottom_face_count", 0),
|
||||
"cylindrical_feature_opening_face_ids": topology.get("cylindrical_feature_opening_face_ids", ()),
|
||||
"cylindrical_feature_opening_face_count": topology.get("cylindrical_feature_opening_face_count", 0),
|
||||
"cylindrical_feature_slot_boundary_face_ids": topology.get(
|
||||
"cylindrical_feature_slot_boundary_face_ids",
|
||||
(),
|
||||
),
|
||||
"cylindrical_feature_slot_boundary_face_count": topology.get(
|
||||
"cylindrical_feature_slot_boundary_face_count",
|
||||
0,
|
||||
),
|
||||
**self._first_level_fact_selection_fields(face_id, scope="cylindrical-feature"),
|
||||
}
|
||||
|
||||
def _feature_info_for_selected_face(self, face_id: int, fallback_info: dict[str, object]) -> dict[str, object]:
|
||||
@@ -275,6 +360,8 @@ class WindowStateMixin:
|
||||
root_info = self.model.feature_info(face_id)
|
||||
if str(root_info.get("surface", "") or "") == "plane":
|
||||
root_info.update(self._face_first_level_selection_fields(face_id))
|
||||
elif str(root_info.get("surface", "") or "") == "cylinder" and detection_level != "current-only":
|
||||
root_info.update(self._cylindrical_first_level_selection_fields(face_id))
|
||||
associated: list[dict[str, object]] = []
|
||||
if detection_level in {"associated-only", "secondary"}:
|
||||
try:
|
||||
@@ -323,6 +410,10 @@ class WindowStateMixin:
|
||||
),
|
||||
}
|
||||
)
|
||||
try:
|
||||
info.update(self.model._recognition_summary_fields(info))
|
||||
except Exception:
|
||||
pass
|
||||
return info
|
||||
|
||||
def _current_feature_detection_level(self) -> str:
|
||||
@@ -1615,6 +1706,38 @@ class WindowStateMixin:
|
||||
is_hole_or_groove = is_cylinder and feature_guess == "hole/groove candidate"
|
||||
is_boss = is_cylinder and feature_guess == "boss/outer-round candidate"
|
||||
is_existing_fillet = is_cylinder and feature_guess == "round/fillet candidate"
|
||||
recognition_fields_present = any(
|
||||
key in action_info
|
||||
for key in (
|
||||
"recognition_score",
|
||||
"recognition_confidence",
|
||||
"recognition_risk",
|
||||
"recognition_blockers",
|
||||
)
|
||||
)
|
||||
recognition_score = _int_or_none(action_info.get("recognition_score"))
|
||||
recognition_confidence = str(action_info.get("recognition_confidence") or "").strip()
|
||||
recognition_risk = str(action_info.get("recognition_risk") or "").strip()
|
||||
recognition_blockers = str(action_info.get("recognition_blockers") or "").strip()
|
||||
analytic_surface_recognition_ready = (
|
||||
not recognition_fields_present
|
||||
or (
|
||||
recognition_risk != "blocked"
|
||||
and not recognition_blockers
|
||||
and recognition_confidence not in {"low", "none"}
|
||||
and (recognition_score is None or recognition_score >= 56)
|
||||
)
|
||||
)
|
||||
analytic_surface_recognition_reason = ""
|
||||
if not analytic_surface_recognition_ready:
|
||||
score_text = _format_float(float(recognition_score)) if recognition_score is not None else "未知"
|
||||
confidence_text = recognition_confidence or "未知"
|
||||
risk_text = recognition_risk or "未知"
|
||||
analytic_surface_recognition_reason = (
|
||||
f"当前解析曲面识别还不够稳定:评分 {score_text},置信度 {confidence_text},风险 {risk_text}。"
|
||||
)
|
||||
if recognition_blockers:
|
||||
analytic_surface_recognition_reason = f"{analytic_surface_recognition_reason} 限制:{recognition_blockers}"
|
||||
is_full_cylinder = angular_span is not None and angular_span >= math.tau * 0.92
|
||||
is_slot_or_half_hole = (
|
||||
is_hole_or_groove
|
||||
@@ -1970,6 +2093,62 @@ class WindowStateMixin:
|
||||
)
|
||||
|
||||
if has_face:
|
||||
topology_depth = _int_or_none(action_info.get("topology_relation_depth"))
|
||||
is_cylindrical_topology = bool(
|
||||
is_cylinder
|
||||
and topology_depth == 1
|
||||
and (
|
||||
"cylindrical_feature_side_face_count" in action_info
|
||||
or "cylindrical-feature" in str(action_info.get("topology_relation_model") or "")
|
||||
)
|
||||
)
|
||||
if is_cylindrical_topology:
|
||||
side_count = _int_or_none(action_info.get("cylindrical_feature_side_face_count")) or 0
|
||||
boundary_edge_count = _int_or_none(action_info.get("cylindrical_feature_boundary_edge_count")) or 0
|
||||
boundary_vertex_count = _int_or_none(action_info.get("cylindrical_feature_boundary_vertex_count")) or (
|
||||
_int_or_none(action_info.get("first_level_boundary_vertex_count")) or 0
|
||||
)
|
||||
adjacent_face_count = _int_or_none(action_info.get("cylindrical_feature_adjacent_face_count")) or 0
|
||||
end_face_count = _int_or_none(action_info.get("cylindrical_feature_end_face_count")) or 0
|
||||
bottom_face_count = _int_or_none(action_info.get("cylindrical_feature_bottom_face_count")) or 0
|
||||
opening_face_count = _int_or_none(action_info.get("cylindrical_feature_opening_face_count")) or 0
|
||||
slot_boundary_face_count = (
|
||||
_int_or_none(action_info.get("cylindrical_feature_slot_boundary_face_count")) or 0
|
||||
)
|
||||
relation_parts = [
|
||||
f"侧壁 Face {side_count} 个",
|
||||
f"边界 Edge {boundary_edge_count} 条",
|
||||
f"边界 Vertex {boundary_vertex_count} 个",
|
||||
f"共享边相邻 Face {adjacent_face_count} 个",
|
||||
]
|
||||
detail_parts = []
|
||||
if end_face_count:
|
||||
detail_parts.append(f"端面/开口 Face {end_face_count} 个")
|
||||
if bottom_face_count:
|
||||
detail_parts.append(f"底面 Face {bottom_face_count} 个")
|
||||
if opening_face_count:
|
||||
detail_parts.append(f"开口 Face {opening_face_count} 个")
|
||||
if slot_boundary_face_count:
|
||||
detail_parts.append(f"槽边界 Face {slot_boundary_face_count} 个")
|
||||
topology_note = str(action_info.get("first_level_topology_note") or "").strip()
|
||||
ignored_note = str(action_info.get("topology_ignored_relation_note") or "").strip()
|
||||
status_message = str(action_info.get("topology_relation_message") or "").strip()
|
||||
topology_tip = "\n".join(
|
||||
item
|
||||
for item in (
|
||||
topology_note,
|
||||
ignored_note,
|
||||
status_message,
|
||||
"当前阶段只把圆柱侧壁及其共享边直接相邻 Face 作为一级关系,不会自动沿相邻面继续传播到二级、三级关系。",
|
||||
)
|
||||
if item
|
||||
)
|
||||
add_readonly_spec(
|
||||
key="cylindrical_feature_first_level_topology",
|
||||
label="一级关系",
|
||||
text=";".join(relation_parts + detail_parts) + "。",
|
||||
tip=topology_tip,
|
||||
)
|
||||
if is_hole_or_groove:
|
||||
if is_slot_or_half_hole:
|
||||
add_readonly_spec(
|
||||
@@ -2025,7 +2204,6 @@ class WindowStateMixin:
|
||||
),
|
||||
)
|
||||
elif is_plane or is_shell_candidate:
|
||||
topology_depth = _int_or_none(action_info.get("topology_relation_depth"))
|
||||
if topology_depth == 1:
|
||||
same_domain_count = _int_or_none(action_info.get("same_domain_face_count")) or 0
|
||||
boundary_edge_count = _int_or_none(action_info.get("first_level_boundary_edge_count")) or 0
|
||||
@@ -3037,18 +3215,32 @@ class WindowStateMixin:
|
||||
current_boss_height = _float_or_none(action_info.get("same_domain_height_estimate"))
|
||||
if current_boss_height is None:
|
||||
current_boss_height = _float_or_none(action_info.get("height_estimate"))
|
||||
boss_height_can_local = bool(
|
||||
is_full_cylinder
|
||||
and current_boss_height is not None
|
||||
and (
|
||||
_int_values(action_info.get("feature_start_end_face_ids"))
|
||||
or _int_values(action_info.get("feature_end_end_face_ids"))
|
||||
)
|
||||
)
|
||||
boss_height_can_scale = bool(
|
||||
current_boss_height is not None
|
||||
and current_boss_height > 0
|
||||
and _triple_or_none(action_info.get("axis_point")) is not None
|
||||
and _triple_or_none(action_info.get("axis")) is not None
|
||||
)
|
||||
add_scoped_spec(
|
||||
key="boss_height",
|
||||
label="高度",
|
||||
current_raw=current_boss_height if current_boss_height is not None else "",
|
||||
target_text=numeric_text(current_boss_height),
|
||||
scope_default="local",
|
||||
scope_default="owning" if boss_height_can_scale else "local",
|
||||
scope_modes={
|
||||
"local": {
|
||||
"label": "推拉端盖",
|
||||
"action": "resize_boss_height",
|
||||
"target_attr": "boss_height_input",
|
||||
"enabled": bool(is_full_cylinder and current_boss_height is not None),
|
||||
"enabled": boss_height_can_local,
|
||||
"enabled_tip": "输入完整圆柱凸台的目标高度;点击修改时程序会再计算并确认可推拉的凸台端盖 Face。",
|
||||
"disabled_tip": "当前凸台候选缺少稳定高度或端盖信息,暂不放行高度修改。",
|
||||
"range_hint": relative_range_hint(current_boss_height, 0.3, 0.8),
|
||||
@@ -3057,12 +3249,7 @@ class WindowStateMixin:
|
||||
"label": "调整整个特征",
|
||||
"action": "resize_cylindrical_height_owning_scale",
|
||||
"target_attr": "boss_height_input",
|
||||
"enabled": bool(
|
||||
current_boss_height is not None
|
||||
and current_boss_height > 0
|
||||
and _triple_or_none(action_info.get("axis_point")) is not None
|
||||
and _triple_or_none(action_info.get("axis")) is not None
|
||||
),
|
||||
"enabled": boss_height_can_scale,
|
||||
"enabled_tip": "输入目标高度;程序会沿圆柱轴向整体缩放所属特征或 Solid,不是推拉凸台端盖。",
|
||||
"disabled_tip": "当前凸台缺少稳定高度、轴线或缩放中心,不能按高度整体缩放所属对象。",
|
||||
"range_hint": (
|
||||
@@ -3153,12 +3340,18 @@ class WindowStateMixin:
|
||||
current_cylinder_height = _float_or_none(action_info.get("same_domain_height_estimate"))
|
||||
if current_cylinder_height is None:
|
||||
current_cylinder_height = _float_or_none(action_info.get("height_estimate"))
|
||||
cylinder_height_can_scale = bool(
|
||||
current_cylinder_height is not None
|
||||
and current_cylinder_height > 0
|
||||
and generic_scale_axis_point is not None
|
||||
and generic_scale_axis_direction is not None
|
||||
)
|
||||
add_scoped_spec(
|
||||
key="cylinder_height",
|
||||
label="高度",
|
||||
current_raw=current_cylinder_height if current_cylinder_height is not None else "",
|
||||
target_text=numeric_text(current_cylinder_height),
|
||||
scope_default="local",
|
||||
scope_default="owning" if cylinder_height_can_scale else "local",
|
||||
scope_modes={
|
||||
"local": {
|
||||
"label": "推拉端盖",
|
||||
@@ -3173,12 +3366,7 @@ class WindowStateMixin:
|
||||
"label": "调整整个特征",
|
||||
"action": "resize_cylindrical_height_owning_scale",
|
||||
"target_attr": "boss_height_input",
|
||||
"enabled": bool(
|
||||
current_cylinder_height is not None
|
||||
and current_cylinder_height > 0
|
||||
and generic_scale_axis_point is not None
|
||||
and generic_scale_axis_direction is not None
|
||||
),
|
||||
"enabled": cylinder_height_can_scale,
|
||||
"enabled_tip": "输入目标高度;程序会沿圆柱轴向整体缩放所属特征或 Solid,不是推拉单个端盖。",
|
||||
"disabled_tip": "当前圆柱缺少稳定高度、轴线或缩放中心,不能按高度整体缩放所属对象。",
|
||||
"range_hint": (
|
||||
@@ -3295,6 +3483,14 @@ class WindowStateMixin:
|
||||
used=("existing_fillet_arc_length_estimate", "existing_fillet_angular_span", "angular_span"),
|
||||
**positive_minimum(),
|
||||
)
|
||||
def analytic_surface_enabled(value_present: bool, capability_supported: bool = True) -> bool:
|
||||
return bool(value_present and capability_supported and analytic_surface_recognition_ready)
|
||||
|
||||
def analytic_surface_disabled_tip(base: str) -> str:
|
||||
if not analytic_surface_recognition_ready and analytic_surface_recognition_reason:
|
||||
return analytic_surface_recognition_reason
|
||||
return base
|
||||
|
||||
if is_cone:
|
||||
current_reference_radius = _float_or_none(action_info.get("reference_radius"))
|
||||
current_reference_diameter = (
|
||||
@@ -3303,7 +3499,10 @@ class WindowStateMixin:
|
||||
reference_radius_supported, reference_radius_disabled_reason = cone_reference_radius_capability(
|
||||
current_reference_radius
|
||||
)
|
||||
reference_radius_enabled = current_reference_radius is not None and reference_radius_supported
|
||||
reference_radius_enabled = analytic_surface_enabled(
|
||||
current_reference_radius is not None,
|
||||
reference_radius_supported,
|
||||
)
|
||||
add_spec(
|
||||
key="cone_reference_radius",
|
||||
label="参考半径",
|
||||
@@ -3313,7 +3512,7 @@ class WindowStateMixin:
|
||||
target_attr="cone_reference_radius_input",
|
||||
enabled=reference_radius_enabled,
|
||||
enabled_tip="输入圆锥面的目标参考半径;简单圆锥会解析重建,嵌入式锥孔会优先局部重切。",
|
||||
disabled_tip=(
|
||||
disabled_tip=analytic_surface_disabled_tip(
|
||||
reference_radius_disabled_reason
|
||||
or "当前圆锥面缺少稳定参考半径,不能直接修改。"
|
||||
),
|
||||
@@ -3332,9 +3531,12 @@ class WindowStateMixin:
|
||||
target_text=numeric_text(current_reference_diameter),
|
||||
action="resize_cone_reference_radius",
|
||||
target_attr="cone_reference_radius_input",
|
||||
enabled=current_reference_diameter is not None and reference_radius_supported,
|
||||
enabled=analytic_surface_enabled(
|
||||
current_reference_diameter is not None,
|
||||
reference_radius_supported,
|
||||
),
|
||||
enabled_tip="输入圆锥面的目标参考直径;程序会换算为参考半径后选择解析重建或锥孔局部重切。",
|
||||
disabled_tip=(
|
||||
disabled_tip=analytic_surface_disabled_tip(
|
||||
reference_radius_disabled_reason
|
||||
or "当前圆锥面缺少稳定参考直径,不能直接修改。"
|
||||
),
|
||||
@@ -3356,6 +3558,7 @@ class WindowStateMixin:
|
||||
current_reference_radius is not None
|
||||
and current_semi_angle is not None
|
||||
and semi_angle_supported
|
||||
and analytic_surface_recognition_ready
|
||||
)
|
||||
add_spec(
|
||||
key="cone_semi_angle_degrees",
|
||||
@@ -3366,7 +3569,7 @@ class WindowStateMixin:
|
||||
target_attr="cone_reference_radius_input",
|
||||
enabled=semi_angle_enabled,
|
||||
enabled_tip="输入圆锥面的目标半角,单位是度;简单圆锥会解析重建,嵌入式锥孔会优先局部重切。",
|
||||
disabled_tip=(
|
||||
disabled_tip=analytic_surface_disabled_tip(
|
||||
semi_angle_disabled_reason
|
||||
or "当前圆锥面缺少稳定参考半径或半角,不能直接修改半角。"
|
||||
),
|
||||
@@ -3390,9 +3593,9 @@ class WindowStateMixin:
|
||||
target_text=numeric_text(current_sphere_radius),
|
||||
action="resize_sphere_radius",
|
||||
target_attr="sphere_radius_input",
|
||||
enabled=current_sphere_radius is not None,
|
||||
enabled=analytic_surface_enabled(current_sphere_radius is not None),
|
||||
enabled_tip="输入球面的目标半径;程序会围绕球心均匀缩放所属对象。",
|
||||
disabled_tip="当前球面缺少稳定半径,不能直接修改。",
|
||||
disabled_tip=analytic_surface_disabled_tip("当前球面缺少稳定半径,不能直接修改。"),
|
||||
value_type="positive",
|
||||
range_hint=f"这是整体缩放所属对象,不是只替换单个球面的历史半径参数。 {relative_range_hint(current_sphere_radius, 0.25, 0.6)}",
|
||||
used=("radius",),
|
||||
@@ -3405,9 +3608,9 @@ class WindowStateMixin:
|
||||
target_text=numeric_text(current_sphere_diameter),
|
||||
action="resize_sphere_radius",
|
||||
target_attr="sphere_radius_input",
|
||||
enabled=current_sphere_diameter is not None,
|
||||
enabled=analytic_surface_enabled(current_sphere_diameter is not None),
|
||||
enabled_tip="输入球面的目标直径;程序会换算为半径后围绕球心均匀缩放所属对象。",
|
||||
disabled_tip="当前球面缺少稳定直径,不能直接修改。",
|
||||
disabled_tip=analytic_surface_disabled_tip("当前球面缺少稳定直径,不能直接修改。"),
|
||||
value_type="positive",
|
||||
range_hint=f"这是整体缩放所属对象,不是只替换单个球面的历史直径参数。 {relative_range_hint(current_sphere_diameter, 0.25, 0.6)}",
|
||||
target_transform="diameter_to_radius",
|
||||
@@ -3430,9 +3633,9 @@ class WindowStateMixin:
|
||||
target_text=numeric_text(current_major_radius),
|
||||
action="resize_torus_major_radius",
|
||||
target_attr="torus_radius_input",
|
||||
enabled=current_major_radius is not None,
|
||||
enabled=analytic_surface_enabled(current_major_radius is not None),
|
||||
enabled_tip="输入环面的目标主半径;当前版本会围绕环面中心均匀缩放所属对象,主半径和小半径会等比例变化。",
|
||||
disabled_tip="当前环面缺少稳定主半径,不能直接修改。",
|
||||
disabled_tip=analytic_surface_disabled_tip("当前环面缺少稳定主半径,不能直接修改。"),
|
||||
value_type="positive",
|
||||
range_hint=f"这是整体缩放所属对象,不是只改环面主半径;小半径和其它尺寸也会跟随变化。 {relative_range_hint(current_major_radius, 0.25, 0.6)}",
|
||||
used=("major_radius", "feature_torus_major_radius"),
|
||||
@@ -3445,9 +3648,9 @@ class WindowStateMixin:
|
||||
target_text=numeric_text(current_major_diameter),
|
||||
action="resize_torus_major_radius",
|
||||
target_attr="torus_radius_input",
|
||||
enabled=current_major_diameter is not None,
|
||||
enabled=analytic_surface_enabled(current_major_diameter is not None),
|
||||
enabled_tip="输入环面的目标主直径;程序会换算为主半径后整体缩放所属对象。",
|
||||
disabled_tip="当前环面缺少稳定主直径,不能直接修改。",
|
||||
disabled_tip=analytic_surface_disabled_tip("当前环面缺少稳定主直径,不能直接修改。"),
|
||||
value_type="positive",
|
||||
range_hint=f"这是整体缩放所属对象,不是只改环面主直径;小半径和其它尺寸也会跟随变化。 {relative_range_hint(current_major_diameter, 0.25, 0.6)}",
|
||||
target_transform="diameter_to_radius",
|
||||
@@ -3461,9 +3664,9 @@ class WindowStateMixin:
|
||||
target_text=numeric_text(current_minor_radius),
|
||||
action="resize_torus_minor_radius",
|
||||
target_attr="torus_radius_input",
|
||||
enabled=current_minor_radius is not None,
|
||||
enabled=analytic_surface_enabled(current_minor_radius is not None),
|
||||
enabled_tip="输入环面的目标小半径;当前版本会围绕环面中心均匀缩放所属对象,主半径和小半径会等比例变化。",
|
||||
disabled_tip="当前环面缺少稳定小半径,不能直接修改。",
|
||||
disabled_tip=analytic_surface_disabled_tip("当前环面缺少稳定小半径,不能直接修改。"),
|
||||
value_type="positive",
|
||||
range_hint=f"这是整体缩放所属对象,不是只改环面小半径;主半径和其它尺寸也会跟随变化。 {relative_range_hint(current_minor_radius, 0.25, 0.6)}",
|
||||
used=("minor_radius", "feature_torus_minor_radius"),
|
||||
@@ -3476,9 +3679,9 @@ class WindowStateMixin:
|
||||
target_text=numeric_text(current_minor_diameter),
|
||||
action="resize_torus_minor_radius",
|
||||
target_attr="torus_radius_input",
|
||||
enabled=current_minor_diameter is not None,
|
||||
enabled=analytic_surface_enabled(current_minor_diameter is not None),
|
||||
enabled_tip="输入环面的目标小直径;程序会换算为小半径后整体缩放所属对象。",
|
||||
disabled_tip="当前环面缺少稳定小直径,不能直接修改。",
|
||||
disabled_tip=analytic_surface_disabled_tip("当前环面缺少稳定小直径,不能直接修改。"),
|
||||
value_type="positive",
|
||||
range_hint=f"这是整体缩放所属对象,不是只改环面小直径;主半径和其它尺寸也会跟随变化。 {relative_range_hint(current_minor_diameter, 0.25, 0.6)}",
|
||||
target_transform="diameter_to_radius",
|
||||
|
||||
Reference in New Issue
Block a user