python API Blender

Identification

Infoforall

42 - Les API dont Blender


Après avoir vu les modules et vu qu'on pouvait y placer des fonctions utilisables de l'extérieur, les fonctions d'interface, nous allons voir aujourd'hui un dernier type d'interface.

Si on résume, nous avons vu sur deux ans :

  • Les interfaces graphiques (turtle, tkinter, Qt...) ou textuelles (console) : des programmes qui permettent de faire communiquer un utilisateur humain et un programme
  • Type d'interfaçage : HUMAIN - PROGRAMME

  • L'interface des structures de donnnées : un ensemble de fonctions qui permet de manipuler des données sans avoir à réfléchir à la façon dont elles sont implémentées concrétement et qui permettent donc à un programme de manipuler des données sans connaître leurs implémentation.
  • Interface et encapsulation

    Type d'interfaçage : PROGRAMME - DONNEES

  • L'interface de la programmation orientée objet, composée des méthodes accessibles par un utilisateur de l'objet (les accesseurs pour lire et les mutateurs pour modifier). Elle permet donc de faire communiquer le programme avec des données et fonctions encapsulées dans l'objet. C'est donc la même chose qu'au dessus.
  • Type d'interfaçage : PROGRAMME - DONNEES

  • L'interface d'un module composée des fonctions d'interface, utilisables par un utilisateur extérieur au module. Dans le cas de Python, elles permettent donc de faire communiquer un programme en Python avec un autre programme en Python.
  • Type d'interfaçage : PROGRAMME PYTHON - PROGRAMME PYTHON

Nous allons voir aujourd'hui qu'il existe une possibilité d'interfacage entre programme encore plus grande.

Principe de l'interfaçage programme-programme API

Type d'interfaçage : APPLICATION (ensemble de programmes) - APPLICATION

Prérequis : les cours parlant des notions précédentes et pour parvenir à utiliser Blender Python :

  • Notions sur les objets (attributs, méthodes)
  • Notions sur les modules
  • Les dictionnaires Python

Logiciel nécessaire pour l'activité : Blender 2.9 ou plus

Evaluation ✎ :

1 - Qu'est-ce qu'une API

API est un acronyme pour interface de programmation d’application. En Anglais, cela veut dire Application Programming Interface.

Il s'agit donc d'un programme (autonome ou pas) qui permet l'utilisation de ces fonctionnalités à travers l'utilisation d'un autre programme.

Parmi les API les plus connues du moment :

  • Azure API de Microsoft : une large offre d'applications disponibles notamment via des interfaces Web. Beaucoup d'entreprises fonctionnent maintenant avec ce type de ressources applicatives disponibles dans le "Cloud". Elles utilisent ainsi les serveurs de Microsoft pour stocker leurs données mais également pour faire tourner leurs logiciels...
  • Graph API de Facebook : cette interface permet d'exporter (un peu) des données de Facebook et surtout d'en importer automatiquement à travers une librairie Python.
  • Google Maps API de Google : permet de facilement réaliser des sites Web ou des applications sur smartphones utilisant ce service de cartographie. On peut interagir facilement avec ce service à l'aide de Javascript.
  • Les API de gestion de Salesforce : peu connue du grand public, cette société californienne est l'un des précurseurs des solutions en Cloud Computing, c'est à dire en louant des machines faisant tourner un service et non pas utiliser les propres machines de l'entreprise.
  • et bien d'autres services...
API

Interfaçage entre une APPLICATION CLIENT et une APPLICATION qui "offre" le service

Le verbe "offre" est entre guillemets car beaucoup d'API sont payantes. Il s'agit d'un service. Par exemple, beaucoup de sociétés utilisent des API de Google Map ou ViaMichelin pour obtenir automatiquement des itinéaires et pouvoir facturer les choses en chose de la distance. Sinon, il faudrait payer un humain pour le faire.

Lorsqu'un logiciel offre une API permettant de l'utiliser depuis l'extérieur, on dit que le logiciel expose une API.

D'ailleurs, on peut presque voir un système d'exploitation comme une sorte particulière d'API puisque les applications communiquent avec le système matériel à travers les fonctions d'interface de l'OS !

L'interface peut être

  • une interaction Web permettant de recevoir des requêtes HTTP et de renvoyer des réponses HTTP ou
  • une interaction logicielle offerte par un module Python par exemple.

