"""Regression at the exporter's pure triangle-reference seam; no bpy or scene startup.""" import ast, math from pathlib import Path source = Path('tools/city-massing/assemble-cad-bim.py').read_text(encoding='utf8') functions = {'facade_profile_flags', 'prism_triangles', 'facade_window_count', 'facade_entrance_edge', 'facade_panel_halfwidth', 'facade_window_positions', 'massing_triangles'} module = ast.Module(body=[n for n in ast.parse(source).body if isinstance(n, ast.FunctionDef) and n.name in functions], type_ignores=[]) scope = {'math': math, 'ARCHITECTURE': True, 'FULL_REVEALS': True, 'FACADE_PROFILE': 'off', 'BANDS': False} exec(compile(module, 'triangle-reference-seam', 'exec'), scope) assert scope['facade_profile_flags']('off', False, False) == { 'profile': 'off', 'architecture': False, 'fullReveals': False, 'bands': False} assert scope['facade_profile_flags']('compact', False, False) == { 'profile': 'compact', 'architecture': True, 'fullReveals': False, 'bands': False} assert scope['facade_profile_flags']('full', True, False)['fullReveals'] is True try: scope['facade_profile_flags']('full', False, False) except RuntimeError: pass else: raise AssertionError('full profile must require near architecture') # A notch-sized edge must remain in the solid but cannot fit the 0.35m facade panel. ring = [(0,0),(.2,0),(.2,5),(0,5)] # 4*n-4 shell + 12 door + 2 long-wall windows * 2 triangles * 4 floors. assert scope['massing_triangles'](ring,4,'lod1') == 12+12+16 scope['ARCHITECTURE'] = False scope['FACADE_PROFILE'] = 'off' # Original large rectangular case retains one window on every edge. assert scope['massing_triangles']([(0,0),(12,0),(12,9),(0,9)],3,'lod1') == 12+12+24 scope['ARCHITECTURE'] = True scope['FULL_REVEALS'] = False scope['FACADE_PROFILE'] = 'compact' scope['BANDS'] = False # 12x9m: 30 windows across 3 floors, except one centered ground window # reserved for the entrance: 12 shell + 12 door + 58 glass + 16 bands = 98. assert scope['massing_triangles']([(0,0),(12,0),(12,9),(0,9)],3,'lod0') == 98 scope['FULL_REVEALS'] = True # Optional reveals add 58*4 triangles, roof edges add 8; the cap remains unchanged. assert scope['massing_triangles']([(0,0),(12,0),(12,9),(0,9)],3,'lod0') == 338 print({'passed':True,'scope':'short surveyed edges plus compact massing facade profile reference','blenderStarted':False})