Comment script des Geometry Nodes dans Blender avec Python (2026)

Comment script des Geometry Nodes dans Blender avec Python (2026)
🐍
La modélisation procédurale devient bien plus puissante lorsque vous générez des nœuds avec du code, plutôt que de les câbler à la main.

Les Geometry Nodes sont une fonctionnalité incroyable de Blender, mais saviez-vous que l’API Python de Blender vous permet aussi de script des geometry nodes, comme n’importe quel autre bloc de données ?

Vous pouvez créer des nœuds, définir leurs paramètres et les connecter par programmation, ouvrant la porte à la génération automatisée de scènes, à des outils personnalisés et au prototypage rapide de modèles avec seulement quelques lignes de code—au lieu de câbler manuellement des dizaines de nœuds.

Dans ce tutoriel, vous allez apprendre comment créer des configurations de geometry nodes entièrement depuis un script Python. Nous couvrirons le processus complet, de la création d’un nouvel arbre de nœuds à son affectation à un objet, avec des exemples clairs que vous pouvez copier-coller directement dans l’éditeur de scripting de Blender.

Au cas où vous l’auriez manqué, jetez d’abord un œil à notre introduction au scripting Blender.


Pourquoi script des Geometry Nodes ?

L’éditeur Geometry Nodes de Blender est un excellent système visuel pour construire des outils procéduraux : il est intuitif, flexible et idéal pour l’expérimentation une fois que vous avez le coup de main. Mais lorsque les projets deviennent plus complexes, gérer manuellement de grands réseaux de nœuds peut devenir fastidieux et difficile à maintenir, surtout si vous devez les réutiliser dans de nombreux pipelines de modélisation 3D.

Une configuration de nœuds scriptée n’est pas liée à un seul fichier .blend : elle peut être stockée, versionnée et partagée comme n’importe quel autre morceau de code. Cela facilite la création d’une bibliothèque d’outils procéduraux réutilisables sur différents projets, ou à partager avec d’autres artistes et développeurs.

Voyons comment le scripting fonctionne dans la pratique avec quelques extraits de code.

💡
Vous cherchez des exemples qui fonctionnent ?

Vous pouvez trouver le code source complet de l’intégration d’exemple présentée dans ce guide sur notre GitHub :

🔗 https://github.com/cgwire/blender-scripting-geometry-nodes

1. Créer une nouvelle arborescence de nœuds

Toute configuration de Geometry Nodes commence comme une arborescence de nœuds, qui stocke les nœuds et leurs connexions. Vous pouvez en créer une depuis Python grâce à l’API de données de Blender :

import bpy

node_tree = bpy.data.node_groups.new("MyGeoNodesTree", 'GeometryNodeTree')

Vous pouvez considérer ce node_tree comme la toile numérique qui contiendra toute la logique procédurale. Une fois créé, vous pouvez ajouter des nœuds, les connecter et définir leurs propriétés comme dans l’interface utilisateur graphique de Blender.


2. Ajouter des nœuds et les connecter

Ensuite, ajoutons quelques nœuds de base. Nous allons créer un nœud Input Geometry, un nœud Subdivision Surface et un nœud Group Output, puis les connecter et appliquer le résultat à notre cube.

# ADD NODES
geo_input = node_tree.interface.new_socket(
    name="Geometry",
    in_out='INPUT',
    socket_type='NodeSocketGeometry'
)
geo_output = node_tree.interface.new_socket(
    name="Geometry",
    in_out='OUTPUT',
    socket_type='NodeSocketGeometry'
)

input_node = node_tree.nodes.new("NodeGroupInput") subdivide_node = node_tree.nodes.new("GeometryNodeSubdivideMesh") output_node = node_tree.nodes.new("NodeGroupOutput")

input_node.location = (-300, 0) subdivide_node.location = (0, 0) output_node.location = (300, 0)

LINK NODES

node_tree.links.new(input_node.outputs'Geometry', subdivide_node.inputs'Mesh') node_tree.links.new(subdivide_node.outputs'Mesh', output_node.inputs'Geometry')

APPLY TO CURRENT OBJECT

obj = bpy.context.object mod = obj.modifiers.new("MyGeoNodesModifier", "NODES") mod.node_group = node_tree


Lorsque vous exécutez ce script, vous obtenez une configuration de geometry nodes fonctionnelle (bien que simple) qui subdivise toute géométrie à laquelle elle est appliquée :


Vous pouvez modifier les paramètres directement via les propriétés du nœud. Par exemple, augmentons le niveau de subdivision et appliquons ce groupe de nœuds à un objet :

subdivide_node.inputs'Level'.default_value = 3

Ajuster default_value pour les entrées est une façon simple de paramétrer votre configuration.

Pour un aperçu complet des paramètres disponibles et de leurs types, reportez-vous à la documentation officielle de l’API Python de Blender.


