from pathlib import Path
import math
import random

import bpy
from mathutils import Vector

OUTPUT_DIR = Path(__file__).resolve().parent
BLEND_PATH = OUTPUT_DIR / "lantern.blend"
RENDER_PATH = OUTPUT_DIR / "render.png"

random.seed(19)
bpy.ops.wm.read_factory_settings(use_empty=True)
scene = bpy.context.scene
scene.render.engine = "BLENDER_EEVEE_NEXT"
scene.render.resolution_x = 960
scene.render.resolution_y = 640
scene.render.resolution_percentage = 100
scene.render.image_settings.file_format = "PNG"
scene.render.image_settings.color_mode = "RGBA"
scene.render.image_settings.color_depth = "8"
scene.render.film_transparent = False
scene.render.use_file_extension = True
scene.render.filepath = str(RENDER_PATH)
scene.frame_set(1)
if hasattr(scene, "eevee"):
    eevee = scene.eevee
    for setting, value in (("taa_render_samples", 32), ("taa_samples", 32), ("use_gtao", True), ("gtao_distance", 3.0), ("use_soft_shadows", True)):
        if hasattr(eevee, setting):
            try:
                setattr(eevee, setting, value)
            except (TypeError, ValueError):
                pass
try:
    scene.view_settings.view_transform = "AgX"
    scene.view_settings.look = "AgX - Medium High Contrast"
except (TypeError, ValueError):
    pass
scene.view_settings.exposure = 0.0
scene.view_settings.gamma = 1.0


def rgba(color, alpha=1.0):
    return (color[0], color[1], color[2], alpha)


def material(name, color, roughness=0.5, metallic=0.0):
    mat = bpy.data.materials.new(name)
    mat.use_nodes = True
    mat.diffuse_color = rgba(color)
    nodes = mat.node_tree.nodes
    links = mat.node_tree.links
    nodes.clear()
    output = nodes.new("ShaderNodeOutputMaterial")
    bsdf = nodes.new("ShaderNodeBsdfPrincipled")
    bsdf.inputs["Base Color"].default_value = rgba(color)
    bsdf.inputs["Roughness"].default_value = roughness
    bsdf.inputs["Metallic"].default_value = metallic
    links.new(bsdf.outputs["BSDF"], output.inputs["Surface"])
    return mat


def emissive_material(name, color, strength=2.0):
    mat = bpy.data.materials.new(name)
    mat.use_nodes = True
    mat.diffuse_color = rgba(color)
    nodes = mat.node_tree.nodes
    links = mat.node_tree.links
    nodes.clear()
    output = nodes.new("ShaderNodeOutputMaterial")
    emission = nodes.new("ShaderNodeEmission")
    emission.inputs["Color"].default_value = rgba(color)
    emission.inputs["Strength"].default_value = strength
    links.new(emission.outputs["Emission"], output.inputs["Surface"])
    return mat


def glass_material():
    mat = bpy.data.materials.new("Sage greenhouse glass")
    mat.use_nodes = True
    mat.diffuse_color = (0.58, 0.78, 0.68, 0.15)
    nodes = mat.node_tree.nodes
    links = mat.node_tree.links
    nodes.clear()
    output = nodes.new("ShaderNodeOutputMaterial")
    transparent = nodes.new("ShaderNodeBsdfTransparent")
    glass = nodes.new("ShaderNodeBsdfGlass")
    glass.inputs["Color"].default_value = (0.62, 0.82, 0.72, 1.0)
    glass.inputs["Roughness"].default_value = 0.12
    glass.inputs["IOR"].default_value = 1.45
    mix = nodes.new("ShaderNodeMixShader")
    mix.inputs[0].default_value = 0.16
    links.new(transparent.outputs["BSDF"], mix.inputs[1])
    links.new(glass.outputs["BSDF"], mix.inputs[2])
    links.new(mix.outputs[0], output.inputs["Surface"])
    if hasattr(mat, "surface_render_method"):
        try:
            mat.surface_render_method = "DITHERED"
        except (TypeError, ValueError):
            pass
    return mat


