Skip to main content Inicio Creadores johnnuwan eva_core blender-scripting-python
blender-scripting-python Scripting Python dans Blender — API bpy, add-ons, automation, batch processing, création d'outils personnalisés, panels, operators, UI, pipeline et intégration.
Ir a la instalación Skills Marketplace Descubre y explora habilidades de IA creadas por la comunidad.
Ocupaciones relacionadas SOC
Basado en la clasificación ocupacional SOC
Instalar con Codex o Claude Copia este prompt, pégalo en Codex, Claude u otro asistente, y deja que revise la página de la skill y la instale por ti.
Copiar promptMostrar detalles del prompt Un comando directo omite el prompt de revisión. Revisa el origen antes de ejecutarlo.
npx skills add https://github.com/JohnNuwan/EVA_CORE --skill blender-scripting-pythonEl comando permanece en una sola línea. Desplázate horizontalmente para revisarlo antes de copiarlo.
¿Prefieres una copia local? Descarga los archivos que SkillsMP tiene disponibles ahora.
Descargar Zip Descargando... name blender-scripting-python description Scripting Python dans Blender — API bpy, add-ons, automation, batch processing, création d'outils personnalisés, panels, operators, UI, pipeline et intégration. version 1.0.0 category creative tags ["blender","python","scripting","bpy","addon","automation","api","pipeline","3d"] prerequisites {"commands":["blender"]} setup {"help":"Blender installé. Python est intégré à Blender (bpy, bmesh, bpy_extras). Utiliser l'interpréteur Python de Blender ('blender --python script.py')."} metadata {"hermes":{"tags":["blender","python","scripting","bpy","addon","automation","api","pipeline"],"related_skills":["blender-modeling","blender-animation","blender-geometry-nodes"],"category":"creative"}}
Blender — Scripting Python
Guide complet du scripting Python dans Blender : API bpy, bmesh,
création d'add-ons, automation, batch processing, panels, operators,
et pipeline d'intégration.
Architecture Blender Python
┌─────────────────────────────────────────┐
│ bpy (module principal) │
│ ┌──────────────┐ ┌────────────────┐ │
│ │ bpy.data │ │ bpy.context │ │
│ │ (BDNA data) │ │ (contexte) │ │
│ └──────┬───────┘ └───────┬────────┘ │
│ │ │ │
│ ┌──────▼──────────────────▼────────┐ │
│ │ bpy.ops (operators) │ │
│ └──────────────────────────────────┘ │
│ ┌──────────────────────────────────┐ │
│ │ bpy.types (classes) │ │
│ └──────────────────────────────────┘ │
│ ┌──────────────────────────────────┐ │
│ │ bmesh (mesh editing) │ │
│ └──────────────────────────────────┘ │
│ ┌──────────────────────────────────┐ │
│ │ bpy.app (timers, handlers) │ │
│ └──────────────────────────────────┘ │
│ ┌──────────────────────────────────┐ │
│ │ mathutils (vectors, mats) │ │
│ └──────────────────────────────────┘ │
└─────────────────────────────────────────┘
bpy — Accès aux Données
bpy.data (Data Blocks)
bpy.data.objects["Cube" ]
bpy.data.objects["Camera" ]
bpy.data.objects["Light" ]
bpy.data.meshes["Cube.001" ]
bpy.data.meshes.new("MonMeshe" )
bpy.data.materials["Material" ]
bpy.data.materials.new("MonMat" )
bpy.data.images["render_output.png" ]
bpy.data.collections["Collection" ]
bpy.context (Contexte)
bpy.context.scene
bpy.context.view_layer
bpy.context.object
bpy.context.selected_objects
bpy.context.visible_objects
bpy.context.active_object
bpy.context.mode
bpy.context.area
bpy.context.space_data
bpy.ops (Operators) Appel des opérateurs Blender :
bpy.ops.mesh.primitive_cube_add(size=2 , location=(0 , 0 , 0 ))
bpy.ops.object .light_add(type ='POINT' , location=(1 , 1 , 5 ))
bpy.ops.object .select_all(action='DESELECT' )
bpy.data.objects["Cube" ].select_set(True )
bpy.ops.object .mode_set(mode='EDIT' )
bpy.ops.object .mode_set(mode='OBJECT' )
bpy.ops.object .mode_set(mode='SCULPT' )
bpy.ops.object .modifier_add(type ='SUBSURF' )
bpy.ops.object .modifier_apply(modifier="Subdivision" )
bpy.ops.wm.open_mainfile(filepath="scene.blend" )
bpy.ops.wm.save_mainfile()
bpy.ops.export_scene.fbx(filepath="output.fbx" )
bpy.app (Application) bpy.app.version
bpy.app.background
bpy.app.debug_value
bpy.app.handlers
bpy.app.timers.register()
bmesh — Edition de Maillage import bmesh
bm = bmesh.new()
v1 = bm.verts.new((0 , 0 , 0 ))
v2 = bm.verts.new((1 , 0 , 0 ))
v3 = bm.verts.new((1 , 1 , 0 ))
v4 = bm.verts.new((0 , 1 , 0 ))
face = bm.faces.new((v1, v2, v3, v4))
ret = bmesh.ops.extrude_face_region(bm, geom=[face])
extruded_verts = [v for v in ret['geom' ] if isinstance (v, bmesh.types.BMVert)]
for v in extruded_verts:
v.co.z += 1.0
mesh = bpy.data.meshes.new("Quad" )
bm.to_mesh(mesh)
bm.free()
Opérations bmesh bmesh.ops.subdivide_edges(bm, edges=bm.edges, cuts=2 )
bmesh.ops.bevel(bm, geom=bm.edges, offset=0.1 )
bmesh.ops.bridge_loops(bm, edges=[edge_list_a, edge_list_b])
bmesh.ops.remove_doubles(bm, dist=0.001 )
bmesh.ops.triangulate(bm, faces=bm.faces)
bmesh.ops.dissolve_limit(bm, angle_limit=5 , verts=bm.verts)
bmesh.ops.transform(bm, matrix=mat, verts=bm.verts)
mathutils — Vecteurs et Matrices import mathutils
from mathutils import Vector, Matrix, Euler, Quaternion
v = Vector((1 , 2 , 3 ))
v2 = Vector((4 , 5 , 6 ))
v.dot(v2)
v.cross(v2)
v.length
v.normalized()
mat = Matrix.Translation(Vector((0 , 0 , 1 )))
rot = Euler((0 , 0 , 1.57 ), 'XYZ' ).to_matrix().to_4x4()
scale = Matrix.Scale(2 , 4 )
transform = mat @ rot @ scale
q = Quaternion((1 , 0 , 0 , 0 ))
q2 = Quaternion((0.707 , 0.707 , 0 , 0 ))
Automatisation et Batch
Script Headless (mode --background) blender scene.blend --background --python mon_script.py
blender --background --python create_scene.py
blender --background --python batch_export.py
Exemple Batch Export FBX
import bpy
import os
import sys
input_dir = sys.argv[-2 ] if len (sys.argv) > 1 else "."
output_dir = sys.argv[-1 ] if len (sys.argv) > 2 else "exports"
os.makedirs(output_dir, exist_ok=True )
for filename in os.listdir(input_dir):
if filename.endswith(".blend" ):
path = os.path.join(input_dir, filename)
bpy.ops.wm.open_mainfile(filepath=path)
basename = os.path.splitext(filename)[0 ]
out_path = os.path.join(output_dir, f"{basename} .fbx" )
bpy.ops.export_scene.fbx(filepath=out_path)
print (f"Exported: {path} -> {out_path} " )
blender --background --python batch_export.py -- ./scenes ./exports
Add-ons (Modules)
Structure d'un Add-on mon_addon/
├── __init__.py # Metadata + register/unregister
├── operators.py # Classes d'opérateurs
├── ui.py # Panels et menus
├── properties.py # PropertyGroups
└── utils.py # Fonctions utilitaires
init .pybl_info = {
"name" : "Mon Addon" ,
"author" : "Moi" ,
"version" : (1 , 0 , 0 ),
"blender" : (4 , 0 , 0 ),
"location" : "View3D > Sidebar > Mon Tab" ,
"description" : "Description de l'addon" ,
"category" : "Object" ,
}
modules = ["operators" , "ui" , "properties" ]
def register ():
for m in modules:
exec (f"import {m} " )
exec (f"{m} .register()" )
def unregister ():
for m in reversed (modules):
exec (f"{m} .unregister()" )
Créer un Operator import bpy
class MES_OT_mon_operateur (bpy.types.Operator):
"""Description de l'opérateur"""
bl_idname = "mesh.mon_operateur"
bl_label = "Mon Opérateur"
bl_options = {'REGISTER' , 'UNDO' }
scale: bpy.props.FloatProperty(
name="Scale" ,
default=1.0 ,
min =0.1 ,
max =10.0 ,
)
@classmethod
def poll (cls, context ):
return context.active_object is not None
def execute (self, context ):
obj = context.active_object
obj.scale = (self .scale, self .scale, self .scale)
return {'FINISHED' }
Créer un Panel class MES_PT_mon_panel (bpy.types.Panel):
bl_label = "Mon Panel"
bl_idname = "MES_PT_mon_panel"
bl_space_type = 'VIEW_3D'
bl_region_type = 'UI'
bl_category = "Mon Outil"
def draw (self, context ):
layout = self .layout
layout.label(text="Paramètres" )
layout.prop(context.active_object, "scale" )
layout.operator("mesh.mon_operateur" )
Properties (PropertyGroup) class MonGroupeProprietes (bpy.types.PropertyGroup):
ma_prop: bpy.props.FloatProperty(
name="Ma Propriété" ,
default=1.0 ,
min =0.0 ,
max =100.0 ,
)
bpy.utils.register_class(MonGroupeProprietes)
bpy.types.Scene.mon_groupe = bpy.props.PointerProperty(
type =MonGroupeProprietes
)
bpy.context.scene.mon_groupe.ma_prop
Handlers et Timers
Handlers (Events) def mon_handler (scene ):
print (f"Frame changed: {scene.frame_current} " )
bpy.app.handlers.frame_change_pre.append(mon_handler)
bpy.app.handlers.render_post.append(mon_handler)
bpy.app.handlers.depsgraph_update_post.append(mon_handler)
Timers import bpy
def mon_timer ():
print ("Timer tick..." )
return 0.5
bpy.app.timers.register(mon_timer)
Types de Handlers Handler Quand frame_change_pre/postAvant/après changement de frame render_init/complete/cancelRendu load_pre/postChargement fichier .blend save_pre/postSauvegarde .blend depsgraph_update_pre/postMise à jour du graphe object_updatedObjet modifié version_updatedMise à jour de version
Exemples de Scripts Utiles
import bpy
for obj in bpy.context.scene.objects:
obj.select_set(True )
bpy.ops.object .transform_apply(location=False , rotation=True , scale=True )
import bpy, os
out = "exports/"
os.makedirs(out, exist_ok=True )
for obj in bpy.data.objects:
bpy.context.view_layer.objects.active = obj
bpy.ops.object .select_all(action='DESELECT' )
obj.select_set(True )
bpy.ops.wm.obj_export(filepath=f"{out} /{obj.name} .obj" )
import bpy, math
obj = bpy.context.active_object
for frame in range (0 , 100 ):
bpy.context.scene.frame_set(frame)
obj.rotation_euler.z = frame * math.radians(3.6 )
obj.keyframe_insert(data_path="rotation_euler" , index=2 )
Débogage
for prop in dir (bpy.context.object ):
if not prop.startswith('_' ):
print (f"{prop} : {getattr (bpy.context.object , prop)} " )
for collection in bpy.data.collections:
print (f"Collection: {collection.name} " )
for obj in collection.objects:
print (f" {obj.name} ({obj.type } )" )
print ([op for op in dir (bpy.ops) if not op.startswith('_' )])
print (bpy.ops.mesh.primitive_cube_add.get_rna().properties)
Pitfalls
bpy n'existe pas en dehors de Blender — tester avec blender --python
bpy.ops échoue en background — certains ops nécessitent un contexte (area)
Scale non uniforme + Modifier — object.scale = (1, 1, 1) avant modificateurs
BMesh non libéré — bm.free() ou fuite mémoire
Context incorrect — passer {'area': ...} ou utiliser override
Blender API changes — Python API change entre versions majeures
Redraw manuel — bpy.context.area.tag_redraw() après changement UI
Add-on non enregistré — bpy.utils.register_class() oublié
Voir Aussi
blender-modeling — Automatisation de modélisation
blender-animation — Scripts d'animation
blender-geometry-nodes — Scripts pour créer/modifier des GN