VTK/Exemple introductif

Un livre de Wikilivres.
Cette page est une feuille volantelink={{{link}}}

Il faudrait la ranger dans un wikilivre où elle aurait sa place.

Pour le manuel de références, on se reportera à la page [1]

Interpréteur[modifier | modifier le wikicode]

À partir d'un interpréteur de commandes Unix, on commence par lancer l'interpréteur de commandes VTK

vtk

C'est un interpréteur Tcl, avec de nouvelles commandes propres à VTK.

Fenêtre de rendu[modifier | modifier le wikicode]

Je vais commencer par créer une fenêtre de visualisation, que je vais appeler "laFenetreDeRendu". C'est la commande "vtkRenderWindow" qui permet cette opération (classe vtkRenderWindow)

vtkRenderWindow laFenetreDeRendu

"laFenetreDeRendu" est un objet VTK. Cela signifie entre autres que c'est une commande, le premier argument de la commande étant appelée "méthode de l'objet". Avant de vraiment voir la fenêtre, on va la redimensionner et lui attacher deux rendeurs, "ren1" et "ren2".

La méthode de définition de la dimension, c'est "SetSize" :

laFenetreDeRendu SetSize 600 300

Rendeurs[modifier | modifier le wikicode]

Affreux néologisme, mais qui évite ici toute ambiguité. C'est ce qui agit permet le rendu, c'est à dire la réalisation graphique. La commande de création des rendeurs, c'est "vtkRenderer" (classe vtkRenderer)

vtkRenderer ren1
vtkRenderer ren2

Il nous faut placer ces rendeurs dans la fenêtre de rendu. C'est la méthode "SetViewport" qui définit les valeurs xmin, ymin, xmax, ymax. Il est à noter que la documentation de cette méthode ne figure pas à la page "vtkRenderer" mais à la page "vtkViewport" (classe vtkViewport.html) parce que "vtkRenderer" hérite de "vtkViewport".

ren1 SetViewport 0.0 0.0 0.5 1.0   ;# moitié gauche de la fenêtre
ren2 SetViewport 0.5 0.0 1.0 1.0   ;# moitié droite de la fenêtre

Pour bien visualiser les deux rendeurs, je change la couleur de fond au moyen de la méthode "SetBackground". Les arguments sont les taux de rouge, vert, bleu

ren1 SetBackground 0.8 0.4 0.2
ren2 SetBackground 0.1 0.2 0.4

Je n'ai pas encore connecté la fenêtre de rendu et ses deux rendeurs. C'est la méthode "AddRenderer" qui établit la connexion.

laFenetreDeRendu AddRenderer ren1
laFenetreDeRendu AddRenderer ren2

Maintenant, il s'agit de voir le résultat. C'est la méthode "Render" de l'objet de type "vtkRenderWindow" qui permet de vraiment montrer la fenêtre et ses deux rendeurs dont le fond est coloré.

laFenetreDeRendu Render

Un cube[modifier | modifier le wikicode]

Créons maintenant un volume. Une base de départ, c'est le cube. La commande qui crée un cube, c'est "vtkCubeSource" (classe vtkCubeSource)

vtkCubeSource unCube

Au départ, ce cube est centré à l'origine et il est de largeur unité.

puts [unCube GetXLength]  ;# -> 1
puts [unCube GetCenter]   ;# -> 0 0 0

Ces propriétés peuvent être modifiées par les méthodes "SetXLength", "SetCenter". Il y a aussi "SetYLength" et "SetZLength". En fait, ce cube est un parallélépipède.

La classe des objets "vtkCubeSource" hérite de la classe des objets polygonaux "vtkPolyDataSource". (class vtkPolyDataSource), comme les sphères, les flèches etc. Ces objets sont abstraits. Pour les rendre concrets, il faut les passer dans une moulinette de conditionnement de la classe "vtkPolyDataMapper" (classe vtkPolyDataMapper)

Le conditionneur[modifier | modifier le wikicode]

Je crée le conditionneur

vtkPolyDataMapper leConditionneurDuCube

et je récupère le canal de sortie de mon cube (méthode GetOutput) pour le brancher sur le canal d'entrée du conditionneur (méthode SetInput)

leConditionneurDuCube SetInput [unCube GetOutput]

L'acteur[modifier | modifier le wikicode]

Ce conditionneur est connecté au rendeur par l'intermédiaire d'un acteur, classe "vtkActor". (classe vtkActor) Cet intermédiaire permet placer à un endroit précis, avec une orientation choisie les objets conditionnés. On commence par utiliser les paramètres par défaut.

