Voici le genre d'objet assez pénible à faire à la main :
Utiliser Python dans Blender va ainsi permettre d'automatiser certains placements.
Commençons par montrer où se trouve la console qui permet de rentrer du code en direct.
01° Ouvrir Python Console plutôt que info.
Agrandir un peu la fenêtre pour voir un peu plus de code. Ou appuyer sur le bouton console pour la placer en plein écran ou revenir à la configuration initiale.
Vous devriez obtenir un message d'accueil du style :
PYTHON INTERACTIVE CONSOLE 3.5.1 (default, Feb 17 2016, 17:09:19) [MSC v.1800 64 bit (AMD64)]
Command History: Up/Down Arrow
Cursor: Left/Right Home/End
Remove: Backspace/Delete
Execute: Enter
Autocomplete: Ctrl-Space
Zoom: Ctrl +/-, Ctrl-Wheel
Builtin Modules: bpy, bpy.data, bpy.ops, bpy.props, bpy.types, bpy.context, bpy.utils, bgl, blf, mathutils
Convenience Imports: from mathutils import *; from math import *
Convenience Variables: C = bpy.context, D = bpy.data
Ce texte vous explique surtout que certains modules sont déja importés dans cette console. Notamment les modules commençant par bpy (pour Blender Python).
02° Faire disparaitre le cube de départ PUIS taper ceci dans la console :
>>> bpy.ops.mesh.primitive_cube_add()
Vous devriez constater qu'un nouveau cube vient d'apparaitre juste sur le curseur 3D.
03° Décaler le cube avec les flèches de direction et retaper la ligne de code (CTRL+C, CTRL+V).
04° Avec un clic gauche, placer le curseur 3D à un autre endroit. Retaper la ligne de code.
Vous devriez au final obtenir un résultat du type :
Comment fonctionne ce code ? Il suffit de faire un clic-droit sur le carré du menu Tools et de sélectionner Online Python reference pour trouver des informations complètes :
Retenons déjà que
bpy.ops.mesh.primitive_cube_add()
veut dire :
bpy
,ops
,mesh
etprimitive_cube_add()
.Les points signalant les liaisons.
La documentation en ligne donne ceci :
bpy.ops.mesh.primitive_cube_add(radius=1.0, calc_uvs=False, view_align=False, enter_editmode=False, location=(0.0, 0.0, 0.0), rotation=(0.0, 0.0, 0.0), layers=(False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False))
Construct a cube mesh.
Parameters:
Remarquons que tous les arguments transmissibles sont optionnels. C'est pour cela qu'on peut créer un cube en ne notant rien entre les parenthèses de la méthode.
Mais on peut créer un cube ayant un radius de 2 en tapant :
>>> bpy.ops.mesh.primitive_cube_add(radius=2.0)
05° Créer un autre objet qu'un cube en vous renseignant sur le code à utiliser :
Imaginons maintenant que nous voulions créer un cube mais en ne le plaçant pas à l'emplacement du curseur 3D. Pour cela, il faut renseigner le paramètre location.
On peut trouver la documentation facilement : plutôt que de rester statique au dessus de la touche de l'objet à créer, il faut faire un clic droit et sélectionner Online Python References. En regardant via la documentation, on trouve alors dans l'intitulé de la méthode :
bpy.ops.mesh.primitive_cube_add(radius=1.0, ... location = (0.0, 0.0, 0.0), rotation = (0.0, 0.0, 0.0), ...)
On voit donc que certains paramètres ont des valeurs par défaut.
Lorsqu'on note bpy.ops.mesh.primitive_cube_add()
, location prend la valeur par défaut : (0.0, 0.0, 0.0)
.
location = (0.0, 0.0, 0.0)
Pourquoi avoir noter cela avec des parenthèses rouges ?
Et bien parce que c'est important pour la suite ! On n'envoie pas un 0.0 puis un 0.0 puis un 0.0.
On envoie les trois 0.0 d'un coup dans un objet qui comporte 3 données. On nomme cela un N-uplets. C'est un type de données :
Ici, nous avons un 3-uplet. On nomme également cela tuple.
06° Créer un cube en utilisant bpy.ops.mesh.primitive_cube_add(location=(5,5,0))
.
Cela donne :
Vous pouvez constatez qu'on travaille depuis l'origine O (0,0,0) du plan. Vous pouvez changer les valeurs pour vous en convaincre.
Voilà pour le premier contact. Il vous reste à voir comment créer un script dans un fichier plutôt que de taper les instructions à chaque fois.
La console est bien pratique mais elle ne permet pas de stocker du code pour pouvoir le réutiliser au besoin. Pour cela, nous allons devoir créer un script : enregistrer un fichier d'extension .py qui va contenir notre "programme". Puisque ce programme n'est pas autonome, mais est destiné à être utilisé par Blender, on ne le nomme pas programme mais script.
07° Pour créer un script, remplacer la console par text editor.
Vous devriez pour l'instant avoir ceci :
Et vous allez passer à :
08° Utiliser new pour créer un nouveau fichier qui va nous permettre de créer un fichier python .py.
Voici le script que nous allons utiliser :
import bpy # On importe la bibliothèque Blender Python
bpy.ops.mesh.primitive_cube_add( location = (0,0,0))
bpy.ops.mesh.primitive_cube_add( location = (5,5,0))
bpy.ops.mesh.primitive_cube_add( location = (5,-5,0))
bpy.ops.mesh.primitive_cube_add( location = (-5,5,0))
bpy.ops.mesh.primitive_cube_add( location = (-5,-5,0))
L'interpréteur Python va suivre le script dans l'ordre, comme si vous aviez tapé les lignes les unes après les autres :
CLIQUEZ ICI POUR VOIR LE DEROULEMENT :
Comme vous pouvez le constater en utilisant la simulation, l'interpréteur va suivre les instructions de façon séquentielle : il les lit et les execute les unes à la suite des autres, dans l'ordre qu'on lui a fourni. Il n'exécute pas les instructions dans un ordre aléatoire.
09° Utiliser le code pour voir le résultat en appuyant sur Run Script.
Et voilà. Vous avez vu les bases fondamentales de la manipulation d'objets via Blender.
Quelques remarques :
Nous allons quitter Blender pendant quelques minutes. Pour aborder cette partie, nous allons revenir à l'utilisation de code Python classique et pas des méthodes propres à Blender. Pour cela, modifier la vue 3D pour y afficher la console Python.
Commençons par voir comment afficher des choses en commande directe sur la console Python.
10° Dans la console Python de Blender (vous devriez voir apparaitre les trois chevrons), taper le code suivant :
>>> 14/3
>>> 9*9+2
>>> 12-2*0.8888
>>> 3E8*12E-15
Bref, on remarquera qu’on lance des calculs en temps réel. Puisqu’on l’utilise notamment pour faire des calculs, on dispose de nombreuses fonctions :
11° Taper les codes suivants qui illustrent trois opérateurs différents :
Opérateur 1/4 :
>>> 14/3
4.666666667
Comme sur les calculatrices, c'est approximatif mais cela devrait permettre une résolution correcte des problèmes.
L'utilisation de /
représente donc bien l'opérateur division.
On retrouve les autres signes standards pour les opérateurs : +
-
et *
.
Opérateur 2/4 :
>>> 14//3
4
L'utilisation de //
permet donc d'obtenir la partie entière de la division de 14 par 3 qui vaut 4,6666666667.
Opérateur 3/4 :
>>> 14%3
2
L'utilisation de %
permet donc d'obtenir le reste de la divison entière : 14 = 4x3 + 2. On parle également de modulo, comme pour les angles qui sont connus modulo 360° ou 2Π rad.
Opérateur 4/4 :
>>> 3**2
9
L'utilisation de **
permet donc de calculer la puissance.
Regardons maintenant comment afficher des caractères dans la console.
12° A votre avis, que fait cette instruction ?
>>> "Hello World !"
>>> print("Hello World !")
...CORRECTION...
On affiche deux fois Hello World !.
La première fois entouré de ' et ' pour indiquer qu'il s'agit d'une chaîne de caractères.
La seconde fois, on utilise la fonction print qui permet d'afficher le résultat. La différence ? Uniquement l'absence des guillements simples pour l'instant. Nous verrons néanmoins que lorsque nous réaliserons un programme en mode non interactif, il faudra utiliser print de façon à afficher le résultat. Pour l'instant les deux méthodes fonctionnent mais le print est ici inutile : en mode interactif, la console affiche directement les contenus qu'on lui demande.
13° Et là ?
>>> "Hello W" + "orld !"
>>> print( "Hello W" + "orld !" )
...CORRECTION...
Dans les deux cas, on voit s'afficher Hello World ! dans la console.
Python sait donc additionner deux strings. On nomme cela la concaténation.
Ce qui apparaît en bleu se nomme un STRING en python : une chaîne de caractères en français.
Un string commence avec des guillements doubles et finit par des guillemet doubles :
"Hello World !"
Mais on peut également utiliser des guillemets simples :
'Hello World !'
Par contre, on doit fermer un string avec le même type de guillemets en ouverture et en fermeture. Le code suivant ne permet pas de créer un string :
'Hello World !"
Si on utilise un guillemet double en ouverture, on ne peut donc plus l'afficher : Python va croire qu'on ferme le string ! En réalité, on peut afficher un " et c’est simple : on utilise l’antislash \
avant le signe lui même.
14° A votre avis, que fait ce code ?
>>> "Comme on dit souvent : \"Hello World !\""
Remarque :
\ se nomme antislash ou backslash.
/ se nomme slash.
Sur la plupart des systèmes d'exploitation, les adresses sur des périphériques de données s'écrivent avec la barre oblique. Pour Microsoft Windows, c'est la barre oblique inversée (exemple : C:\Mes Documents\Mes Images) alors que dans les systèmes UNIX, ainsi que pour les adresses réseau et internet (URL), les adresses de fichier s'écrivent avec la barre oblique normale (exemple dans votre barre d'adresse).
Dernière chose : pour formater un affichage via des tabulations, on peut utiliser \t
, avec t comme tabulations.
Du coup, l’antislash est un caractère spécial puisqu’il sert à coder des fonctions particulières comme la tabulation. Comment afficher un antislash alors ? C’est simple … on en met deux à la suite.
15° Qu’affiche le code ci-dessous ?
>>> print("Nom\tPrenom\tAge")
>>> print("ARG\tBob\t17")
>>> print("Voilà un antislash \\")
...CORRECTION...
Vous devriez voir que \t permet de créer une tabulation.
Vous devriez voir que \\ permet d'afficher l'anti-slash.
Attention : ici, le print est obligatoire pour que l'interpréteur applique bien la tabulation.
Pour afficher un nombre (120 par exemple), vous pouvez utiliser deux façons de faire :
>>> "120"
'120'
>>> 120
120
Pour un humain, c'est pareil mais pas pour l'ordinateur : Pour lui, "120" est du même type qu'une chaîne comme "ABC".
16° Tenter de deviner ce que vont afficher les codes suivants. Taper et exécuter le code une fois que vous pensez avoir la réponse.
>>> 120*2
>>> "120"*2
>>> "120"+2
17° A votre avis, pourquoi le dernier cas ne donne-t-il rien d’interprétable ?
...CORRECTION...
Si on veut deux fois le nombre 120, on obtient 240.
Si on veut deux fois la chaîne "120", on obtient "120120".
Par contre, Python ne sait absolument pas additionner une chaîne de caractères et un nombre ... En même temps, que feriez-vous si on vous demandait de faire la somme de "ABC" et du nombre 2.
Il nous reste à voir le passage à la ligne. Si vous voulez afficher "Bon"
sur une ligne et "jour"
sur la ligne suivante, il suffit d'utilser un caractère spécial à la fin de "Bon"
. Lequel ? \n : on obtient alors la chaîne de caractères "Bon\njour"
.
18° Afficher, avec un print("Bon\njour")
, la chaîne "Bon\njour"
pour voir comment Python interprète votre chaîne.
On obtient donc :
>>> print("Bon\njour")
Bon
jour
Attention : ici, le print est obligatoire pour que l'interpréteur applique bien le passage à la ligne.
Voilà. Vous connaissez les bases de l'affichage via la console.
Voyons maintenant comment stocker des informations pour les réutiliser plus tard.
19° Taper ceci dans la Console Python :
>>> a = 5
>>> a
5
Et voilà, vous venez de créer votre première variable : vous avez stocké 5 dans une zone mémoire qu'on pourra retrouver en tapant simplement a.
Ainsi, à chaque fois qu'on tapera a dans le script, Python remplacera cette variable par ce qui est stocké à l'adresse correspondante.
Vous pouvez voir les variables comme un raccourci pour atteindre une zone mémoire sans avoir à fournir son adresse réelle.
Ici, votre variable contient un entier, un Integer en langage informatique.
20° Expliquer (sans la taper) ce que va alors donner l'instruction ci-dessous ? Taper l'instruction pour vérifier.
>>> a*2
10
Et si nous plaçions un string dans la variable a ?
>>> a = "5"
>>> a*2
'55'
21° Pourquoi obtient-on "55" et pas 10 ?
...CORRECTION...
On crée une variable a qui désigne l'adresse d'une zone mémoire qui contient un STRING "5".
Lorsqu'on demande de multiplier le string par 2, Python va alors simplement comprendre qu'on veut 2 "5" , soit "55" .
Comme vous le voyez, connaitre le type des données est important. Comment savoir à l'avance ce que désigne une variable ? Il faut utiliser une fonction native de Python : type.
22° Lancer les instructions suivantes pour comprendre ce que fait cette fonction :
>>> premiere = 5
>>> type(premiere)
>>> deuxieme = "5"
>>> type(deuxieme)
>>> troisieme = 5.0
>>> type(troisieme)
...CORRECTION...
La fonction type permet donc d'obtenir le type de données stockées à l'adresse mémoire pointée par la variable.
Si on stocke 5, on obtient une variable de type int pour integer (nombre entier)
Si on stocke "5", on obtient une variable de type str pour string (chaîne de caractères)
Si on stocke 5.0, on obtient une variable de type float pour float (nombre réel ou nombre à virgule flottante)
Les types de variables disponibles et les contenus attendus de ces variables sont donnés ci-dessous :
Type de variable | Nom du type pour Python | Ce qu'il peut contenir |
---|---|---|
Booléen/Boolean | bool | False or True (avec une majuscule) |
Entier/Integer | int | Un nombre entier comme 12 |
Nombre réel | float | Un nombre à virgule comme 12.0 ou 12.5 |
Nombre complexe | complex | Un nombre complexe comme z = 145 + 2i |
Chaîne de caractère | string | Une chaîne de caractères, c'est-à-dire un mot ou une phrase. On la définit entre deux guillemets ou apostrophes."chaîne de caractère"'autre chaîne de caractère' |
On peut bien entendu tenter de transformer un type de variable en une autre. Pour cela, on utilise les fonctions natives suivantes :
23° Lancer les instructions suivantes pour comprendre ce que font ces fonctions :
>>> a = 5
>>> type(a)
>>> a*2
>>> b = str(a)
>>> type(b)
>>> b*2
...CORRECTION...
1e cas : a est un integer. On obtient un string b.
b désigne "5".
2*b désigne "55"
>>> c = 5
>>> type(c)
>>> c*2
>>> d = float(c)
>>> type(d)
>>> d*2
...CORRECTION...
2e cas : c est un integer. On obtient un float d.
d désigne 5.0
2*d désigne 10.
>>> e = "5"
>>> type(e)
>>> e*2
>>> f = int(e)
>>> type(f)
>>> f*2
...CORRECTION...
1e cas : e est un string. On obtient un integer b.
b désigne 5.
2*b désigne 10.
Remarque : vous remarquerez que tous les types de variables commencent par une minuscule, pas une majuscule.
Nous allons pouvoir les utiliser pour réaliser un script qui créer sensiblement la même chose à chaque mais en fonction d'un paramètre qu'on peut changer.
24° Revenir à une configuration de type Ecran pour la vue 3D et Text Editor pour la fenêtre du haut. Utiliser ensuite new pour créer un nouveau fichier qui va nous permettre de créer un fichier python .py.
Voici le script Python que nous avions executé au début:
import bpy # On importe la bibliothèque Blender Python
bpy.ops.mesh.primitive_cube_add( location = (0,0,0))
bpy.ops.mesh.primitive_cube_add( location = (5,5,0))
bpy.ops.mesh.primitive_cube_add( location = (5,-5,0))
bpy.ops.mesh.primitive_cube_add( location = (-5,5,0))
bpy.ops.mesh.primitive_cube_add( location = (-5,-5,0))
Et bien, nous pourrions réecrire la même chose mais en utilisant une variable pour stocker 5.
25° Modifier le programme pour stocker ce 5 dans une variable puis utiliser cette variable pour dessiner les cubes plutôt que de taper réellement 5... Lancer votre script.
...CORRECTION...
import bpy # On importe la bibliothèque Blender Python
distance = 5
bpy.ops.mesh.primitive_cube_add( location = (0,0,0))
bpy.ops.mesh.primitive_cube_add( location = (distance,distance,0))
bpy.ops.mesh.primitive_cube_add( location = (distance,-distance,0))
bpy.ops.mesh.primitive_cube_add( location = (-distance,distance,0))
bpy.ops.mesh.primitive_cube_add( location = (-distance,-distance,0))
26° Relancer le script mais en stockant 15 et non pas 5 dans votre variable. Pratique non ?
...CORRECTION...
import bpy # On importe la bibliothèque Blender Python
distance = 15
bpy.ops.mesh.primitive_cube_add( location = (0,0,0))
bpy.ops.mesh.primitive_cube_add( location = (distance,distance,0))
bpy.ops.mesh.primitive_cube_add( location = (distance,-distance,0))
bpy.ops.mesh.primitive_cube_add( location = (-distance,distance,0))
bpy.ops.mesh.primitive_cube_add( location = (-distance,-distance,0))
27° Réaliser un script qui crée un cube à une distance donnée, puis à 3 fois cette distance puis à 5 fois cette distance.
...CORRECTION...
import bpy # On importe la bibliothèque Blender Python
distance = 3
bpy.ops.mesh.primitive_cube_add( location = (distance,0,0))
bpy.ops.mesh.primitive_cube_add( location = (distance*2,0,0))
bpy.ops.mesh.primitive_cube_add( location = (distance*3,0,0))
28° Dernière question : faites preuve d'imagination et réalisez une scène difficilement réalisable si on ne connait recours pas aux variables. En gros, il s'agit des scènes où un grand nombre de formes sont précisement positionnées et déformées.
A titre d'exemple, voici ce qu'on peut obtenir à l'aide du script suivant : on génère les cubes.
J'ai ensuite dû associer manuellement deux matériaux différents aux différents cubes.
Les couleurs sont le rose et le vert avec :
Dans l'activité suivante, nous verrons comment éviter de taper trop de lignes identiques à l'aide des boucles.
import bpy # On importe la bibliothèque Blender Python
decalage = 2
# Création des cubes dans le plan xy (z reste à 0)
bpy.ops.mesh.primitive_cube_add( location = (0,0,0))
bpy.ops.mesh.primitive_cube_add( location = (decalage,0,0))
bpy.ops.mesh.primitive_cube_add( location = (decalage,decalage,0))
bpy.ops.mesh.primitive_cube_add( location = (decalage*2,0,0))
bpy.ops.mesh.primitive_cube_add( location = (decalage*2,decalage,0))
bpy.ops.mesh.primitive_cube_add( location = (decalage*2,decalage*2,0))
bpy.ops.mesh.primitive_cube_add( location = (decalage*3,0,0))
bpy.ops.mesh.primitive_cube_add( location = (decalage*3,decalage,0))
bpy.ops.mesh.primitive_cube_add( location = (decalage*3,decalage*2,0))
bpy.ops.mesh.primitive_cube_add( location = (decalage*3,decalage*3,0))
bpy.ops.mesh.primitive_cube_add( location = (decalage*4,0,0))
bpy.ops.mesh.primitive_cube_add( location = (decalage*4,decalage,0))
bpy.ops.mesh.primitive_cube_add( location = (decalage*4,decalage*2,0))
bpy.ops.mesh.primitive_cube_add( location = (decalage*4,decalage*3,0))
bpy.ops.mesh.primitive_cube_add( location = (decalage*4,decalage*4,0))
# Création des cubes dans le plan yz (x reste à 0)
bpy.ops.mesh.primitive_cube_add( location = (0,0,decalage))
bpy.ops.mesh.primitive_cube_add( location = (0,decalage,decalage))
bpy.ops.mesh.primitive_cube_add( location = (0,0,decalage*2))
bpy.ops.mesh.primitive_cube_add( location = (0,decalage,decalage*2))
bpy.ops.mesh.primitive_cube_add( location = (0,decalage*2,decalage*2))
bpy.ops.mesh.primitive_cube_add( location = (0,0,decalage*3))
bpy.ops.mesh.primitive_cube_add( location = (0,decalage,decalage*3))
bpy.ops.mesh.primitive_cube_add( location = (0,decalage*2,decalage*3))
bpy.ops.mesh.primitive_cube_add( location = (0,decalage*3,decalage*3))
bpy.ops.mesh.primitive_cube_add( location = (0,0,decalage*4))
bpy.ops.mesh.primitive_cube_add( location = (0,decalage,decalage*4))
bpy.ops.mesh.primitive_cube_add( location = (0,decalage*2,decalage*4))
bpy.ops.mesh.primitive_cube_add( location = (0,decalage*3,decalage*4))
bpy.ops.mesh.primitive_cube_add( location = (0,decalage*4,decalage*4))
Comme vous le voyez, nous faisons souvent la même chose où presque. Heureusement, il existe un moyen d'automatiser encore plus tout cela : la boucle FOR. C'est dans l'activité suivante.
Il nous reste une petite chose à voir pour comprendre certains codes : certains bouts de code apparaissent dans une couleur différente lorsqu'on écrit un dièse #
. Pourquoi ?
Simplement car le dièse vous permet d'insérer des commentaires : les commentaires sont des textes que l'interpréteur ne va même pas lire. Il sont destinés à fournir des indications sur le fonctionnement du code.
Tout le texte situé derrière le dièse sera totalement invisible pour l'interpréteur.
Les commentaires sont un élément fondamental d'un script : ils vous permettent de recomprendre le code que vous aviez créé il y a plusieurs mois. Dès qu'un script est compliqué, une absence de commentaires va impliquer qu'une modification ou une mise à jour va être très très compliquée...
Pour vos projets, pensez bien à donner des indications à l'aide de cet outil de conception.
Un exemple pour montrer que le commentaire n'est pas analysé :
decalage = 2
# decalage = 100
print(decalage)
Ce code va afficher 2
dans la console. Pas 100.