"""Final pictures of the kit in Cycles, queued on a timer (each render is longer than an MCP call). renders/MPK_sheet_top.png: the sheet's own view (orthographic, from above), to lay beside the user's picture; renders/MPK_oblique.png and MPK_close_*.png: perspective views that show the heights the sheet cannot.""" import math, time import bpy OUT = r"D:\HADAL - The Descent\models\machine-parts-kit\renders" U = 0.003 NS = bpy.app.driver_namespace def _cam(name, loc, rot, lens=50, ortho=None): c = bpy.data.collections["_preview"] cam = bpy.data.objects.get(name) if cam is None: cam = bpy.data.objects.new(name, bpy.data.cameras.new(name)); c.objects.link(cam) cam.location = loc; cam.rotation_euler = [math.radians(a) for a in rot] if ortho: cam.data.type = 'ORTHO'; cam.data.ortho_scale = ortho else: cam.data.type = 'PERSP'; cam.data.lens = lens cam.data.clip_end = 50 return cam def sheet(px, py): return ((px - 1000) * U, -(py - 470) * U) SHOTS = [ ("MPK_sheet_top", "PV_Camera", None, 2000, 1000, 128), ("MPK_oblique", "PV_Oblique", None, 2000, 1100, 96), ("MPK_close_rowA", "PV_CloseA", (sheet(700, 150), (0, -1.15, 0.95), (50, 0, 0), 40), 1600, 900, 128), ("MPK_close_rowD", "PV_CloseD", (sheet(1330, 640), (0, -1.0, 0.85), (50, 0, 0), 40), 1600, 900, 128), ] def start(): sc = bpy.context.scene for o in bpy.data.objects: if o.name.startswith("PV_"): o.hide_render = False for o in bpy.data.objects: if o.name.startswith("UCX_"): o.hide_render = True sc.render.engine = 'CYCLES' sc.cycles.device = 'GPU' sc.cycles.use_denoising = True sc.view_settings.view_transform = 'AgX' q = list(SHOTS) NS["mpk_render"] = "queued" def _step(): if not q: NS["mpk_render"] = "done" sc.camera = bpy.data.objects["PV_Camera"] return None name, camname, spec, w, h, smp = q.pop(0) t = time.time() if spec: (x, y), (dx, dy, dz), rot, lens = spec cam = _cam(camname, (x + dx, y + dy, dz), rot, lens) else: cam = bpy.data.objects[camname] sc.camera = cam sc.render.resolution_x, sc.render.resolution_y, sc.render.resolution_percentage = w, h, 100 sc.cycles.samples = smp sc.render.filepath = f"{OUT}\\{name}.png" bpy.ops.render.render(write_still=True) NS["mpk_render"] = f"{name} {time.time() - t:.0f}s; left {[s[0] for s in q]}" return 0.2 bpy.app.timers.register(_step, first_interval=0.2)