stone = material("Warm limestone", (0.76, 0.69, 0.56), 0.78)
stone_light = material("Limestone edge", (0.9, 0.82, 0.68), 0.72)
stone_dark = material("Path stone", (0.52, 0.49, 0.43), 0.9)
soil = material("Roof soil", (0.12, 0.1, 0.08), 0.98)
sage = material("Sage frame", (0.22, 0.42, 0.31), 0.38, 0.05)
sage_light = material("Sage frame highlight", (0.42, 0.58, 0.4), 0.42)
terracotta = material("Terracotta", (0.64, 0.28, 0.15), 0.72)
terracotta_light = material("Terracotta rim", (0.78, 0.39, 0.2), 0.64)
wood = material("Bench honey wood", (0.42, 0.2, 0.1), 0.62)
wood_light = material("Bench seat highlight", (0.62, 0.31, 0.14), 0.5)
brass = material("Lantern brass", (0.72, 0.43, 0.12), 0.28, 0.72)
leaf_sage = material("Leaf sage", (0.18, 0.47, 0.27), 0.76)
leaf_deep = material("Leaf deep green", (0.08, 0.25, 0.17), 0.82)
leaf_light = material("Leaf moonlit", (0.35, 0.6, 0.33), 0.7)
vein = material("Leaf vein", (0.1, 0.32, 0.18), 0.8)
lavender_floor = material("Twilight lavender floor", (0.28, 0.24, 0.39), 0.94)
lavender_wall = material("Twilight lavender wall", (0.34, 0.29, 0.47), 0.96)
lavender_glow = emissive_material("Lavender dusk glow", (0.42, 0.32, 0.66), 0.42)
lantern_glow = emissive_material("Lantern warm glow", (1.0, 0.35, 0.08), 8.0)
lantern_core = emissive_material("Lantern core", (1.0, 0.62, 0.18), 12.0)
glass = glass_material()


def select_only(obj):
    bpy.ops.object.select_all(action="DESELECT")
    obj.select_set(True)
    bpy.context.view_layer.objects.active = obj


def apply_scale(obj):
    select_only(obj)
    bpy.ops.object.transform_apply(location=False, rotation=False, scale=True)


def bevel(obj, width=0.03, segments=3):
    modifier = obj.modifiers.new("Soft miniature edges", "BEVEL")
    modifier.width = width
    modifier.segments = segments
    return modifier


def add_cube(name, location, dimensions, mat, bevel_width=0.03, rotation=(0.0, 0.0, 0.0)):
    bpy.ops.mesh.primitive_cube_add(size=1.0, location=location, rotation=rotation)
    obj = bpy.context.object
    obj.name = name
    obj.dimensions = dimensions
    apply_scale(obj)
    obj.data.materials.append(mat)
    if bevel_width:
        bevel(obj, bevel_width)
    return obj


def add_cylinder(name, location, radius, depth, mat, rotation=(0.0, 0.0, 0.0), vertices=32, bevel_width=0.02, scale=(1.0, 1.0, 1.0)):
    bpy.ops.mesh.primitive_cylinder_add(vertices=vertices, radius=radius, depth=depth, location=location, rotation=rotation)
    obj = bpy.context.object
    obj.name = name
    obj.scale = scale
    apply_scale(obj)
    obj.data.materials.append(mat)
    for polygon in obj.data.polygons:
        polygon.use_smooth = True
    if bevel_width:
        bevel(obj, bevel_width, 2)
    return obj


def add_sphere(name, location, scale, mat, segments=24, rings=12):
    bpy.ops.mesh.primitive_uv_sphere_add(segments=segments, ring_count=rings, radius=1.0, location=location)
    obj = bpy.context.object
    obj.name = name
    obj.scale = scale
    apply_scale(obj)
    obj.data.materials.append(mat)
    for polygon in obj.data.polygons:
        polygon.use_smooth = True
    return obj


def add_beam(name, start, end, radius, mat):
    start = Vector(start)
    end = Vector(end)
    direction = end - start
    obj = add_cylinder(name, (start + end) / 2, radius, direction.length, mat, bevel_width=0.008, vertices=20)
    obj.rotation_euler = direction.to_track_quat("Z", "Y").to_euler()
    return obj


def add_curve(name, points, radius, mat, cyclic=False):
    curve = bpy.data.curves.new(name, "CURVE")
    curve.dimensions = "3D"
    curve.resolution_u = 2
    curve.bevel_depth = radius
    curve.bevel_resolution = 3
    curve.use_fill_caps = True
    spline = curve.splines.new("POLY")
    spline.points.add(len(points) - 1)
    for point, coordinate in zip(spline.points, points):
        point.co = (*coordinate, 1.0)
    spline.use_cyclic_u = cyclic
    obj = bpy.data.objects.new(name, curve)
    bpy.context.collection.objects.link(obj)
    obj.data.materials.append(mat)
    return obj


