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