Parametric surfaces visualization with VTK and Tcl-Tk

GS : The following example shows how to use VTK (Visualization ToolKit) and Tcl/Tk to display parametric surfaces.

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

You can test it easily on Windows without compiling VTK libraries thanks to VTKit (a tclkit extended with VTK library based on VTK5.5 and Tcl/Tk 8.5.7). [L1 ]

You can dowload VTKit5.5 here [L2 ]

img_vtk-parametric

 # 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
 }