import struct, sys

VTX_TAGS = {0x80: 12, 0x81: 24, 0x82: 28, 0x88: 20, 0x89: 32, 0x8A: 36}
CONTAINERS = {0x03, 0x40, 0x41, 0x42, 0x46, 0x48, 0x70}  # HEADER OBJECT LOD PATCH PMESH SPHERE_LIST BOUND

def bounds(path):
    data = open(path, 'rb').read()
    assert data[:8] == b'DIV-BIZ2', path
    lo = [1e9, 1e9, 1e9]
    hi = [-1e9, -1e9, -1e9]
    nverts = 0

    def walk(pos, end):
        nonlocal nverts
        while pos < end - 2:
            tagword, = struct.unpack_from('<H', data, pos)
            tag = tagword & 0x2fff
            wide = (tagword >> 14) & 3
            if wide == 1:
                ln, = struct.unpack_from('<H', data, pos + 2)
                hdr = 4
            else:
                ln = data[pos + 2]
                hdr = 3
            payload = pos + hdr
            if tag in VTX_TAGS:
                stride = VTX_TAGS[tag]
                n = ln // stride
                for i in range(n):
                    x, y, z = struct.unpack_from('<3f', data, payload + i * stride)
                    for a, v in enumerate((x, y, z)):
                        if v < lo[a]: lo[a] = v
                        if v > hi[a]: hi[a] = v
                nverts += n
            elif tag in CONTAINERS:
                walk(payload, payload + ln)
            pos = payload + ln
    walk(8, len(data))
    print('%-14s verts=%5d  X[%7.2f %7.2f]  Y[%7.2f %7.2f]  Z[%7.2f %7.2f]'
          % (path.split('\\')[-1], nverts, lo[0], hi[0], lo[1], hi[1], lo[2], hi[2]))

base = r'C:\git\bt411\content\VIDEO\GEO\%s'
for f in ['BLX_COP.BGF']:
    try:
        bounds(base % f)
    except Exception as e:
        print(f, 'ERR', e)