4. Créer un groupe de nœuds personnalisé « Cube Crowd Generator » par programmation

Nous savons maintenant comment définir des geometry nodes par programmation, mais qu’en est-il de la création de nœuds personnalisés réutilisables ?

Travaillons sur un nouvel exemple qui construit un mini-système procédural qui disperse beaucoup de cubes sur une surface. Le script crée un groupe Geometry Nodes qui prend une surface, disperse des points dessus, décale aléatoirement ces points, place un cube sur chaque point (instances), convertit les instances en géométrie réelle, puis affiche le maillage final comme « Cubes ».

1) Créer un nouveau groupe de nœuds

Tout d’abord, créons un nouveau groupe Geometry Node dans Blender nommé "CubeCrowdGenerator".

crowd_group = bpy.data.node_groups.new("CubeCrowdGenerator", "GeometryNodeTree")

Comme une fonction, nous voulons pouvoir attacher ce nœud à n’importe quel objet avec un modificateur Geometry Nodes plus tard.

2) Ajouter des nœuds d’entrée et de sortie de groupe (points UI/entrée)

Nous plaçons les groupes d’entrée et de sortie standard sur la toile, comme d’habitude :

group_in = crowd_group.nodes.new("NodeGroupInput")
group_out = crowd_group.nodes.new("NodeGroupOutput")

group_in.location = (-600, 0) group_out.location = (600, 0)

  • group_in et group_out sont les prises visibles du groupe de nœuds dans l’éditeur Geometry Nodes.
  • Le script les positionne aussi pour que le graphe soit lisible.

3) Définir l’interface du groupe (ce que le groupe accepte/retourne)

Nous devons exposer une prise d’entrée nommée Surface dans laquelle nous brancherons le maillage que vous voulez remplir (par ex. un plan), et une prise de sortie nommée Cubes, la géométrie résultante.

interface = crowd_group.interface
interface.new_socket(name="Surface", in_out="INPUT", socket_type="NodeSocketGeometry")
interface.new_socket(name="Cubes", in_out="OUTPUT", socket_type="NodeSocketGeometry")

Dans la pratique, lorsque vous ajoutez ce groupe de nœuds à un objet, vous branchez sa surface (la géométrie originale de l’objet) dans Surface.

4) Créer les nœuds internes (les blocs de construction)

Nous pouvons ensuite travailler sur la logique interne réelle :

distribute = crowd_group.nodes.new("GeometryNodeDistributePointsOnFaces")
rand_vec = crowd_group.nodes.new("FunctionNodeRandomValue")
set_pos = crowd_group.nodes.new("GeometryNodeSetPosition")
cube = crowd_group.nodes.new("GeometryNodeMeshCube")
instance = crowd_group.nodes.new("GeometryNodeInstanceOnPoints")
realize = crowd_group.nodes.new("GeometryNodeRealizeInstances")
  • GeometryNodeDistributePointsOnFaces : crée des points sur la surface d’entrée (contrôle le nombre de points, la distribution).
  • FunctionNodeRandomValue (Float Vector) : génère un vecteur 3D aléatoire par point, utilisé comme décalage.
  • GeometryNodeSetPosition : déplace chaque point par un vecteur (le décalage aléatoire).
  • GeometryNodeMeshCube : génère un maillage de cube qui sera utilisé comme objet d’instance.
  • GeometryNodeInstanceOnPoints : place le cube sur chaque point. Il ne crée pas de géométrie réelle, c’est juste une instance « légère » du cube d’origine.
  • GeometryNodeRealizeInstances : convertit les instances en géométrie de maillage réelle afin de pouvoir les afficher comme un maillage unique.

5) Configurer le nœud de vecteur aléatoire

Nous configurons le nœud Random Value pour qu’il renvoie un vecteur à 3 composantes que nous pouvons utiliser pour décaler les cubes générés dans l’espace 3D :

rand_vec.data_type = "FLOAT_VECTOR"
rand_vec.inputs"Min".default_value = (-0.5, -0.5, 0.0)
rand_vec.inputs"Max".default_value = (0.5, 0.5, 0.5)
  • Min et Max définissent la plage pour chaque composante. Par exemple, X est entre -0.5 et 0.5.
  • Résultat : chaque point reçoit un décalage légèrement différent, donc les cubes ne se superposent pas exactement.

6) Disposition des nœuds (UI uniquement)

Nous positionnons ensuite les nœuds internes pour qu’ils soient faciles à comprendre si nous voulons vérifier notre workflow dans Blender :

distribute.location = (-400, 0)
rand_vec.location = (-200, -200)
set_pos.location = (-100, 0)
instance.location = (100, 0)
cube.location = (-400, -200)
realize.location = (300, 0)

Ces affectations de location ne concernent que la manière dont les nœuds sont arrangés visuellement dans l’éditeur de nœuds. Elles n’affectent pas le fonctionnement du graphe.

7) Câbler les nœuds entre eux