def add_arc_slab(name, center, inner_radius, outer_radius, z, thickness, start_angle, end_angle, mat):
    center = Vector(center)
    segments = 28
    vertices = []
    for index in range(segments + 1):
        fraction = index / segments
        angle = math.radians(start_angle + (end_angle - start_angle) * fraction)
        for radius, height in ((inner_radius, z - thickness / 2), (outer_radius, z - thickness / 2), (inner_radius, z + thickness / 2), (outer_radius, z + thickness / 2)):
            vertices.append((center.x + math.cos(angle) * radius, center.y + math.sin(angle) * radius, height))
    faces = []
    for index in range(segments):
        a = index * 4
        b = (index + 1) * 4
        faces.extend(((a, b, b + 1, a + 1), (a + 2, a + 3, b + 3, b + 2), (a, a + 2, b + 2, b), (a + 1, b + 1, b + 3, a + 3)))
    faces.append((0, 1, 3, 2))
    last = segments * 4
    faces.append((last, last + 2, last + 3, last + 1))
    mesh = bpy.data.meshes.new(name)
    mesh.from_pydata(vertices, [], faces)
    mesh.update()
    obj = bpy.data.objects.new(name, mesh)
    bpy.context.collection.objects.link(obj)
    obj.data.materials.append(mat)
    bevel(obj, 0.035, 3)
    for polygon in obj.data.polygons:
        polygon.use_smooth = True
    return obj


def add_leaf(name, base, tip, width, mat):
    base = Vector(base)
    tip = Vector(tip)
    direction = tip - base
    side = direction.cross(Vector((0.0, 0.0, 1.0)))
    if side.length < 0.01:
        side = Vector((1.0, 0.0, 0.0))
    side.normalize()
    normal = side.cross(direction).normalized()
    outline = [
        base,
        base + direction * 0.25 + side * width,
        base + direction * 0.66 + side * width * 0.78,
        tip,
        base + direction * 0.66 - side * width * 0.78,
        base + direction * 0.25 - side * width,
    ]
    ridge = base + direction * 0.52 + normal * 0.065
    vertices = [tuple(point) for point in outline] + [tuple(ridge)]
    faces = [(6, 0, 1), (6, 1, 2), (6, 2, 3), (6, 3, 4), (6, 4, 5), (6, 5, 0)]
    mesh = bpy.data.meshes.new(name)
    mesh.from_pydata(vertices, [], faces)
    mesh.update()
    obj = bpy.data.objects.new(name, mesh)
    bpy.context.collection.objects.link(obj)
    obj.data.materials.append(mat)
    for polygon in mesh.polygons:
        polygon.use_smooth = True
    solidify = obj.modifiers.new("Leaf thickness", "SOLIDIFY")
    solidify.thickness = 0.018
    bevel(obj, 0.012, 2)
    add_curve(name + " vein", [tuple(base + normal * 0.025), tuple(ridge + normal * 0.02), tuple(tip + normal * 0.018)], 0.008, vein)
    return obj


def add_pot(name, x, y, z, size=1.0):
    add_cylinder(name + " saucer", (x, y, z + 0.035 * size), 0.48 * size, 0.07 * size, terracotta_light, bevel_width=0.02 * size, scale=(1.0, 1.0, 1.0))
    add_cylinder(name + " body", (x, y, z + 0.25 * size), 0.32 * size, 0.42 * size, terracotta, bevel_width=0.025 * size, vertices=32)
    bpy.ops.mesh.primitive_torus_add(major_radius=0.36 * size, minor_radius=0.045 * size, major_segments=32, minor_segments=10, location=(x, y, z + 0.46 * size))
    rim = bpy.context.object
    rim.name = name + " rim"
    rim.data.materials.append(terracotta_light)
    for polygon in rim.data.polygons:
        polygon.use_smooth = True
    add_cylinder(name + " soil", (x, y, z + 0.455 * size), 0.33 * size, 0.035 * size, soil, bevel_width=0.006 * size, vertices=32)
    return z + 0.48 * size


