58 lines
3.6 KiB
Python
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))
|