Owner directives 2026-07-14~15: run the DWG pipeline; split floorplan into DWG and JPG tabs. - tools/cad/dwg_extract.py: DWG(LibreDWG dwg2dxf) -> DXF -> layer inventory / keyword extraction / grid-label anchor detection (ezdxf, recover fallback) - tools/cad/render_hall_png.py: render hall-band crops from the K1 combined plan+trench drawing (x0=293.5m, width 171m, Y bands 80.1m + 63m pitch, single load -> multi-crop). Real trench layout confirmed: 7 horizontal runs at ~9m pitch + central feeder (differs from assumed 6m grid seed - V61 later) - public/media/floorplans/dwg/hall1..5.png: K1 hall underlays (3m margin crop, deterministic calibration from render params) - Editor left panel new tool group with JPG/DWG tabs; DWG disabled for halls without CAD render yet (K2 pending). Canvas switches url+region. - docs/analysis/cad-extraction.md: pipeline findings, limits (A3002 LibreDWG crash, band-to-hall numbering direction to confirm), next steps Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
73 lines
2.6 KiB
Python
73 lines
2.6 KiB
Python
# -*- coding: utf-8 -*-
|
|
"""CAD DXF → 홀별 DWG-탭 언더레이 PNG 렌더 (ezdxf drawing addon + matplotlib).
|
|
|
|
제1전시장 `전기,설비 트렌치.dwg`(평면+트렌치 통합 도면) 기준:
|
|
- 구조 그리드 Y 라벨이 63m 피치(y=80.1 시작) = 홀1~5 Y밴드
|
|
- X 원점·폭은 인자로 조정(렌더 결과를 눈으로 검증하며 캘리브레이션)
|
|
|
|
사용:
|
|
python tools/cad/render_hall_png.py <dxf> <hall_no 1~5 | 1-5> <x0_m> <width_m> <out.png|outdir> [margin_m]
|
|
예:
|
|
python tools/cad/render_hall_png.py k1_trench.dxf 1 293.5 171 hall1_dwg.png 3
|
|
python tools/cad/render_hall_png.py k1_trench.dxf 1-5 293.5 171 out_dir 3 # 1회 로드로 5개 crop
|
|
"""
|
|
import sys
|
|
|
|
import ezdxf
|
|
from ezdxf.addons.drawing import Frontend, RenderContext
|
|
from ezdxf.addons.drawing.matplotlib import MatplotlibBackend
|
|
import matplotlib
|
|
|
|
matplotlib.use("Agg")
|
|
import matplotlib.pyplot as plt
|
|
|
|
# 잡음 레이어(치수·주석·표제) — 언더레이 가독성 우선
|
|
EXCLUDE_PREFIX = ("DIM", "E-TEXT", "1-TEXT", "nember", "0-기호")
|
|
EXCLUDE_TYPES = {"TEXT", "MTEXT", "ATTDEF"}
|
|
|
|
Y0_BASE_M = 80.1 # 홀1 밴드 시작(구조 그리드 Y 라벨 실측)
|
|
BAND_M = 63.0
|
|
|
|
def main():
|
|
import os
|
|
|
|
src, hall_arg, x0_m, width_m, out = sys.argv[1], sys.argv[2], float(sys.argv[3]), float(sys.argv[4]), sys.argv[5]
|
|
margin = float(sys.argv[6]) if len(sys.argv) > 6 else 3.0
|
|
if "-" in hall_arg:
|
|
a, b = hall_arg.split("-")
|
|
halls = list(range(int(a), int(b) + 1))
|
|
else:
|
|
halls = [int(hall_arg)]
|
|
|
|
doc = ezdxf.readfile(src)
|
|
msp = doc.modelspace()
|
|
|
|
# 1회 로드·1회 드로우 → 밴드별 xlim/ylim 변경 후 저장(재렌더 비용 회피)
|
|
fig = plt.figure(figsize=(17.1, 6.3), dpi=160)
|
|
ax = fig.add_axes([0, 0, 1, 1])
|
|
ctx = RenderContext(doc)
|
|
backend = MatplotlibBackend(ax)
|
|
|
|
def keep(e):
|
|
if e.dxftype() in EXCLUDE_TYPES:
|
|
return False
|
|
layer = e.dxf.layer.upper()
|
|
return not any(layer.startswith(p.upper()) for p in EXCLUDE_PREFIX)
|
|
|
|
Frontend(ctx, backend).draw_entities(e for e in msp if keep(e))
|
|
|
|
mm = 1000.0
|
|
for hall_no in halls:
|
|
y0_m = Y0_BASE_M + (hall_no - 1) * BAND_M
|
|
ax.set_xlim((x0_m - margin) * mm, (x0_m + width_m + margin) * mm)
|
|
ax.set_ylim((y0_m - margin) * mm, (y0_m + BAND_M + margin) * mm)
|
|
ax.set_aspect("equal")
|
|
ax.axis("off")
|
|
dest = os.path.join(out, f"hall{hall_no}.png") if len(halls) > 1 else out
|
|
fig.savefig(dest, facecolor="white")
|
|
print(f"OK -> {dest} band y[{y0_m}..{y0_m+BAND_M}]m x[{x0_m}..{x0_m+width_m}]m")
|
|
|
|
|
|
if __name__ == "__main__":
|
|
main()
|