Skip to main content

Scripting & Batch Processing

Automate the full resin-to-FDM conversion workflow from Python scripts, including headless batch processing via blender --background.

Where to get the scripting files

The scripting files (batch_cli.py, wizard.bat, wizard.sh, etc.) are included in the Google Drive folder shared with Patreon subscribers, and in the free Gumroad package.

Addon must be enabled

The scripting API requires the Resin2FDM addon to be enabled in Blender's preferences. The --background flag skips the UI but still loads enabled addons.


Quick Start

Process a single model from Blender's Script Editor

from Resin2FDM.scripting import process_model

result = process_model(
    filepath="C:/models/my_mini.stl",
    output_folder="C:/output",
    support_thickness=1.0,
)

print("Success!" if result.success else f"Failed: {result.error}")

Batch process a folder (headless)

blender --background --python scripts/batch_cli.py -- --input C:/models --output C:/output

Interactive Wizard

The easiest way to get started. The wizard walks you through every setting with sensible defaults and saves your config for re-use.

Windows — double-click scripts/wizard.bat, or run from a terminal:

scripts\wizard.bat

macOS / Linux:

./scripts/wizard.sh

Manual launch:

blender --background --python scripts/batch_cli.py -- --interactive

The wizard will ask for:

  1. Input / output folders
  2. Export mode (STL both, combined, separate, miniature-only, supports-only, or 3MF)
  3. Support thickness (mm of wall added to supports)
  4. Auto-select sensitivity (defaults to 50 — required for headless mode)
  5. Tip detection — if enabled, also asks for tip thickness and separate-tips option
  6. Mesh repair toggle
  7. 3MF options (if export mode is 3MF) — enhanced vs basic, slicer profile selection

After confirming, it runs in quiet mode by default (only progress lines and a summary are printed). Use --verbose to see full per-model output.

The wizard offers to save your settings to a JSON config file so you can re-run with --config next time.


Batch Processing with Config Files

Instead of passing a dozen flags on the command line, save your settings in a JSON config file.

Generate a starter config

blender --background --python scripts/batch_cli.py -- --generate-config my_preset.json

This creates a my_preset.json you can edit:

{
  "input": "C:/models/to_process",
  "output": "C:/models/output",
  "pattern": "*",
  "export_mode": "both",
  "support_thickness": 1.0,
  "tips_thickness": 0.5,
  "run_tip_detection": true,
  "run_mesh_repair": false,
  "auto_select_sensitivity": 50,
  "separate_tips": false,
  "tip_type": "CONICAL",
  "tip_sensitivity": 50,
  "skip_support_repair": false,
  "slicer_profile": "DEFAULT",
  "support_preset": "DEFAULT",
  "use_enhanced_3mf": true,
  "quiet": false
}

Run with the config

blender --background --python scripts/batch_cli.py -- --config my_preset.json

Override individual settings per-run

CLI flags take priority over the config file, so you can have a base preset and tweak values:

blender --background --python scripts/batch_cli.py -- --config my_preset.json --thickness 1.5

Create a .bat shortcut (Windows)

Save as run_batch.bat next to your config:

@echo off
blender --background --python scripts/batch_cli.py -- --config my_preset.json
pause

Config File Reference

KeyTypeDefaultDescription
inputstring""Input folder containing STL/OBJ/3MF files
outputstring""Output folder for exports (defaults to input folder)
patternstring"*"Glob pattern to filter filenames (e.g. "dragon*")
export_modestring"both""both", "combined", "separate", "miniature", "supports", or "3mf"
support_thicknessfloat | nullnullmm of wall thickness added to supports (null = addon default)
tips_thicknessfloat | nullnullmm of wall thickness added to tips (null = addon default)
run_tip_detectionbooltrueRun tip detection & assignment (Advanced edition only)
run_mesh_repairboolfalseRun manifold mesh repair
auto_select_sensitivityfloat | nullnull0–100 miniature auto-select sensitivity (null = skip auto-select)
separate_tipsboolfalseExport support tips as a separate file (STL or 3MF object)
tip_typestring | nullnull"CONICAL" or "SPHERICAL" tip shape (null = addon default)
tip_sensitivityfloat | nullnull0–100 tip detection sensitivity (null = addon default)
skip_support_repairboolfalseOnly repair miniature, skip supports during mesh repair
slicer_profilestring | nullnullPrinter profile name for 3MF (e.g. "DEFAULT")
support_presetstring | nullnullSupport print settings preset for 3MF (e.g. "DEFAULT")
use_enhanced_3mfbooltrueUse ThreeMF-io enhanced 3MF with Orca slicer settings. false = basic 3MF
quietboolfalseSuppress per-model output, show only progress lines and summary

CLI Flag Reference

blender --background --python scripts/batch_cli.py -- [FLAGS]
FlagDescription
--interactiveLaunch the step-by-step setup wizard
--config PATHLoad settings from a JSON config file
--generate-config PATHGenerate a starter config file and exit
--input PATHInput folder with model files
--output PATHOutput folder (default: same as input)
--thickness NSupport thickness in mm
--tips-thickness NTip thickness in mm
--export-mode MODEboth, combined, separate, miniature, supports, or 3mf
--no-tipsSkip tip detection
--repairRun manifold mesh repair
--auto-select NMiniature auto-select sensitivity (0–100). Omit to skip
--separate-tipsExport support tips as a separate file
--tip-type TYPETip shape: CONICAL or SPHERICAL
--tip-sensitivity NTip detection sensitivity (0=strict, 100=loose)
--skip-support-repairOnly repair miniature mesh, skip supports
--slicer-profile NAMEPrinter profile name for 3MF export
--support-preset NAMESupport print settings preset for 3MF export
--basic-3mfUse basic 3MF export without Orca slicer metadata
--quiet, -qSuppress per-model output, show only progress and summary
--verbose, -vShow full per-model output (overrides --quiet)
--pattern PATGlob filter for filenames (default: *)