2 - API Blender

Blender 3D est un logiciel libre (le code source est accessible à tous) et gratuit, réalisé par une communauté de d'informaticiens passionnés.

Logo Blender

Il permet de réaliser des scènes 3D pour ensuite réaliser des images 3D, des animations 3D ou même des jeux interactifs 3D.

Il s'agit d'un logiciel possédant des boutons, des menus et on peut créer des scènes sans toucher la moindre ligne de code. Comme un traitement de texte, un tableur ou un logiciel permettant de créer des présentations.

01° Aller sur la courte activité proposée ci-dessous si vous ne connaissez pas Blender 3D (en version 2.80+) puis revenir ici une fois que vous avez pris l'interface graphique en main. Ne faites pas la dernière question qui vous demande de réaliser une petite scène 3D.

Vers l'activité découverte de Blender

En quoi est-ce une API ?

Le logiciel Blender 3D intègre des fonctions d'interface permettant à Python d'interagir avec lui : on peut donc profiter des fonctionnalités du logiciel, sans passer par l'interface utilisateur mais uniquement en le contrôlant avec un script Python.

Principe de l'interfaçage programme-programme

Qu'allons nous faire aujourd'hui :

  1. Créer des objets avec le script
  2. Les déplacer, les modifier avec un script
  3. Modifier le placement de la caméra et l'intensité des lumières avec un script
  4. Enregistrer l'image... avec un scipt

Vous allez ainsi voir qu'on pourra créer une image 3D avec Blender 3D en passant par un simple programme python et sans utiliser réellement l'interface graphique de Blender.

Nous pourrions même ne pas ouvrir Blender 3D du tout. Mais cela demande d'intervenir dans divers fichiers de configuration : il faut dire à Python où se trouve le programme Blender par exemple. Aujourd'hui, nous allons directement placer le code Python dans un menu de Blender fait pour cela, c'est plus simple et cela vous demandera moins de configuration si vous voulez le faire chez vous.

3 - Module Blender Python

02° Ouvrir Blender 3D pour obtenir la scène de base : un unique cube au milieu de la scène. Cliquer sur scripting.

Localisation du scripting : au bout de la ligne du menu principal

Vous obtenez alors un écran correspondant à la vue adaptée au mode script Python de Blender :

La vue scripting

Vous devriez visualiser un message d'accueil de ce style dans la console Python de Blender :

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). Du coup, il n'est pas utile de taper import bpy dans cette console. Nous le ferons néanmoins pour prendre l'habitude de l'importer.

bpy

Que veut dire bpy ? Tout simplement Blender PYthon.

Il s'agit d'un module Python permettant d'interagir avec l'API de Blender en utilisant un code Python.

03° Faire disparaitre le cube de départ (click gauche puis touche Supprimer) PUIS taper ceci dans la console :

>>> import bpy >>> bpy.ops.mesh.primitive_cube_add()

Vous devriez constater qu'un nouveau cube vient d'apparaitre juste sur le curseur 3D.

04° Placer le curseur de la souris dans la vue 3D et appuyer sur la touche  T  du clavier pour faire apparaître les outils (Tools).

Utiliser l'outil Déplacer (le bouton avec les 4 flèches) pour déplacer le cube nouvellement créé.

Déplacement du cube

05° Utiliser l'outil Curseur 3D (le bouton avec le cercle) pour déplacer le curseur ailleurs qu'au milieu de l'écran.

Taper ensuite ceci dans la console Blender Python :

>>> import bpy >>> bpy.ops.mesh.primitive_cube_add(size=1.0)
Deux cubes

Comment obtenir de la documentation sur les fonctions d'interface disponibles via la bibliothèque bpy ?

Le plus simple est encore d'aller voir en ligne : Vers la documentation de API Blender Python

On trouve ceci :

Documentation sur primitive_cube_add
bpy.ops.mesh.primitive_cube_add(size=2.0, calc_uvs=True, enter_editmode=False, align='WORLD', location=(0.0, 0.0, 0.0), rotation=(0.0, 0.0, 0.0)) Construct a cube mesh Parameters size (float in [0, inf], (optional)) – Size calc_uvs (boolean, (optional)) – Generate UVs, Generate a default UV map enter_editmode (boolean, (optional)) – Enter Editmode, Enter editmode when adding this object align (enum in ['WORLD', 'VIEW', 'CURSOR'], (optional)) – Align, The alignment of the new object WORLD World, Align the new object to the world. VIEW View, Align the new object to the view. CURSOR 3D Cursor, Use the 3D cursor orientation for the new object. location (float array of 3 items in [-inf, inf], (optional)) – Location, Location for the newly added object rotation (float array of 3 items in [-inf, inf], (optional)) – Rotation, Rotation for the newly added object

