Infoforall

BLENDER PYTHON - 05 - Test IF

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çaisCodage Python
SI on peut encore aller à droite alorsif (x < xmax) :
    Autoriser le déplacement à droite    Autoriser_droite()
SINON SI on peut encore aller à gauche alorselif (x > xmin) :
    Autoriser le déplacement à gauche    Autoriser_gauche()
Fin du test


X actuelle = 250
X minimale = 150
X maximale = 350
avec un test X > XMIN valant
avec un test X < XMAX valant

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.

A = 50
B = 50
Symbole du testSignificationExempleResultat du test
==Est égal àA == B?
!=Est différent deA != 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.

1 - Test logique IF

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 :

Le Si

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çaisCodage Python
SI la première condition est vraie alorsif condition_1 :
    Fait les actions 1    Instructions_1
SINON SI la deuxième condition est vraie alorselif (condition_2) :
    Fait les actions 2    Instructions_2
SINONelse :
    Fait les actions 3    Instructions_3
Fin du testRien 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 LOGIQUEEn FrançaisEn Python
andcode ETA and B : Renvoie True si les deux conditions A et B sont True.
orcode OUA or B : Renvoie True si l'une deux conditions au moins est True.
notcode NONnot(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.

2 - Les collections d'objets et de matériaux

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 :

( '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"

3 - Module Random

On peut même aller plus loin : on peut utiliser le module random pour créer des nombres aléatoires :

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 )

4 - Créer avec un même nom

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.

5 -Destruction

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.