fix(B07): DXF·DWG 불러오기 작은 원·호 뭉개짐 고침 — 곡선 토막마다 8마디 이상 · 부분 타원 닫는 줄 없앰(99-3)
- 원인: 펴기 허용오차 0.2 고정 — m 단위 도면(중력식 사방댐 시트 폭 약 80)에서 반지름 0.071 원이 길이 0 선 1개 · 0.15~0.2 원이 삼각형 · 0.36~0.46 호가 직선 한 마디 - 고침: 원·호·타원·스플라인·bulge 폴리선 모두 ezdxf 경로로 펴고 90° 이하 토막마다 8마디 이상 - 원본 DWG 대조: 원 42 · 호 16 오차 반지름의 0.5% 이하 · 호 16 모두 원래 각 범위 안(큰 호로 뒤집힘 0) · 불러오기 1.45 s · 도형 1,959 - 시험: test_b07_frame_import_shapes 작은 원·호 시험 하나 더함 Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_015KYZ2HWWdUwZWYnn3tQz7X
This commit is contained in:
@@ -39,6 +39,8 @@ _IMPORT_NS = uuid5(NAMESPACE_URL, "aislo/b07/frame-import")
|
||||
_DEFAULT_COLOR = "#f5f7fa"
|
||||
# 곡선을 선분으로 풀 때 허용 오차(mm) — 도각 크기(840x594mm)에서 눈에 띄지 않는다.
|
||||
_FLATTEN_MM = 0.2
|
||||
# 곡선 한 토막(90° 이하)을 적어도 이만큼 나눔 — 단위가 m 인 도면의 작은 원 · 호가 점 · 삼각형 · 직선으로 뭉개지지 않게.
|
||||
_CURVE_SEGMENTS = 8
|
||||
_MAX_ENTITIES = 20000
|
||||
# 블록 속 블록을 풀 깊이 — 자기를 품는 깨진 블록에서 끝없이 돌지 않게.
|
||||
_MAX_BLOCK_DEPTH = 16
|
||||
@@ -149,10 +151,19 @@ def _text(
|
||||
}
|
||||
|
||||
|
||||
def _flatten(entity: Any) -> list[Any] | None:
|
||||
"""원·호·타원·스플라인을 선분 점열로 편다. 못 펴면 None."""
|
||||
def _path_points(entity: Any) -> list[Any]:
|
||||
"""도형 → WCS 경로 점열 — 곡선 토막마다 `_CURVE_SEGMENTS` 이상으로 나눔."""
|
||||
return list(ezdxf_path.make_path(entity).flattening(_FLATTEN_MM, segments=_CURVE_SEGMENTS))
|
||||
|
||||
|
||||
def _flatten(entity: Any) -> tuple[list[Any], bool] | None:
|
||||
"""원·호·타원·스플라인 → (선분 점열, 닫힘). 경로는 닫는 마디까지 넣음 · 못 펴면 None."""
|
||||
try:
|
||||
return list(entity.flattening(_FLATTEN_MM))
|
||||
return _path_points(entity), False
|
||||
except Exception:
|
||||
pass
|
||||
try:
|
||||
return list(entity.flattening(_FLATTEN_MM)), entity.dxftype() == "CIRCLE"
|
||||
except Exception:
|
||||
return None
|
||||
|
||||
@@ -164,7 +175,7 @@ def _polyline_points(entity: Any) -> tuple[list[Any], bool]:
|
||||
면 · 메시 POLYLINE 처럼 경로로 못 바꾸면 꼭짓점을 그대로 잇는다.
|
||||
"""
|
||||
try:
|
||||
return list(ezdxf_path.make_path(entity).flattening(_FLATTEN_MM)), False
|
||||
return _path_points(entity), False
|
||||
except Exception:
|
||||
if entity.dxftype() == "LWPOLYLINE":
|
||||
return list(entity.get_points("xy")), bool(entity.closed)
|
||||
@@ -203,10 +214,10 @@ def _convert_entity(index: int, entity: Any) -> list[dict[str, Any]]:
|
||||
shape = _polyline(index, entity, points, closed)
|
||||
return [shape] if shape else []
|
||||
if kind in ("CIRCLE", "ARC", "ELLIPSE", "SPLINE"):
|
||||
points = _flatten(entity)
|
||||
if not points:
|
||||
flat = _flatten(entity)
|
||||
if not flat:
|
||||
return []
|
||||
shape = _polyline(index, entity, points, kind in ("CIRCLE", "ELLIPSE"))
|
||||
shape = _polyline(index, entity, *flat)
|
||||
return [shape] if shape else []
|
||||
if kind == "POINT":
|
||||
location = entity.dxf.location
|
||||
|
||||
Reference in New Issue
Block a user