SOURCES=[('before', 'E:\\GDRIVE\\SERVEUR ET PRODUCTION WEB\\2025\\REBIRTH\\BIG EGG\\big-egg-3d\\tools\\dev\\runs\\brute_original.glb'), ('after', 'E:\\GDRIVE\\SERVEUR ET PRODUCTION WEB\\2025\\REBIRTH\\BIG EGG\\big-egg-3d\\assets\\models\\enemies\\barnacle_brute\\barnacle_brute.glb')]
import bpy, bmesh, collections
result = {}
for label, path in SOURCES:
 bpy.ops.wm.read_factory_settings(use_empty=True)
 bpy.ops.import_scene.gltf(filepath=path)
 mesh=next(o for o in bpy.context.scene.objects if o.type == 'MESH')
 bm=bmesh.new(); bm.from_mesh(mesh.data); deform=bm.verts.layers.deform.verify()
 def bone(v): return max(v[deform].items(), key=lambda pair:pair[1])[0]
 edge_counts=collections.Counter()
 for face in bm.faces:
  for loop in face.loops:
   ends=[(bone(v),*tuple(v.co)) for v in (loop.vert,loop.link_loop_next.vert)]
   edge_counts[tuple(sorted(ends))] += 1
 stats={'open_edges':sum(n == 1 for n in edge_counts.values()), 'unpaired_edges':sum(n % 2 != 0 for n in edge_counts.values()), 'mixed_bone_faces':sum(len(set(bone(v) for v in f.verts)) > 1 for f in bm.faces)}
 result[label]=stats
 bm.free()
assert result['before']['open_edges'] > 0
assert result['after']['open_edges'] == 0
assert result['after']['unpaired_edges'] == 0
assert result['after']['mixed_bone_faces'] == 0

import json
print("TOPOLOGY CHECK OK",json.dumps(result),flush=True)
