Nous allons aujourd'hui continuer à explorer le monde des conditions et tests logiques. Cela nous permettra de réaliser des vidéos d'objets en mouvement en quelques lignes.
A titre d'exemple, voici une animation qui vous propose deux boutons : GAUCHE permet d'aller à gauche et DROITE permet d'aller ... à droite.
Oui mais que faire si on demande d'aller à droite alors qu'on est déjà au bout du rectangle ? Il faut refuser d'avancer. Le script fait donc bien un choix logique IF en fonction de la position x du cercle au moment où le mouvement doit avoir lieu.
En français | Codage Python |
---|---|
SI on peut encore aller à droite alors | if (x < xmax) : |
Autoriser le déplacement à droite | Autoriser_droite() |
SINON SI on peut encore aller à gauche alors | elif (x > xmin) : |
Autoriser le déplacement à gauche | Autoriser_gauche() |
Fin du test |
En introduction, voilà le codage de différents test de conditions logiques entre deux variables :
Vous pouvez toucher aux curseurs pour voir l'évolution des différentes réponses.
Symbole du test | Signification | Exemple | Resultat du test |
---|---|---|---|
== | Est égal à | A == B | ? |
!= | Est différent de | A != B | ? |
> | Est supérieur à | A > B | ? |
>= | Est supérieur ou égal à | A >= B | ? |
< | Est inférieur à | A < B | ? |
<= | Est inférieur ou égal à | A <= B | ? |
Chacun de ces tests ne peut donner normalement que deux résultats : True pour vrai ou False pour faux.
On notera la présence d'une majuscule en Python : True et False. La plupart des langages utilisent simplement true et false.
Deuxième chose importante : la comparaison s'écrit avec deux signes =, pas un seul ! Il va falloir faire attention.
Commençons par voir comment choisir une action en fonction d’une entrée.
01° Voici un programme qui va déplacer le Cube initial à droite, à gauche puis retour au centre. Placez-vous en affichage SCRIPTING et lancer le code. La variable x contient-elle la coordonnée réelle du cube ou la coordonnée du cube au moment où on a fait l'affectation ?
# -*-coding:Utf-8 -*
import bpy # On importe la bibliothèque Blender Python
refCube = bpy.data.objects['Cube']
# Récupération des coordonnées du cube
x, y, z = refCube.location
# Déplacement éventuel du cube
if x > 0 :
refCube.location = ( -5, 0, 0 )
elif x == 0 :
refCube.location = ( 5, 0, 0 )
else :
refCube.location = ( 0, 0, 0 )
CLIQUEZ SUR UN BOUTON-REPONSE :
x :
position réelle :
Remarque : c’est la tabulation (ou 4 espaces) qui permet de savoir qu’une instruction est rattachée au bloc. Normalement, on utilise soit les 4 espaces, soit la touche TAB. Sinon, ça plante. Pour uniformiser votre code, dans la vue TEXT EDITOR, on peut tout transformer avec Format - Convert Whitespace.
...CORRECTION...
La variable x contient uniquement la valeur de la coordonnée au moment où on réalise l'affectation. Si la coordonné x du cube change, la variable x de Python n'est pas modifiée.
Comme vous l'avez vu, on ne rentre que dans un des cas disponibles :
Soit :
if x > 0 :
refCube.location = ( -5, 0, 0 )
Soit :
elif x == 0 :
refCube.location = ( 5, 0, 0 )
Soit :
else :
refCube.location = ( 0, 0, 0 )
Voyons maintenant comment symboliser et expliquer tout ceci.
Description en français : l'action logique qu’on peut traduire en texte par
SI la première condition est vraie alors |
Fait les actions 1 |
SINON SI la deuxième condition est vraie alors |
Fait les actions 2 |
SINON |
Fait les actions 3 |
Fin du test |
Représentation graphique : la même action logique sous forme graphique :
On voit que la condition est un losange qui possède deux sorties uniquement.
Les instructions sont des rectangles.
Description en code Python : l'action logique se traduit en code par
En français | Codage Python |
---|---|
SI la première condition est vraie alors | if condition_1 : |
Fait les actions 1 | Instructions_1 |
SINON SI la deuxième condition est vraie alors | elif (condition_2) : |
Fait les actions 2 | Instructions_2 |
SINON | else : |
Fait les actions 3 | Instructions_3 |
Fin du test | Rien sinon le retour à l'indentation de base |
On remarquera d’abord qu’on met double point [ : ] après la condition de if, else if (elif en Python) ou else.
Cela permet à l’interpréteur de savoir quand commence la condition à tester (après le if, elif ou else) et quand la condition est définie (au : justement).
Pour l'instant, vous ne savez pas encore tester la présence ou non d'un objet 3D. si nous faisons référence dans Python à un objet 3D de Blender, il faut donc que cet objet soit présent. Sinon cela va déclencher une erreur.
02° Lancer le code suivant qui tente de modifier le texte affiché par un objet Text3D nommé 'MonTexte'. Que constate-t-on ? Ouvrir la console de Blender pour voir l'erreur (menu info - WINDOW - Toggle System Console
# -*-coding:Utf-8 -*
import bpy # On importe la bibliothèque Blender Python
# Récupération de la référence des objets
refCube = bpy.data.objects['Cube']
refTexte = bpy.data.objects['monTexte']
# Modification du texte affiché
refTexte.data.body = "Voici le message à afficher"
# Récupération des coordonnées du cube
x, y, z = refCube.location
# Déplacement éventuel du cube
if x > 0 :
refCube.location = ( -5, y, z )
elif x == 0 :
refCube.location = ( 5, y, z )
else :
refCube.location = ( 0, y, z )
...CORRECTION...
On constate le message suivant :
KeyError: 'bpy_prop_collection[key]: key "MonTexte" not found'
Error: Python script fail, look in the console for now...
Cela veut dire qu'il a cherché dans sa collection d'objets 3D et qu'il n'en a pas trouvé un qui se nomme bien "MonTexte".
03° Revenir temporairement en mode Default, insérer un Text3D avec le menu Create, changer son nom en monTexte à l'aide du menu de droite de l'interface. Si vous ne vous en souvenez plus, les Texts 3D sont sous les objets 3D et sous les Lamps. Lancer à nouveau le code. Comment parvient-on à changer le contenu affiché dans le Text3D ?
...CORRECTION...
Cette fois, cela fonctionne : le programme parvient bien à stocker la référence de l'objet 3D dans la variable refTexte
On change le texte à afficher en allant chercher les données (data) de cet objet et en modifiant l'attribut body contenu dans data. On remarquera la présence des points pour indiquer à chaque fois qu'on chercher quelque chose dans quelque chose :
refTexte.data.body = "Voici le message à afficher"
En français, cela veut dire : va chercher refTexte. Dans refTexte, cherche data. Dans ce data, cherche l'adresse de body.
04° Modifier maintenant le programme pour que le texte 3D affiche si le cube et à droite, à gauche ou au centre.
...CORRECTION...
# -*-coding:Utf-8 -*
import bpy # On importe la bibliothèque Blender Python
# Récupération de la référence des objets 3D
refCube = bpy.data.objects['Cube']
refTexte = bpy.data.objects['monTexte']
# Récupération des coordonnées du cube
x, y, z = refCube.location
# Déplacement éventuel du cube
if x > 0 :
refCube.location = ( -5, y, z )
refTexte.data.body = "à gauche"
elif x == 0 :
refCube.location = ( 5, y, z )
refTexte.data.body = "à droite"
else :
refCube.location = ( 0, y, z )
refTexte.data.body = "au centre"
On peut exécuter plusieurs instructions dans le if ou le elif(else if). Python attend simplement le elif ou else suivant et comprend en attendant qu’il s’agit d’un bloc à exécuter si la condition est validée. On peut même imbriquer un bloc if dans un if.
05° Rajouter un nouveau test IF dans le bloc correspondant au dernier cas : lorsqu'on revient à gauche, on doit augmenter z de 1 si z est positif. Au contraire, on doit diminuer z de 1 si z est négatif ou nulle.
...CORRECTION...
# -*-coding:Utf-8 -*
import bpy # On importe la bibliothèque Blender Python
# Récupération de la référence des objets 3D
refCube = bpy.data.objects['Cube']
refTexte = bpy.data.objects['monTexte']
# Récupération des coordonnées du cube
x, y, z = refCube.location
# Déplacement éventuel du cube
if x > 0 :
if z > 0 :
z = z+1
else :
z = z-1
refCube.location = ( -5, y, z )
refTexte.data.body = "à gauche"
elif x == 0 :
refCube.location = ( 5, y, z )
refTexte.data.body = "à droite"
else :
refCube.location = ( 0, y, z )
refTexte.data.body = "au centre"
Si on analyse le code en terme de blocs imbriqués l'un dans l'autre, on obtient ceci :
if x > 0 :
if z > 0 :
z = z+1
else :
z = z-1
refCube.location = ( -5, y, z )
refTexte.data.body = "à gauche"
elif x == 0 :
refCube.location = ( 5, y, z )
refTexte.data.body = "à droite"
else :
refCube.location = ( 0, y, z )
refTexte.data.body = "au centre"
Il reste à tester des conditions doubles. Rappel : une condition renvoie un booléen qui est true (True en Python, avec un T majuscule) ou false (False en Python, avec un F majuscule).
Voici comment :
On peut tester plusieurs conditions à la fois à l’aide des codages suivants :
TEST LOGIQUE | En Français | En Python |
---|---|---|
and | code ET | A and B : Renvoie True si les deux conditions A et B sont True. |
or | code OU | A or B : Renvoie True si l'une deux conditions au moins est True. |
not | code NON | not(A) : Renvoie True si A == False et renvoie False si A == True. |
06° Trouver l'affichage obtenu pour une note a de 13, de 19 et de 8 à partir du programme ci-dessous.
# -*-coding:Utf-8 -*
import bpy # On importe la bibliothèque Blender Python
# Récupération de la référence des objets 3D
refTexte = bpy.data.objects['monTexte']
a = 17
appreciation = ""
if a>0 :
if (a>10 and a<16) :
appreciation = "C'est pas mal comme note, mais, avoir plus c'est mieux !"
elif a>= 16 :
appreciation = "C'est bien !"
else :
appreciation ="C'est pas bien !"
else :
appreciation = "Le prof a dû se tromper, votre note est négative. Ou alors ..."
refTexte.data.body = appreciation
...CORRECTION...
La note de 13 donne "C'est pas mal comme note.".
La note de 19 donne "C'est bien !".
La note de 8 donne "C'est pas bien !".
En analysant la structure des tabulations :
if a>0 :
if (a>10 and a<16) :
appreciation = "C'est pas mal comme note, mais, avoir plus c'est mieux !"
elif a>= 16 :
appreciation = "C'est bien !"
else :
appreciation ="C'est pas bien !"
else :
appreciation = "Le prof a dû se tromper, votre note est négative. Ou alors ..."
Si on analyse le test ET / AND :
a | b | a and b |
---|---|---|
VRAI | VRAI | VRAI |
FAUX | VRAI | FAUX |
VRAI | FAUX | FAUX |
FAUX | FAUX | FAUX |
Si on analyse le test OU / OR :
a | b | a or b |
---|---|---|
VRAI | VRAI | VRAI |
FAUX | VRAI | VRAI |
VRAI | FAUX | VRAI |
FAUX | FAUX | FAUX |
Chacun de ces tests ne peut donner normalement que deux résultats : True pour vrai ou False pour faux.
On notera la présence d'une majuscule en Python, là où la plupart des langages utilisent true et false.
Si vous voulez plus de précision sur les tests and, or ..., vous pouvez trouver des précision sur ces deux fiches :
Nous avons vu que le code pouvait provoquer une erreur si on tente de trouver la référence d'un objet 3D inexistant. Nous allons maintenant voir comment éviter cela.
La méthode ? Tenter de voir si l'objet est présent. Et s'il n'est pas présent, on le crée.
07° Fermer puis ouvrir Blender. Se mettre en affichage SCRIPTING. Tapez les instructions suivantes dans la console Python de Blender (celle contenant les 3 chevrons >>>) ?
>>> bpy.data.objects
>>> bpy.data.objects.items()
Vous devriez voir apparaitre ceci :
<bpy_collection[3], BlendDataObjects>
[('Camera', bpy.data.objects['Camera']), ('Cube', bpy.data.objects['Cube']), ('Lamp', bpy.data.objects['Lamp'])]
On pourrait écrire la dernière ligne de cette façon pour la rendre plus compréhensible :
[
( 'Camera', bpy.data.objects['Camera'] ),
( 'Cube' , bpy.data.objects['Cube'] ),
( 'Lamp' , bpy.data.objects['Lamp'] )
]
Pourquoi obtient-on cela ? Réponse :
bpy.data.objects
renvoie la collection des objets 3D présents dans l'interface Blender. La console n'affiche malheureusement pas le contenu de cette structure de données.bpy.data.objects.items()
permet d'utiliser la méthode items sur cette collection. On voit alors apparaitre le contenu : des tuples contenant la clé permettant d'accéder à chaque item et l'item correspond :( 'Camera', bpy.data.objects['Camera'] )
( 'Cube' , bpy.data.objects['Cube'] )
( 'Lamp' , bpy.data.objects['Lamp'] )
08° Lire et tester le code ci-dessous. Quelle est la partie du code qui permet de vérifier la présence ou l'absence d'un objet 3D ayant le bon nom ? Que fait le code s'il ne trouve pas d'objet 3D préexistant ?
# -*-coding:Utf-8 -*
import bpy # On importe la bibliothèque Blender Python
# Création ou modification du Texte 3D
if ('Texte_de_position' in bpy.data.objects) :
refTexte = bpy.data.objects['Texte_de_position']
else :
bpy.ops.object.text_add()
refTexte = bpy.context.object
refTexte.name = 'Texte_de_position'
# Récupération du cube et des coordonnées du cube
refCube = bpy.data.objects['Cube']
x, y, z = refCube.location
# Déplacement éventuel du cube
if x > 0 :
if z > 0 :
z = z+1
else :
z = z-1
refCube.location = ( -5, y, z )
refTexte.data.body = "à gauche"
elif x == 0 :
refCube.location = ( 5, y, z )
refTexte.data.body = "à droite"
else :
refCube.location = ( 0, y, z )
refTexte.data.body = "au centre"
...CORRECTION...
On teste la présence d'un objet 3D nommé 'Texte_de_position' avec la ligne suivante :
if ('Texte_de_position' in bpy.data.objects) :
Si la réponse au test suivant est False, on va alors faire les actions décrites dans le else : à savoir :
Création d'un objet Text 3D :
bpy.ops.object.text_add()
On place dans une variable la référence de notre nouveau obket 3D :
refTexte = bpy.context.object
On change le nom de cet objet dans l'interface pour que son nom d'identification soit celui qu'on veut :
refTexte.name = 'Texte_de_position'
Ce n'est pas mal mais on initialise la variable refTexte à deux endroits différents en fonction des cas. Cela peut engendrer des erreurs de codage à terme.
On peut faire mieux avec un simple not qui peut inverser la signification d'un test : un False devient True par exemple.
# -*-coding:Utf-8 -*
import bpy # On importe la bibliothèque Blender Python
# Création ou modification du Texte 3D
if (not('Texte_de_position' in bpy.data.objects)) :
bpy.ops.object.text_add()
refNouveau = bpy.context.object
refNouveau.name = 'Texte_de_position'
refTexte = bpy.data.objects['Texte_de_position']
# Récupération du cube et des coordonnées du cube
refCube = bpy.data.objects['Cube']
x, y, z = refCube.location
# Déplacement éventuel du cube
if x > 0 :
if z > 0 :
z = z+1
else :
z = z-1
refCube.location = ( -5, y, z )
refTexte.data.body = "à gauche"
elif x == 0 :
refCube.location = ( 5, y, z )
refTexte.data.body = "à droite"
else :
refCube.location = ( 0, y, z )
refTexte.data.body = "au centre"
09° Pourquoi n'a-t-on plus besoin de else après le premier test ?
...CORRECTION...
Si l'objet n'existe pas encore, on fait cela :
bpy.ops.object.text_add()
refNouveau = bpy.context.object
refNouveau.name = 'Texte_de_position'
Une fois qu'on passe à la suite, l'objet existe donc nécessairement : soit il existait déjà, soit on vient de le créer. La ligne suivante doit donc normalement trouver un objet portant le bon nom :
refTexte = bpy.data.objects['Texte_de_position']
10° Modifier maintenant le code pour qu'il fonctionne également que le Cube nommé 'Cube' soit présent initialement ou non. S'il n'existe pas, il faudra le créer. Sinon, on utilisera le Cube qui existe déjà.
...CORRECTION...
# -*-coding:Utf-8 -*
import bpy # On importe la bibliothèque Blender Python
# Création ou récupération du Texte 3D
if (not('Texte_de_position' in bpy.data.objects)) :
bpy.ops.object.text_add()
refNouveau = bpy.context.object
refNouveau.name = 'Texte_de_position'
refTexte = bpy.data.objects['Texte_de_position']
# Création ou récupération du cube et des coordonnées du cube
if (not('Cube' in bpy.data.objects)) :
bpy.ops.mesh.primitive_cube_add()
refNouveau = bpy.context.object
refNouveau.name = 'Cube'
refCube = bpy.data.objects['Cube']
x, y, z = refCube.location
# Déplacement éventuel du cube
if x > 0 :
if z > 0 :
z = z+1
else :
z = z-1
refCube.location = ( -5, y, z )
refTexte.data.body = "à gauche"
elif x == 0 :
refCube.location = ( 5, y, z )
refTexte.data.body = "à droite"
else :
refCube.location = ( 0, y, z )
refTexte.data.body = "au centre"
Il nous reste à écrire ce code de façon à regrouper ensemble les codes similaires : voici donc le même code mais j'ai regroupé les deux créations éventuels au début.
# -*-coding:Utf-8 -*
import bpy # On importe la bibliothèque Blender Python
# Créations éventuelles des objets 3D ayant le bon nom
if (not('Texte_de_position' in bpy.data.objects)) :
bpy.ops.object.text_add()
refNouveau = bpy.context.object
refNouveau.name = 'Texte_de_position'
if (not('Cube' in bpy.data.objects)) :
bpy.ops.mesh.primitive_cube_add()
refNouveau = bpy.context.object
refNouveau.name = 'Cube'
# Récupération des références du texte et du cube et des coordonnées du cube
refTexte = bpy.data.objects['Texte_de_position']
refCube = bpy.data.objects['Cube']
x, y, z = refCube.location
# Déplacement éventuel du cube
if x > 0 :
if z > 0 :
z = z+1
else :
z = z-1
refCube.location = ( -5, y, z )
refTexte.data.body = "à gauche"
elif x == 0 :
refCube.location = ( 5, y, z )
refTexte.data.body = "à droite"
else :
refCube.location = ( 0, y, z )
refTexte.data.body = "au centre"
Il s'agit d'une structure que nous allons recontrer souvent dans les scripts pour Blender :
Nous venons de voir la collection des objets 3D.
Dans l'activité précédente, nous avons vu comment gérer les matériaux. Et bien, on peut également récupérer la collection des matériaux déjà créés :
if (not('Nom_du_materiau' in bpy.data.materials)) :
Ce simple test permet de savoir si le matériau est déja existant.
Tentons donc une dernière chose : nous voudrions que le cube possède un matériau "couleur" qu'on pourrait changer au fil des clics :
11° Utilisez le code ci-dessous pour parvenir à rendre le cube de plus en plus rouge au fur et à mesure des clics sur le script.
# -*-coding:Utf-8 -*
import bpy # On importe la bibliothèque Blender Python
# Créations éventuelles du material et des objets 3D ayant le bon nom
if (not('couleur' in bpy.data.materials)) :
bpy.data.materials.new( 'couleur' )
bpy.data.materials['couleur'].diffuse_color = (0.2, 0.2, 0.2)
if (not('Texte_de_position' in bpy.data.objects)) :
bpy.ops.object.text_add()
refNouveau = bpy.context.object
refNouveau.name = 'Texte_de_position'
if (not('Cube' in bpy.data.objects)) :
bpy.ops.mesh.primitive_cube_add()
refNouveau = bpy.context.object
refNouveau.name = 'Cube'
# Récupération des références du texte et du cube et des coordonnées du cube
refTexte = bpy.data.objects['Texte_de_position']
refCube = bpy.data.objects['Cube']
refMaterial = bpy.data.materials['couleur']
refCube.active_material = refMaterial
x, y, z = refCube.location
# Déplacement éventuel du cube
if x > 0 :
if z > 0 :
z = z+1
else :
z = z-1
refCube.location = ( -5, y, z )
refTexte.data.body = "à gauche"
elif x == 0 :
refCube.location = ( 5, y, z )
refTexte.data.body = "à droite"
else :
refCube.location = ( 0, y, z )
refTexte.data.body = "au centre"
Pour parvenir à modifier les couleurs RGB, il faudra donc un code du style :
refMaterial.diffuse_color = (r, g, b)
...CORRECTION...
# -*-coding:Utf-8 -*
import bpy # On importe la bibliothèque Blender Python
# Créations éventuelles du material et des objets 3D ayant le bon nom
if (not('couleur' in bpy.data.materials)) :
bpy.data.materials.new( 'couleur' )
bpy.data.materials['couleur'].diffuse_color = (0.2, 0.2, 0.2)
if (not('Texte_de_position' in bpy.data.objects)) :
bpy.ops.object.text_add()
refNouveau = bpy.context.object
refNouveau.name = 'Texte_de_position'
if (not('Cube' in bpy.data.objects)) :
bpy.ops.mesh.primitive_cube_add()
refNouveau = bpy.context.object
refNouveau.name = 'Cube'
# Récupération des références du texte et du cube et des coordonnées du cube
refTexte = bpy.data.objects['Texte_de_position']
refCube = bpy.data.objects['Cube']
refMaterial = bpy.data.materials['couleur']
refCube.active_material = refMaterial
x, y, z = refCube.location
# Récupération des couleurs du material
r, g, b = refMaterial.diffuse_color
r = r+0.1
g = g-0.1
b = b-0.1
if r > 1 :
r = 1
if g < 0 :
g = 0
if b < 0 :
b = 0
refMaterial.diffuse_color = ( r, g, b )
# Déplacement éventuel du cube
if x > 0 :
if z > 0 :
z = z+1
else :
z = z-1
refCube.location = ( -5, y, z )
refTexte.data.body = "à gauche"
elif x == 0 :
refCube.location = ( 5, y, z )
refTexte.data.body = "à droite"
else :
refCube.location = ( 0, y, z )
refTexte.data.body = "au centre"
On peut même aller plus loin : on peut utiliser le module random pour créer des nombres aléatoires :
random.randint(20,80)
va fournir un nombre entier aléatoire entre 20 inclus et 80 inclus.random.randrange(20,80,10)
fait de même mais uniquement pour 20, 30, 40, 50, 60, 70 et 80.random.choice(liste)
choisit un élément de la liste, par exemple liste = ['red','green','blue','yellow']
.Ce module n'est pas propre à Blender, c'est un module basique de Python.
Il faudra par contre penser à l'importer en début de code, comme pour le module bpy.
import bpy
import random
12° Modifier une dernière fois le programme : à chaque fois qu'on le lance, il doit bouger aléatoirement le cube sur des coordonnées variant de -5 à +5 et changer aléatoirement les couleurs RGB entre 0 et 1.
...CORRECTION...
# -*-coding:Utf-8 -*
import bpy # On importe la bibliothèque Blender Python
import random
# Créations éventuelles du material et des objets 3D ayant le bon nom
if (not('couleur' in bpy.data.materials)) :
bpy.data.materials.new( 'couleur' )
bpy.data.materials['couleur'].diffuse_color = (0.2, 0.2, 0.2)
if (not('Texte_de_position' in bpy.data.objects)) :
bpy.ops.object.text_add()
refNouveau = bpy.context.object
refNouveau.name = 'Texte_de_position'
if (not('Cube' in bpy.data.objects)) :
bpy.ops.mesh.primitive_cube_add()
refNouveau = bpy.context.object
refNouveau.name = 'Cube'
# Récupération des références du texte et du cube et des coordonnées du cube
refTexte = bpy.data.objects['Texte_de_position']
refCube = bpy.data.objects['Cube']
refMaterial = bpy.data.materials['couleur']
refCube.active_material = refMaterial
# Récupération des couleurs du material
r = (random.randint(0,100))/100
g = (random.randint(0,100))/100
b = (random.randint(0,100))/100
refMaterial.diffuse_color = ( r, g, b )
# Déplacement éventuel du cube
x = (random.randint(-50,50))/10
y = (random.randint(-50,50))/10
z = (random.randint(-50,50))/10
refCube.location = ( x, y, z )
Regardons maintenant comment Blender gère les nouveaux objets : comment se nomme par défaut les objets qu'on crée les uns à la suite des autres ? Imaginons qu'on crée un Cube. Blender le note 'Cube'. Ok. Mais les autres ?
# -*-coding:Utf-8 -*
import bpy # On importe la bibliothèque Blender Python
import random
# Créations éventuelles du material et des objets 3D ayant le bon nom
for x in range(20) :
bpy.ops.mesh.primitive_cube_add()
refNouveau = bpy.context.object
x = (random.randint(-50,50))/10
y = (random.randint(-50,50))/10
z = (random.randint(-50,50))/10
refNouveau.location = ( x, y, z )
13° Lancer le code. Vous devriez obtenir 20 cubes repartis au hasard sur la zone centrale.
14° Observez les noms des cubes dans l'interface. Les cubes portent-ils par défaut le même nom.
...CORRECTION...
On peut voir ceci dans l'interface ou en utilisant la méthode items sur la collection des objets :
>>> bpy.data.objects.items()
Comme vous pouvez le voir, on a le droit de créer des objets qui portent déjà le nom d'un objet créé : Blender va donc rajouter .001 puis .002 ect ...
C'est ue problème à gérer avec Blender : on peut lui demander de créer un objet qui porte le nom d'un objet déjà existant. Il va rajouter une indication au nom en rajoutant un point et une suite de 3 chiffres.
Avec l'exemple des 20 cubes, on obtient donc :
[('Camera', bpy.data.objects['Camera']), ('Cube', bpy.data.objects['Cube']), ('Cube.001',
bpy.data.objects['Cube.001']), ('Cube.002', bpy.data.objects['Cube.002']), ('Cube.003',
bpy.data.objects['Cube.003']), ('Cube.004', bpy.data.objects['Cube.004']), ('Cube.005',
bpy.data.objects['Cube.005']), ('Cube.006', bpy.data.objects['Cube.006']), ('Cube.007',
bpy.data.objects['Cube.007']), ('Cube.008', bpy.data.objects['Cube.008']), ('Cube.009',
bpy.data.objects['Cube.009']), ('Cube.010', bpy.data.objects['Cube.010']), ('Cube.011',
bpy.data.objects['Cube.011']), ('Cube.012', bpy.data.objects['Cube.012']), ('Cube.013',
bpy.data.objects['Cube.013']), ('Cube.014', bpy.data.objects['Cube.014']), ('Cube.015',
bpy.data.objects['Cube.015']), ('Cube.016', bpy.data.objects['Cube.016']), ('Cube.017',
bpy.data.objects['Cube.017']), ('Cube.018', bpy.data.objects['Cube.018']), ('Cube.019',
bpy.data.objects['Cube.019']), ('Lamp', bpy.data.objects['Lamp']), ('Texte_de_position',
bpy.data.objects['Texte_de_position'])]
15° Renommer plusieurs cubes à l'aide de l'interface (double clic sur le nom dans la fenêtre de droite). Utilisez par exemple le nom TOTO. Conclusion ?
Il faudra donc vraiment faire attention à cela : avant de vouloir changer le nom d'un objet, vérifier que le nom n'est pas déjà pris. Pourquoi ? Sinon, votre objet va s'appeller toto.001 par exemple. Et vous aurez beau agir sur toto, et bien votre objet toto.001 ne bougera pas d'un poil... C'est frustrant de ne pas comprendre pourquoi votre beau code ne fonctionne pas alors que tout à l'air d'être correct.
Comme nous l'avons vu, il est génant de vouloir renommer un nouvel objet sans être certain qu'il n'existe pas encore d'objet qui porte ce même nom.
Nous allons donc voir comment supprimer l'ancien objet avant de renommer un nouvel objet qui porte le même nom.
Pour cela, nous allons aller récupérer la référence de la collection des objets et appliquer sur celle-ci la méthode remove :
# -*-coding:Utf-8 -*
import bpy # On importe la bibliothèque Blender Python
# Récupération et stockage de la référence de la collection des objets
objets = bpy.data.objects
# Récupération et stockage de la référence de l'objet à supprimer
refCube = bpy.data.objects['Cube']
# Destruction de l'objet Blender refCube présent dans la collection objets
objets.remove( refCube, True)
16° Créer un cube nommé Cube dans Blender et lancer le script. Normalement, il disparait.
Bien entendu, vous n'êtes pas obligé de tout décomposer si vous n'avez que ce cube à faire disparaitre.
# -*-coding:Utf-8 -*
import bpy # On importe la bibliothèque Blender Python
# Destruction de l'objet Blender 'Cube' présent dans la collection des objets
bpy.data.objects.remove( bpy.data.objects['Cube'], True)
17° Tester ce dernier code.
18 - EVALUATION° Réaliser un code qui cherche à déterminer si un objet 'Cube' existe dans l'interface. En cas de réponse positive, faire supprimer l'objet via le code Python.