chore: import 3d-drawing history from local Code/3d-drawing (subfolder, history preserved)
This commit is contained in:
commit
7b754e810b
51 files changed
+20300
No files matched your search
@@ -0,0 +1,85 @@
|
||||
#!/usr/bin/env python3
|
||||
"""Inventory the main-line (본선) DXF drawings: header, layers, entity counts,
|
||||
extents, 3D flag and text samples. Read-only on the source RAG folder."""
|
||||
import collections
|
||||
import glob
|
||||
import json
|
||||
import os
|
||||
import sys
|
||||
|
||||
import ezdxf
|
||||
from ezdxf import bbox, recover
|
||||
|
||||
RAG_DIR = sys.argv[1]
|
||||
OUT_JSON = sys.argv[2]
|
||||
# 본선 scope (approved 2026-10-21): 02 평면·종단, 03 본선굴착, 04 본선기타
|
||||
SUBDIRS = ["02_평면 및 종단면도", "03_본선터널굴착", "04_본선터널기타"]
|
||||
|
||||
|
||||
def inventory(path):
|
||||
rec = {"file": os.path.basename(path), "ok": False}
|
||||
rec["recovered"] = False
|
||||
try:
|
||||
doc = ezdxf.readfile(path)
|
||||
except Exception as exc: # strict load failed: retry in recover mode and record it
|
||||
strict_error = f"{type(exc).__name__}: {exc}"
|
||||
try:
|
||||
doc, _auditor = recover.readfile(path)
|
||||
rec["recovered"] = True
|
||||
rec["strict_error"] = strict_error
|
||||
except Exception as exc2:
|
||||
rec["error"] = f"{strict_error} | recover: {type(exc2).__name__}: {exc2}"
|
||||
return rec
|
||||
hdr = doc.header
|
||||
rec["dxfversion"] = doc.dxfversion
|
||||
rec["insunits"] = hdr.get("$INSUNITS")
|
||||
rec["codepage"] = hdr.get("$DWGCODEPAGE")
|
||||
rec["layers"] = len(doc.layers)
|
||||
msp = doc.modelspace()
|
||||
counts = collections.Counter(e.dxftype() for e in msp)
|
||||
rec["entity_counts"] = dict(counts.most_common())
|
||||
rec["blocks"] = len([b for b in doc.blocks if not b.name.startswith("*")])
|
||||
z_vals = []
|
||||
texts = []
|
||||
for e in msp:
|
||||
t = e.dxftype()
|
||||
if t == "LINE":
|
||||
z_vals += [e.dxf.start.z, e.dxf.end.z]
|
||||
elif t in ("TEXT", "MTEXT"):
|
||||
s = e.dxf.text if t == "TEXT" else e.plain_text()
|
||||
if s and len(texts) < 40:
|
||||
texts.append(s.strip()[:80])
|
||||
elif t in ("POINT", "INSERT", "CIRCLE", "ARC"):
|
||||
z_vals.append(e.dxf.location.z if t == "POINT" else e.dxf.insert.z if t == "INSERT" else e.dxf.center.z)
|
||||
rec["z_min"] = round(min(z_vals), 3) if z_vals else None
|
||||
rec["z_max"] = round(max(z_vals), 3) if z_vals else None
|
||||
rec["has_3d_geometry"] = bool(z_vals) and (max(z_vals) - min(z_vals)) > 1e-6
|
||||
try:
|
||||
ext = bbox.extents(msp)
|
||||
rec["extents_min"] = [round(v, 2) for v in ext.extmin]
|
||||
rec["extents_max"] = [round(v, 2) for v in ext.extmax]
|
||||
except Exception as exc:
|
||||
rec["extents_error"] = str(exc)
|
||||
rec["text_sample"] = texts
|
||||
rec["ok"] = True
|
||||
return rec
|
||||
|
||||
|
||||
def main():
|
||||
paths = []
|
||||
for sub in SUBDIRS:
|
||||
paths += sorted(glob.glob(os.path.join(RAG_DIR, sub, "*.dxf")))
|
||||
results = [inventory(p) for p in paths]
|
||||
os.makedirs(os.path.dirname(OUT_JSON), exist_ok=True)
|
||||
with open(OUT_JSON, "w", encoding="utf-8") as fh:
|
||||
json.dump(results, fh, ensure_ascii=False, indent=2)
|
||||
ok = sum(r["ok"] for r in results)
|
||||
print(f"files={len(results)} ok={ok} failed={len(results) - ok}")
|
||||
for r in results:
|
||||
status = "OK " if r["ok"] else "ERR"
|
||||
detail = r.get("error") or f"ents={sum(r['entity_counts'].values())} 3D={r['has_3d_geometry']} units={r['insunits']} cp={r['codepage']} recovered={r['recovered']}"
|
||||
print(f"{status} {r['file'][:60]:60s} {detail}")
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
Reference in new issue
Block a user