Introduction

Premiers pas

Pour découvrir comment coder en Python avec Blender, commençons par interagir avec la console. Dites: « Bonjour! » et appuyez sur la touche Entrée.

Parfait! Continuons…

Nous pouvons faire des additions, par exemple:

1 + 1

Calculer

Nous pouvons ainsi utiliser tous les opérateurs mathématiques généralement utilisés avec une machine à calculer (vous remarquez que pour multiplier on utilise le symbole étoile *):

(10 + cos(3.14)) * 2

Les objets

Encore plus utile, on peut récupérer des informations sur les objets Blender.

Pour cela il faut utiliser la «bibliothèque» interne (on dit library en anglais) de fonctions, elle s'appelle bpy (BlenderPYthon).

Dans la console, commencez par taper la lettre b puis utilisez la touche TAB (tabulation) pour faire apparaître une série de mots-clés disponibles.

Vous pouvez parcourir l'ensemble des fonctions internes ainsi, en explorant et en complétant lettre par lettre, l'orthographe de ces mots.

Si, après avoir tapé b vous ajoutez un p (cela fait bp) et que vous «tabulez», vous voyez que la console vous a complété automatiquement le mot bpy en ajoutant également un point . à la fin. Si vous poursuivez maintenant la «tabulation», vous voyez apparaître les «sous-catégories» de bpy : app, context, data, etc...