vtkActor acteurDuCube
acteurDuCube SetMapper leConditionneurDuCube
ren1 AddViewProp acteurDuCube #; version 4: ren1 AddProp acteurDuCube 
ren1 ResetCamera
laFenetreDeRendu Render
acteurDuCube RotateX 30.0
acteurDuCube RotateY 20.0
laFenetreDeRendu Render

Résumé des connexions[modifier | modifier le wikicode]

En résumé, on a une chaine d'objets connectés comme suit :

vtkCubeSource     unCube
vtkPolyDataMapper leConditionneurDuCube
vtkActor          acteurDuCube
vtkRenderer       ren1
vtkRenderWindow   laFenetreDeRendu

Cela parait compliqué mais permet une grande souplesse de manipulation.

Manipulation[modifier | modifier le wikicode]

Supposons que je veuille observer l'effet du changement de largeur du parallèlépipède. J'ai besoin d'appeler à la fois "unCube SetXLength ..." et "laFenetreDeRendu Render". Je crée une procédure Tcl qui fait les deux :

proc modifie_hauteur h {unCube SetZLength $h ; laFenetreDeRendu Render}

et un curseur de manipulation

scale .s -command modifie_hauteur ; pack .s
.s configure -from 0.1 -to 2 -resolution 0.01

Pour la manipulation du point de vue, on peut créer un objet d'interaction de la class vtkRenderWindowInteractor (classe vtkRenderWindowInteractor)

vtkRenderWindowInteractor l_Interacteur

Il faut attacher le fenêtre de rendu à l'interacteur et initialiser celui-ci

l_Interacteur SetRenderWindow laFenetreDeRendu
l_Interacteur Initialize

Maintenant, les 3 boutons de la souris permettent de contrôler la visualisation du cube.

Opérations booléennes[modifier | modifier le wikicode]

Passons à des opérations booléennes (classe vtkImplicitBoolean)

vtkCubeSource unCube2
unCube2 SetXLength 0.5
unCube2 SetYLength 0.5
unCube2 SetZLength 2
vtkImplicitBoolean bidule
bidule AddFunction unCube
bidule AddFunction unCube2
bidule SetOperationType 0;#union

Un autre exemple[modifier | modifier le wikicode]

unix$ tclsh

package require vtk
package require vtkinteraction

    vtkCylinderSource         leCylindre
    vtkCylinderSource         leCylindre2
set leCylindrePolyData       [leCylindre  GetOutput]
set leCylindrePolyData2      [leCylindre2 GetOutput]
    vtkPolyDataMapper         leMappeurDuCylindre  ; leMappeurDuCylindre  SetInput        $leCylindrePolyData
    vtkPolyDataMapper         leMappeurDuCylindre2 ; leMappeurDuCylindre2 SetInput        $leCylindrePolyData2
    vtkActor                  l_ActeurDuCylindre   ; l_ActeurDuCylindre   SetMapper       leMappeurDuCylindre
    vtkActor                  l_ActeurDuCylindre2  ; l_ActeurDuCylindre2  SetMapper       leMappeurDuCylindre2

    vtkRenderer               leRendeur            ; leRendeur            AddActor        l_ActeurDuCylindre
                                                     leRendeur            AddActor        l_ActeurDuCylindre2
    vtkRenderWindow           leRendeurDeFenetre   ; leRendeurDeFenetre   AddRenderer     leRendeur
                                                     leRendeurDeFenetre   Render

    vtkRenderWindowInteractor l_Interacteur        ; l_Interacteur        SetRenderWindow leRendeurDeFenetre
                                                     l_Interacteur        Initialize

leCylindre2          SetHeight      1.5
leCylindre2          SetRadius      0.25
leCylindre2          SetCapping      0                            ; leRendeurDeFenetre Render

leCylindre           SetResolution   32                           ; leRendeurDeFenetre Render
leCylindre2          SetResolution   32                           ; leRendeurDeFenetre Render
l_ActeurDuCylindre   RotateX         30.0                         ; leRendeurDeFenetre Render
l_ActeurDuCylindre   RotateY        -45.0                         ; leRendeurDeFenetre Render
[l_ActeurDuCylindre  GetProperty] SetColor 1.0000 0.3882 0.27844  ; leRendeurDeFenetre Render
leRendeur            SetBackground 0.1 0.2 0.4                    ; leRendeurDeFenetre Render
leRendeurDeFenetre   SetSize 300 300                              ; leRendeurDeFenetre Render