Python API Reference

All functions are importable from Resin2FDM.scripting.

process_model()

process_model(filepath, ...) → ProcessResult

Runs the entire workflow on one file: prepare scene → import → split → thicken → export.

from Resin2FDM.scripting import process_model

result = process_model(
    filepath="C:/models/mini.stl",
    output_folder="C:/output",       # default: same folder as input
    support_thickness=1.0,            # default: addon preference
    tips_thickness=0.5,               # default: addon preference
    export_mode="both",               # "both", "combined", "separate", "miniature", "supports", "3mf"
    run_tip_detection=True,           # skip with False
    run_mesh_repair=False,            # enable with True
    auto_select_sensitivity=50,       # 0-100, or None to skip auto-select
    separate_tips=False,              # export tips as separate file
    tip_type="CONICAL",               # "CONICAL" or "SPHERICAL"
    tip_sensitivity=50,               # 0-100, or None for addon default
    skip_support_repair=False,        # True to skip support repair
    slicer_profile="DEFAULT",         # printer profile for 3MF
    support_preset="DEFAULT",         # support settings preset for 3MF
    use_enhanced_3mf=True,            # False for basic 3MF without Orca settings
)

print(result.success)          # bool
print(result.exported_files)   # list of output file paths
print(result.elapsed)          # seconds
print(result.error)            # error message if failed

batch_process()

batch_process(input_folder, ...) → BatchResult

Processes every supported file in a folder.

from Resin2FDM.scripting import batch_process

result = batch_process(
    input_folder="C:/models",
    output_folder="C:/output",
    file_pattern="*",                 # glob filter, e.g. "dragon*"
    support_thickness=1.0,
    tips_thickness=0.5,
    export_mode="both",
    run_tip_detection=True,
    run_mesh_repair=False,
    auto_select_sensitivity=50,       # 0-100, or None to skip auto-select
    separate_tips=False,
    tip_type="CONICAL",
    tip_sensitivity=50,
    skip_support_repair=False,
    slicer_profile="DEFAULT",
    support_preset="DEFAULT",
    use_enhanced_3mf=True,
    quiet=True,                       # suppress per-model output
)

print(f"{result.succeeded}/{len(result.results)} succeeded")
print(f"Total time: {result.total_elapsed:.1f}s")

Individual Step Functions

For custom pipelines where you need control over each step:

from Resin2FDM.scripting import (
    prepare_scene,
    import_model,
    split_model,
    select_miniature_parts,
    assign_miniature,
    detect_and_assign_tips,
    make_manifold,
    thicken_supports,
    thicken_tips,
    apply_thickness,
    apply_tips_thickness,
    generate_level,
    set_output_folder,
    export_miniature,
    export_supports,
    export_both,
    export_combined,
    export_3mf,
)

# Run your own custom pipeline
prepare_scene()
import_model("C:/models/mini.stl")
split_model()
select_miniature_parts(sensitivity=50)  # auto-detect miniature vs supports
assign_miniature()                       # commit the selection
thicken_supports(thickness=1.2)
apply_thickness()
generate_level()
set_output_folder("C:/output")
export_both()

Each function returns True on success, False on failure/skip. Optional feature functions (tips, mesh repair) return False gracefully if the feature isn't available in your edition.


Export Modes Explained

ModeFiles CreatedContents
"both"{name}-miniature.stl, {name}-supports.stlMiniature and supports as separate STL files
"combined"{name}-combined.stlEverything in a single STL
"separate"{name}-miniature.stl, {name}-supports.stlSame as "both"
"miniature"{name}-miniature.stlOnly the miniature + level cube
"supports"{name}-supports.stlOnly the supports + level cube
"3mf"{name}.3mf3MF archive — enhanced mode embeds Orca slicer settings; basic mode skips slicer metadata

All STL modes respect separate_tips: when True, SUPPORT_TIPS gets its own {name}-SUPPORT_TIPS.stl instead of being merged with supports. For 3MF, tips become a distinct object inside the archive.


How It Works

Resin2FDM's operators are designed for Blender's interactive UI with modal progress dialogs. The scripting system makes them work headlessly by:

  1. Detecting background mode — When bpy.app.background is True (i.e. blender --background), modal operators run all steps synchronously in a loop instead of using timers and the event loop.
  2. Wrapping operators as functions — Each bpy.ops.resin2fdm.* call is wrapped in a Python function with proper arguments and return values.
  3. Scene reset between modelsprocess_model() calls prepare_scene() at the start, which resets all state so each file in a batch gets a clean workspace.

Tips & Notes

Supported file formats

The scripting API accepts .stl, .obj, and .3mf files. 3MF input requires the ThreeMF-io addon to be installed.

  • Run from the addon directory or make sure Blender can find the Resin2FDM package. It is automatically available when the addon is enabled in preferences.
  • Feature availability: Tip detection and support reinforcement are Advanced edition features. The scripting API skips them gracefully if unavailable. Mesh repair is available in both Lite and Advanced.
  • Custom filenames: Set bpy.context.scene.resin2fdm_custom_filename before exporting to override the output filename.
  • Orca slicer settings: For 3MF export, configure bpy.context.scene.resin2fdm_orca_* properties before calling export_3mf().