提交关于N5功能,“involute_gear渐开线齿廓与齿条专用生成”的改动
This commit is contained in:
@@ -46,6 +46,9 @@ class ProfileCadRuntime:
|
||||
"selected_edges_exist": self._preflight_selected_edges_exist,
|
||||
"source_features_exist": self._preflight_source_features_exist,
|
||||
"mirror_plane_exists": self._preflight_mirror_plane_exists,
|
||||
"loft_profiles_exist": self._preflight_loft_profiles_exist,
|
||||
"loft_profiles_closed": self._preflight_loft_profiles_closed,
|
||||
"loft_profiles_single_region": self._preflight_loft_profiles_single_region,
|
||||
}
|
||||
schema_path = Path(str(self.engine.__file__)).with_name("profile_schema.json")
|
||||
try:
|
||||
@@ -990,6 +993,56 @@ class ProfileCadRuntime:
|
||||
if len(supplied) != 1 or not isinstance(selectors.get(supplied[0]), dict) or selectors[supplied[0]].get("kind") != "plane":
|
||||
raise RuntimeAdapterError("RUNTIME_PRECONDITION_FAILED: mirror plane is absent or stale")
|
||||
|
||||
def _loft_profile_sketches(self, fragment: dict[str, Any], base: dict[str, Any] | None) -> list[dict[str, Any]]:
|
||||
"""Resolve ``profile_sketch_ids`` against the base document's sketches."""
|
||||
ids = [str(value) for value in fragment.get("feature", {}).get("params", {}).get("profile_sketch_ids") or ()]
|
||||
sketches = (base or {}).get("geometry", {}).get("sketches") if isinstance((base or {}).get("geometry"), dict) else None
|
||||
by_id = {
|
||||
str(sketch.get("id") or ""): sketch
|
||||
for sketch in (sketches or ())
|
||||
if isinstance(sketch, dict)
|
||||
}
|
||||
resolved: list[dict[str, Any]] = []
|
||||
for sketch_id in ids:
|
||||
sketch = by_id.get(sketch_id)
|
||||
if not isinstance(sketch, dict):
|
||||
raise RuntimeAdapterError("RUNTIME_PRECONDITION_FAILED: loft profile sketch is not part of current head")
|
||||
resolved.append(sketch)
|
||||
if not resolved:
|
||||
raise RuntimeAdapterError("RUNTIME_PRECONDITION_FAILED: loft has no profile sketches")
|
||||
return resolved
|
||||
|
||||
def _preflight_loft_profiles_exist(self, fragment: dict[str, Any], _selectors: dict[str, dict[str, Any]], base: dict[str, Any] | None, _require_through: bool) -> None:
|
||||
self._loft_profile_sketches(fragment, base)
|
||||
|
||||
def _preflight_loft_profiles_closed(self, fragment: dict[str, Any], _selectors: dict[str, dict[str, Any]], base: dict[str, Any] | None, _require_through: bool) -> None:
|
||||
# circle/polygon 草图类型闭合性由 schema 保证;analytic_contours 需要
|
||||
# 每条参与轮廓显式 closed。
|
||||
for sketch in self._loft_profile_sketches(fragment, base):
|
||||
profile = sketch.get("profile") if isinstance(sketch.get("profile"), dict) else None
|
||||
if profile is None:
|
||||
raise RuntimeAdapterError("RUNTIME_PRECONDITION_FAILED: loft profile sketch has no profile")
|
||||
if profile.get("type") == "analytic_contours":
|
||||
contours = profile.get("contours")
|
||||
if not isinstance(contours, list) or not contours:
|
||||
raise RuntimeAdapterError("RUNTIME_PRECONDITION_FAILED: loft profile has no contours")
|
||||
for contour in contours:
|
||||
if not isinstance(contour, dict) or not contour.get("closed"):
|
||||
raise RuntimeAdapterError("RUNTIME_PRECONDITION_FAILED: loft profile contour is not closed")
|
||||
|
||||
def _preflight_loft_profiles_single_region(self, fragment: dict[str, Any], _selectors: dict[str, dict[str, Any]], base: dict[str, Any] | None, _require_through: bool) -> None:
|
||||
# 每个放样截面必须是单连通区域:analytic_contours 只允许恰好一条
|
||||
# outer 闭合轮廓,不得携带 inner 环或 open 段。
|
||||
for sketch in self._loft_profile_sketches(fragment, base):
|
||||
profile = sketch.get("profile") if isinstance(sketch.get("profile"), dict) else None
|
||||
if profile is None:
|
||||
raise RuntimeAdapterError("RUNTIME_PRECONDITION_FAILED: loft profile sketch has no profile")
|
||||
if profile.get("type") == "analytic_contours":
|
||||
contours = [contour for contour in (profile.get("contours") or []) if isinstance(contour, dict)]
|
||||
outer = [contour for contour in contours if contour.get("role") == "outer" and contour.get("closed")]
|
||||
if len(outer) != 1 or len(outer) != len(contours):
|
||||
raise RuntimeAdapterError("RUNTIME_PRECONDITION_FAILED: loft profile must be a single closed region")
|
||||
|
||||
@staticmethod
|
||||
def _polygon_self_intersects(vertices: list[Any]) -> bool:
|
||||
points = [(float(point[0]), float(point[1])) for point in vertices if isinstance(point, list) and len(point) == 2]
|
||||
|
||||
Reference in New Issue
Block a user