"""정식 원본의 실제 누락·포함·부피 실패와 수정 성공을 기록한다.""" import argparse import json from pathlib import Path import subprocess ROOT=Path(__file__).resolve().parents[3] PROJECT=ROOT/'projects/water-hydrogen-bond-surface-tension' BLENDER='C:/Program Files/Blender Foundation/Blender 5.2/blender.exe' VERIFY=PROJECT/'blender/verify_production.py' parser=argparse.ArgumentParser() parser.add_argument('--stage',choices=['references','images'],required=True) args=parser.parse_args() BASE=PROJECT/f'stages/{"10-references" if args.stage=="references" else "11-images"}/r2' SOURCE=BASE/f'generated-source/{"references" if args.stage=="references" else "animation"}.blend' records=[] def execute(arguments,expected,reason=None): command=[BLENDER,'--background','--disable-autoexec','--python-exit-code','1']+arguments value=subprocess.run(command,cwd=ROOT,capture_output=True,text=True,encoding='utf-8') records.append(dict(command=command,exit_code=value.returncode,expected_exit_code=expected,matched_reason=reason,assertion_errors=[line for line in value.stderr.splitlines() if line.startswith('AssertionError:')])) (BASE/'model-test-results.json').write_text(json.dumps(dict(result='RUNNING',executions=records),ensure_ascii=False,indent=2)+'\n',encoding='utf-8') assert value.returncode==expected,(value.stdout,value.stderr) assert not reason or reason in value.stderr,(reason,value.stderr) def check(source,expected,reason=None,out=None): options=['--source',str(source),'--out',str(out or BASE/'generated-source/invalid-result.json')] if args.stage=='images': options.append('--animated') execute(['--python',str(VERIFY),'--']+options,expected,reason) check(BASE/'generated-source/missing.blend',1,'원본 파일 없음') check(PROJECT/'stages/08-scenes/r3/generated-source/preview.blend',1,'대표 Scene 누락/혼입') for name,edit,reason in [ ('missing-scene',"bpy.data.scenes.remove(bpy.data.scenes['SingleMolecule'])",'대표 Scene 누락/혼입'), ('outside-mesh',"bpy.data.objects['Liquid9_H1'].data.vertices[0].co.x=10",'물 영역 밖 또는 여백 부족')]: fixture=BASE/f'generated-source/{name}.blend' expression=f'import bpy; bpy.ops.wm.open_mainfile(filepath={str(SOURCE)!r}); {edit}; bpy.ops.wm.save_as_mainfile(filepath={str(fixture)!r})' execute(['--python-expr',expression],0) check(fixture,1,reason) check(SOURCE,0,out=BASE/'model-check.json') (BASE/'model-test-results.json').write_text(json.dumps(dict(result='GREEN',negative_cases=4,positive_cases=1,executions=records),ensure_ascii=False,indent=2)+'\n',encoding='utf-8') print('정식 원본 RED→GREEN 확인',args.stage)