On voit bien que size est un paramètre optionnel : sa valeur par défaut est de 2.0. C'est pour celà que le premier cube était plus gros.

06° Avec cette documentation, créer un nouveau cube de taille 4.0 situé aux coordonnées x = 4.0, y = 2.0 et z = -1.0.

Gros cube

...CORRECTION...

>>> bpy.ops.mesh.primitive_cube_add(size=4.0, location=[4.0, 2.0, -1.0]) {'FINISHED'}

07° La fonction renvoie-t-elle visiblement la réference-mémoire permettant d'agir sur notre nouvel objet ?

Gros cube

...CORRECTION...

>>> bpy.ops.mesh.primitive_cube_add(size=4.0, location=[4.0, 2.0, -1.0]) {'FINISHED'}

On voit bien que la fonction ne renvoie pas un dictionnaire : la clé n'est pas associée à une valeur.

Il s'agit d'un type nommé set, comme ensemble. C'est une sorte de list mais où on ne peut pas placer deux fois le même élément.

>>> {5,5} {5}

Je ne parlerai plus de set ensuite : pas au programme de NSI. On se débrouille très bien avec les types que vous connaissez déjà.

Comment faire alors pour mémoriser la référence d'un objet qu'on vient de créer et parvenir à le modifier ensuite ?

Créer, mémoriser et modifier un objet 3D avec Blender

On peut récupérer la référence de l'objet actuellement sélectionné à l'écran en utilisant ceci :

>>> objet3D = bpy.context.object >>> type(objet3D) <class 'bpy_types.Object'> >>> objet3D bpy.data.objects['Cube.002']