Enfin, nous définissons le flux de données :

links.new(group_in.outputs"Surface", distribute.inputs"Mesh")
links.new(distribute.outputs"Points", set_pos.inputs"Geometry")
links.new(rand_vec.outputs"Value", set_pos.inputs"Offset")
links.new(set_pos.outputs"Geometry", instance.inputs"Points")
links.new(cube.outputs"Mesh", instance.inputs"Instance")
links.new(instance.outputs"Instances", realize.inputs"Geometry")
links.new(realize.outputs"Geometry", group_out.inputs"Cubes")
  1. Surface → DistributePointsOnFaces : la surface d’entrée (plan) est utilisée pour créer des points dispersés.
  2. Points → SetPosition (Geometry) : Set position reçoit les points sous forme de géométrie à déplacer.
  3. RandomValue → SetPosition (Offset) : chaque point reçoit un vecteur de décalage aléatoire.
  4. SetPosition → InstanceOnPoints (Points) : les points déplacés deviennent les positions d’ancrage pour les instances.
  5. Cube Mesh → InstanceOnPoints (Instance) : chaque point reçoit une instance de cube.
  6. InstanceOnPoints → RealizeInstances : les instances sont converties en géométrie de maillage.
  7. RealizeInstances → Group Output (« Cubes ») : le résultat final est disponible en tant que sortie du groupe.

Voici le code complet que nous avons obtenu :

import bpy

Create a new Geometry Node group

crowd_group = bpy.data.node_groups.new("CubeCrowdGenerator", "GeometryNodeTree")

Create input/output nodes

group_in = crowd_group.nodes.new("NodeGroupInput") group_out = crowd_group.nodes.new("NodeGroupOutput")

group_in.location = (-600, 0) group_out.location = (600, 0)

Define group interface sockets

interface = crowd_group.interface interface.new_socket(name="Surface", in_out="INPUT", socket_type="NodeSocketGeometry") interface.new_socket(name="Cubes", in_out="OUTPUT", socket_type="NodeSocketGeometry")

Create internal nodes

distribute = crowd_group.nodes.new("GeometryNodeDistributePointsOnFaces") instance = crowd_group.nodes.new("GeometryNodeInstanceOnPoints") cube = crowd_group.nodes.new("GeometryNodeMeshCube") realize = crowd_group.nodes.new("GeometryNodeRealizeInstances") set_pos = crowd_group.nodes.new("GeometryNodeSetPosition") rand_vec = crowd_group.nodes.new("FunctionNodeRandomValue")

Configure random vector node

rand_vec.data_type = "FLOAT_VECTOR" rand_vec.inputs"Min".default_value = (-0.5, -0.5, 0.0)  # minimum offset rand_vec.inputs"Max".default_value = (0.5, 0.5, 0.5)  # maximum offset

Layout nodes

distribute.location = (-400, 0) rand_vec.location = (-200, -200) set_pos.location = (-100, 0) instance.location = (100, 0) cube.location = (-400, -200) realize.location = (300, 0)

Create links

links = crowd_group.links links.new(group_in.outputs"Surface", distribute.inputs"Mesh") links.new(distribute.outputs"Points", set_pos.inputs"Geometry") links.new(rand_vec.outputs"Value", set_pos.inputs"Offset") links.new(set_pos.outputs"Geometry", instance.inputs"Points") links.new(cube.outputs"Mesh", instance.inputs"Instance") links.new(instance.outputs"Instances", realize.inputs"Geometry") links.new(realize.outputs"Geometry", group_out.inputs"Cubes")

Maintenant, il ne reste plus qu’à copier-coller ce script dans l’espace de travail de scripting, l’exécuter, puis vous pourrez ajouter notre nœud personnalisé depuis l’espace de travail des geometry nodes :

Nous pouvons ouvrir le groupe de nœuds pour voir ce qu’il contient en double-cliquant dessus :


Conclusion

Avec seulement quelques dizaines de lignes de code, vous pouvez script des configurations de Geometry Nodes qui prendraient beaucoup plus de temps à assembler manuellement. Dans cet article, vous avez appris comment créer des arborescences de nœuds Geometry Node, ajouter et connecter des nœuds par programmation, contrôler les paramètres et assigner des arborescences de nœuds aux objets, puis construire un système procédural complet.

Jetez un œil à l’annuaire du code sur Github pour essayer l’exemple vous-même !

Cette approche libère un potentiel d’automatisation sans fin, du développement d’outils à l’art génératif.

📽️
Pour en savoir plus sur le processus d’animation, envisagez de rejoindre notre communauté Discord ! Nous échangeons avec plus d’un millier d’experts qui partagent les meilleures pratiques et organisent parfois des événements en personne. Nous serions ravis de vous accueillir ! 😊

Vous appréciez cet article ?

Abonnez-vous à notre newsletter pour plus d'analyses, de tutoriels et d'actualités du secteur.