def add_plant(name, x, y, z, size=1.0, variant=0):
    soil_z = add_pot(name, x, y, z, size)
    stem_top = soil_z + 1.0 * size
    add_curve(name + " stem", [(x, y, soil_z), (x + 0.03 * size, y - 0.02 * size, soil_z + 0.52 * size), (x, y + 0.02 * size, stem_top)], 0.025 * size, leaf_deep)
    leaf_materials = (leaf_sage, leaf_deep, leaf_light)
    count = 6
    for index in range(count):
        angle = variant * 0.45 + index * (math.tau / count) + 0.2
        level = 0.28 + (index % 3) * 0.18
        base = Vector((x + math.cos(angle) * 0.04 * size, y + math.sin(angle) * 0.04 * size, soil_z + level * size))
        reach = (0.42 + 0.12 * (index % 2)) * size
        tip = base + Vector((math.cos(angle) * reach, math.sin(angle) * reach, (0.24 + 0.12 * (index % 2)) * size))
        add_leaf(name + " leaf " + str(index), base, tip, 0.15 * size, leaf_materials[(index + variant) % len(leaf_materials)])
    top_base = Vector((x, y, soil_z + 0.72 * size))
    top_tip = top_base + Vector((0.02 * size, 0.01 * size, 0.44 * size))
    add_leaf(name + " crown", top_base, top_tip, 0.12 * size, leaf_light)


def add_lantern(name, x, y, z):
    add_beam(name + " hanger", (x, y, z + 0.62), (x, y, z + 0.22), 0.014, brass)
    add_cylinder(name + " cap", (x, y, z + 0.19), 0.15, 0.07, brass, bevel_width=0.015, vertices=24)
    add_cube(name + " glow", (x, y, z - 0.01), (0.2, 0.2, 0.27), lantern_glow, bevel_width=0.035)
    add_sphere(name + " core", (x, y, z - 0.01), (0.075, 0.075, 0.12), lantern_core, segments=20, rings=10)
    add_cylinder(name + " lower cap", (x, y, z - 0.19), 0.14, 0.06, brass, bevel_width=0.012, vertices=24)
    for dx in (-0.115, 0.115):
        add_beam(name + " side rail", (x + dx, y - 0.105, z - 0.15), (x + dx, y - 0.105, z + 0.14), 0.01, brass)
        add_beam(name + " side rail back", (x + dx, y + 0.105, z - 0.15), (x + dx, y + 0.105, z + 0.14), 0.01, brass)
    light_data = bpy.data.lights.new(name + " light", "POINT")
    light_data.energy = 38
    light_data.color = (1.0, 0.22, 0.045)
    light_data.shadow_soft_size = 0.38
    light = bpy.data.objects.new(name + " light", light_data)
    bpy.context.collection.objects.link(light)
    light.location = (x, y, z - 0.04)


def add_stones():
    stones = [(-0.02, -2.05, 0.42, 0.3), (0.2, -1.58, 0.48, -0.16), (-0.25, -1.08, 0.43, 0.24), (0.16, -0.58, 0.5, -0.2)]
    for index, (x, y, sx, rotation) in enumerate(stones):
        obj = add_cylinder("Stepping stone " + str(index), (x, y, 0.17), 0.38, 0.13, stone_dark if index % 2 else stone, rotation=(0.0, 0.0, rotation), bevel_width=0.035, scale=(sx, 0.78, 1.0))
        obj.rotation_euler.z += random.uniform(-0.08, 0.08)


def add_bench():
    add_arc_slab("Curved bench seat", (0.72, 0.55), 0.72, 1.02, 0.73, 0.14, 25, 155, wood_light)
    points = []
    for index in range(19):
        angle = math.radians(25 + (155 - 25) * index / 18)
        points.append((0.72 + math.cos(angle) * 0.91, 0.55 + math.sin(angle) * 0.91, 1.18))
    add_curve("Curved bench back", points, 0.075, wood)
    for angle in (35, 90, 145):
        radians = math.radians(angle)
        x = 0.72 + math.cos(radians) * 0.84
        y = 0.55 + math.sin(radians) * 0.84
        add_beam("Bench leg", (x, y, 0.3), (x, y, 0.72), 0.055, wood)
    add_beam("Bench front rail", (0.72 + math.cos(math.radians(25)) * 0.88, 0.55 + math.sin(math.radians(25)) * 0.88, 0.56), (0.72 + math.cos(math.radians(155)) * 0.88, 0.55 + math.sin(math.radians(155)) * 0.88, 0.56), 0.045, wood)