Maintenant, sélectionnez un objet dans la vue 3D, puis revenez dans la console Python et tapez (en vous servant de l'auto-complétion par tabulation, donc) la «formule» suivante:

bpy.context.object.location.x

La console vous a «renvoyé» la valeur de la position en X de l'objet sélectionné.

Encore mieux, vous pouvez modifier cette valeur en ajoutant un signe d'égalité (=) suivi d'une valeur, par exemple 2.

bpy.context.object.location.x = 2

Vous venez de déplacer l'objet sélectionné à la coordonnée x=2.

Bravo!

Les données

Voir Données

Grâce à la console Python, nous avons donc accès à l'ensemble des objets et de leurs propriétés.

Continuons d'explorer ces données. Toujours avec un objet maillé sélectionné, regardons comment récupérer les coordonnées de ses points.

Avec le mot-clé object dans la catégorie context, nous pouvons récupérer l'objet sélectionné:

bpy.context.object

Par exemple:

bpy.data.objects['Plan']

Avec le mot-clé data de la catégorie object, nous accédons au maillage de l'objet:

bpy.context.object.data

Il s'agit d'une donnée de type mesh stockée dans la catégorie meshes:

bpy.data.meshes['Plan']

Nous voyons que ce maillage est identifié par un nom: Plan (ici, le même que le nom de l'objet)

Un maillage contient des points (vertices), des lignes, des faces, entre autres.

Nous accédons aux points du maillage en ajoutant le mot-clé vertices

bpy.context.object.data.vertices

Ces points sont stockés dans une liste qui est numérotée à partir de 0.

Pour accéder à un élément d'une liste, il suffit d'utiliser les crochets [ et ] en spécifiant le numéro de l'élément auquel nous souhaitons accéder. Pour accéder au premier point, il faut donc écrire:

bpy.context.object.data.vertices[0]

Chaque point contient un certain nombre d'informations. Pour ce qui concerne ses coordonnées dans l'espace, il faut utiliser le mot-clé co (abréviation de coordonnées:

bpy.context.object.data.vertices[0].co

La console nous renvoie alors un vecteur, par exemple:

Vector((-1.0, -1.0, 0.0))

Enfin, pour accéder aux coordonnées suivant chacun des axes, nous pouvons spécifier le nom (en minuscule) de cet axe. Pour récupérer la coordonnée en X de ce point nous écrivons donc:

bpy.context.object.data.vertices[0].co.x

La console renvoie ici la valeur:

-1.0

Les variables

Voir Variables

Imaginons maintenant que nous voulions calculer la longueur d'une arête horizontale (c'est-à-dire une une ligne, ou edge en anglais) de l'objet en question.

Pour cela nous allons successivement stocker les informations qui sont nécessaires à ce calcul.

Commençons par stocker les coordonnées en X du premier point.

Pour cela nous utilisons le signe = ainsi:

a = bpy.context.object.data.vertices[0].co.x

Nous venons de créer une variable nommée a, et cette variable contient maintenant la valeur x de ce point.

Nous pouvons vérifier cela en «appelant» la variable par son nom et en validant avec entrée:

a

La console nous renvoie la valeur qui est stockée dans la variable a:

-1.0

Maintenant, faisons la même chose avec le deuxième point. Nous créons une deuxième variable nommée b pour stocker cette nouvelle information. Vous remarquez que cette fois-ci nous accédons au deuxième point en spécifiant le numéro 1 dans la liste des vertices : vertices[1] (n'oubliez pas que les listes sont numérotées à partir de 0).

b = bpy.context.object.data.vertices[1].co.x

De la même façon, nous pouvons vérifier la coordonnée en x du point b :

b

La console nous renvoie la valeur qui est stockée dans la variable b, ici :

1.0

Cette formule est vraiment fastidieuse à écrire. Mais pas besoin de l'écrire deux fois. Il suffit d'utiliser les flèches du clavier (flèche du haut et flèche du bas) pour «naviguer» dans l'historique des commandes que nous avons déjà tapé. Appuyez donc sur la flèche du haut pour faire apparaître la formule que nous avons précédemment tapée puis, avec les flèches horizontales, déplacez-vous jusqu'au numéro que nous souhaitons modifier. Il ne reste plus qu'à valider (avec la touche entrée).

Nous voici donc maintenant avec 2 variables a et b qui contiennent les coordonnées x des deux premiers points.

Nous pouvons maintenant faire une soustraction pour déterminer la longueur de cette arête.

b - a

La console nous renvoie ici:

2.0

Si les deux points a et b sont horizontaux (leurs valeurs en y sont les mêmes) nous pouvons dire que nous avons ainsi calculé la longueur de cette ligne.

Nous pouvons stocker cette longueur dans une variable pour de futurs calculs:

l = b - a

Les fonctions

Voir Fonctions

Nous venons de voir que nous pouvons créer des «formules» qui peuvent nous être utiles pour faire «nos calculs» sur les objets 3D.

Pour que ces «formules» nous soient vraiment utiles, nous allons les «stocker» dans des fonctions. C'est-à-dire que nous allons créer une sorte de variable qui va stocker la formule avec ses opérations. Nous pourrons ainsi «appeler» cette formule autant de fois que nous le souhaitons, en la convocant par son nom.

Mais ici, la console Python n'est plus adaptée, il nous faut donc ouvrir l'éditeur de texte et créer un nouveau fichier en prenant soin de spécifier son extension qui doit être ici de type .py, c'est l'extension que nous donnons aux fichiers Python.

Par exemple, créons un nouveau fichier formules.py

À présent, écrivons une fonction qui va calculer la longueur l que nous avons précédemment calculée.

Pour créer une fonction, nous commençons par utiliser le mot-clé def (abréviation de definition) puis nous choisissons le nom de la fonction, par exemple longueur, enfin nous ajoutons deux parenthèses, dans lesquelles, plus tard, nous spécifierons les variables que nous voulons utiliser. Enfin, nous ajoutons deux points : pour terminer.

def longueur():

Pour commencer, écrivons une fonction qui affiche la valeur qu'on lui envoie.

Pour cela nous allons donc ajouter un nom de variable entre les parenthèses:

def longueur(val):

Nous avons choisi ici d'appeler cette variable val (pour «valeur»).

Pour l'instant, cette variable est encore assez «abstraite», nous verrons juste après comment elle fonctionne. En tout cas, nous savons que maintenant elle est à «disposition» dans le corps de notre fonction; nous pouvons par exemple écrire, après avoir ajouté un espace avec la touche TAB sur une seconde ligne, le mot-clé print suivi de la variable val entre parenthèses:

def longueur(val): print(val)

Nous venons d'écrire notre première fonction!

Corps

Pour écrire des fonctions, rien de plus simple.

Nous commençons avec la ligne de définition def qui contient le nom de la fonction, les parenthèses (obligatoires même si elles sont «vides»), d'éventuels noms de variables, puis les deux points :

Ensuite nous écrivons le «corps» de la fonction (en anglais cette partie s'appelle body).

Le corps de la fonction, c'est la suite d'instructions qui va être exécutée quand nous «appellerons» cette fonction (par son nom, donc).

Tabulations

Pour écrire le corps de la fonction, il faut ajouter une tabulation avant d'écrire la première ligne qui nous intéresse ici print(val).

Une tabulation, c'est un espace (ou plusieurs espaces en fonction de la valeur qui a été fixée pour une tabulation).

Pour ajouter une tabulation, on utilise la touche TAB. Cette même touche qui nous sert à: (1) passer en mode édition et (2) faire une auto-complétion dans la console.

Ici donc, la touche TAB nous sert à ajouter un espace, ou plutôt une série d'espaces (qui sont donc «invisibles»). Par défaut, la touche TAB ajoute 4 espaces.

Vous remarquerez égalemment qu'en fait cette tabulation est créée automatiquement par l'éditeur de texte quand on fait un «retour chariot» (pas de crainte, c'est un terme qui nous vient des machines à écrire!) c'est-à-dire quand on appuie sur la touche entrée à la fin de la ligne de définition def longueur(): pour écrire la suite du texte (enfin, du code en l'occurence) sur une nouvelle ligne.

Pour écrire le corps d'une fonction, il faut donc ajouter une tabulation devant chaque ligne.

Cette tabulation est ajoutée automatiquement par l'éditeur après le :, puis sur chaque nouvelle ligne du corps de la fonction.

Instructions

Dans le corps de la fonction nous écrivons une série d'instructions, c'est-à-dire une série d'opérations et de calculs que nous souhaitons effectuer. Il s'agit souvent d'appeler d'autres fonctions existantes ou que nous avons nous-mêmes codé.

Dans notre exemple, nous appelons une fonction prédéfinie (on peut parler de fonction «système») très utile, la fonction print qui, comme son nom l'indique en anglais, sert à «imprimer», c'est-à-dire à afficher quelque chose dans la console.

Ici, il s'agit de la console du système (et pas de la console Python avec laquelle nous avons commencé).

Pour afficher cette console et voir le résultat, il faut aller dans le menu Fenêtre :

Sur Mac, il faut lancer Blender depuis un terminal.

def longueur(val): print(val)

Ici, notre fonction longueur va simplement afficher la valeur de la variable que nous spécifions quand nous «appelons» la fonction.

Faisons un essai avant de clarifier tout cela.

Nous avons pour l'instant «déclaré» une nouvelle fonction.

Mais pour l'instant elle ne nous sert à rien tant que nous ne nous en servons pas.

Il faut maintenant appeler la fonction pour s'en servir.

Pour cela, après la ligne print(val) nous ajoutons une nouvelle ligne (toujours avec la touche entrée)

Ce qui a pour effet donc, d'ajouter une tabulation.

Mais comme nous souhaitons à présent «clore» notre fonction, nous supprimons cette tabulation (avec la touche «retour arrière» au-dessus de la touche entrée).

Nous sommes donc maintenant revenus au début de la ligne (il n'y a plus de tabulation; la déclaration de notre fonction est terminée.

Nous pouvons ajouter une nouvelle ligne pour rendre un peu plus lisible notre code.

Et sur cette nouvelle ligne nous pouvons «appeler», c'est-à-dire «exécuter», la fonction que nous venons de définir.

Il suffit d'écrire le nom de la fonction suivi des deux parenthèses avec une valeur de test, par exemple le nombre 10:

longueur(10)

Notre code ressemble donc à cela:

def longueur(val): print(val) longueur(10)

Très bien! Mais il ne se passe toujours pas grand chose, car pour l'instant nous ne faisons qu'«écrire du code».

Il faut maintenant l'«exécuter» (c'est un terme un peu dur, j'en conviens...)

Pour cela il y a un petit bouton qui contient une flèche blanche, à côté du nom du fichier que nous avons créé.

Appuyez sur cette flèche et consultez le résultat dans la petite fenêtre que nous avons affichée avec le menu Fenêtre (la console système).

Vous devriez donc voir le résultat 10 affiché dans cette console.

Distance

À présent, faisons quelque chose d'utile, une fonction qui nous calcule automatiquement la distance entre deux coordonnées.

Renommons notre fonction distance et définissons deux variables a et b.

Dans ces variables nous pourrons spécifier les numéros des points avec lesquels nous souhaitons travailler:

def distance(a,b):

Dans le corps de la fonction nous ajoutons:

ax = bpy.context.object.data.vertices[a].co.x bx = bpy.context.object.data.vertices[b].co.x

Cela nous permet donc de récupérer les valeurs en X des deux points que nous stockons dans deux variables ax et bx

Puis faisons une soustraction:

d = bx - ax

Enfin, nous affichons le résultat:

print(d)

Voici à quoi ressemble notre fonction:

def distance(a,b): ax = bpy.context.object.data.vertices[a].co.x bx = bpy.context.object.data.vertices[b].co.x d = bx - ax print(d)

Puis nous ajoutons donc sur une nouvelle ligne, un appel de fonction, avec par exemple les deux premiers points dans la liste.

distance(0,1)

Il suffit maintenant de sélectionner un objet maillé dans la vue 3D, puis d'appuyer sur la petite flèche blanche...

def distance(a,b): ax = bpy.context.object.data.vertices[a].co.x bx = bpy.context.object.data.vertices[b].co.x d = bx - ax print(d) distance(0,1) distance(1,2)

Pour visualiser l'indice d'un point, c'est-à-dire sa position dans la liste des points (object.data.vertices), donc le numéro qui permet, en comptant à partir de zéro, d'accéder à l'élément dans la liste; pour visualiser ce numéro, il faut activer l'option «développeur» dans les préférences de Blender.

Ensuite, dans la vue 3D, activer Indices