feat(B07): LibreDWG 변환기 동봉 및 자동 탐색
- 저장소에 LibreDWG 0.14.8594 Windows 실행 파일 동봉 (dwg2dxf/dxf2dwg + 필요한 DLL 4개, 약 33MB) 실제 파일은 메인 워크트리 B07_DesignDetail/openwebcad/tools/libredwg 에 두고 보조 워크트리는 junction 으로 연결 - 파이썬 바인딩 미포함 (import 시 GPL 이 본 프로그램까지 확산) — 별도 프로세스 호출 방식 유지 - GPL v3 전문(COPYING)과 원본 출처·구성·교체 방법 README 동봉 - 변환기 탐색 순서: .env 경로 → 동봉본 → PATH - 옛 DXF 의 유니코드 escape 를 복원해 DWG 왕복 시 한글 깨짐 해결, DWG 출력용 DXF 는 R2004 로 생성 - DWG 왕복 검증 테스트 추가 (tmp/tests, git 추적 제외) Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -21,10 +21,14 @@ from typing import Any
|
||||
|
||||
import ezdxf
|
||||
|
||||
from B07_DesignDetail.B07_DesignDetail_Engine_Frame_Import import bundled_tool
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
# 내보내는 DXF 형식 — LibreDWG 가 읽어 DWG 로 바꿀 수 있는 범위에 맞춘다.
|
||||
# 파일로 내려보내는 DXF 형식. DWG 로 갈 때는 LibreDWG 가 쓰는 R2004 로 맞춘다 —
|
||||
# 더 새 형식을 주면 한글이 깨진 채로 DWG 에 박힌다(2026-09-06 실측).
|
||||
_DXF_VERSION = "R2018"
|
||||
_DWG_SOURCE_VERSION = "R2004"
|
||||
_DEFAULT_TEXT_MM = 3.0
|
||||
|
||||
|
||||
@@ -99,12 +103,14 @@ def _add_entity(
|
||||
_add_entity(space, child, layers, skipped)
|
||||
|
||||
|
||||
def drawing_to_dxf(drawing: dict[str, Any]) -> tuple[bytes, dict[str, int]]:
|
||||
def drawing_to_dxf(
|
||||
drawing: dict[str, Any], version: str = _DXF_VERSION
|
||||
) -> tuple[bytes, dict[str, int]]:
|
||||
"""캐드 도면(JSON)을 DXF 바이트로. 건너뛴 도형 수를 함께 돌려준다."""
|
||||
entities = drawing.get("entities")
|
||||
if not isinstance(entities, list) or not entities:
|
||||
raise ValueError("내보낼 도형이 없습니다.")
|
||||
document = ezdxf.new(_DXF_VERSION)
|
||||
document = ezdxf.new(version)
|
||||
space = document.modelspace()
|
||||
layers: set[str] = {layer.dxf.name for layer in document.layers}
|
||||
skipped: dict[str, int] = {}
|
||||
@@ -117,11 +123,11 @@ def drawing_to_dxf(drawing: dict[str, Any]) -> tuple[bytes, dict[str, int]]:
|
||||
|
||||
|
||||
def _dxf2dwg_path() -> str | None:
|
||||
"""LibreDWG 의 DWG 쓰기 도구. `.env` 값이 먼저고, 없으면 PATH 에서 찾는다."""
|
||||
"""LibreDWG 의 DWG 쓰기 도구 — `.env` 값 → 동봉본 → PATH 순으로 찾는다."""
|
||||
configured = os.getenv("LIBREDWG_DXF2DWG_PATH", "").strip()
|
||||
if configured:
|
||||
return configured if Path(configured).is_file() else None
|
||||
return shutil.which("dxf2dwg")
|
||||
return bundled_tool("dxf2dwg.exe") or shutil.which("dxf2dwg")
|
||||
|
||||
|
||||
def dxf_to_dwg(dxf_bytes: bytes) -> bytes:
|
||||
@@ -151,9 +157,9 @@ def dxf_to_dwg(dxf_bytes: bytes) -> bytes:
|
||||
|
||||
def export_drawing(drawing: dict[str, Any], file_format: str) -> tuple[bytes, dict[str, int]]:
|
||||
"""도면을 요청한 형식(dxf·dwg) 파일 바이트로 낸다."""
|
||||
dxf_bytes, skipped = drawing_to_dxf(drawing)
|
||||
if file_format == "dxf":
|
||||
return dxf_bytes, skipped
|
||||
return drawing_to_dxf(drawing)
|
||||
if file_format == "dwg":
|
||||
dxf_bytes, skipped = drawing_to_dxf(drawing, _DWG_SOURCE_VERSION)
|
||||
return dxf_to_dwg(dxf_bytes), skipped
|
||||
raise ValueError("DXF 또는 DWG 로만 내보낼 수 있습니다.")
|
||||
|
||||
Reference in New Issue
Block a user