feat: 扩展Face保持关系编辑语义
This commit is contained in:
+134
-11
@@ -262,6 +262,8 @@ class OperationMixin:
|
||||
self,
|
||||
face_id: int,
|
||||
plan: dict[str, object],
|
||||
*,
|
||||
operation_label: str = "拉伸/切除",
|
||||
) -> dict[str, object]:
|
||||
relation_status = str(plan.get("first_level_planar_relation_status") or "")
|
||||
relation_scope = str(plan.get("first_level_planar_relation_scope") or "")
|
||||
@@ -313,10 +315,13 @@ class OperationMixin:
|
||||
)
|
||||
else:
|
||||
summary = (
|
||||
"Face保持关系:可按拉伸/切除执行并反查一级平面关系;"
|
||||
f"Face保持关系:可按{operation_label}执行并反查一级平面关系;"
|
||||
f"平行 {parallel_count},垂直 {perpendicular_count}。"
|
||||
)
|
||||
return {
|
||||
"face_planar_relation_constraint_requested": True,
|
||||
"face_planar_relation_constraint_label": "保持一级平面关系",
|
||||
"face_planar_relation_constraint_operation": operation_label,
|
||||
"face_push_pull_planar_relation_constraint_requested": True,
|
||||
"face_push_pull_planar_relation_constraint_label": "保持一级平面关系",
|
||||
"face_push_pull_planar_constraint_status": "blocked" if blockers else "ready",
|
||||
@@ -339,16 +344,23 @@ class OperationMixin:
|
||||
),
|
||||
}
|
||||
|
||||
def push_pull_keep_relations_plan(self, face_id: int, distance: float) -> dict[str, object]:
|
||||
plan = self.push_pull_plan(face_id, distance)
|
||||
constraint_fields = self._face_push_pull_planar_relation_constraint_fields(face_id, plan)
|
||||
plan.update(constraint_fields)
|
||||
plan["resize_strategy"] = "push-pull-planar-face-keep-relations"
|
||||
plan["edit_strategy_label"] = "保持一级平面关系的拉伸/切除"
|
||||
plan["edit_semantics"] = (
|
||||
"沿当前 Face 法向拉伸/切除,同时要求当前 Face 与共享边一级相邻平面的平行/垂直关系"
|
||||
"在执行前可验证,并在执行后反查。"
|
||||
def _with_face_planar_relation_constraint(
|
||||
self,
|
||||
face_id: int,
|
||||
plan: dict[str, object],
|
||||
*,
|
||||
operation_label: str,
|
||||
edit_strategy_label: str,
|
||||
edit_semantics: str,
|
||||
) -> dict[str, object]:
|
||||
constraint_fields = self._face_push_pull_planar_relation_constraint_fields(
|
||||
face_id,
|
||||
plan,
|
||||
operation_label=operation_label,
|
||||
)
|
||||
plan.update(constraint_fields)
|
||||
plan["edit_strategy_label"] = edit_strategy_label
|
||||
plan["edit_semantics"] = edit_semantics
|
||||
if plan["status"] != "blocked" and constraint_fields["face_push_pull_planar_constraint_status"] == "blocked":
|
||||
blockers = str(constraint_fields.get("face_push_pull_planar_constraint_blockers") or "")
|
||||
plan["status"] = "blocked"
|
||||
@@ -368,6 +380,21 @@ class OperationMixin:
|
||||
plan["message"] = str(constraint_fields["face_push_pull_planar_constraint_summary"])
|
||||
return plan
|
||||
|
||||
def push_pull_keep_relations_plan(self, face_id: int, distance: float) -> dict[str, object]:
|
||||
plan = self.push_pull_plan(face_id, distance)
|
||||
self._with_face_planar_relation_constraint(
|
||||
face_id,
|
||||
plan,
|
||||
operation_label="拉伸/切除",
|
||||
edit_strategy_label="保持一级平面关系的拉伸/切除",
|
||||
edit_semantics=(
|
||||
"沿当前 Face 法向拉伸/切除,同时要求当前 Face 与共享边一级相邻平面的平行/垂直关系"
|
||||
"在执行前可验证,并在执行后反查。"
|
||||
),
|
||||
)
|
||||
plan["resize_strategy"] = "push-pull-planar-face-keep-relations"
|
||||
return plan
|
||||
|
||||
def _multistep_prismatic_plan_blocker(self, face_id: int, operation_label: str) -> str:
|
||||
try:
|
||||
quick_info = self.quick_face_info(face_id)
|
||||
@@ -4070,6 +4097,23 @@ class OperationMixin:
|
||||
),
|
||||
}
|
||||
|
||||
def face_center_local_move_keep_relations_plan(
|
||||
self,
|
||||
face_id: int,
|
||||
target_center: tuple[float, float, float],
|
||||
) -> dict[str, object]:
|
||||
plan = self.face_center_owning_translation_plan(face_id, target_center)
|
||||
return self._with_face_planar_relation_constraint(
|
||||
face_id,
|
||||
plan,
|
||||
operation_label="中心移动",
|
||||
edit_strategy_label="保持一级平面关系的中心移动",
|
||||
edit_semantics=(
|
||||
"把目标中心换算成平移量并移动所属特征或 Solid,同时要求当前 Face 与共享边一级相邻平面的"
|
||||
"平行/垂直关系在执行前可验证,并在执行后反查;不做单面局部扭曲。"
|
||||
),
|
||||
)
|
||||
|
||||
def existing_chamfer_resize_plan(self, face_id: int, target_distance: float) -> dict[str, object]:
|
||||
if face_id < 0 or face_id >= len(self.faces):
|
||||
raise ValueError(f"Unknown face id {face_id}")
|
||||
@@ -4604,6 +4648,26 @@ class OperationMixin:
|
||||
),
|
||||
}
|
||||
|
||||
def face_size_local_resize_keep_relations_plan(
|
||||
self,
|
||||
face_id: int,
|
||||
target_size: float,
|
||||
axis: str = "width",
|
||||
) -> dict[str, object]:
|
||||
axis_key = "height" if str(axis).strip().lower() in {"height", "h", "v", "y"} else "width"
|
||||
axis_label = "面内宽度" if axis_key == "height" else "面内长度"
|
||||
plan = self.face_size_owning_scale_plan(face_id, target_size, axis_key)
|
||||
return self._with_face_planar_relation_constraint(
|
||||
face_id,
|
||||
plan,
|
||||
operation_label=f"{axis_label}修改",
|
||||
edit_strategy_label=f"保持一级平面关系的{axis_label}修改",
|
||||
edit_semantics=(
|
||||
f"沿当前 Face 的{axis_label}方向缩放所属特征或 Solid,同时要求当前 Face 与共享边一级相邻平面的"
|
||||
"平行/垂直关系在执行前可验证,并在执行后反查;不做单面局部扭曲。"
|
||||
),
|
||||
)
|
||||
|
||||
def _rectangular_prismatic_size_resize_plan(
|
||||
self,
|
||||
*,
|
||||
@@ -8144,6 +8208,35 @@ class OperationMixin:
|
||||
f"risk={plan['risk']}. {result_check}"
|
||||
)
|
||||
|
||||
def move_face_center_local_keep_relations(
|
||||
self,
|
||||
face_id: int,
|
||||
target_center: tuple[float, float, float],
|
||||
) -> str:
|
||||
plan = self.face_center_local_move_keep_relations_plan(face_id, target_center)
|
||||
if plan["status"] == "blocked":
|
||||
raise ValueError(str(plan["message"]))
|
||||
|
||||
self._remember_face_target_logical_id(plan, face_id)
|
||||
vector = tuple(plan["translation_vector"])
|
||||
result, result_check = self._run_checked_face_edit(
|
||||
plan,
|
||||
lambda: (
|
||||
self.translate_solid(int(plan["solid_id"]), vector)
|
||||
if plan.get("target_kind") == "solid"
|
||||
else self.translate_part(int(plan["part_id"]), vector)
|
||||
),
|
||||
)
|
||||
return (
|
||||
"Face center move completed with first-level planar relations: "
|
||||
f"face {face_id}, "
|
||||
f"current_center={plan.get('current_face_center')}, "
|
||||
f"target_center={plan.get('target_face_center')}, "
|
||||
f"move={plan.get('face_center_move_vector')}, "
|
||||
f"target={plan.get('target_kind')}, "
|
||||
f"risk={plan['risk']}. {result_check} {result}"
|
||||
)
|
||||
|
||||
def face_area_local_resize_preview_polydata(
|
||||
self,
|
||||
face_id: int,
|
||||
@@ -8243,6 +8336,33 @@ class OperationMixin:
|
||||
f"risk={plan['risk']}. {result_check}"
|
||||
)
|
||||
|
||||
def resize_face_size_local_keep_relations(self, face_id: int, target_size: float, axis: str = "width") -> str:
|
||||
plan = self.face_size_local_resize_keep_relations_plan(face_id, target_size, axis)
|
||||
if plan["status"] == "blocked":
|
||||
raise ValueError(str(plan["message"]))
|
||||
|
||||
self._remember_face_target_logical_id(plan, face_id)
|
||||
_action_result, result_check = self._run_checked_face_edit(
|
||||
plan,
|
||||
lambda: (
|
||||
self._apply_local_face_deform(plan)
|
||||
if plan.get("owning_face_size_rebuild_mode") == "planar-rebuild"
|
||||
else self._apply_edge_length_affine_transform(plan)
|
||||
),
|
||||
)
|
||||
return (
|
||||
"Face owning size resize completed with first-level planar relations: "
|
||||
f"face {face_id}, "
|
||||
f"axis={plan.get('face_size_axis')}, "
|
||||
f"current_size={float(plan['current_face_size']):g}, "
|
||||
f"target_size={float(plan['target_face_size']):g}, "
|
||||
f"delta={float(plan['face_size_delta']):g}, "
|
||||
f"scale={float(plan['face_size_scale']):g}, "
|
||||
f"rebuild_mode={plan.get('owning_face_size_rebuild_mode')}, "
|
||||
f"target={plan.get('affine_target_kind')}, "
|
||||
f"risk={plan['risk']}. {result_check}"
|
||||
)
|
||||
|
||||
def face_size_owning_scale_preview_polydata(
|
||||
self,
|
||||
face_id: int,
|
||||
@@ -8318,7 +8438,10 @@ class OperationMixin:
|
||||
matched_face_id: int,
|
||||
facts: dict[str, object],
|
||||
) -> str:
|
||||
if plan.get("face_push_pull_planar_relation_constraint_requested") is not True:
|
||||
if (
|
||||
plan.get("face_planar_relation_constraint_requested") is not True
|
||||
and plan.get("face_push_pull_planar_relation_constraint_requested") is not True
|
||||
):
|
||||
return ""
|
||||
if str(plan.get("face_push_pull_planar_constraint_status") or "") != "ready":
|
||||
raise RuntimeError("Face planar relation check was requested but the original constraint plan is not ready.")
|
||||
|
||||
Reference in New Issue
Block a user