"""Isolated A/B trial of the installed Studio baker; never edits the shared backend. Blender -- --job DIR --output DIR --ray-mode legacy|adaptive Uses the same source geometry and Studio UVs, keeping baked/exported normals consistent. """ import argparse import hashlib import json import sys from pathlib import Path parser = argparse.ArgumentParser() parser.add_argument('--job', required=True) parser.add_argument('--output', required=True) parser.add_argument('--ray-mode', choices=['legacy', 'adaptive'], default='adaptive') args = parser.parse_args(sys.argv[sys.argv.index('--') + 1:]) job, out = Path(args.job).resolve(), Path(args.output).resolve() out.mkdir(parents=True, exist_ok=True) backend = Path('D:/UD/AI/XModel/LLM3DGraphics/backend/blender_lowpoly_bake.py') source = backend.read_text(encoding='utf-8') baseline_hash = hashlib.sha256(backend.read_bytes()).hexdigest() needle = 'outward_faces = bias_normals_outward(low)' assert source.count(needle) == 1 source = source.replace(needle, 'outward_faces = 0 # Preserve the same tangent basis used by the normal bake') if args.ray_mode == 'adaptive': needle = 'ray = estimate_ray_distance(low)' assert source.count(needle) == 1 source = source.replace(needle, ''' # Trial: surface separation rather than a fixed 4% of the full bounding box. _bvh = BVHTree.FromObject(high, bpy.context.evaluated_depsgraph_get()) _distances = [] for _poly in low.data.polygons: _hit = _bvh.find_nearest(low.matrix_world @ _poly.center) if _hit[0] is not None: _distances.append(float(_hit[3])) _diag = float(low.dimensions.length) _p99 = float(np.percentile(_distances, 99)) ray = min(max(_p99 * 1.5, _diag * .0005), _diag * .01) print('TRIAL_PROJECTION ' + json.dumps(dict(p99=_p99, bbox_diagonal=_diag, cage_extrusion=ray, legacy_cage_extrusion=_diag*.04))) ''') sys.argv = [str(backend), '--', str(job/'model.glb'), str(out/'model_baked.glb'), '1', '1024', str(job/'model_lowpoly_uv.glb')] (out/'baker_snapshot.py').write_text(source, encoding='utf-8') (out/'trial_settings.json').write_text(json.dumps(dict( source_job=str(job), shared_backend_sha256=baseline_hash, ray_mode=args.ray_mode, post_bake_normal_bias=False, preserve_studio_uv=True, source_unchanged=True), indent=2), encoding='utf-8') exec(compile(source, str(out/'baker_snapshot.py'), 'exec'), {'__file__': str(backend), '__name__': '__main__'})