"""Preview scene for the kit: a top-down orthographic camera framing the whole sheet (2000 x 1000 px = 6 x 3 m), a light grey floor and soft light, in collection '_preview' (not exported). render(path, engine) writes one picture.""" import bpy, math def setup(): sc = bpy.context.scene c = bpy.data.collections.get("_preview") or bpy.data.collections.new("_preview") if c.name not in sc.collection.children: sc.collection.children.link(c) cam = bpy.data.objects.get("PV_Camera") if cam is None: cam = bpy.data.objects.new("PV_Camera", bpy.data.cameras.new("PV_Camera")); c.objects.link(cam) cam.data.type = 'ORTHO'; cam.data.ortho_scale = 6.0 cam.location = (0.0, -(500 - 470) * 0.003, 8.0); cam.rotation_euler = (0, 0, 0) cam.data.clip_end = 50 sc.camera = cam fl = bpy.data.objects.get("PV_Floor") if fl is None: me = bpy.data.meshes.new("PV_Floor") me.from_pydata([(-6, -4, 0), (6, -4, 0), (6, 4, 0), (-6, 4, 0)], [], [(0, 1, 2, 3)]) fl = bpy.data.objects.new("PV_Floor", me); c.objects.link(fl) m = bpy.data.materials.new("PV_Floor"); m.use_nodes = True b = m.node_tree.nodes["Principled BSDF"]; b.inputs["Base Color"].default_value = (0.8, 0.8, 0.82, 1) b.inputs["Roughness"].default_value = 0.8 me.materials.append(m) sun = bpy.data.objects.get("PV_Sun") if sun is None: sun = bpy.data.objects.new("PV_Sun", bpy.data.lights.new("PV_Sun", 'SUN')); c.objects.link(sun) sun.data.energy = 2.2; sun.data.angle = math.radians(25) sun.rotation_euler = (math.radians(28), math.radians(-12), math.radians(20)) w = sc.world or bpy.data.worlds.new("World"); sc.world = w; w.use_nodes = True w.node_tree.nodes["Background"].inputs[0].default_value = (0.9, 0.9, 0.92, 1) w.node_tree.nodes["Background"].inputs[1].default_value = 0.9 sc.render.resolution_x, sc.render.resolution_y, sc.render.resolution_percentage = 2000, 1000, 100 sc.view_settings.view_transform = 'AgX' return cam def render(path, engine='BLENDER_EEVEE', samples=32): sc = bpy.context.scene setup() sc.render.engine = engine if engine == 'CYCLES': sc.cycles.samples = samples; sc.cycles.use_denoising = True try: sc.cycles.device = 'GPU' except Exception: pass sc.render.filepath = path bpy.ops.render.render(write_still=True) return path