fix(engine): 保留并正交化平面 y_dir 方向

This commit is contained in:
2026-08-27 14:36:08 +08:00
parent 2ef31db17e
commit c5f789c385
3 changed files with 60 additions and 7 deletions
+24 -5
View File
@@ -44,14 +44,33 @@ def _to_3d(workplane: _Ctx, u: float, v: float) -> list[float]:
origin = workplane.get("origin_mm") or [0, 0, 0]
x_dir = workplane.get("x_dir") or [1, 0, 0]
normal = workplane.get("normal") or [0, 0, 1]
y_dir = [
normal[1] * x_dir[2] - normal[2] * x_dir[1],
normal[2] * x_dir[0] - normal[0] * x_dir[2],
normal[0] * x_dir[1] - normal[1] * x_dir[0],
]
y_raw = workplane.get("y_dir")
y_dir = _default_y_dir(x_dir, normal)
if y_raw:
magnitude = math.sqrt(sum(component * component for component in y_raw))
if magnitude > 1e-12:
y_unit = [component / magnitude for component in y_raw]
# 与 PlaneSpec.from_mapping 同策略:只有与 x_dir / normal 正交的
# y_dir 才尊重(SolidWorks 导出的 y_dir==x_dir 占位数据与 X 平行,
# 直接使用会让轮廓塌缩成一条线,必须回退到 normal×x_dir)。
if abs(_dot(y_unit, x_dir)) <= 1e-6 and abs(_dot(y_unit, normal)) <= 1e-6:
y_dir = y_unit
return [origin[0] + u * x_dir[0] + v * y_dir[0], origin[1] + u * x_dir[1] + v * y_dir[1], origin[2] + u * x_dir[2] + v * y_dir[2]]
def _dot(left: Iterable[float], right: Iterable[float]) -> float:
return sum(a * b for a, b in zip(left, right))
def _default_y_dir(x_dir: Iterable[float], normal: Iterable[float]) -> list[float]:
x, n = list(x_dir), list(normal)
return [
n[1] * x[2] - n[2] * x[1],
n[2] * x[0] - n[0] * x[2],
n[0] * x[1] - n[1] * x[0],
]
def _transform_contours(contours: list[_Ctx], workplane: _Ctx) -> list[_Ctx]:
transformed: list[_Ctx] = []
normal = workplane.get("normal") or [0, 0, 1]