Visualiser des surfaces paramétriques avec VTK et Tcl-Tk

 

GS L'exemple qui suit illustre l'utilisation de VTK (Visualization ToolKit) [1] et de Tcl/Tk pour afficher des surfaces paramétriques) :

 vtkParametricTorus vtkParametricEllipsoid vtkParametricSuperEllipsoid
 vtkParametricSuperToroid vtkParametricConicSpiral vtkParametricDini
 vtkParametricBoy vtkParametricCrossCap vtkParametricRoman
 vtkParametricMobius vtkParametricFigure8Klein vtkParametricKlein
 vtkParametricEnneper vtkParametricRandomHills

Il est possible de le tester aisément sous Windows sans avoir à compiler la bibliothèque VTK grâce à VTKit (une version de tclkit étendu avec VTK et basé sur VTK5.5 et Tcl-Tk 8.5.7) [2].

VTKit5.5 est téléchargeable ici [3]

 # param-vtk.tcl
 # Author:      Gerard Sookahet
 # Date:        25 August 2018
 # Version:     0.1
 # Description: Parametric surfaces visualization with VTK and Tcl-Tk user interface
 #              torus, ellipsoid, supertoroid, superellipsoid, Mobius strip, ....

 # load the VTK Tcl package and load the vtkinteraction package that contains
 # default bindings for handling mouse and keyboard events for a render widget
 # Default keyboard events are :
 #  e / q / ESC : exit
 #  s : surface rendering
 #  w : wireframe rendering
 #  r : reset camera
 package require vtk
 package require vtkinteraction

 # Flat UI
 option add *Button.relief flat
 option add *Button.foreground white
 option add *Button.background blue
 option add *Button.width 14
 option add *Label.foreground blue
 option add *Label.background orange
 option add *Label.width 14
 option add *Entry.relief flat
 option add *Entry.background lightblue
 option add *Entry.width 2
 option add *Text.foreground lightgreen
 option add *Text.background black

 global color
 global renWin
 set color 1

 set w .param
 catch {destroy $w}
 toplevel $w
 wm title $w "Parametric Surface Visualization"
 wm protocol $w WM_DELETE_WINDOW ::vtk::cb_exit

 # Create render window inside a Tk widget and bind the mouse events
 ::vtk::bind_tk_render_widget [vtkTkRenderWidget $w.rw -width 600 -height 600]
 #
 # Get the render window associated with the widget
 set renWin [$w.rw GetRenderWindow]
 vtkRenderer ren
 $renWin AddRenderer ren

 # Start VTK pipeline
 # Source -> Mapper -> Actor ->  Renderer

 # Create an instance of a parametric object (vtkParametricTorus)
 # and Tessellate the parametric function
 vtkParametricTorus p
 vtkParametricFunctionSource obj
 obj SetParametricFunction p

 # Create an instance of vtkPolyDataMapper to map the polygonal data
 # into graphics primitives and connect the output of the obj source
 # to the input of this mapper
 vtkPolyDataMapper objMapper
 objMapper SetInputConnection [obj GetOutputPort]

 # Create an actor to represent the obj. The actor coordinates rendering of
 # the graphics primitives for a mapper. We set this actor's mapper to be
 # the mapper which we created above.
 vtkLODActor actor
 actor SetMapper objMapper

 # Assign a blue color to our actor
 [actor GetProperty] SetColor 0 0 1

 # Create the Renderer and add actors to it (ren AddViewProp actor also works)
 # A renderer is like a viewport. It is part or all of a window on the screen
 # and it is responsible for drawing the actors it has.
 ren AddActor actor

 # Set the background color and render
 ren SetBackground 0 0 0
 ren Render

 # prevent the tk window from showing up then start the event loop
 wm withdraw .

 set f0 [frame $w.f0 -bg black]
 set f1 [frame $f0.f1 -relief flat -borderwidth 0 -bg black]
 set f2 [frame $f0.f2 -relief flat -borderwidth 0 -bg black]
 pack $f1 $f2 -pady 4

 label $f1.l1 -text "       Rendering       "
 button $f1.clr -text "Change Color" -width 14 -command {ChangeColor}

 pack {*}[winfo children $f1] -pady 2

 label $f2.l2 -text "          Object          "
 set l {vtkParametricTorus vtkParametricEllipsoid vtkParametricSuperEllipsoid \
        vtkParametricSuperToroid vtkParametricConicSpiral vtkParametricDini \
        vtkParametricBoy vtkParametricCrossCap vtkParametricRoman \
        vtkParametricMobius vtkParametricFigure8Klein vtkParametricKlein \
        vtkParametricEnneper vtkParametricRandomHills}
 foreach i $l {
  button $f2.$i -text [string map {vtkParametric ""} $i] -command "ChangeObject $i"
 }

 pack {*}[winfo children $f2] -pady 2

 button $f0.exit  -text Quit  -width 14 -command {exit}
 button $f0.about -text About -width 14 -command {About}
 pack $f0.exit -side bottom -pady 2
 pack $f0.about -side bottom

 pack $w.rw $f0 -side left -anchor nw -fill both -expand 1

 # Change obj color between red green blue
 proc ChangeColor {} {
     global color
     global renWin

  switch $color {
        0 {
           set rgb "0 0 1"
           set color 1
        }
        1 {
           set rgb "0 1 0"
           set color 2
        }
        2 {
           set rgb "1 0 0"
           set color 0
        }
  }

  for {set i 1} {$i <= 100} {incr i 5} {
     after 30
     set r [lindex $rgb 0]
     set g [lindex $rgb 1]
     set b [lindex $rgb 2]
     set i100 [expr {$i/100.0}]
     [actor GetProperty] SetColor [expr {$i100*$r}] [expr {$i100*$g}] [expr {$i100*$b}]
     $renWin Render
  }
 }

 # Change obj parametric surface and set some of its properties
 proc ChangeObject {class} {
     global renWin

  p Delete
  obj Delete
  $class p
  vtkParametricFunctionSource obj
  obj SetParametricFunction p

  switch $class {
    vtkParametricEllipsoid {
       p SetXRadius 1
       p SetYRadius 2
       p SetZRadius 1
    }
    vtkParametricSuperEllipsoid {
       p SetN1 3
       p SetN2 2.8
    }
    vtkParametricSuperToroid {
       p SetN1 0.8
       p SetN2 1.8
    }
    vtkParametricConicSpiral {
       p SetA .4
       p SetB 2
       p SetC .4
    }
    vtkParametricBoy {p SetZScale 0.1}
    vtkParametricMobius {p SetRadius 1.3}
    vtkParametricRoman {p SetRadius 1.8}
    vtkParametricFigure8Klein {p SetRadius 1.1}
  }
  objMapper SetInputConnection [obj GetOutputPort]
  $renWin Render
 }

 proc About {} {
  set w .about
  catch {destroy $w}
  toplevel $w
  .about configure -bg black
  wm title $w "About VTK primitive"
  set txt "VTK Parametric Surface Visualization \n August 2018 \n Gerard Sookahet"
  message $w.msg -justify left -aspect 250 -relief flat -bg black -fg lightblue -text $txt
  button $w.bquit -text " OK " -command {destroy .about}
  pack $w.msg $w.bquit
 }