On constate qu'on parvient bien à récupérer la référence d'un objet dont la classe est visiblement Object (c'est certainement une vraie instance d'une classe POO puisqu'il y a une majuscule).

Vous allez donc pouvoir placer cette référence dans une variable ou le stocker comme élément d'un type construit (liste-tableau, liste chainée, dictionnaire, tuple...).

Et une fois qu'on a la référence-mémoire, nous pouvons agir sur l'objet !

Déplacer un objet

Il suffit pour cela d'agir sur l'"attribut" location et de lui fournir un nouveau tableau.

>>> bpy.ops.mesh.primitive_cube_add() {'FINISHED'} >>> objet3D = bpy.context.object >>> objet3D.location = [0.0, 4.0, 0.0]

Avec ce code, on parvient à placer l'objet en x=0, y=4 et z=0.

Déplacer

Modifier la taille d'un objet

Le paramètre size est uniquement le nom du paramètre optionnel qu'on peut fournir au Constructeur.

Pour modifier la taille en x, y ou z, il faut agir sur l'"attribut" dimensions et de lui fournir un nouveau tableau.

>>> objet3D.dimensions = [0.5, 2.0, 8.0]

Avec ce code, on parvient à créer une sorte de poutre.

Taille

Modifier l'inclinaison d'un objet

C'est plus délicat : on peut faire tourner l'objet selon les trois axes !

On peut créer une rotation autour de l'axe X ou autour de l'axe Y ou autour de l'axe Z.

Ou autour des trois puisqu'on doit fournir un tableau contenant l'angle de rotation sur l'axe X, l'angle de rotation sur l'axe Y et l'angle de rotation sur l'axe Z.

Le paramètre size est uniquement le nom du paramètre optionnel qu'on peut fournir au Constructeur.

Pour modifier la taille en x, y ou z, il faut agir sur l'"attribut" rotation_euler et de lui fournir un nouveau tableau des angles. Problème : on doit fournir les angles en radians et pas en degrés.

Imaginons qu'on veuille créer une rotation de 90° sur l'axe X, avec ce code cela ne fonctionne pas car on donne 90 en croyant qu'on attend des degrés :

>>> objet3D.rotation_euler = [90, 0, 0]

On voit clairement que l'angle n'est pas bon.

Rotation

Il faut donc convertir les angles en degrés en radians. Pour cela, il faut bien entendu soit connaître la conversion, soit utiliser les outils du module math.

Comme nous ne sommes pas là pour avoir les résultats précis, nous allons faire simple : l'angle en radians vaut l'angle en degrés divisé par 180 et multiplié par PI (on prendra 3.14 et ça ira bien).

>>> angleX = 90/180*3.14 >>> objet3D.rotation_euler = [angleX, 0, 0]
Rotation 90°

Ou pour une rotation à 45° :

>>> angleX = 45 / 180 *3.14 >>> objet3D.rotation_euler = [angleX, 0, 0]
Rotation 45°

08° Utiliser la documentation ci-dessus pour manipuler correctement un "Cube" qu'il faudra déplacer, déformer et faire tourner.

09° Lire la documentation de Blender API et dessiner des sphères, des cones....

En ligne : Vers la documentation de API Blender Python

4 - Programme

Lorsqu'on veut réalise un programme et pas taper les instructions en direct via la console, on peut soit créer un script externe (mais il faut configurer correctement la machine pour que Python trouve Blender, ça peut être pénible) ou alors directement travailler dans l'éditeur de code de Blender 3D.

La vue scripting

10° Dans la zone de droite, créer un nouveau script avec le bouton NOUVEAU au haut et au milieu de la vue EDITEUR DE CODE.

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
import bpy def supprimer_anciens(): for cle in bpy.data.meshes.keys(): try: bpy.data.objects.remove(bpy.data.objects[cle]) except: pass supprimer_anciens() cubes = [None for x in range(5)] for x in range(5): bpy.ops.mesh.primitive_cube_add() cube3D = bpy.context.object cube3D.location = [0, x*2, 0] cube3D.dimensions = [1,1,x] cubes[x] = cube3D

On obtient ici un tableau qui contient tous les "Cubes" qui ont été ajoutés. Vous pourriez donc encore agir dessus.

11° Lancer le script en utilisant la flèche.

Je vous laisse vous amuser. Il reste bien entendu beaucoup de choses à voir :

  • Comment gérer les lumières et les caméras
  • Comment gérer les couleurs des objets
  • Comment enregistrer une image 3D
  • Comment créer une animation

Tout ceci est possible avec un simple script Python. Mais en 1h, vous avez déjà vu pas mal de choses.

Une image scriptée parmi tant d'autres :

Image créée par script

Une vidéo scriptée parmi tant d'autres :

5 - Les autres actions

A faire : il faut que je mette à jour mes tutos Blender Python : entre la versino 2.79 et 2.80 beaucoup de choses ont été modifié malheureusement.

En attendant : vers d'autres connaissances

6 - FAQ

Blender API ne permet pas d'accéder directement aux objets et autres éléments ?

Si, mais l'API stocke les éléments dans une structure de données que vous n'avez pas encore vu : la collection. C'est une sorte de dictionnaire où on peut accéder aux éléments à l'aide d'une clé ET aussi à l'aide d'un numéro d'index. C'est donc une sorte de mélange de listes et de dictionnaires.

>>> objet3D = bpy.context.object >>> type(objet3D) <class 'bpy_types.Object'> >>> objet3D bpy.data.objects['Cube.002']

On constate qu'on parvient bien à récupérer la référence d'un objet dont la classe est visiblement Object (c'est certainement une vraie instance d'une classe POO puisqu'il y a une majuscule).

Si on demande à visualiser le contenu de cette variable, on voit que l'API renvoie une information claire (une fois qu'on sait la lire) : la référence de l'objet est stockée dans une collection nommée objects et on peut y accéder à l'aide de la clé 'Cube.002'.

Tout comme set, les Collections ne sont pas au programme. Il s'agit d'une sorte de mélange entre dictionnaire et tableau. On peut accéder aux éléments à l'aide d'une clé mais on peut aussi itérer sur leurs positions indexées.

>>> for objet in bpy.data.objects : objet ... bpy.data.objects['Camera'] bpy.data.objects['Cube'] bpy.data.objects['Cube.001'] bpy.data.objects['Cube.002'] bpy.data.objects['Light']

On peut accéder à la référence-mémoire de la caméra de deux façons :

>>> bpy.data.objects[0] bpy.data.objects['Camera'] >>> bpy.data.objects['Camera'] bpy.data.objects['Camera']