def add_greenhouse():
    floor_z = 0.57
    x_left, x_right = -2.3, 2.3
    y_front, y_back = -1.28, 1.35
    post_top = 3.22
    for x in (x_left, x_right):
        for y in (y_front, y_back):
            add_beam("Greenhouse upright", (x, y, floor_z), (x, y, post_top), 0.065, sage)
    for y in (y_front, y_back):
        add_beam("Greenhouse lower rail", (x_left, y, 0.95), (x_right, y, 0.95), 0.045, sage_light)
        add_beam("Greenhouse upper rail", (x_left, y, 2.35), (x_right, y, 2.35), 0.045, sage)
    for x in (x_left, x_right):
        add_beam("Greenhouse side rail", (x, y_front, 1.55), (x, y_back, 1.55), 0.045, sage_light)
        add_beam("Greenhouse side upper", (x, y_front, 2.8), (x, y_back, 2.8), 0.045, sage)
    arch_points = []
    for index in range(9):
        fraction = index / 8
        x = x_left + (x_right - x_left) * fraction
        arch_height = 3.22 + 0.95 * math.sin(math.pi * fraction)
        arch_points.append((x, y_back, arch_height))
    add_curve("Greenhouse back arch", arch_points, 0.065, sage)
    front_arch = [(x, y_front, z) for x, _, z in arch_points]
    add_curve("Greenhouse front arch", front_arch, 0.06, sage)
    for index in (2, 4, 6):
        x, _, z = arch_points[index]
        add_beam("Greenhouse roof rib", (x, y_front, z), (x, y_back, z), 0.035, sage_light)
    add_cube("Rear glass panel", (0, y_back + 0.015, 1.82), (4.35, 0.022, 2.42), glass, bevel_width=0.0)
    add_cube("Left glass panel", (x_left + 0.015, 0.03, 1.82), (0.022, 2.48, 2.42), glass, bevel_width=0.0)
    add_cube("Right glass panel", (x_right - 0.015, 0.03, 1.82), (0.022, 2.48, 2.42), glass, bevel_width=0.0)
    add_cube("Greenhouse threshold", (0, y_front, 0.64), (4.75, 0.12, 0.12), stone_light, bevel_width=0.025)


def add_backdrop():
    bpy.ops.mesh.primitive_plane_add(size=200, location=(0, 0, -0.015))
    floor = bpy.context.object
    floor.name = "Lavender ground"
    floor.data.materials.append(lavender_floor)
    add_cube("Lavender cyclorama", (0, 4.1, 4.3), (18, 0.2, 9.5), lavender_wall, bevel_width=0.0)
    add_sphere("Twilight moon", (-1.4, 3.92, 5.2), (2.0, 0.08, 2.0), lavender_glow, segments=48, rings=24)
    for index in range(11):
        x = random.uniform(-5.4, 5.4)
        z = random.uniform(3.1, 6.3)
        add_sphere("Distant star " + str(index), (x, 3.95, z), (0.035, 0.02, 0.035), lavender_glow, segments=12, rings=6)


def aim_at(obj, target):
    direction = Vector(target) - obj.location
    obj.rotation_euler = direction.to_track_quat("-Z", "Y").to_euler()


def area_light(name, location, target, energy, color, size):
    data = bpy.data.lights.new(name, "AREA")
    data.energy = energy
    data.color = color
    data.shape = "DISK"
    data.size = size
    obj = bpy.data.objects.new(name, data)
    bpy.context.collection.objects.link(obj)
    obj.location = location
    aim_at(obj, target)
    return obj


def add_lighting():
    world = bpy.data.worlds.new("Lavender twilight world")
    world.use_nodes = True
    world.node_tree.nodes["Background"].inputs["Color"].default_value = (0.18, 0.14, 0.3, 1.0)
    world.node_tree.nodes["Background"].inputs["Strength"].default_value = 0.32
    scene.world = world
    area_light("Warm key", (-4.2, -4.5, 7.5), (0, 0, 1.5), 520, (1.0, 0.62, 0.3), 5.0)
    area_light("Lavender fill", (4.5, -1.0, 5.5), (0, 0, 1.7), 280, (0.48, 0.38, 0.9), 4.0)
    area_light("Cool rim", (0, 3.0, 6.4), (0, 0, 1.5), 340, (0.38, 0.72, 0.8), 3.0)
    add_lantern("Left lantern", -1.25, -0.2, 2.95)
    add_lantern("Center lantern", 0.0, 0.45, 3.15)
    add_lantern("Right lantern", 1.35, -0.05, 2.86)


