feat: 完善 STEP 编辑器最小系统和稳定性

This commit is contained in:
2026-07-28 14:05:14 +08:00
parent 26216064e0
commit 7c263d1e96
19 changed files with 3173 additions and 931 deletions
+83 -51
View File
@@ -271,48 +271,79 @@ class FeatureMixin:
break
plane_count = 0
shell_thickness_count = 0
shell_thickness_limit = max(2, min(per_type_limit, limit // 10))
face_scan_limit = len(self.faces) if max_scan_faces is None else min(len(self.faces), max(0, int(max_scan_faces)))
for face_id, face in enumerate(self.faces[:face_scan_limit]):
if progress_callback is not None and face_id % 30 == 0:
progress_callback()
if plane_count >= per_type_limit:
if plane_count >= per_type_limit and shell_thickness_count >= shell_thickness_limit:
break
surf = BRepAdaptor_Surface(face)
if surf.GetType() != GeomAbs_Plane:
continue
props = GProp_GProps()
brepgprop.SurfaceProperties(face, props)
if detailed:
direction_info = self._plane_push_pull_direction(face_id, surf)
confidence = str(direction_info["confidence"])
risk = "low" if confidence == "high" else "medium"
status = "ready" if confidence == "high" else "caution"
note = str(direction_info["note"])
else:
confidence = "pending"
risk = "medium"
status = "caution"
note = "快速扫描:推拉方向会在选中 face 或执行编辑前再详细判断。"
candidates.append(
{
"operation_key": "push_pull_plane",
"operation": "推拉平面",
"target_kind": "face",
"target_id": face_id,
"face_id": face_id,
"part_id": self.face_part_ids[face_id],
"solid_id": self.face_solid_ids[face_id],
"surface": "plane",
"feature_guess": "planar push/pull candidate",
"current_value": props.Mass(),
"current_value_label": "area",
"status": status,
"risk": risk,
"confidence": confidence,
"note": note,
}
)
plane_count += 1
if plane_count < per_type_limit:
if detailed:
direction_info = self._plane_push_pull_direction(face_id, surf)
confidence = str(direction_info["confidence"])
risk = "low" if confidence == "high" else "medium"
status = "ready" if confidence == "high" else "caution"
note = str(direction_info["note"])
else:
confidence = "pending"
risk = "medium"
status = "caution"
note = "快速扫描:推拉方向会在选中Face或执行编辑前再详细判断。"
candidates.append(
{
"operation_key": "push_pull_plane",
"operation": "推拉平面",
"target_kind": "face",
"target_id": face_id,
"face_id": face_id,
"part_id": self.face_part_ids[face_id],
"solid_id": self.face_solid_ids[face_id],
"surface": "plane",
"feature_guess": "planar push/pull candidate",
"current_value": props.Mass(),
"current_value_label": "area",
"status": status,
"risk": risk,
"confidence": confidence,
"note": note,
}
)
plane_count += 1
if shell_thickness_count < shell_thickness_limit:
feature = self.feature_info(face_id)
if feature.get("shell_region_status") == "candidate":
shell_confidence = str(feature.get("shell_confidence", "low"))
shell_risk = "low" if shell_confidence == "high" else "medium" if shell_confidence == "medium" else "high"
candidates.append(
{
"operation_key": "resize_shell_thickness",
"operation": "调整薄壁厚度",
"target_kind": "face",
"target_id": face_id,
"face_id": face_id,
"part_id": self.face_part_ids[face_id],
"solid_id": self.face_solid_ids[face_id],
"surface": "plane",
"feature_guess": "thin-wall opposite plane candidate",
"current_value": feature.get("shell_thickness_estimate"),
"current_value_label": "shell_thickness",
"status": "ready" if shell_confidence == "high" else "caution",
"risk": shell_risk,
"confidence": shell_confidence,
"note": (
"快速扫描:已找到投影重叠的相对平面;点击后会填入参考目标厚度,"
"执行时会移动当前平面区域来改变局部薄壁/壳体厚度。"
),
}
)
shell_thickness_count += 1
fillet_edge_count = 0
chamfer_edge_count = 0
@@ -342,7 +373,7 @@ class FeatureMixin:
candidates.append(
{
"operation_key": "fillet_edge",
"operation": "添加圆角",
"operation": "Edge添加圆角",
"target_kind": "edge",
"target_id": edge_id,
"edge_id": edge_id,
@@ -363,7 +394,7 @@ class FeatureMixin:
candidates.append(
{
"operation_key": "chamfer_edge",
"operation": "添加倒角",
"operation": "Edge添加倒角",
"target_kind": "edge",
"target_id": edge_id,
"edge_id": edge_id,
@@ -384,7 +415,7 @@ class FeatureMixin:
candidates.append(
{
"operation_key": "resize_edge_length",
"operation": "直接修改边长",
"operation": "修改Edge长度",
"target_kind": "edge",
"target_id": edge_id,
"edge_id": edge_id,
@@ -397,7 +428,7 @@ class FeatureMixin:
"status": "caution",
"risk": "medium" if is_line_edge or is_circle_edge else "high",
"confidence": "pending",
"note": "快速扫描:直线边优先尝试端面推拉;圆边会尝试换算相邻圆柱直径;其他边使用几何缩放 fallback",
"note": "快速扫描:直线边优先局部形变;圆边优先换算相邻圆柱直径;椭圆/平面曲线会尝试径向缩放;其他边使用后备策略",
}
)
edge_length_count += 1
@@ -411,10 +442,11 @@ class FeatureMixin:
"suppress_cylinder": 3,
"resize_depth": 4,
"inspect_existing_fillet": 5,
"push_pull_plane": 6,
"fillet_edge": 7,
"chamfer_edge": 8,
"resize_edge_length": 9,
"resize_shell_thickness": 6,
"push_pull_plane": 7,
"fillet_edge": 8,
"chamfer_edge": 9,
"resize_edge_length": 10,
}
candidates.sort(
key=lambda item: (
@@ -488,7 +520,7 @@ class FeatureMixin:
return {
"status": "blocked",
"risk": "blocked",
"message": "当前选中的 face 不是圆柱面,不能执行圆柱切削。",
"message": "当前选中的 Face 不是圆柱面,不能执行圆柱切削。",
}
current_diameter = float(info["diameter"])
feature = self.feature_info(face_id)
@@ -550,7 +582,7 @@ class FeatureMixin:
return {
"status": "blocked",
"risk": "blocked",
"message": "当前选中的 face 不是圆柱面,不能调整圆柱凸台直径。",
"message": "当前选中的 Face 不是圆柱面,不能调整圆柱凸台直径。",
}
current_diameter = float(info["diameter"])
@@ -609,7 +641,7 @@ class FeatureMixin:
return {
"status": "blocked",
"risk": "blocked",
"message": "当前选中的 face 不是圆柱面,不能封堵圆柱孔。",
"message": "当前选中的 Face 不是圆柱面,不能封堵圆柱孔。",
}
feature = self.feature_info(face_id)
axis_range = self._cylindrical_axis_range(
@@ -664,7 +696,7 @@ class FeatureMixin:
return {
"status": "blocked",
"risk": "blocked",
"message": "当前选中的 face 不是圆柱面,不能调整盲孔深度。",
"message": "当前选中的 Face 不是圆柱面,不能调整盲孔深度。",
}
feature = self.feature_info(face_id)
@@ -742,7 +774,7 @@ class FeatureMixin:
if surf.GetType() != GeomAbs_Cylinder:
return {
"context_status": "blocked",
"context_message": "当前选中的 face 不是圆柱面。",
"context_message": "当前选中的 Face 不是圆柱面。",
}
manual_bottom_face_id = None
@@ -775,7 +807,7 @@ class FeatureMixin:
if not bottom_face_ids:
return {
"context_status": "blocked",
"context_message": "第一版孔深调整需要疑似底面;如果自动识别失败,请手动填写底面 Face ID。",
"context_message": "当前版本的孔深调整需要疑似底面;如果自动识别失败,请手动填写底面Face ID。",
}
cyl = surf.Cylinder()
@@ -912,7 +944,7 @@ class FeatureMixin:
if surf.GetType() != GeomAbs_Cylinder:
return {
"cutter_strategy": "unavailable",
"cutter_note": "selected face is not cylindrical",
"cutter_note": "选中Face不是圆柱面",
}
cyl = surf.Cylinder()
@@ -954,7 +986,7 @@ class FeatureMixin:
"cutter_strategy": "bounded-to-selected-cylinder-v-range",
"cutter_note": (
"有限长度切削:优先按同域圆柱侧壁整体 V 范围生成 cutter,"
"如果没有同域拆分则退回选中 face 范围,减少贯穿整个零件的误切风险。"
"如果没有同域拆分则退回选中Face范围,减少贯穿整个零件的误切风险。"
),
"cutter_scope_face_ids": axis_range["same_domain_face_ids"],
"cutter_scope_face_count": axis_range["same_domain_face_count"],
@@ -982,7 +1014,7 @@ class FeatureMixin:
if surf.GetType() != GeomAbs_Cylinder:
return {
"fill_strategy": "unavailable",
"fill_note": "selected face is not cylindrical",
"fill_note": "选中Face不是圆柱面",
}
cyl = surf.Cylinder()
@@ -1019,7 +1051,7 @@ class FeatureMixin:
if surf.GetType() != GeomAbs_Cylinder:
return {
"boss_tool_strategy": "unavailable",
"boss_tool_note": "selected face is not cylindrical",
"boss_tool_note": "选中Face不是圆柱面",
}
cyl = surf.Cylinder()
@@ -1055,7 +1087,7 @@ class FeatureMixin:
"boss_tool_note": (
"扩大凸台会在同域圆柱侧壁整体 V 范围内生成目标半径圆柱并 Fuse;"
"缩小凸台会先用旧半径包络体移除原凸台范围,再 Fuse 目标半径圆柱重建。"
"第一版会给轴向两端保留少量重叠,让布尔结果更容易和原实体合并。"
"当前版本会给轴向两端保留少量重叠,让布尔结果更容易和原实体合并。"
),
"boss_tool_scope_face_ids": axis_range["same_domain_face_ids"],
"boss_tool_scope_face_count": axis_range["same_domain_face_count"],