import sys, json, pickle, collections sys.path += ['/root/.local/lib/python3.13/site-packages','/usr/local/lib/python3.13/dist-packages','/usr/lib/python3/dist-packages'] import numpy as np from build123d import import_step, Shape from OCP.BRepAlgoAPI import BRepAlgoAPI_Section from OCP.gp import gp_Pln, gp_Pnt, gp_Dir from OCP.BRepBuilderAPI import BRepBuilderAPI_MakeFace from OCP.TopExp import TopExp_Explorer from OCP.TopAbs import TopAbs_EDGE solids = import_step("/mnt/user-data/uploads/97.과제/Code/3d-drawing/model/tunnel_solids.step").solids() mp = pickle.load(open('/tmp/verify_daesan2_run/mapping.pkl','rb'))['mapping'] caps = json.load(open('/tmp/verify_daesan2_run/caps.json')) ch = json.load(open('/tmp/verify_daesan2_run/chain.json')) meta = json.load(open('/mnt/user-data/uploads/97.과제/Code/3d-drawing/model/tunnel_solids_meta.json')) comps = {c['id']: c for c in meta['components'] if c['group']!='시설한계(참조선)'} solid_comp = {v:k for k,v in mp.items()} # 1) boundary points from lining chain pts = [] for k in ch['lin']: pts.append(np.array(ch['starts'][k])); pts.append(np.array(ch['ends'][k])) P = np.array(pts)[:, :2] uniq = [] for p in P: if not any(np.linalg.norm(p-q) < 1e-3 for q in uniq): uniq.append(p) uniq = np.array(uniq) print("unique boundary points", len(uniq), "(expect 41)") D = P[-1]-P[0] if False else (np.array(ch['ends'][ch['lin'][-1]])[:2]-np.array(ch['starts'][ch['lin'][0]])[:2]) proj = uniq@D/np.linalg.norm(D) order = np.argsort(proj); B = uniq[order] cum = np.concatenate([[0], np.cumsum(np.linalg.norm(np.diff(B,axis=0),axis=1))]) Sb = 4745 + cum M = sorted(set([c['from_sta'] for c in comps.values()] + [5480])) print("boundary count", len(Sb), "meta boundary count", len(M)) print("max |station_chain - meta_boundary| (m):", round(float(np.max(np.abs(Sb-np.array(M)))),3) if len(Sb)==len(M) else 'count mismatch') # 2) station for each solid by centroid projection def station_of(p): best=None for k in range(len(B)-1): a,b=B[k],B[k+1]; t=b-a; L2=t@t f=np.clip(((p-a)@t)/L2,0,1); q=a+f*t; d=np.linalg.norm(p-q) if best is None or d