Extrait de code Houdini

Avant-propos

Cette section fournie quelques commandes de base pour commencer à scripter dans Houdini.

Le script passe par le module hou. Sa documentation, très bien faite, est disponible ici.

Le Python Shell est disponible dans le menu Windows :

houdini_python_shell_menu

Les nœuds

Récupérer les nœuds sélectionnés

La fonction hou.selectedNodes() revoit la liste des nœuds sélectionnés :

for node in hou.selectedNodes():
   print node

Récupérer un nœud par son chemin

La fonction hou.node() permet de récupérer un nœud Houdini sous forme d’objet depuis son chemin :

root = hou.node('/obj')

Notez que la variable root fait référence au nœud /obj dans les exemples qui suivent.

Créer et supprimer des nœuds

La fonction hou.Node.createNode() permet de créer un nœud du type donné, sous le nœud courant.

Ici, un nœud de type geo sous /obj :

node = root.createNode('geo')  # hou.ObjNode of type geo at /obj/geo1>

Cette fonction prend de nombreux paramètres que je vous invite à regarder.

On peut accéder au type d’un nœud via hou.Node.type() :

node.type().name()  # 'geo'

Le type est également accessible en cliquant sur l’icône Operator Info, depuis l’interface :

houdini_operator_info_001

Il apparaît dans la fenêtre (ici, geo) :

houdini_operator_info_002

Il est aussi disponible en faisant bouton-droit sur un nœud :

houdini_operator_info_bouton_milieu

Pour supprimer un nœud, il faut appeler la méthode destroy() :

node.destroy()

Récupérer l’enfant d’un nœud par son nom

child = root.node('geo1')

Lister les enfants d’un nœud

for node in root.children():
    print node

La version récursive est hou.Node.allSubChidren() :

for node in root.allSubChidren():
    print node

Activer un nœud

node.setDisplayFlag(True)

Cela revient à cliquer sur le bouton bleu à droite d’un nœud.

La position des nœuds

x, y = node.position()
node.setPosition(x, y)

Un nœud peut être automatiquement positionné :

node.moveToGoodPosition()

Paramètres des nœuds

Récupérer le paramètre d’un nœud par son nom (ou son chemin)

Le nom des paramètres est disponible depuis l’interface en plaçant le curseur sur le paramètre :

houdini_parameter_name

Ici, tx, ty, et tz.

La méthode .parm() d’un nœud permet de récupérer un paramètre par son nom :

node = root.createNode('geo')  # <hou.ObjNode of type geo at /obj/geo1>
node.parm('tx')  # <hou.Parm tx in /obj/geo1>

Notez que vous pouvez récupérer un paramètre depuis son chemin complet via la commande hou.parm() :

hou.parm('obj/geo1/tx')  # <hou.Parm tx in /obj/geo1>

Lister les paramètres d’un nœud

for param in node.allParms():
    print param.name()

Récupérer la valeur d’un paramètre d’un nœud

Dans Houdini, il y a deux façons de récupérer la valeur d’un paramètre :

La première renvoie la valeur tel que défini dans le paramètre : Dans le cas d’une expression, il renvoie l’expression, et non son résultat.

La seconde évalue le contenu du paramètre et renvoi son résultat : Dans le cas d’une expression, il renvoie le résultat de l’expression.

node = root.createNode('geo')  # <hou.ObjNode of type geo at /obj/geo1>

param = node.parm('tx')  # <hou.Parm tx in /obj/geo1>
param.rawValue()  # '0'
param.eval()  # 0.0

On peut lui assigner une valeur via la méthode .set() :

param.set(20)

On peut lui assigner une expression via .setExpression() :

param.setExpression('ch("../my_node/value")')

Cliquer sur un paramètre de type bouton

Certains paramètres sont des boutons. Par exemple, le paramètre buildHierarchy d’un nœud alembicarchive est de type Button :

houdini_parameter_name

Pour les exécuter il suffit d’appeler la méthode .pressButton() :

node.parm('buildHierarchy').pressButton()

La timeline

Récupérer et modifier la time line.

houdini_time_line

current_frame = hou.frame()
start, end = hou.playbar.frameRange()
start, end = hou.playbar.playbackRange()
frame_rate = hou.fps()

hou.setFrame(1)
hou.playbar.setFrameRange(1, 100)
hou.playbar.setPlaybackRange(1, 100)
hou.setFps(24)

Un network box

Ces nœuds servent à empaqueter des nœuds entre eux :

houdini_network_box

box = root.createNetworkBox(item_name)

box.setComment('foo')
box.setColor(hou.Color(1.0, 1.0, 0.7))  # Background color.

for node in nodes:  # Puts nodes inside box.
    box.addNode(node)

# Adjust size to content.
box.fitAroundContents()

Accéder à la géométrie d’un nœud

Les SopNode sont des nœuds représentants une géométrie (sous un ObjNode, tel que /obj/box1/box1, quand on fait un cube).

On peut accéder aux informations de géométries depuis la fonction hou.SopNode.geometry()qui nous renvois un objet hou.Geometry :

geo = node.geometry()  # <hou.Geometry in /obj/box1/box1 read-only>

Ici, node peut être n’importe quel nœud SOP ; alembic, box, etc.

Note sur la modification des géométries

Les hou.Geometry ne sont pas modifiables. Ils permettent d’accéder à la géométrie d’un objet, mais vous ne pouvez les modifier directement. Si vous tentez de le faire, vous lèverez l’exception GeometryPermissionError.

Pourtant, des fonctions pour modifier la géométrie existent , tel que setPointIntAttribValues, setPointIntAttribValues.

Une géométrie ne peut être modifiée que via un nœud du graph Houdini. Certains nœuds sont dédiés à ce type de taches :

C’est dans le nœud python que vous pouvez utiliser les fonctions de modification de géométrie ci-dessus.

Lister les attributs de primitives d’une géométrie.

Il peut être intéressant d’avoir accès à des attributs de primitive.

Dans l’exemple suivant, on liste les path d’une géométrie venant d’un Alembic.

for prim in node.geometry().prims():  # `node` is an alembic type node.

    prim.number(), prim.attribValue('path')

L’attribut path est en lecture-seule. Si vous tentez de le modifier, vous lèverez l’exception GeometryPermissionError :

for prim in node.geometry().prims():  # `node` is an alembic type node.

    prim.setAttribValue('path', 'toto')
GeometryPermissionError: Geometry is read-only.

Dernière mise à jour : mer. 15 février 2023