feat: 完善参数化编辑语义和槽孔中心距
This commit is contained in:
@@ -0,0 +1,90 @@
|
||||
from __future__ import annotations
|
||||
|
||||
import argparse
|
||||
from pathlib import Path
|
||||
import sys
|
||||
import tempfile
|
||||
|
||||
from OCC.Core.BRepBuilderAPI import BRepBuilderAPI_MakeEdge, BRepBuilderAPI_MakeFace, BRepBuilderAPI_MakeWire
|
||||
from OCC.Core.gp import gp_Ax2, gp_Dir, gp_Elips, gp_Pnt
|
||||
|
||||
PROJECT_ROOT = Path(__file__).resolve().parent.parent
|
||||
if str(PROJECT_ROOT) not in sys.path:
|
||||
sys.path.insert(0, str(PROJECT_ROOT))
|
||||
|
||||
from step_editor.model import StepModel
|
||||
from step_editor.step_io import _write_step
|
||||
|
||||
|
||||
def _write_ellipse_face_model(path: Path) -> None:
|
||||
edge = BRepBuilderAPI_MakeEdge(
|
||||
gp_Elips(gp_Ax2(gp_Pnt(0.0, 0.0, 0.0), gp_Dir(0.0, 0.0, 1.0)), 5.0, 2.0)
|
||||
).Edge()
|
||||
wire = BRepBuilderAPI_MakeWire(edge).Wire()
|
||||
face = BRepBuilderAPI_MakeFace(wire).Face()
|
||||
_write_step(face, path)
|
||||
|
||||
|
||||
def _ellipse_edge_ids(model: StepModel) -> list[int]:
|
||||
return [edge_id for edge_id in range(len(model.edges)) if model.edge_info(edge_id).get("curve") == "ellipse"]
|
||||
|
||||
|
||||
def _run_case(axis_kind: str, target: float, expected_other: float, tolerance: float) -> None:
|
||||
with tempfile.TemporaryDirectory(prefix=f"geom_param_ellipse_{axis_kind}_") as temp_dir:
|
||||
model_path = Path(temp_dir) / "ellipse.step"
|
||||
_write_ellipse_face_model(model_path)
|
||||
model = StepModel.load(model_path)
|
||||
edge_ids = _ellipse_edge_ids(model)
|
||||
if not edge_ids:
|
||||
raise SystemExit("no ellipse Edge was recognized")
|
||||
edge_id = edge_ids[0]
|
||||
before = model.stats()
|
||||
plan = model.ellipse_edge_axis_radius_plan(edge_id, target, axis_kind=axis_kind)
|
||||
if plan["status"] == "blocked":
|
||||
raise SystemExit(f"{axis_kind} radius plan was blocked: {plan['message']}")
|
||||
expected_strategy = f"ellipse-edge-{axis_kind}-axis-affine"
|
||||
if plan.get("resize_strategy") != expected_strategy:
|
||||
raise SystemExit(f"expected {expected_strategy}, got {plan.get('resize_strategy')}")
|
||||
result = model.resize_ellipse_edge_axis_radius(edge_id, target, axis_kind=axis_kind)
|
||||
after = model.stats()
|
||||
sampled = model._ellipse_edge_axis_radius_sampled_result(plan)
|
||||
if sampled is None:
|
||||
raise SystemExit("could not sample the edited ellipse-like Edge")
|
||||
verified_edge, value, other, error = sampled
|
||||
other_error = abs(other - expected_other)
|
||||
if error > tolerance:
|
||||
raise SystemExit(f"{axis_kind} radius verification failed: target={target:g}, value={value:g}, error={error:g}")
|
||||
if other_error > tolerance:
|
||||
raise SystemExit(
|
||||
f"{axis_kind} radius changed the other radius too much: expected={expected_other:g}, "
|
||||
f"value={other:g}, error={other_error:g}"
|
||||
)
|
||||
|
||||
print(f"mode={axis_kind}")
|
||||
print(f"source_edge={edge_id}")
|
||||
print(f"strategy={plan.get('resize_strategy')}")
|
||||
print(f"before={before}")
|
||||
print(f"after={after}")
|
||||
print(f"verified_edge={verified_edge}")
|
||||
print(f"target={target:.6f} value={value:.6f} error={error:.6g}")
|
||||
print(f"other_radius={other:.6f} other_error={other_error:.6g}")
|
||||
print(result.encode("ascii", "backslashreplace").decode("ascii"))
|
||||
|
||||
|
||||
def main() -> int:
|
||||
parser = argparse.ArgumentParser(description="Verify ellipse Edge major/minor radius resize operations.")
|
||||
parser.add_argument("--mode", default="all", choices=["all", "major", "minor"])
|
||||
parser.add_argument("--major-radius", type=float, default=7.5)
|
||||
parser.add_argument("--minor-radius", type=float, default=3.0)
|
||||
parser.add_argument("--tolerance", type=float, default=5e-3)
|
||||
args = parser.parse_args()
|
||||
|
||||
if args.mode in {"all", "major"}:
|
||||
_run_case("major", args.major_radius, expected_other=2.0, tolerance=args.tolerance)
|
||||
if args.mode in {"all", "minor"}:
|
||||
_run_case("minor", args.minor_radius, expected_other=5.0, tolerance=args.tolerance)
|
||||
return 0
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
raise SystemExit(main())
|
||||
Reference in New Issue
Block a user