Blender Addon Development
Build Blender C/C++ addons and Python extensions using msvc-kit.
Requirements
| Blender Version | MSVC Version | Python |
|---|---|---|
| Blender 4.2+ | 14.38 | 3.11 |
| Blender 4.0-4.1 | 14.36 | 3.10 |
| Blender 3.6 LTS | 14.34 | 3.10 |
| Blender 3.3 LTS | 14.32 | 3.10 |
Setup
1. Download MSVC
bash
# For Blender 4.2+
msvc-kit download --msvc-version 14.38 --sdk-version 10.0.22621.02. Setup Environment
powershell
msvc-kit setup --script --shell powershell | Invoke-ExpressionPython C Extension
Most Blender addons are pure Python, but you can write C extensions for performance.
Extension Source (fast_mesh.c)
c
#define PY_SSIZE_T_CLEAN
#include <Python.h>
#include <numpy/arrayobject.h>
static PyObject* calculate_normals(PyObject* self, PyObject* args) {
PyArrayObject* vertices;
PyArrayObject* faces;
if (!PyArg_ParseTuple(args, "O!O!",
&PyArray_Type, &vertices,
&PyArray_Type, &faces)) {
return NULL;
}
// Fast normal calculation here...
Py_RETURN_NONE;
}
static PyMethodDef FastMeshMethods[] = {
{"calculate_normals", calculate_normals, METH_VARARGS, "Calculate vertex normals"},
{NULL, NULL, 0, NULL}
};
static struct PyModuleDef fastmeshmodule = {
PyModuleDef_HEAD_INIT,
"fast_mesh",
NULL,
-1,
FastMeshMethods
};
PyMODINIT_FUNC PyInit_fast_mesh(void) {
import_array();
return PyModule_Create(&fastmeshmodule);
}Build
powershell
msvc-kit setup --script --shell powershell | Invoke-Expression
$BLENDER = "C:\Program Files\Blender Foundation\Blender 4.2"
$PYTHON = "$BLENDER\4.2\python"
cl /c /O2 /MD /EHsc `
/I"$PYTHON\include" `
/I"$PYTHON\include\numpy" `
fast_mesh.c
link /DLL /OUT:fast_mesh.pyd `
fast_mesh.obj `
/LIBPATH:"$PYTHON\libs" `
python311.libBlender as a Module
Build scripts that use Blender as a Python module:
bpy Extension
cpp
#include <pybind11/pybind11.h>
#include <pybind11/numpy.h>
namespace py = pybind11;
py::array_t<float> process_mesh_data(py::array_t<float> vertices) {
auto buf = vertices.request();
float* ptr = static_cast<float*>(buf.ptr);
// Process vertices...
return vertices;
}
PYBIND11_MODULE(mesh_processor, m) {
m.def("process_mesh_data", &process_mesh_data, "Process mesh vertex data");
}Build with pybind11
powershell
msvc-kit setup --script --shell powershell | Invoke-Expression
$BLENDER = "C:\Program Files\Blender Foundation\Blender 4.2"
$PYTHON = "$BLENDER\4.2\python"
cl /c /O2 /MD /EHsc `
/I"$PYTHON\include" `
/I"path\to\pybind11\include" `
mesh_processor.cpp
link /DLL /OUT:mesh_processor.pyd `
mesh_processor.obj `
/LIBPATH:"$PYTHON\libs" `
python311.libCMake Build
CMakeLists.txt
cmake
cmake_minimum_required(VERSION 3.20)
project(BlenderAddon)
set(CMAKE_CXX_STANDARD 17)
# Blender Python
set(BLENDER_ROOT "C:/Program Files/Blender Foundation/Blender 4.2"
CACHE PATH "Blender installation")
set(BLENDER_PYTHON "${BLENDER_ROOT}/4.2/python")
find_package(pybind11 REQUIRED)
# Extension module
pybind11_add_module(mesh_processor
src/mesh_processor.cpp
)
target_include_directories(mesh_processor PRIVATE
${BLENDER_PYTHON}/include
)
target_link_directories(mesh_processor PRIVATE
${BLENDER_PYTHON}/libs
)Build
powershell
msvc-kit setup --script --shell powershell | Invoke-Expression
cmake -B build -G "NMake Makefiles" -DCMAKE_BUILD_TYPE=Release
cmake --build buildAddon Structure
my_addon/
├── __init__.py
├── operators.py
├── ui.py
└── native/
├── fast_mesh.pyd
└── __init__.pyinit.py
python
bl_info = {
"name": "My Addon",
"blender": (4, 2, 0),
"category": "Mesh",
}
from . import operators, ui
from .native import fast_mesh
def register():
operators.register()
ui.register()
def unregister():
operators.unregister()
ui.unregister()Library API Usage
rust
use msvc_kit::{download_msvc, download_sdk, setup_environment, DownloadOptions};
use std::process::Command;
async fn build_blender_extension() -> msvc_kit::Result<()> {
let options = DownloadOptions {
msvc_version: Some("14.38".to_string()),
..Default::default()
};
let msvc = download_msvc(&options).await?;
let sdk = download_sdk(&options).await?;
let env = setup_environment(&msvc, Some(&sdk))?;
std::env::set_var("INCLUDE", env.include_path_string());
std::env::set_var("LIB", env.lib_path_string());
let blender_python = "C:\\Program Files\\Blender Foundation\\Blender 4.2\\4.2\\python";
let cl = env.cl_exe_path().expect("cl.exe not found");
Command::new(&cl)
.args([
"/c", "/O2", "/MD", "/EHsc",
&format!("/I{}\\include", blender_python),
"fast_mesh.c"
])
.status()?;
let link = env.link_exe_path().expect("link.exe not found");
Command::new(&link)
.args([
"/DLL", "/OUT:fast_mesh.pyd",
"fast_mesh.obj",
&format!("/LIBPATH:{}\\libs", blender_python),
"python311.lib"
])
.status()?;
Ok(())
}Installation
Copy the addon to Blender's addon directory:
powershell
$ADDON_DIR = "$env:APPDATA\Blender Foundation\Blender\4.2\scripts\addons"
Copy-Item -Recurse my_addon "$ADDON_DIR\"Troubleshooting
Import Error
Ensure the .pyd file matches Blender's Python version:
python
import sys
print(sys.version) # Should match your buildNumPy Not Found
Install NumPy in Blender's Python:
powershell
& "C:\Program Files\Blender Foundation\Blender 4.2\4.2\python\bin\python.exe" -m pip install numpy