"""Read-only: compare source corners with the viewer's actual bend geometry.""" import argparse import json from pathlib import Path import subprocess import sys root=Path(__file__).resolve().parents[1] sys.path.insert(0,str(root/'src/backend'if (root/'src/backend').is_dir()else root)) from repair_source_cycle_connections import path_key def inspect(path,node): import server server.require_modeling_rules() data=json.loads(path.read_text());group=data['group'] kernel=root/'model_kernel.js' if not kernel.is_file():kernel=root/'src/frontend/src/model_kernel.js' script="const fs=require('fs');require(process.argv[1]);const g=JSON.parse(fs.readFileSync(0,'utf8'));process.stdout.write(JSON.stringify(g.instance_paths_m.map((p,i)=>ModelKernel.bendPath(p,g,i))));" process=subprocess.run([node,'-e',script,str(kernel)],input=json.dumps(group), capture_output=True,text=True,check=True) bends=json.loads(process.stdout);previous={path_key(p)for p in data['previous_paths']} rows=[] for i,(raw,bend)in enumerate(zip(group['instance_paths_m'],bends)): if path_key(raw)in previous:continue before,first_raw=server.tube_path_outside_component_union( [raw],group['diameter_mm'],data['concrete_components']) after,first_bent=server.tube_path_outside_component_union( [bend['path']],group['diameter_mm'],data['concrete_components']) rows.append({'index':i,'source_length_m':bend['sourceLengthM'], 'rounded_length_m':bend['lengthM'],'warnings':bend['warnings'], 'source_corner_outside_samples':before,'rounded_outside_samples':after, 'first_source_outside':first_raw,'first_rounded_outside':first_bent}) return {'id':group['id'],'rows':rows,'published':False} if __name__=='__main__': parser=argparse.ArgumentParser(description=__doc__) parser.add_argument('candidate',type=Path);parser.add_argument('--node',default='node') args=parser.parse_args();print(json.dumps(inspect(args.candidate,args.node),ensure_ascii=False,indent=2))