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 :
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 :
Une fois que les élèves ont vu le principe on peut partir sur la notion de variables.
Dans les activités suivantes, ils verront comment éviter de taper trop de lignes identiques à l'aide des boucles. Ect, ect... Le principe est d'amener la notion au moment où ils se rendront compte de son utilité.
10° 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.
11° 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.
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))
12° 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. Normalement, après cela les élèves sont convaincus de l'utilité des boucles !
J'ai ensuite dû associer manuellement deux matériaux différents aux différents cubes. Nous verrons cela bientôt.
Si vous savez déjà comment gérer les matériaux, voici quelques indications.
Les couleurs sont le rose et le vert avec :
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))
Voici le genre de vue trop complexe à faire sans boucle :
La partie suivante vous présente des fonctions bien pratiques pour traiter du déplacement d'objets et des animations.
L'un des points 'faibles' de Blender en Python, c'est la multiplicité des sources d'informations et d'affichage. Pour rappel :
La console ou le terminal de votre ordinateur correspond en windows à l'invité de commande qu'on trouve dans le sous-menu Système Windows. On ne l'utilise pas avec Blender.
Même si Blender fonctionne avec Python, nul besoin de passer par votre propre interpréteur Python : tout est intégré directement à Blender. Oubliez donc le IDLE Python (icone blanche) et l'icone vers la console Python (icone noire) que vous avez peut-être sur votre ordinateur.
Dans Blender, il existe trois endroits qu'il faut savoir activer :
13° Changer la disposition par défaut pour utiliser plutôt la disposition Scripting.
On arrive normalement à ceci :
Toutes les fenêtres utiles pour programmer sont là.
14° Dans TextEditor, sélectionner la numérotation des lignes et la mise en couleur synthaxique.
15° Tirer le menu Info pour qu'il prenne un peu plus de place si possible. Sélectionner ensuite Window - Toggle System Console. Attention, je parle bien de la console Systeme, pas juste la console Python qu'on peut sélectionner comme fenêtre active.
Au final, vous devriez avoir la bonne configuration de travail, à savoir une interface qui ressemble à ceci:
Et avec cela, nous allons pouvoir travailler correctement.
16° Tenter de voir ce que fait le code suivant puis le lancer dans Blender.
import bpy # On importe la bibliothèque Blender Python
for x in range(-16,17,4):
bpy.ops.mesh.primitive_cube_add(location = (x,0,0))
...CORRECTION...
On part de -16 et on augmente de 4 à chaque retour de boucle.
Ceci est vrai tant que le compteur donne un résultat strictement inférieur à 17.
Il devrait vous créer des cubes en x = -16, x = -12, x = -8, x = -4, x = 0, x = 4, x = 8, x = 12 et x = 16.
Pour supprimer les objets créés, vous pouvez utiliser la touche C pour activer le curseur de sélection. Appuyer sur le bouton de gauche le temps de sélectionner les objets voulus, cliquer sur le bouton de droite puis supprimer la sélection avec la touche SUPPR.
On peut aussi gérer les rotations. Il faut alors faire un peu de math, surtout de la trigonométrie.
Imaginons qu'on désire créer un cercle de cube. Il faut falloir importer le module math pour parvenir à calculer les sinus et les cosinus. Et convertir les angles qu'on exprime en degrés en radians, unité naturelle des angles pour Python.
Voici le code qui permet d'obtenir les coordonnées d'un cube qui subit une rotation autour de (0,0) avec un rayon fourni dans la variable rayon :
import bpy # On importe la bibliothèque Blender Python
import math # On importe la bibliothèque math pour calculer les cos...
rayon = 10
for angle_degre in range(-0,360,36):
angle = math.radians(angle_degre) # math.radians permet de convertir en radians
x = rayon*math.cos(angle)
y = rayon*math.sin(angle)
bpy.ops.mesh.primitive_cube_add(location=(x,y,0))
Nous allons donc plusieurs calculs en boucle avec les valeurs angle_degre de 0°, 36°, 72° ... puisqu'on part de 0 et qu'on augmente de 36° à chaque retour.
17° Lancer le code pour voir le résultat. Tentons d'en comprendre le sens :
rayon = 10
permet de définir le rayon voulu pour la disposition.for angle_degre in range(-0,360,36):
permet de prendre successivement angle_degre à 0, 36, 72 ...angle = math.radians(angle_degre)
permet de convertir l'angle en radians graçe à la méthode radians() contenu dans la bibliothèque math.x = rayon*math.cos(angle)
permet de définir la coordonnée x du cube en cours.y = rayon*math.sin(angle)
permet de définir la coordonnée y du cube en cours.bpy.ops.mesh.primitive_cube_add(location=(x,y,0))
affiche le cube.17° Je vous laisse tenter de faire ceci (vous ne pouvez pas faire la colorisation via un script pour l'instant) :
Une proposition de correction : un for dans un for et un nombre de cubes et une altitude variable en fonction du rayon;
import bpy # On importe la bibliothèque Blender Python
import math # On importe la bibliothèque math pour calculer les cos...
rayon = 10
for rayon in range (6,23,4):
for angle_degre in range(0,360,int(36*6/rayon)):
angle = math.radians(angle_degre) # math.radians permet de convertir en radians
x = rayon*math.cos(angle)
y = rayon*math.sin(angle)
altitude = -rayon//2
bpy.ops.mesh.primitive_cube_add( location=(x,y,altitude) )
Les lumières, le plan et son effet miroir ont été rajoutés après l'utilisation du script pour permettre de mieux voir la structure obtenue.
Faire cette structure à la main aurait demandé des heures de travail (et un positionnement final approximatif, à moins de refaire les calculs un à un).