Render a folder full of STL files to PNG images

I wanted to create images out of all the STL-files I had 3D-printed so far. Here is a script that automates the process using Blender.

import bpy
import os
import math
from bpy_extras.object_utils import world_to_camera_view

def clear_scene():
    bpy.ops.object.select_all(action='SELECT')
    bpy.ops.object.delete()

def setup_camera_light():
    bpy.ops.object.camera_add(location=(0, -10, 5))
    camera = bpy.context.active_object
    camera.rotation_euler = (1.0, 0, 0)
    bpy.context.scene.camera = camera

    bpy.ops.object.light_add(type='SUN', align='WORLD', location=(0, 0, 10))
    light = bpy.context.active_object
    light.rotation_euler = (1.0, 0, 0)

def create_red_material():
    red_material = bpy.data.materials.new(name="RedMaterial")
    red_material.use_nodes = True
    red_material.node_tree.nodes["Principled BSDF"].inputs["Base Color"].default_value = (1, 0, 0, 1)
    return red_material



from mathutils import Vector

def set_camera_position(camera, obj):
    bound_box = obj.bound_box
    min_x, max_x = min(v[0] for v in bound_box), max(v[0] for v in bound_box)
    min_y, max_y = min(v[1] for v in bound_box), max(v[1] for v in bound_box)
    min_z, max_z = min(v[2] for v in bound_box), max(v[2] for v in bound_box)
    
    # Calculate object dimensions
    width = max_x - min_x
    height = max_y - min_y
    depth = max_z - min_z

    # Calculate object center
    center_x = min_x + (width / 2)
    center_y = min_y + (height / 2)
    center_z = min_z + (depth / 2)

    # Calculate distance from camera to object center
    distance = max(width, height, depth) * 2.5  # Increase the multiplier from 2 to 2.5

    # Set camera location and rotation
    camera.location = (center_x, center_y - distance, center_z + (distance / 2))
    camera.rotation_euler = (math.radians(60), 0, 0)




def import_stl_and_render(input_path, output_path):
    clear_scene()
    setup_camera_light()

    bpy.ops.import_mesh.stl(filepath=input_path)
    obj = bpy.context.selected_objects[0]

    # Set camera position based on object bounding box
    camera = bpy.context.scene.objects['Camera']
    set_camera_position(camera, obj)
    
    # Apply red material to the object
    red_material = create_red_material()
    if len(obj.data.materials) == 0:
        obj.data.materials.append(red_material)
    else:
        obj.data.materials[0] = red_material

    # Set render settings
    bpy.context.scene.render.image_settings.file_format = 'PNG'
    bpy.context.scene.render.filepath = output_path
    bpy.ops.render.render(write_still=True)
    
     # Set transparent background
    bpy.context.scene.render.film_transparent = True

    # Set render settings
    bpy.context.scene.render.image_settings.file_format = 'PNG'
    bpy.context.scene.render.filepath = output_path
    bpy.ops.render.render(write_still=True)

def render_stl_images(input_folder, output_folder):
    for root, _, files in os.walk(input_folder):
        for file in files:
            if file.lower().endswith(".stl"):
                input_path = os.path.join(root, file)
                output_file = os.path.splitext(file)[0] + ".png"
                output_path = os.path.join(output_folder, output_file)

                import_stl_and_render(input_path, output_path)

if __name__ == "__main__":

    if __name__ == "__main__":
        input_folder = "3D Prints"
        output_folder = "/outputSTL"

    if not os.path.exists(output_folder):
        os.makedirs(output_folder)

    try:
        render_stl_images(input_folder, output_folder)
    except Exception as e:
        print(f"Error: {e}")

How to use:

Save the script in a python file. You can call it for example renderSTL.py. Change the input and output folders in the script to fit your situation.

Make sure you have Blender in PATH so that you can run it by simply typing “Blender” in a command prompt. If you don’t have it in PATH, open “enviroments variables” and edit the “PATH” variable under “system”. Add the path to your Blender installation as a new path.

Open up a command line in the folder which has the proper path to your STL root folder and paste this command in:
blender –background –factory-startup –python renderSTL.py

Blender should now render images out of all your STL files in the background and save them into the output folder.

Leave a Reply

Your email address will not be published. Required fields are marked *