Outils pour utilisateurs

Outils du site


blender

Différences

Ci-dessous, les différences entre deux révisions de la page.

Lien vers cette vue comparative

Les deux révisions précédentes Révision précédente
Prochaine révision
Révision précédente
blender [2017/10/20 15:05]
jcombier
blender [2017/12/15 15:50] (Version actuelle)
jcombier
Ligne 121: Ligne 121:
  
 =====Rendu depuis un script python==== =====Rendu depuis un script python====
 +Les commandes pythons correspondantes aux actions en cours dans la GUI sont affichées dans la console python intégrée: https://​www.youtube.com/​watch?​v=K0yb4sZ7B4g
 +
 +
 +https://​wiki.blender.org/​index.php/​Doc:​FR/​2.4/​Manual/​Extensions/​Python/​Example
 +
 +Exemple de rendu avec caméra fisheye: https://​blender.stackexchange.com/​questions/​32848/​script-for-rendering-a-simple-scene
 +====Execution d'un script====
 +
 Utiliser l’interpréteur python intégré à blender depuis la ligne de commande Utiliser l’interpréteur python intégré à blender depuis la ligne de commande
  
Ligne 203: Ligne 211:
 [[https://​blender.stackexchange.com/​questions/​5820/​how-is-cycles-different-from-blender-internal]] [[https://​blender.stackexchange.com/​questions/​5820/​how-is-cycles-different-from-blender-internal]]
   ​   ​
-Notions à connaître : ray-tracing et anti-aliasing +Notions à connaître : ray-tracing et anti-aliasing ​(cours) ​:
-Cours :+
  
 [[https://​www.cs.cmu.edu/​afs/​cs/​academic/​class/​15462-s09/​www/​lec/​13/​lec13.pdf]] [[https://​www.cs.cmu.edu/​afs/​cs/​academic/​class/​15462-s09/​www/​lec/​13/​lec13.pdf]]
Ligne 555: Ligne 562:
 sys.exit(0) sys.exit(0)
 </​file>​ </​file>​
 +
 +
 +==== Ajout de modules python externes ====
 +Blender est livré avec son propre python. On le trouve à l'​emplacement suivant : "​chemin_vers_le_dossier_blender/​blender-2.79-linux-glibc219-x86_64/​2.79/​python/​lib/​python3.5/"​. Votre version de blender (ici 2.79) et de python (ici 3.5) sera à adapter à votre configuration. On retrouve à l'​emplacement "​python3.5/​site-packages"​ les modules "​numpy"​ et "​requests"​ déjà présent dans blender.
 +
 +Pour importer de nouveaux modules dans mes scripts, j'ai appliqué la solution suivante :
 +  * faire en sorte que la version de python installé et celle de blender coïncide. Télécharger la dernière version de blender dont le python intégré a la bonne version.
 +  * télécharger les modules voulus sur le python3 installé dans /usr/local/ (l'​adresse dépend de votre installation)
 +  * ajouter dans le script python les chemins vers les modules externes recherchés : sys.path.append('/​usr/​local/​lib/​python3.5/​site-packages/'​) et sys.path.append('/​usr/​local/​lib/​python3.5/​lib-dynload/'​) pour tkinter utilisé par matplotlib. Les chemins doivent être ajouté avant d'​inclure les modules avec "​import"​.
 +  * ajouter sys.path.append('​chemin_vers_le_dossier_contenant_le_script'​) et lancer la commande ./​chemin_vers_blender/​blender -P mon_script.py,​ si le script n'est pas à emplacement de l'​exécutable python
 +
 +Si la version de numpy de blender ne coïncide pas avec celle utilisée par les modules externes, renommez le numpy de blender (par exemple en '​numpy_1.10.1'​). Le script utilisera alors le numpy installé dans /​usr/​local/​.
 +
 +Pour voir la version de numpy, entrer dans la console python :
 +  >>>​ import numpy
 +  >>>​ numpy.version.version
 +
 +
 +=====Animation modèle de visage=====
 +
 +charger la scène Swirski-EyeModel.blend
 +
 +Mode d'​affichage default
 +
 +Développer l'​arbre Armature Head->​the rig->​Pose_head.002->​eyetargetparent
 +
 +à droite, choisir mode Bone (OS)
 +
 +en bas, chosir Pose Mode
 +
 +à droite dans  transform->​Location,​ changer x,y,z pour spécifier la cible visée par l'oeil
 +
 +passer en mode scripting
 +
 +recliquer sur Bone et changer ​ transform->​Location,​ la commande python correspondante apparait dans la console:
 +  bpy.context.object.pose.bones["​eyetargetparent"​].location[0] = -0.113456
 +
 +bpy.context dépend de l'​objet actuellement selectionné dans la GUI, pour modifier dans le script, il faut retrouver dans l'​arborescence de la scene (s'​aider de l'auto complétion avec CTRL+SPACE)
 +  scene = bpy.context.scene
 +  armature = bpy.data.objects['​Armature Head']
 +  armature.pose.bones['​eyetargetparent'​].location[0] = -0.113456
 +
 +
 +  ./​blender-2.74-linux-glibc211-x86_64/​blender --python ./​Swirski-EyeModel.py -b
 +
 +<file python Swirski-EyeModel.py>​
 +import bpy
 +import math
 +import mathutils
 +import os
 +import sys
 +import numpy as np
 +#lancer avec  ./​blender-2.74-linux-glibc211-x86_64/​blender --python ./​Swirski-EyeModel.py -b 
 +
 +
 +
 +#****** CREATE DIRECTORY WHERE TO SAVE IMAGES ***********
 +img_dir = '/​tmp/​images/'​
 +if not os.path.exists(img_dir):​
 +    os.makedirs(img_dir)
 +
 +
 +
 +bpy.ops.wm.open_mainfile(filepath="/​media/​HD500GO/​blender/​Swirski-EyeModel.blend"​)
 +
 +scene = bpy.context.scene
 +armature = bpy.data.objects['​Armature Head']
 +camera_obj = bpy.data.objects['​Camera'​]
 +camera = bpy.data.cameras['​Camera'​]
 +
 +eyeL = bpy.data.objects['​eye.L'​]
 +pupilGroup = eyeL.vertex_groups['​eyepulpex.L'​]
 +pupilVertices = [v for v in eyeL.data.vertices if pupilGroup.index in [g.group for g in v.groups]]
 +
 +pupil_base_radius = max((v1.co - v2.co).length for v1 in pupilVertices for v2 in pupilVertices) * eyeL.scale[1]
 +
 +eyeLbone = armature.pose.bones['​def_eye.L'​]
 +pupilLbone = armature.pose.bones['​eyepulpex.L'​]
 +
 +def strVec(vec):​
 +    return "​({},​{},​{})"​.format(vec[0],​ vec[1], vec[2])
 +
 +datafilepath = os.path.join(os.path.dirname(bpy.data.filepath),​ "​render_eye_data.txt"​)
 +
 +
 +
 +# switch on nodes
 +scene.use_nodes = True
 +tree = scene.node_tree
 +links = tree.links
 + 
 +# clear default nodes
 +for n in tree.nodes:
 +    tree.nodes.remove(n)
 + 
 +# create input render layer node
 +rl = tree.nodes.new('​CompositorNodeRLayers'​) ​     ​
 +rl.location = 185,285
 + 
 +# create output node
 +v = tree.nodes.new('​CompositorNodeViewer'​) ​  
 +v.location = 750,210
 +v.use_alpha = False
 + 
 +# create output node
 +of_c_node = tree.nodes.new('​CompositorNodeOutputFile'​)
 +of_c_node.location = 600, 200
 +#​of_node.base_path = 
 +of_c_node.format.file_format = '​PNG'​
 + 
 +# Links
 +links.new(rl.outputs[0],​ v.inputs[0]) ​ # link Image output to Viewer input
 +links.new(rl.outputs[0],​ of_c_node.inputs[0])
 + 
 +# Define path where to save image
 +base_path = "/​tmp/​images"​ #"​./​images_test_png"​
 + 
 +
 +
 +
 +with open(datafilepath,​ "​w"​) as datafile:
 +    #for frame in range(scene.frame_end+1):​
 +    for frame in range(2):
 +        scene.frame_set(frame)
 +        #​modification position de visée de l'oeil
 +        print('​Jessica et Bertrand sont passés par la');
 +        armature.pose.bones['​eyetargetparent'​].location[0] = -0.113456
 +
 +        camera_mat = camera_obj.matrix_world * mathutils.Matrix([[1,​0,​0,​0],​[0,​-1,​0,​0],​[0,​0,​-1,​0],​[0,​0,​0,​1]])
 +        ​
 +        camera_invmat = camera_mat.inverted()
 +        armature_mat = armature.matrix_world
 +        ​
 +        head_world = armature_mat*eyeLbone.head
 +        tail_world = armature_mat*eyeLbone.tail
 +        ​
 +        head_cam = camera_invmat*head_world
 +        tail_cam = camera_invmat*tail_world
 +        ​
 +        eye_centre = head_cam
 +        eye_radius = eyeLbone.bone.length
 +        pupil_gaze = (tail_cam - head_cam).normalized()
 +        pupil_radius = pupilLbone.scale[0] * pupil_base_radius
 +        pupil_centre = eye_centre + eye_radius*pupil_gaze
 +        ​
 +        #framestr = "{} | head_world: {} | tail_world: {} | vec_world: {} | head_cam: {} | tail_cam: {} | vec_cam {}"​.format(
 +        #       ​frame,​ *[strVec(x) for x in [head_world,​tail_world,​vec_world,​head_cam,​tail_cam,​vec_cam]])
 +        framestr = "{} {} {} {} {} {}"​.format(
 +            frame,
 +            strVec(eye_centre),​
 +            eye_radius,
 +            strVec(pupil_centre),​
 +            strVec(pupil_gaze),​
 +            pupil_radius
 +            )
 +        print(framestr)
 +        print(framestr,​ file=datafile)
 +        #​************* RENDER AND SAVE IMAGES ***********
 +# Define image resolution for rendering
 +        scene.render.resolution_x = 250
 +        scene.render.resolution_y = 250
 +# resolution percentage : have to be 100% to have the whole image resolution defined earlier
 +        scene.render.resolution_percentage = 100
 + 
 +# Activate which camera will be used for rendering
 +# (if more than one camera are defined, the rendering have to be repeated for each camera)
 +        scene.camera = bpy.data.objects["​Camera"​]
 + 
 + 
 +# get viewer pixels directly
 +        #pixels = bpy.data.images['​Viewer Node'​].pixels
 +        #​print(len(pixels)) # size is always width * height * 4 (rgba)
 + 
 +# copy buffer to numpy array for faster manipulation
 +#       arr = np.array(pixels[:​])
 +#        print('​one pixel \n',​arr[100:​104])
 + 
 +
 +# Define path where to save images
 +        str4 = base_path + "/​image"​
 +        of_c_node.base_path = str4 + "​000"​
 +        #​out_z_node.base_path = str4 +"​_Z_"​+ "​000"​
 + 
 +# Render
 +        bpy.ops.render.render()#​write_still=True)
 + 
 +#​************* EXIT BLENDER ​ ***********
 +        sys.exit(0)
 +
 +</​file>​
 +
 +
 +{{http://​homepages.laas.fr/​bvandepo/​files/​oeil.png}}
 +
 +
 +
 +
 +==== Accélérer le rendu ====
 +
 +Plusieurs astuces existent pour accelérer le rendu. Ces astuces diffèrent suivant si on est en "​Blender render"​ ou en "Cycle render"​.
 +
 +Lien pour le "Cycle render":​
 +  * [[https://​www.blenderguru.com/​articles/​4-easy-ways-to-speed-up-cycles]]
 +  * [[http://​boundlessblending.com/​blender-fast-rendering/​]]
 +
 +Lien pour "​Blender render":​
 +  * [[https://​www.blenderguru.com/​articles/​13-ways-to-reduce-render-times]]
 +
 +Pour le calcul de Blender occupe 100% du CPU il faut indiquer le bon nombre de threads et la bonne taille de tuile ("Tile size") : [[https://​blenderartists.org/​forum/​showthread.php?​410469-Why-Blender-Cycles-Rendering-Not-Using-100-CPU]]
 +
blender.1508504735.txt.gz · Dernière modification: 2017/10/20 15:05 par jcombier