def add_base_and_plants():
    add_cube("Cream stone plinth", (0, 0, 0.22), (6.15, 4.45, 0.44), stone, bevel_width=0.2)
    add_cube("Stone upper terrace", (0, 0, 0.49), (5.72, 4.0, 0.14), stone_light, bevel_width=0.08)
    add_cube("Dark soil bed", (0, 0.13, 0.59), (5.35, 3.5, 0.09), soil, bevel_width=0.04)
    add_plant("Left broadleaf", -1.55, 0.48, 0.65, 0.9, 0)
    add_plant("Right broadleaf", 1.55, 0.62, 0.65, 0.92, 1)
    add_plant("Front left broadleaf", -1.52, -0.72, 0.65, 0.68, 2)
    add_plant("Front right broadleaf", 1.52, -0.76, 0.65, 0.72, 3)
    add_bench()
    add_stones()
    add_cube("VERDE plaque", (0, -2.28, 0.48), (1.45, 0.06, 0.42), sage, bevel_width=0.05)
    text_data = bpy.data.curves.new("VERDE plaque lettering", "FONT")
    text_data.body = "VERDE"
    text_data.align_x = "CENTER"
    text_data.size = 0.27
    text_data.extrude = 0.008
    text = bpy.data.objects.new("VERDE plaque lettering", text_data)
    bpy.context.collection.objects.link(text)
    text.location = (0, -2.32, 0.38)
    text.rotation_euler = (math.radians(90), 0, 0)
    text.data.materials.append(stone_light)


def add_camera():
    camera_data = bpy.data.cameras.new("Orthographic conservatory camera")
    camera = bpy.data.objects.new("Orthographic conservatory camera", camera_data)
    bpy.context.collection.objects.link(camera)
    camera.location = (7.2, -9.8, 7.4)
    camera_data.type = "ORTHO"
    camera_data.ortho_scale = 9.2
    camera_data.lens = 50
    camera_data.clip_end = 100
    aim_at(camera, (0, 0.05, 1.65))
    scene.camera = camera
    return camera


def add_compositor_glow():
    try:
        scene.use_nodes = True
        tree = scene.node_tree
        tree.nodes.clear()
        render_layers = tree.nodes.new("CompositorNodeRLayers")
        glare = tree.nodes.new("CompositorNodeGlare")
        composite = tree.nodes.new("CompositorNodeComposite")
        for setting, value in (("glare_type", "FOG_GLOW"), ("quality", "HIGH"), ("threshold", 1.15), ("size", 7), ("mix", -0.78)):
            if hasattr(glare, setting):
                try:
                    setattr(glare, setting, value)
                except (TypeError, ValueError):
                    pass
        render_layers.location = (-320, 0)
        glare.location = (-60, 0)
        composite.location = (200, 0)
        tree.links.new(render_layers.outputs["Image"], glare.inputs["Image"])
        tree.links.new(glare.outputs["Image"], composite.inputs["Image"])
    except (RuntimeError, TypeError, KeyError):
        scene.use_nodes = False


add_backdrop()
add_base_and_plants()
add_greenhouse()
add_lighting()
add_camera()
add_compositor_glow()

for obj in bpy.context.selected_objects:
    obj.select_set(False)
bpy.context.view_layer.objects.active = scene.camera
scene.camera.select_set(True)
bpy.ops.wm.save_as_mainfile(filepath=str(BLEND_PATH), check_existing=False)
bpy.ops.render.render(write_still=True)
print("BLENDER_VERSION=" + bpy.app.version_string)
print("BLENDER_ENGINE=" + scene.render.engine)
print("BLEND_FILE=" + str(BLEND_PATH))
print("RENDER_FILE=" + str(RENDER_PATH))
print("RENDER_SIZE=" + str(scene.render.resolution_x) + "x" + str(scene.render.resolution_y))
