Files
Pier_v1/도면작성/extract_template.py
T
2026-11-04 13:34:51 +09:00

58 lines
3.6 KiB
Python

"""Extract the supplied DWG's actual frame and note text; never change the source."""
import json
import math
from pathlib import Path
import sys
sys.path.insert(0,str(Path(__file__).resolve().parent.parent/'pierzainer_ground'))
from pierzainer_ground.dxf_terrain import read_source_document
from ezdxf.disassemble import recursive_decompose
from ezdxf import path as ezpath
from ezdxf import bbox, colors
ROOT=Path(__file__).resolve().parent
doc,_=read_source_document(ROOT/'.cache/[교각-T 형] 01 일반도_20260619.dxf',ROOT/'.cache')
frame=next(e for e in doc.modelspace().query('INSERT') if e.dxf.name=='CXBLKA1')
entities=[]
def p(q): return [float(q[0])/100,float(q[1])/100]
for e in recursive_decompose([frame]):
typ=e.dxftype()
bb=bbox.extents([e],fast=True)
logo=bb.has_data and bb.extmin.x>5000 and bb.extmax.x<18000 and bb.extmin.y>1000 and bb.extmax.y<6000
base=dict(layer='FRAME',source=dict(member='reference-logo' if logo else 'reference-frame',index=len(entities),pier=''))
layer=doc.layers.get(e.dxf.layer)
aci=e.dxf.get('color',256)
if aci in (0,256):aci=layer.dxf.color
base['cad']=dict(layer=e.dxf.layer,color=abs(aci),linetype=e.dxf.get('linetype','BYLAYER'),lineweight=e.dxf.get('lineweight',-1),textStyle=e.dxf.all_existing_dxf_attribs().get('style','Standard'))
if typ=='ATTRIB': continue
if typ=='LINE': entities.append(dict(**base,kind='line',a=p(e.dxf.start),b=p(e.dxf.end)))
elif typ in ('ARC','ELLIPSE','LWPOLYLINE'):
try:
pts=[p(q) for q in ezpath.make_path(e).flattening(5)]
if len(pts)>1: entities.append(dict(**base,kind='polyline',points=pts,closed=bool(getattr(e,'is_closed',False))))
except (TypeError,ValueError): pass
elif typ=='TEXT':
pt=e.dxf.align_point if e.dxf.get('valign',0) else e.dxf.insert
entities.append(dict(**base,kind='text',point=p(pt),text=e.dxf.text,height=e.dxf.height/100,rotation=e.dxf.get('rotation',0),align='left'))
elif typ=='HATCH':
loops=[[p(q) for q in path.flattening(5)] for path in ezpath.from_hatch(e)]
loops=[pts for pts in loops if len(pts)>2]
aci=e.dxf.get('color',256)
rgb=e.rgb or (colors.aci2rgb(aci) if 0<aci<256 and aci!=7 else (0,0,0))
color='#'+''.join(f'{v:02x}' for v in rgb)
if loops: entities.append(dict(**base,kind='hatch',points=loops[0],holes=loops[1:],pattern='SOLID',spacing=3,angle=45,color=color))
attrs=[]
for a in frame.attribs:
if a.dxf.tag=='ES': continue
attrs.append(dict(tag=a.dxf.tag,label=a.dxf.tag,value=a.dxf.text,point=p(a.dxf.insert),height=a.dxf.height/100,rotation=a.dxf.get('rotation',0)))
texts=[e for e in doc.modelspace().query('TEXT') if 68000<e.dxf.insert.x<82000 and 33500<e.dxf.insert.y<50000]
rows={}
for e in texts: rows.setdefault(round(e.dxf.insert.y/10)*10,[]).append(e)
notes=[]
for y,es in sorted(rows.items(),reverse=True):
es.sort(key=lambda e:e.dxf.insert.x)
notes.append(' '.join(e.dxf.text.strip() for e in es))
result=dict(version=1,name='원본 CXBLKA1 도곽 · 20260619',source='[교각-T 형] 01 일반도_20260619.dwg',sha256='156570dc5389650e20840e91c3d9a974a92c40687669f8d00aafb62073fb2b6b',width=841,height=594,entities=entities,fields=attrs,notes='\n'.join(notes))
(ROOT/'.cache/reference-template.json').write_text(json.dumps(result,ensure_ascii=False,indent=2),encoding='utf-8')
(ROOT/'reference-template.ts').write_text('// Generated from the supplied DWG by extract_template.py.\nexport default '+json.dumps(result,ensure_ascii=False,indent=2)+';\n',encoding='utf-8')
print('frame entities',len(entities),'editable fields',len(attrs),'note lines',len(notes))