feat: 推进一级关系参数化编辑与参数导出
This commit is contained in:
+60
-20
@@ -3269,9 +3269,13 @@ class OperationMixin:
|
||||
outward_direction = _tuple_normalized(_tuple_or_none(info.get("push_pull_outward_direction")))
|
||||
current_plane_position = None
|
||||
target_plane_position = None
|
||||
current_plane_center = _tuple_or_none(info.get("area_center")) or _tuple_or_none(info.get("bbox_center"))
|
||||
target_plane_center = None
|
||||
if plane_origin is not None and outward_direction is not None:
|
||||
current_plane_position = _tuple_dot(plane_origin, outward_direction)
|
||||
target_plane_position = current_plane_position + float(distance)
|
||||
if current_plane_center is not None:
|
||||
target_plane_center = _tuple_add(current_plane_center, _tuple_scale(outward_direction, float(distance)))
|
||||
|
||||
return {
|
||||
"status": status,
|
||||
@@ -3294,6 +3298,8 @@ class OperationMixin:
|
||||
"plane_direction": outward_direction,
|
||||
"current_plane_position": current_plane_position,
|
||||
"target_plane_position": target_plane_position,
|
||||
"current_plane_center": current_plane_center,
|
||||
"target_plane_center": target_plane_center,
|
||||
"push_pull_inward_material_depth": inward_material_depth,
|
||||
"push_pull_inward_cut_ratio": inward_cut_ratio,
|
||||
"cylindrical_cap_extension_old_height": (
|
||||
@@ -8746,6 +8752,7 @@ class OperationMixin:
|
||||
metric = ""
|
||||
target: float | tuple[float, ...] | None = None
|
||||
tolerance = 1e-4
|
||||
center_tolerance: float | None = None
|
||||
getter: Callable[[int], float | tuple[float, ...] | None] | None = None
|
||||
|
||||
target_area = _float_or_none(plan.get("target_area"))
|
||||
@@ -8794,6 +8801,8 @@ class OperationMixin:
|
||||
target = target_position
|
||||
bbox_diagonal = _float_or_none(plan.get("bbox_diagonal")) or _shape_diagonal(self.shape)
|
||||
tolerance = max(bbox_diagonal * 1e-4, abs(target_position) * 1e-5, 1e-4)
|
||||
target_plane_center = _tuple_or_none(plan.get("target_plane_center"))
|
||||
center_tolerance = max(bbox_diagonal * 0.15, tolerance * 20.0, 1e-3) if target_plane_center is not None else None
|
||||
|
||||
def plane_position_getter(face_id: int) -> float | None:
|
||||
if face_id < 0 or face_id >= len(self.faces):
|
||||
@@ -8890,6 +8899,46 @@ class OperationMixin:
|
||||
plan_face_id = _int_or_none(plan.get("face_id"))
|
||||
if plan_face_id is not None:
|
||||
preferred_ids.append(plan_face_id)
|
||||
def candidate_center_error(face_id: int) -> float | None:
|
||||
if metric != "plane_position":
|
||||
return None
|
||||
target_center = _tuple_or_none(plan.get("target_plane_center"))
|
||||
if target_center is None:
|
||||
return None
|
||||
try:
|
||||
info = self.quick_face_info(face_id)
|
||||
except Exception:
|
||||
return None
|
||||
actual_center = _tuple_or_none(info.get("area_center")) or _tuple_or_none(info.get("bbox_center"))
|
||||
if actual_center is None:
|
||||
return None
|
||||
return _vector_length(_tuple_sub(actual_center, target_center))
|
||||
|
||||
def candidate_record(face_id: int, actual: object, error: float) -> dict[str, object]:
|
||||
record: dict[str, object] = {
|
||||
"face_id": face_id,
|
||||
"metric": metric,
|
||||
"actual": actual,
|
||||
"target": target,
|
||||
"error": error,
|
||||
"tolerance": tolerance,
|
||||
"scope": scope,
|
||||
}
|
||||
center_error = candidate_center_error(face_id)
|
||||
if center_error is not None:
|
||||
record["center_error"] = center_error
|
||||
if center_tolerance is not None:
|
||||
record["center_tolerance"] = center_tolerance
|
||||
return record
|
||||
|
||||
def candidate_sort_key(record: dict[str, object]) -> tuple[int, float, float]:
|
||||
center_error = _float_or_none(record.get("center_error"))
|
||||
center_limit = _float_or_none(record.get("center_tolerance"))
|
||||
center_penalty = 0
|
||||
if center_error is not None and center_limit is not None and center_error > center_limit:
|
||||
center_penalty = 1
|
||||
return (center_penalty, float(record["error"]), center_error if center_error is not None else 0.0)
|
||||
|
||||
if preferred_ids:
|
||||
preferred_best: dict[str, object] | None = None
|
||||
for face_id in preferred_ids:
|
||||
@@ -8902,16 +8951,9 @@ class OperationMixin:
|
||||
if actual is None:
|
||||
continue
|
||||
error = _result_value_error(actual, target)
|
||||
if preferred_best is None or error < float(preferred_best["error"]):
|
||||
preferred_best = {
|
||||
"face_id": face_id,
|
||||
"metric": metric,
|
||||
"actual": actual,
|
||||
"target": target,
|
||||
"error": error,
|
||||
"tolerance": tolerance,
|
||||
"scope": scope,
|
||||
}
|
||||
record = candidate_record(face_id, actual, error)
|
||||
if preferred_best is None or candidate_sort_key(record) < candidate_sort_key(preferred_best):
|
||||
preferred_best = record
|
||||
if preferred_best is not None and float(preferred_best["error"]) <= tolerance:
|
||||
return preferred_best
|
||||
|
||||
@@ -8924,16 +8966,9 @@ class OperationMixin:
|
||||
if actual is None:
|
||||
continue
|
||||
error = _result_value_error(actual, target)
|
||||
if best is None or error < float(best["error"]):
|
||||
best = {
|
||||
"face_id": face_id,
|
||||
"metric": metric,
|
||||
"actual": actual,
|
||||
"target": target,
|
||||
"error": error,
|
||||
"tolerance": tolerance,
|
||||
"scope": scope,
|
||||
}
|
||||
record = candidate_record(face_id, actual, error)
|
||||
if best is None or candidate_sort_key(record) < candidate_sort_key(best):
|
||||
best = record
|
||||
if best is not None:
|
||||
return best
|
||||
return {
|
||||
@@ -9011,6 +9046,11 @@ class OperationMixin:
|
||||
all_ids = filtered(range(len(self.faces)))
|
||||
if not all_ids and solid_id is not None and solid_id >= 0:
|
||||
all_ids = filtered(range(len(self.faces)), require_solid=False)
|
||||
elif target_kind == "solid" and solid_id is not None and solid_id >= 0 and surface == "plane":
|
||||
relaxed_ids = filtered(range(len(self.faces)), require_solid=False)
|
||||
for face_id in relaxed_ids:
|
||||
if face_id not in all_ids:
|
||||
all_ids.append(face_id)
|
||||
combined: list[int] = []
|
||||
for face_id in [*primary_ids, *all_ids]:
|
||||
if face_id not in combined:
|
||||
|
||||
Reference in New Issue
Block a user