"""Builds the machine parts kit into the open Blender file (run through the Blender MCP: exec this file). build(keys=None) makes every item of mpk_items.ITEMS (or the given keys), replacing an item's objects if they exist. Objects: SM_MPK__ (static, origin at its centre on the floor) and SM_MPK___ for moving parts (child of the item, origin on its axis, rotation 0, scale 1). Laid out as on the user's sheet. """ import importlib, math, os, sys import bpy HERE = os.path.dirname(os.path.abspath(__file__)) if "__file__" in dir() else BUILD_DIR if HERE not in sys.path: sys.path.insert(0, HERE) import mpk_lib, mpk_items importlib.reload(mpk_lib); importlib.reload(mpk_items) from mpk_lib import U, audit COLL = "MPK | Parts" MATS = ("MPK_Paint", "MPK_Dark", "MPK_Steel") def coll(name, parent=None): c = bpy.data.collections.get(name) or bpy.data.collections.new(name) p = parent or bpy.context.scene.collection if c.name not in p.children: p.children.link(c) return c def mat(name): mt = bpy.data.materials.get(name) if mt is None: mt = bpy.data.materials.new(name) mt.diffuse_color = {"MPK_Paint": (0.42, 0.36, 0.28, 1), "MPK_Dark": (0.05, 0.05, 0.05, 1), "MPK_Steel": (0.3, 0.3, 0.3, 1)}[name] return mt def make_obj(name, bm, c, loc, parent=None): old = bpy.data.objects.get(name) if old is not None: me_old = old.data bpy.data.objects.remove(old) if me_old.users == 0: bpy.data.meshes.remove(me_old) me = bpy.data.meshes.new(name) bm.to_mesh(me) bm.free() for n in MATS: me.materials.append(mat(n)) me.shade_smooth() me.set_sharp_from_angle(angle=math.radians(40)) ob = bpy.data.objects.new(name, me) c.objects.link(ob) if parent is not None: ob.parent = parent ob.matrix_parent_inverse.identity() ob.location = loc return ob def build(keys=None): c = coll(COLL) report = {} for key, name, (cx, cy), fn in mpk_items.ITEMS: if keys and key not in keys: continue # children first, so a rebuild leaves no orphans for ob in [o for o in bpy.data.objects if o.name.startswith(f"SM_MPK_{key}_")]: me = ob.data bpy.data.objects.remove(ob) if me and me.users == 0: bpy.data.meshes.remove(me) k = mpk_lib.Kit() moving = fn(k) or [] ob = make_obj(f"SM_MPK_{key}_{name}", k.finish(), c, ((cx - 1000) * U, -(cy - 470) * U, 0.0)) ob["mpk_key"] = key ob["mpk_collision"] = [list(b[0]) + list(b[1]) for b in k.boxes] r = {"main": dict(audit(ob.data), culled=k.culled)} for suf, kk, piv, axis in moving: ch = make_obj(f"SM_MPK_{key}_{name}_{suf}", kk.finish(floor=False), c, tuple(v * U for v in piv), ob) ch["mpk_axis"] = axis r[suf] = dict(audit(ch.data), culled=kk.culled) report[key] = r return report