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). [
1]
You can dowload VTKit5.5 here [
2]
# 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
}