source: branches/blt4/gui/scripts/vtkviewer.tcl @ 1881

Last change on this file since 1881 was 1881, checked in by gah, 14 years ago
File size: 53.1 KB
Line 
1
2# ----------------------------------------------------------------------
3#  COMPONENT: contourresult - contour plot in a ResultSet
4#
5#  This widget is a contour plot for 2D meshes with a scalar value.
6#  It is normally used in the ResultViewer to show results from the
7#  run of a Rappture tool.  Use the "add" and "delete" methods to
8#  control the dataobjs showing on the plot.
9# ======================================================================
10#  AUTHOR:  Michael McLennan, Purdue University
11#  Copyright (c) 2004-2005  Purdue Research Foundation
12#
13#  See the file "license.terms" for information on usage and
14#  redistribution of this file, and for a DISCLAIMER OF ALL WARRANTIES.
15# ======================================================================
16package require Itk
17package require vtk
18package require vtkinteraction
19package require BLT
20#package require Img
21
22option add *VtkViewer.width 4i widgetDefault
23option add *VtkViewer.height 4i widgetDefault
24option add *VtkViewer.foreground black widgetDefault
25option add *VtkViewer.controlBackground gray widgetDefault
26option add *VtkViewer.controlDarkBackground #999999 widgetDefault
27option add *VtkViewer.plotBackground black widgetDefault
28option add *VtkViewer.plotForeground white widgetDefault
29option add *VtkViewer.font \
30    -*-helvetica-medium-r-normal-*-12-* widgetDefault
31
32itcl::class Rappture::VtkViewer {
33    inherit itk::Widget
34
35    itk_option define -plotforeground plotForeground Foreground ""
36    itk_option define -plotbackground plotBackground Background ""
37
38    private variable _dlist ""     ;# list of data objects
39    private variable _dims ""      ;# dimensionality of data objects
40    private variable _obj2color    ;# maps dataobj => plotting color
41    private variable _obj2width    ;# maps dataobj => line width
42    private variable _obj2raise    ;# maps dataobj => raise flag 0/1
43    private variable _obj2vtk      ;# maps dataobj => vtk objects
44    private variable _actors ""    ;# list of actors for each renderer
45    private variable _lights       ;# list of lights for each renderer
46    private variable _click        ;# info used for _move operations
47    private variable _slicer       ;# vtk transform used for 3D slice plane
48    private variable _limits       ;# autoscale min/max for all axes
49    private variable _view         ;# view params for 3D view
50    private variable _download ""  ;# snapshot for download
51
52    private variable _renderer "";
53    private variable _window "";
54    private variable _interactor "";
55    private variable _style "";
56    private variable _light "";
57    private variable _cubeAxesActor ""
58    private variable _axesActor ""
59    private variable _axesWidget "";
60    private variable _settings
61    constructor {args} {
62        # defined below
63    }
64    destructor {
65        # defined below
66    }
67
68    public method add {dataobj {settings ""}}
69    public method get {}
70    public method delete {args}
71    public method scale {args}
72    public method parameters {title args} {
73        # do nothing
74    }
75    public method download {option args}
76
77    protected method Rebuild {}
78    protected method Clear {}
79    protected method Zoom {option}
80    protected method Move {option x y}
81    protected method Slice {option args}
82    protected method _3dView {theta phi}
83    protected method _fixLimits {}
84    protected method Slicertip {axis}
85    protected method _color2rgb {color}
86    protected method SetActorProperties { actor style }
87
88    private method ComputeLimits { args }
89    private method GetLimits {}
90    private method BuildCameraTab {}
91    private method BuildCutplanesTab {}
92    private method BuildViewTab {}
93    private method BuildVolumeTab {}
94    protected method FixSettings {what {value ""}}
95
96}
97
98itk::usual VtkViewer {
99    keep -background -foreground -cursor -font
100    keep -plotbackground -plotforeground
101}
102
103# ----------------------------------------------------------------------
104# CONSTRUCTOR
105# ----------------------------------------------------------------------
106itcl::body Rappture::VtkViewer::constructor {args} {
107    option add hull.width hull.height
108    pack propagate $itk_component(hull) no
109
110    set _slicer(xplane) ""
111    set _slicer(yplane) ""
112    set _slicer(zplane) ""
113    set _slicer(xslice) ""
114    set _slicer(yslice) ""
115    set _slicer(zslice) ""
116    set _slicer(readout) ""
117    set _view(theta) 0
118    set _view(phi) 0
119
120    array set _limits {
121        xMin 0
122        xMax 1
123        yMin 0
124        yMax 1
125        zMin 0
126        zMax 1
127        vMin 0
128        vMax 1
129    }
130
131    itk_component add main {
132        Rappture::SidebarFrame $itk_interior.main
133    }
134    pack $itk_component(main) -expand yes -fill both
135    set f [$itk_component(main) component frame]
136
137    itk_component add controls {
138        frame $f.cntls
139    } {
140        usual
141        rename -background -controlbackground controlBackground Background
142    }
143    pack $itk_component(controls) -side right -fill y
144
145    itk_component add zoom {
146        frame $itk_component(controls).zoom
147    } {
148        usual
149        rename -background -controlbackground controlBackground Background
150    }
151    pack $itk_component(zoom) -side top
152
153    itk_component add reset {
154        button $itk_component(zoom).reset \
155            -borderwidth 1 -padx 1 -pady 1 \
156            -bitmap [Rappture::icon reset] \
157            -command [itcl::code $this Zoom reset]
158    } {
159        usual
160        ignore -borderwidth
161        rename -highlightbackground -controlbackground controlBackground Background
162    }
163    pack $itk_component(reset) -padx 4 -pady 4
164    Rappture::Tooltip::for $itk_component(reset) "Reset the view to the default zoom level"
165
166    itk_component add zoomin {
167        button $itk_component(zoom).zin \
168            -borderwidth 1 -padx 1 -pady 1 \
169            -bitmap [Rappture::icon zoomin] \
170            -command [itcl::code $this Zoom in]
171    } {
172        usual
173        ignore -borderwidth
174        rename -highlightbackground -controlbackground controlBackground Background
175    }
176    pack $itk_component(zoomin) -padx 4 -pady 4
177    Rappture::Tooltip::for $itk_component(zoomin) "Zoom in"
178
179    itk_component add zoomout {
180        button $itk_component(zoom).zout \
181            -borderwidth 1 -padx 1 -pady 1 \
182            -bitmap [Rappture::icon zoomout] \
183            -command [itcl::code $this Zoom out]
184    } {
185        usual
186        ignore -borderwidth
187        rename -highlightbackground -controlbackground controlBackground Background
188    }
189    pack $itk_component(zoomout) -padx 4 -pady 4
190    Rappture::Tooltip::for $itk_component(zoomout) "Zoom out"
191
192    #
193    # RENDERING AREA
194    #
195    itk_component add area {
196        frame $f.area
197    }
198    pack $itk_component(area) -expand yes -fill both
199
200    set _renderer [vtkRenderer $this-Renderer]
201    set _window [vtkRenderWindow $this-RenderWindow]
202    itk_component add plot {
203        vtkTkRenderWidget $itk_component(area).plot -rw $_window \
204            -width 1 -height 1
205    } {
206    }
207    pack $itk_component(plot) -expand yes -fill both
208    $_window AddRenderer $_renderer
209    $_window LineSmoothingOn
210    $_window PolygonSmoothingOn
211
212
213    set _interactor [vtkRenderWindowInteractor $this-Interactor]
214    set _style [vtkInteractorStyleTrackballCamera $this-InteractorStyle]
215    $_interactor SetRenderWindow $_window
216    $_interactor SetInteractorStyle $_style
217    $_interactor Initialize
218
219    set _cubeAxesActor [vtkCubeAxesActor $this-CubeAxesActor]
220    $_cubeAxesActor SetCamera [$_renderer GetActiveCamera]
221    $_renderer AddActor $_cubeAxesActor
222
223    # Supply small axes guide.
224    set _axesActor [vtkAxesActor $this-AxesActor]
225    set _axesWidget [vtkOrientationMarkerWidget $this-AxesWidget]
226    $_axesWidget SetOrientationMarker $_axesActor
227    $_axesWidget SetInteractor $_interactor
228    $_axesWidget SetEnabled 1
229    $_axesWidget SetInteractive 0
230    $_axesWidget SetViewport .7 0 1.0 0.3
231
232    $_cubeAxesActor SetXTitle "X Axis (units)"
233    $_cubeAxesActor SetYTitle "Y Axis (units)"
234
235    BuildViewTab
236    BuildVolumeTab
237    BuildCutplanesTab
238    BuildCameraTab
239
240    set v0 0
241    set v1 1
242    set _lookup [vtkLookupTable $this-Lookup]
243    $_lookup SetTableRange $v0 $v1
244    $_lookup SetHueRange 0.66667 0.0
245    $_lookup Build
246
247
248    #
249    # 3D CUT PLANES
250    #
251    foreach axis {x y z} norm {{1 0 0} {0 1 0} {0 0 1}} {
252
253        set plane [vtkPlane $this-${axis}cutplane]
254        eval $plane SetNormal $norm
255        set _slicer(${axis}plane) $plane
256       
257        set cutter [vtkCutter $this-${axis}cutter]
258        $cutter SetCutFunction $plane
259       
260        set mapper [vtkPolyDataMapper  $this-${axis}cutmapper]
261        $mapper SetInput [$cutter GetOutput]
262        $mapper SetScalarRange $v0 $v1
263        $mapper SetLookupTable $_lookup
264       
265        #lappend _obj2vtk($dataobj) $cutplane $cutter $mapper
266       
267        set actor [vtkActor $this-${axis}actor]
268        $actor VisibilityOn
269        $actor SetMapper $mapper
270        $actor SetPosition 0 0 0
271        [$actor GetProperty] SetColor 0 0 0
272        set _slicer(${axis}slice) $actor
273       
274        $_renderer AddActor $actor
275        lappend _actors $actor
276        #lappend _obj2vtk($dataobj) $actor
277    }
278   
279    #
280    # CUT PLANE READOUT
281    #
282    set mapper [vtkTextMapper $this-text]
283    set props [$mapper GetTextProperty]
284    #eval $props SetColor [_color2rgb $itk_option(-plotforeground)]
285    $props SetVerticalJustificationToTop
286    set _slicer(readout) $mapper
287           
288    set actor [vtkActor2D $this-texta]
289    $actor SetMapper $mapper
290    set coords [$actor GetPositionCoordinate]
291    $coords SetCoordinateSystemToNormalizedDisplay
292    $coords SetValue 0.02 0.98
293           
294    $_renderer AddActor $actor
295    lappend _actors $actor
296    #lappend _obj2vtk($dataobj) $mapper $actor
297
298    # turn off all slicers by default
299    foreach axis {x y z} {
300        $itk_component(${axis}CutScale) configure -state normal
301        $itk_component(${axis}CutScale) set 50
302        Slice move $axis 50
303        Slice axis $axis off
304    }
305
306    set _light [vtkLight $this-Light]
307    $_light SetColor 1 1 1
308    $_light SetAttenuationValues 0 0 0
309    $_light SetFocalPoint 0 0 0
310    $_light SetLightTypeToHeadlight
311    $_renderer AddLight $_light
312
313    #
314    # Create a picture for download snapshots
315    #
316    set _download [image create picture]
317
318    eval itk_initialize $args
319}
320
321# ----------------------------------------------------------------------
322# DESTRUCTOR
323# ----------------------------------------------------------------------
324itcl::body Rappture::VtkViewer::destructor {} {
325    Clear
326    after cancel [itcl::code $this Rebuild]
327
328    foreach c [info commands $this-vtk*] {
329        rename $c ""
330    }
331    image delete $_download
332}
333
334# ----------------------------------------------------------------------
335# USAGE: add <dataobj> ?<settings>?
336#
337# Clients use this to add a data object to the plot.  The optional
338# <settings> are used to configure the plot.  Allowed settings are
339# -color, -brightness, -width, -linestyle, and -raise.
340# ----------------------------------------------------------------------
341itcl::body Rappture::VtkViewer::add {dataobj {settings ""}} {
342    array set params {
343        -color auto
344        -width 1
345        -linestyle solid
346        -brightness 0
347        -raise 0
348        -description ""
349        -param ""
350    }
351    foreach {opt val} $settings {
352        if {![info exists params($opt)]} {
353            error "bad setting \"$opt\": should be [join [lsort [array names params]] {, }]"
354        }
355        set params($opt) $val
356    }
357    if {$params(-color) == "auto" || $params(-color) == "autoreset"} {
358        # can't handle -autocolors yet
359        set params(-color) black
360    }
361
362    set pos [lsearch -exact $dataobj $_dlist]
363    if {$pos < 0} {
364        lappend _dlist $dataobj
365        set _obj2color($dataobj) $params(-color)
366        set _obj2width($dataobj) $params(-width)
367        set _obj2raise($dataobj) $params(-raise)
368
369        after cancel [itcl::code $this Rebuild]
370        after idle [itcl::code $this Rebuild]
371    }
372}
373
374# ----------------------------------------------------------------------
375# USAGE: get
376#
377# Clients use this to query the list of objects being plotted, in
378# order from bottom to top of this result.
379# ----------------------------------------------------------------------
380itcl::body Rappture::VtkViewer::get {} {
381    # put the dataobj list in order according to -raise options
382    set dlist $_dlist
383    foreach obj $dlist {
384        if {[info exists _obj2raise($obj)] && $_obj2raise($obj)} {
385            set i [lsearch -exact $dlist $obj]
386            if {$i >= 0} {
387                set dlist [lreplace $dlist $i $i]
388                lappend dlist $obj
389            }
390        }
391    }
392    return $dlist
393}
394
395# ----------------------------------------------------------------------
396# USAGE: delete ?<dataobj1> <dataobj2> ...?
397#
398# Clients use this to delete a dataobj from the plot.  If no dataobjs
399# are specified, then all dataobjs are deleted.
400# ----------------------------------------------------------------------
401itcl::body Rappture::VtkViewer::delete {args} {
402    if {[llength $args] == 0} {
403        set args $_dlist
404    }
405
406    # delete all specified dataobjs
407    set changed 0
408    foreach dataobj $args {
409        set pos [lsearch -exact $_dlist $dataobj]
410        if {$pos >= 0} {
411            set _dlist [lreplace $_dlist $pos $pos]
412            catch {unset _obj2color($dataobj)}
413            catch {unset _obj2width($dataobj)}
414            catch {unset _obj2raise($dataobj)}
415            set changed 1
416        }
417    }
418
419    # if anything changed, then rebuild the plot
420    if {$changed} {
421        after cancel [itcl::code $this Rebuild]
422        after idle [itcl::code $this Rebuild]
423    }
424}
425
426# ----------------------------------------------------------------------
427# USAGE: scale ?<data1> <data2> ...?
428#
429# Sets the default limits for the overall plot according to the
430# limits of the data for all of the given <data> objects.  This
431# accounts for all objects--even those not showing on the screen.
432# Because of this, the limits are appropriate for all objects as
433# the user scans through data in the ResultSet viewer.
434# ----------------------------------------------------------------------
435itcl::body Rappture::VtkViewer::scale {args} {
436    eval ComputeLimits $args
437    _fixLimits
438}
439
440# ----------------------------------------------------------------------
441# USAGE: download coming
442# USAGE: download controls <downloadCommand>
443# USAGE: download now
444#
445# Clients use this method to create a downloadable representation
446# of the plot.  Returns a list of the form {ext string}, where
447# "ext" is the file extension (indicating the type of data) and
448# "string" is the data itself.
449# ----------------------------------------------------------------------
450itcl::body Rappture::VtkViewer::download {option args} {
451    switch $option {
452        coming {
453            if {[catch {$_download snap $itk_component(area)} errs] != 0 } {
454                global errorInfo
455                puts stderr "$errorInfo"
456                $_download blank #000000
457            }
458        }
459        controls {
460            # no controls for this download yet
461            return ""
462        }
463        now {
464            set writer [vtkJPEGWriter $this-vtkJPEGWriter]
465            set large [vtkRenderLargeImage $this-RenderLargeImage]
466            $_axesWidget SetEnabled 0
467            $large SetInput $_renderer
468            $large SetMagnification 4
469            $writer SetInputConnection [$large GetOutputPort]
470
471            $writer SetFileName junk.jpg
472            $writer Write
473            rename $writer ""
474            rename $large ""
475            $_axesWidget SetEnabled 1
476
477            $_download export jpg -quality 100 -data bytes
478            return [list .jpg $bytes]
479        }
480        default {
481            error "bad option \"$option\": should be coming, controls, now"
482        }
483    }
484}
485
486# ----------------------------------------------------------------------
487# USAGE: Clear
488#
489# Used internally to clear the drawing area and tear down all vtk
490# objects in the current scene.
491# ----------------------------------------------------------------------
492itcl::body Rappture::VtkViewer::Clear {} {
493    # clear out any old constructs
494    foreach actor $_actors {
495        $_renderer RemoveActor $actor
496    }
497    set _actors ""
498    foreach ren [array names _lights] {
499        foreach light $_lights($ren) {
500            $ren RemoveLight $light
501            rename $light ""
502        }
503        set _lights($ren) ""
504    }
505    foreach dataobj [array names _obj2vtk] {
506        foreach cmd $_obj2vtk($dataobj) {
507            rename $cmd ""
508        }
509        set _obj2vtk($dataobj) ""
510    }
511    set _slicer(xplane) ""
512    set _slicer(yplane) ""
513    set _slicer(zplane) ""
514    set _slicer(xslice) ""
515    set _slicer(yslice) ""
516    set _slicer(zslice) ""
517    set _slicer(readout) ""
518}
519
520# ----------------------------------------------------------------------
521# USAGE: Zoom in
522# USAGE: Zoom out
523# USAGE: Zoom reset
524#
525# Called automatically when the user clicks on one of the zoom
526# controls for this widget.  Changes the zoom for the current view.
527# ----------------------------------------------------------------------
528itcl::body Rappture::VtkViewer::Zoom {option} {
529    set camera [$_renderer GetActiveCamera]
530    switch -- $option {
531        in {
532            $camera Zoom 1.25
533            $_window Render
534        }
535        out {
536            $camera Zoom 0.8
537            $_window Render
538        }
539        reset {
540            if {$_dims == "3D"} {
541                $camera SetViewAngle 30
542                $_renderer ResetCamera
543                _3dView 45 45
544            } else {
545                $_renderer ResetCamera
546                $camera Zoom 1.5
547            }
548            $_window Render
549            if 0 {
550            $this-vtkRenderWindow2 Render
551            }
552        }
553    }
554}
555
556# ----------------------------------------------------------------------
557# USAGE: Move click <x> <y>
558# USAGE: Move drag <x> <y>
559# USAGE: Move release <x> <y>
560#
561# Called automatically when the user clicks/drags/releases in the
562# plot area.  Moves the plot according to the user's actions.
563# ----------------------------------------------------------------------
564itcl::body Rappture::VtkViewer::Move {option x y} {
565    switch -- $option {
566        click {
567            blt::busy configure $itk_component(area) -cursor fleur
568            set _click(x) $x
569            set _click(y) $y
570            set _click(theta) $_view(theta)
571            set _click(phi) $_view(phi)
572        }
573        drag {
574            if {[array size _click] == 0} {
575                Move click $x $y
576            } else {
577                set w [winfo width $itk_component(plot)]
578                set h [winfo height $itk_component(plot)]
579                set scalex [expr {$_limits(xMax)-$_limits(xMin)}]
580                set scaley [expr {$_limits(yMax)-$_limits(yMin)}]
581                set dx [expr {double($x-$_click(x))/$w*$scalex}]
582                set dy [expr {double($y-$_click(y))/$h*$scaley}]
583
584                if {$_dims == "2D"} {
585                    #
586                    # Shift the contour plot in 2D
587                    #
588                    foreach actor $_actors {
589                        foreach {ax ay az} [$actor GetPosition] break
590                        $actor SetPosition [expr {$ax+$dx}] [expr {$ay-$dy}] 0
591                    }
592                    $_window Render
593                } elseif {$_dims == "3D"} {
594                    #
595                    # Rotate the camera in 3D
596                    #
597                    set theta [expr {$_view(theta) - $dy*180}]
598                    if {$theta < 2} { set theta 2 }
599                    if {$theta > 178} { set theta 178 }
600                    set phi [expr {$_view(phi) - $dx*360}]
601
602                    _3dView $theta $phi
603                    $_window Render
604                }
605                set _click(x) $x
606                set _click(y) $y
607            }
608        }
609        release {
610            Move drag $x $y
611            blt::busy configure $itk_component(area) -cursor left_ptr
612            catch {unset _click}
613        }
614        default {
615            error "bad option \"$option\": should be click, drag, release"
616        }
617    }
618}
619
620# ----------------------------------------------------------------------
621# USAGE: Slice axis x|y|z ?on|off|toggle?
622# USAGE: Slice move x|y|z <newval>
623#
624# Called automatically when the user drags the slider to move the
625# cut plane that slices 3D data.  Gets the current value from the
626# slider and moves the cut plane to the appropriate point in the
627# data set.
628# ----------------------------------------------------------------------
629itcl::body Rappture::VtkViewer::Slice {option args} {
630    if {$_slicer(xplane) == ""} {
631        # no slicer? then bail out!
632        return
633    }
634    switch -- $option {
635        axis {
636            if {[llength $args] < 1 || [llength $args] > 2} {
637                error "wrong # args: should be \"Slice axis x|y|z ?on|off|toggle?\""
638            }
639            set axis [lindex $args 0]
640            set op [lindex $args 1]
641            if {$op == ""} { set op "on" }
642
643            set current $_settings($this-${axis}cutplane)
644            if {$op == "toggle"} {
645                set op [expr $current==0]
646            }
647
648            if {$op} {
649                $itk_component(${axis}CutScale) configure -state normal
650                $_slicer(${axis}slice) VisibilityOn
651                $itk_component(${axis}CutButton) select
652            } else {
653                $itk_component(${axis}CutScale) configure -state disabled
654                $_slicer(${axis}slice) VisibilityOff
655                $itk_component(${axis}CutButton) deselect
656            }
657            $_window Render
658        }
659        move {
660            if {[llength $args] != 2} {
661                error "wrong # args: should be \"Slice move x|y|z newval\""
662            }
663            set axis [lindex $args 0]
664            set newval [lindex $args 1]
665
666            set xm [expr {0.5*($_limits(xMax)+$_limits(xMin))}]
667            set ym [expr {0.5*($_limits(yMax)+$_limits(yMin))}]
668            set zm [expr {0.5*($_limits(zMax)+$_limits(zMin))}]
669
670            set newval [expr {0.01*($newval-50)
671                *($_limits(${axis}Max)-$_limits(${axis}Min))
672                  + 0.5*($_limits(${axis}Max)+$_limits(${axis}Min))}]
673
674            # show the current value in the readout
675            if {$_slicer(readout) != ""} {
676                $_slicer(readout) SetInput "$axis = $newval"
677            }
678
679            # keep a little inside the volume, or the slice will disappear!
680            if {$newval == $_limits(${axis}Min)} {
681                set range [expr {$_limits(${axis}Max)-$_limits(${axis}Min)}]
682                set newval [expr {$newval + 1e-6*$range}]
683            }
684
685            # xfer new value to the proper dimension and move the cut plane
686            set ${axis}m $newval
687            $_slicer(${axis}plane) SetOrigin $xm $ym $zm
688
689            $_window Render
690        }
691        default {
692            error "bad option \"$option\": should be axis or move"
693        }
694    }
695}
696
697# ----------------------------------------------------------------------
698# USAGE: _3dView <theta> <phi>
699#
700# Used internally to change the position of the camera for 3D data
701# sets.  Sets the camera according to the angles <theta> (angle from
702# the z-axis) and <phi> (angle from the x-axis in the x-y plane).
703# Both angles are in degrees.
704# ----------------------------------------------------------------------
705itcl::body Rappture::VtkViewer::_3dView {theta phi} {
706    set deg2rad 0.0174532927778
707    set xn [expr {sin($theta*$deg2rad)*cos($phi*$deg2rad)}]
708    set yn [expr {sin($theta*$deg2rad)*sin($phi*$deg2rad)}]
709    set zn [expr {cos($theta*$deg2rad)}]
710
711    set xm [expr {0.5*($_limits(xMax)+$_limits(xMin))}]
712    set ym [expr {0.5*($_limits(yMax)+$_limits(yMin))}]
713    set zm [expr {0.5*($_limits(zMax)+$_limits(zMin))}]
714
715    set cam [$_renderer GetActiveCamera]
716    set zoom [$cam GetViewAngle]
717    $cam SetViewAngle 30
718
719    $cam SetFocalPoint $xm $ym $zm
720    $cam SetPosition [expr {$xm-$xn}] [expr {$ym-$yn}] [expr {$zm+$zn}]
721    $cam ComputeViewPlaneNormal
722    $cam SetViewUp 0 0 1  ;# z-dir is up
723    $cam OrthogonalizeViewUp
724    $_renderer ResetCamera
725    $cam SetViewAngle $zoom
726
727    set _view(theta) $theta
728    set _view(phi) $phi
729}
730
731# ----------------------------------------------------------------------
732# USAGE: _fixLimits
733#
734# Used internally to apply automatic limits to the axes for the
735# current plot.
736# ----------------------------------------------------------------------
737itcl::body Rappture::VtkViewer::_fixLimits {} {
738    $_renderer ResetCamera
739    set camera [$_renderer GetActiveCamera]
740    $camera Zoom 1.5
741    $_window Render
742    if 0 {
743    $this-vtkRenderWindow2 Render
744    }
745}
746
747# ----------------------------------------------------------------------
748# USAGE: Slicertip <axis>
749#
750# Used internally to generate a tooltip for the x/y/z slicer controls.
751# Returns a message that includes the current slicer value.
752# ----------------------------------------------------------------------
753itcl::body Rappture::VtkViewer::Slicertip {axis} {
754    set val [$itk_component(${axis}slicer) get]
755    set val [expr {0.01*($val-50)
756        *($_limits(${axis}Max)-$_limits(${axis}Min))
757          + 0.5*($_limits(${axis}Max)+$_limits(${axis}Min))}]
758    return "Move the [string toupper $axis] cut plane.\nCurrently:  $axis = $val"
759}
760
761# ----------------------------------------------------------------------
762# USAGE: _color2rgb <color>
763#
764# Used internally to convert a color name to a set of {r g b} values
765# needed for vtk.  Each r/g/b component is scaled in the range 0-1.
766# ----------------------------------------------------------------------
767itcl::body Rappture::VtkViewer::_color2rgb {color} {
768    foreach {r g b} [winfo rgb $itk_component(hull) $color] break
769    set r [expr {$r/65535.0}]
770    set g [expr {$g/65535.0}]
771    set b [expr {$b/65535.0}]
772    return [list $r $g $b]
773}
774
775# ----------------------------------------------------------------------
776# CONFIGURATION OPTION: -plotbackground
777# ----------------------------------------------------------------------
778itcl::configbody Rappture::VtkViewer::plotbackground {
779    foreach {r g b} [_color2rgb $itk_option(-plotbackground)] break
780    $_renderer SetBackground $r $g $b
781    $_window Render
782    if 0 {
783    $this-vtkRenderer2 SetBackground $r $g $b
784    $this-vtkRenderWindow2 Render
785    }
786}
787
788# ----------------------------------------------------------------------
789# CONFIGURATION OPTION: -plotforeground
790# ----------------------------------------------------------------------
791itcl::configbody Rappture::VtkViewer::plotforeground {
792    after cancel [itcl::code $this Rebuild]
793    after idle [itcl::code $this Rebuild]
794}
795
796itcl::body Rappture::VtkViewer::SetActorProperties { actor style } {
797    array set props {
798        -color \#6666FF
799        -edgevisibility yes
800        -edgecolor black
801        -linewidth 1.0
802        -opacity 1.0
803    }
804    # Parse style string.
805    array set props $style
806    set prop [$actor GetProperty]
807    eval $prop SetColor [_color2rgb $props(-color)]
808    if { $props(-edgevisibility) } {
809        $prop EdgeVisibilityOn
810    } else {
811        $prop EdgeVisibilityOff
812    }
813    set _settings($this-edges) $props(-edgevisibility)
814    eval $prop SetEdgeColor [_color2rgb $props(-edgecolor)]
815    $prop SetLineWidth $props(-linewidth)
816    $prop SetOpacity $props(-opacity)
817    set _settings($this-opacity) [expr $props(-opacity) * 100.0]
818}
819
820# ----------------------------------------------------------------------
821# USAGE: Rebuild
822#
823# Called automatically whenever something changes that affects the
824# data in the widget.  Clears any existing data and rebuilds the
825# widget to display new data.
826# ----------------------------------------------------------------------
827itcl::body Rappture::VtkViewer::Rebuild {} {
828    Clear
829    set id 0
830
831    # determine the dimensionality from the topmost (raised) object
832    set dlist [get]
833    set dataobj [lindex $dlist end]
834    if {$dataobj != ""} {
835        set _dims [lindex [lsort [$dataobj components -dimensions]] end]
836    } else {
837        set _dims "0D"
838    }
839    ComputeLimits
840    $_cubeAxesActor SetCamera [$_renderer GetActiveCamera]
841    puts stderr limits=[GetLimits]
842    eval $_cubeAxesActor SetBounds [GetLimits]
843
844    #
845    # LOOKUP TABLE FOR COLOR CONTOURS
846    #
847    # use vmin/vmax if possible, otherwise get from data
848    if {$_limits(vMin) == "" || $_limits(vMax) == ""} {
849        set v0 0
850        set v1 1
851        if {[info exists _obj2vtk($dataobj)]} {
852            set pd [lindex $_obj2vtk($dataobj) 0]
853            if {"" != $pd} {
854                foreach {v0 v1} [$pd GetScalarRange] break
855            }
856        }
857    } else {
858        set v0 $_limits(vMin)
859        set v1 $_limits(vMax)
860    }
861
862    if 0 {
863        set lu $this-vtkLookup
864        vtkLookupTable $lu
865        $lu SetTableRange $v0 $v1
866        $lu SetHueRange 0.66667 0.0
867        $lu Build
868       
869        lappend _obj2vtk($dataobj) $lu
870       
871        #
872        # 3D LIGHTS (on both sides of all three axes)
873        #
874        set x0 $_limits(xMin)
875        set x1 $_limits(xMax)
876        set xm [expr {0.5*($x0+$x1)}]
877        set y0 $_limits(yMin)
878        set y1 $_limits(yMax)
879        set ym [expr {0.5*($y0+$y1)}]
880        set z0 $_limits(zMin)
881        set z1 $_limits(zMax)
882        set zm [expr {0.5*($z0+$z1)}]
883        set xr [expr {$x1-$x0}]
884        set yr [expr {$y1-$y0}]
885        set zr [expr {$z1-$z0}]
886
887        set light [vtkLight $this-vtkLight]
888        $light SetColor 1 1 1
889        $light SetAttenuationValues 0 0 0
890        $light SetFocalPoint $xm $ym $zm
891        $light SetLightTypeToHeadlight
892        $_renderer AddLight $light
893        lappend _lights($_renderer) $light
894    }
895    # scan through all data objects and build the contours
896    set firstobj 1
897    foreach dataobj [get] {
898        foreach comp [$dataobj components] {
899            set actor [$dataobj values $comp]
900            set style [$dataobj style $comp]
901
902            $_renderer AddActor $actor
903            SetActorProperties $actor $style
904            set mapper [$dataobj data $comp]
905            $this-xcutter SetInput [$mapper GetInput]
906            #$_cubeAxesActor SetCamera [$_renderer GetActiveCamera]
907            #eval $_cubeAxesActor SetBounds [$actor GetBounds]
908
909
910            if 0 {
911            #
912            # Add color contours.
913            #
914            if {$firstobj} {
915                if {$_dims == "3D"} {
916                    pack $itk_component(slicers) -side bottom -padx 4 -pady 4
917                    pack $itk_component(reset) -side left
918                    pack $itk_component(zoomin) -side left
919                    pack $itk_component(zoomout) -side left
920
921                    #
922                    # 3D DATA SET
923                    #
924                    set mesh [$dataobj mesh $comp]
925                    if {"" == $mesh} {
926                        set x [expr {[winfo rootx $itk_component(area)]+10}]
927                        set y [expr {[winfo rooty $itk_component(area)]+10}]
928                        Rappture::Tooltip::cue @$x,$y "This data requires the visualization server, and that appears to be down.  Please try your simulation again later."
929                        return
930                    }
931                    switch -- [$mesh GetClassName] {
932                      vtkPoints {
933                        # handle cloud of 3D points
934                        set pd $this-polydata
935                        vtkPolyData $pd
936                        $pd SetPoints $mesh
937                        [$pd GetPointData] SetScalars [$dataobj values $comp]
938
939                        set tr $this-triangles
940                        vtkDelaunay3D $tr
941                        $tr SetInput $pd
942                        $tr SetTolerance 0.0000000000001
943                        set source [$tr GetOutput]
944
945                        set mp $this-mapper
946                        vtkPolyDataMapper $mp
947
948                        lappend _obj2vtk($dataobj) $pd $tr $mp
949                      }
950                      vtkUnstructuredGrid {
951                        # handle 3D grid with connectivity
952                        set gr $this-grdata
953                        vtkUnstructuredGrid $gr
954                        $gr ShallowCopy $mesh
955                        [$gr GetPointData] SetScalars [$dataobj values $comp]
956                        set source $gr
957
958                        lappend _obj2vtk($dataobj) $gr
959                      }
960                      vtkRectilinearGrid {
961                        # handle 3D grid with connectivity
962                        set gr $this-grdata
963                        vtkRectilinearGrid $gr
964                        $gr ShallowCopy $mesh
965                        [$gr GetPointData] SetScalars [$dataobj values $comp]
966                        set source $gr
967
968                        lappend _obj2vtk($dataobj) $gr
969                      }
970                      default {
971                        error "don't know how to handle [$mesh GetClassName] data"
972                      }
973                    }
974
975                    #
976                    # 3D ISOSURFACES
977                    #
978                    set iso $this-iso
979                    vtkContourFilter $iso
980                      $iso SetInput $source
981
982                    set mp $this-isomap
983                    vtkPolyDataMapper $mp
984                      $mp SetInput [$iso GetOutput]
985
986                    set ac $this-isoactor
987                    vtkActor $ac
988                      $ac SetMapper $mp
989                      [$ac GetProperty] SetOpacity 0.3
990                      [$ac GetProperty] SetDiffuse 0.5
991                      [$ac GetProperty] SetAmbient 0.7
992                      [$ac GetProperty] SetSpecular 10.0
993                      [$ac GetProperty] SetSpecularPower 200.0
994                    $_renderer AddActor $ac
995
996                    lappend _obj2vtk($dataobj) $iso $mp $ac
997                    lappend _actors $ac
998
999                    catch {unset style}
1000                    array set style [lindex [$dataobj components -style $comp] 0]
1001                    if {[info exists style(-color)]} {
1002                        $mp ScalarVisibilityOff  ;# take color from actor
1003                        eval [$ac GetProperty] SetColor [_color2rgb $style(-color)]
1004                    }
1005
1006                    if {[info exists style(-opacity)]} {
1007                        [$ac GetProperty] SetOpacity $style(-opacity)
1008                    }
1009
1010                    set levels 5
1011                    if {[info exists style(-levels)]} {
1012                        set levels $style(-levels)
1013                    }
1014                    if {$levels == 1} {
1015                        $iso SetValue 0 [expr {0.5*($v1-$v0)+$v0}]
1016                    } else {
1017                        $iso GenerateValues [expr {$levels+2}] $v0 $v1
1018                    }
1019
1020                    #
1021                    # 3D CUT PLANES
1022                    #
1023                    if {$id == 0} {
1024                        foreach axis {x y z} norm {{1 0 0} {0 1 0} {0 0 1}} {
1025                            set pl $this-${axis}cutplane$id
1026                            vtkPlane $pl
1027                            eval $pl SetNormal $norm
1028                            set _slicer(${axis}plane) $pl
1029
1030                            set ct $this-${axis}cutter$id
1031                            vtkCutter $ct
1032                            $ct SetInput $source
1033                            $ct SetCutFunction $pl
1034
1035                            set mp $this-${axis}cutmapper$id
1036                            vtkPolyDataMapper $mp
1037                            $mp SetInput [$ct GetOutput]
1038                            $mp SetScalarRange $v0 $v1
1039                            $mp SetLookupTable $lu
1040
1041                            lappend _obj2vtk($dataobj) $pl $ct $mp
1042
1043                            set ac $this-${axis}actor$id
1044                            vtkActor $ac
1045                            $ac VisibilityOff
1046                            $ac SetMapper $mp
1047                            $ac SetPosition 0 0 0
1048                            [$ac GetProperty] SetColor 0 0 0
1049                            set _slicer(${axis}slice) $ac
1050
1051                            $_renderer AddActor $ac
1052                            lappend _actors $ac
1053                            lappend _obj2vtk($dataobj) $ac
1054                        }
1055
1056                        #
1057                        # CUT PLANE READOUT
1058                        #
1059                        set tx $this-text$id
1060                        vtkTextMapper $tx
1061                        set tp [$tx GetTextProperty]
1062                        eval $tp SetColor [_color2rgb $itk_option(-plotforeground)]
1063                        $tp SetVerticalJustificationToTop
1064                        set _slicer(readout) $tx
1065
1066                        set txa $this-texta$id
1067                        vtkActor2D $txa
1068                        $txa SetMapper $tx
1069                        [$txa GetPositionCoordinate] \
1070                            SetCoordinateSystemToNormalizedDisplay
1071                        [$txa GetPositionCoordinate] SetValue 0.02 0.98
1072
1073                        $_renderer AddActor $txa
1074                        lappend _actors $txa
1075
1076                        lappend _obj2vtk($dataobj) $tx $txa
1077
1078                        # turn off all slicers by default
1079                        foreach axis {x y z} {
1080                            $itk_component(${axis}slicer) configure -state normal
1081                            $itk_component(${axis}slicer) set 50
1082                            Slice move $axis 50
1083                            Slice axis $axis off
1084                        }
1085                    }
1086
1087                } else {
1088                    pack forget $itk_component(slicers)
1089                    pack $itk_component(reset) -side top
1090                    pack $itk_component(zoomin) -side top
1091                    pack $itk_component(zoomout) -side top
1092
1093                    set pd $this-polydata$id
1094                    vtkPolyData $pd
1095                    $pd SetPoints [$dataobj mesh $comp]
1096                    [$pd GetPointData] SetScalars [$dataobj values $comp]
1097
1098                    set tr $this-triangles$id
1099                    vtkDelaunay2D $tr
1100                    $tr SetInput $pd
1101                    $tr SetTolerance 0.0000000000001
1102                    set source [$tr GetOutput]
1103
1104                    set mp $this-mapper$id
1105                    vtkPolyDataMapper $mp
1106                    $mp SetInput $source
1107                    $mp SetScalarRange $v0 $v1
1108                    $mp SetLookupTable $lu
1109
1110                    set ac $this-actor$id
1111                    vtkActor $ac
1112                    $ac SetMapper $mp
1113                    $ac SetPosition 0 0 0
1114                    [$ac GetProperty] SetColor 0 0 0
1115                    $_renderer AddActor $ac
1116                    lappend _actors $ac
1117
1118                    lappend _obj2vtk($dataobj) $pd $tr $mp $ac
1119                }
1120            } else {
1121                #
1122                # Add color lines
1123                #
1124                set cf $this-clfilter$id
1125                vtkContourFilter $cf
1126                $cf SetInput $source
1127                $cf GenerateValues 20 $v0 $v1
1128
1129                set mp $this-clmapper$id
1130                vtkPolyDataMapper $mp
1131                $mp SetInput [$cf GetOutput]
1132                $mp SetScalarRange $v0 $v1
1133                $mp SetLookupTable $lu
1134
1135                set ac $this-clactor$id
1136                vtkActor $ac
1137                $ac SetMapper $mp
1138                [$ac GetProperty] SetColor 1 1 1
1139                $ac SetPosition 0 0 0
1140                $_renderer AddActor $ac
1141                lappend _actors $ac
1142
1143                lappend _obj2vtk($dataobj) $cf $mp $ac
1144            }
1145
1146            #
1147            # Add an outline around the data
1148            #
1149            if {$id == 0} {
1150                set olf $this-olfilter$id
1151                vtkOutlineFilter $olf
1152                $olf SetInput $source
1153
1154                set olm $this-olmapper$id
1155                vtkPolyDataMapper $olm
1156                $olm SetInput [$olf GetOutput]
1157
1158                set ola $this-olactor$id
1159                vtkActor $ola
1160                $ola SetMapper $olm
1161                eval [$ola GetProperty] SetColor [_color2rgb $itk_option(-plotforeground)]
1162                $_renderer AddActor $ola
1163                lappend _actors $ola
1164
1165                lappend _obj2vtk($dataobj) $olf $olm $ola
1166
1167                if {$_dims == "3D"} {
1168                    # pick a good scale factor for text
1169                    if {$xr < $yr} {
1170                        set tscale [expr {0.1*$xr}]
1171                    } else {
1172                        set tscale [expr {0.1*$yr}]
1173                    }
1174
1175                    foreach {i axis px py pz rx ry rz} {
1176                        0  x   $xm   0   0   90   0   0
1177                        1  y     0 $ym   0   90 -90   0
1178                        2  z   $x1   0 $zm   90   0 -45
1179                    } {
1180                        set length "[expr {[set ${axis}1]-[set ${axis}0]}]"
1181
1182                        set vtx $this-${axis}label$id
1183                        vtkVectorText $vtx
1184                        $vtx SetText "$axis"
1185
1186                        set vmp $this-${axis}lmap$id
1187                        vtkPolyDataMapper $vmp
1188                        $vmp SetInput [$vtx GetOutput]
1189
1190                        set vac $this-${axis}lact$id
1191                        vtkActor $vac
1192                        $vac SetMapper $vmp
1193                        $vac SetPosition [expr $px] [expr $py] [expr $pz]
1194                        $vac SetOrientation $rx $ry $rz
1195                        $vac SetScale $tscale
1196                        $_renderer AddActor $vac
1197
1198                        lappend _obj2vtk($dataobj) $vtx $vmp $vac
1199                        lappend _actors $vac
1200
1201                        $vmp Update
1202                        foreach {xx0 xx1 yy0 yy1 zz0 zz1} [$vac GetBounds] break
1203                        switch -- $axis {
1204                          x {
1205                            set dx [expr {-0.5*($xx1-$xx0)}]
1206                            set dy 0
1207                            set dz [expr {1.3*($zz0-$zz1)}]
1208                          }
1209                          y {
1210                            set dx 0
1211                            set dy [expr {0.5*($yy1-$yy0)}]
1212                            set dz [expr {$zz0-$zz1}]
1213                          }
1214                          z {
1215                            set dx [expr {0.2*$tscale}]
1216                            set dy $dx
1217                            set dz [expr {-0.5*($zz1-$zz0)}]
1218                          }
1219                        }
1220                        $vac AddPosition $dx $dy $dz
1221                    }
1222                }
1223            }
1224
1225            #
1226            # Add a legend with the scale.
1227            #
1228            if {$id == 0} {
1229                set lg $this-legend$id
1230                vtkScalarBarActor $lg
1231                $lg SetLookupTable $lu
1232                [$lg GetPositionCoordinate] SetCoordinateSystemToNormalizedViewport
1233                [$lg GetPositionCoordinate] SetValue 0.1 0.1
1234                $lg SetOrientationToHorizontal
1235                $lg SetWidth 0.8
1236                $lg SetHeight 1.0
1237
1238                set tp [$lg GetLabelTextProperty]
1239                eval $tp SetColor [_color2rgb $itk_option(-plotforeground)]
1240                $tp BoldOff
1241                $tp ItalicOff
1242                $tp ShadowOff
1243                #eval $tp SetShadowColor [_color2rgb gray]
1244
1245                if 0 {
1246                $this-vtkRenderer2 AddActor2D $lg
1247                lappend _actors $lg
1248                lappend _obj2vtk($dataobj) $lg
1249                }
1250            }
1251            }
1252            incr id
1253        }
1254        set firstobj 0
1255    }
1256    _fixLimits
1257    Zoom reset
1258    $_interactor Start
1259    $_window Render
1260
1261    #
1262    # HACK ALERT!  A single ResetCamera doesn't seem to work for
1263    #   some contour data.  You have to do it multiple times to
1264    #   get to the right zoom factor on data.  I hope 20 times is
1265    #   enough.  I hate Vtk sometimes...
1266    #
1267    for {set i 0} {$i < 20} {incr i} {
1268        $_renderer ResetCamera
1269        [$_renderer GetActiveCamera] Zoom 1.5
1270    }
1271
1272    # prevent interactions -- use our own
1273    blt::busy hold $itk_component(area) -cursor left_ptr
1274    bind $itk_component(area)_Busy <ButtonPress> \
1275        [itcl::code $this Move click %x %y]
1276    bind $itk_component(area)_Busy <B1-Motion> \
1277        [itcl::code $this Move drag %x %y]
1278    bind $itk_component(area)_Busy <ButtonRelease> \
1279        [itcl::code $this Move release %x %y]
1280}
1281
1282itcl::body Rappture::VtkViewer::BuildViewTab {} {
1283    foreach { key value } {
1284        edges           1
1285        axes            1
1286        wireframe       0
1287        volume          1
1288        legend          1
1289        particles       1
1290        lic             1
1291    } {
1292        set _settings($this-$key) $value
1293    }
1294
1295    set fg [option get $itk_component(hull) font Font]
1296    #set bfg [option get $itk_component(hull) boldFont Font]
1297
1298    set tab [$itk_component(main) insert end \
1299        -title "View Settings" \
1300        -icon [Rappture::icon wrench]]
1301    blt::scrollset $tab.ss \
1302        -xscrollbar $tab.ss.xs \
1303        -yscrollbar $tab.ss.ys \
1304        -window $tab.ss.frame
1305    pack $tab.ss -fill both -expand yes
1306    blt::tk::scrollbar $tab.ss.xs               
1307    blt::tk::scrollbar $tab.ss.ys               
1308    set inner [blt::tk::frame $tab.ss.frame]
1309    $inner configure -borderwidth 4
1310
1311    set ::Rappture::VtkViewer::_settings($this-isosurface) 0
1312    checkbutton $inner.isosurface \
1313        -text "Isosurface shading" \
1314        -variable [itcl::scope _settings($this-isosurface)] \
1315        -command [itcl::code $this FixSettings isosurface] \
1316        -font "Arial 9"
1317
1318    checkbutton $inner.axes \
1319        -text "Axes" \
1320        -variable [itcl::scope _settings($this-axes)] \
1321        -command [itcl::code $this FixSettings axes] \
1322        -font "Arial 9"
1323
1324    checkbutton $inner.edges \
1325        -text "Edges" \
1326        -variable [itcl::scope _settings($this-edges)] \
1327        -command [itcl::code $this FixSettings edges] \
1328        -font "Arial 9"
1329
1330    checkbutton $inner.wireframe \
1331        -text "Wireframe" \
1332        -variable [itcl::scope _settings($this-wireframe)] \
1333        -command [itcl::code $this FixSettings wireframe] \
1334        -font "Arial 9"
1335
1336    checkbutton $inner.legend \
1337        -text "Legend" \
1338        -variable [itcl::scope _settings($this-legend)] \
1339        -command [itcl::code $this FixSettings legend] \
1340        -font "Arial 9"
1341
1342    checkbutton $inner.volume \
1343        -text "Volume" \
1344        -variable [itcl::scope _settings($this-volume)] \
1345        -command [itcl::code $this FixSettings volume] \
1346        -font "Arial 9"
1347
1348    blt::table $inner \
1349        0,0 $inner.axes  -columnspan 2 -anchor w \
1350        1,0 $inner.edges  -columnspan 2 -anchor w \
1351        2,0 $inner.wireframe  -columnspan 2 -anchor w \
1352        3,0 $inner.volume  -columnspan 2 -anchor w \
1353        4,0 $inner.legend  -columnspan 2 -anchor w
1354
1355    if 0 {
1356    bind $inner <Map> [itcl::code $this GetVolumeInfo $inner]
1357    }
1358    blt::table configure $inner r* -resize none
1359    blt::table configure $inner r5 -resize expand
1360}
1361
1362itcl::body Rappture::VtkViewer::BuildVolumeTab {} {
1363    foreach { key value } {
1364        light           40
1365        transp          50
1366        opacity         1000
1367    } {
1368        set _settings($this-$key) $value
1369    }
1370
1371    set tab [$itk_component(main) insert end \
1372        -title "Volume Settings" \
1373        -icon [Rappture::icon volume-on]]
1374    blt::scrollset $tab.ss \
1375        -xscrollbar $tab.ss.xs \
1376        -yscrollbar $tab.ss.ys \
1377        -window $tab.ss.frame
1378    pack $tab.ss -fill both -expand yes
1379    blt::tk::scrollbar $tab.ss.xs               
1380    blt::tk::scrollbar $tab.ss.ys               
1381    set inner [blt::tk::frame $tab.ss.frame]
1382    $inner configure -borderwidth 4
1383
1384    set fg [option get $itk_component(hull) font Font]
1385    #set bfg [option get $itk_component(hull) boldFont Font]
1386
1387    checkbutton $inner.vol -text "Show volume" -font $fg \
1388        -variable [itcl::scope _settings($this-volume)] \
1389        -command [itcl::code $this FixSettings volume]
1390    label $inner.shading -text "Shading:" -font $fg
1391
1392    label $inner.dim -text "Dim" -font $fg
1393    ::scale $inner.light -from 0 -to 100 -orient horizontal \
1394        -variable [itcl::scope _settings($this-light)] \
1395        -width 10 \
1396        -showvalue off -command [itcl::code $this FixSettings light]
1397    label $inner.bright -text "Bright" -font $fg
1398
1399    label $inner.fog -text "Fog" -font $fg
1400    ::scale $inner.transp -from 0 -to 100 -orient horizontal \
1401        -variable [itcl::scope _settings($this-transp)] \
1402        -width 10 \
1403        -showvalue off -command [itcl::code $this FixSettings transp]
1404    label $inner.plastic -text "Plastic" -font $fg
1405
1406    label $inner.clear -text "Clear" -font $fg
1407    ::scale $inner.opacity -from 0 -to 100 -orient horizontal \
1408        -variable [itcl::scope _settings($this-opacity)] \
1409        -width 10 \
1410        -showvalue off -command [itcl::code $this FixSettings opacity]
1411    label $inner.opaque -text "Opaque" -font $fg
1412
1413    blt::table $inner \
1414        0,0 $inner.vol -columnspan 4 -anchor w -pady 2 \
1415        1,0 $inner.shading -columnspan 4 -anchor w -pady {10 2} \
1416        2,0 $inner.dim -anchor e -pady 2 \
1417        2,1 $inner.light -columnspan 2 -pady 2 -fill x \
1418        2,3 $inner.bright -anchor w -pady 2 \
1419        3,0 $inner.fog -anchor e -pady 2 \
1420        3,1 $inner.transp -columnspan 2 -pady 2 -fill x \
1421        3,3 $inner.plastic -anchor w -pady 2 \
1422        4,0 $inner.clear -anchor e -pady 2 \
1423        4,1 $inner.opacity -columnspan 2 -pady 2 -fill x\
1424        4,3 $inner.opaque -anchor w -pady 2
1425
1426    blt::table configure $inner c0 c1 c3 r* -resize none
1427    blt::table configure $inner r6 -resize expand
1428}
1429
1430itcl::body Rappture::VtkViewer::BuildCutplanesTab {} {
1431
1432    set tab [$itk_component(main) insert end \
1433        -title "Cutplane Settings" \
1434        -icon [Rappture::icon cutbutton]]
1435    blt::scrollset $tab.ss \
1436        -xscrollbar $tab.ss.xs \
1437        -yscrollbar $tab.ss.ys \
1438        -window $tab.ss.frame
1439    pack $tab.ss -fill both -expand yes
1440    blt::tk::scrollbar $tab.ss.xs               
1441    blt::tk::scrollbar $tab.ss.ys               
1442    set inner [blt::tk::frame $tab.ss.frame]
1443    $inner configure -borderwidth 4
1444
1445    # X-value slicer...
1446    itk_component add xCutButton {
1447        Rappture::PushButton $inner.xbutton \
1448            -onimage [Rappture::icon x-cutplane] \
1449            -offimage [Rappture::icon x-cutplane] \
1450            -command [itcl::code $this FixSettings xcutplane] \
1451            -variable [itcl::scope _settings($this-xcutplane)]
1452    }
1453    Rappture::Tooltip::for $itk_component(xCutButton) \
1454        "Toggle the X cut plane on/off"
1455
1456    itk_component add xCutScale {
1457        ::scale $inner.xval -from 100 -to 0 \
1458            -width 10 -orient vertical -showvalue off -state disabled \
1459            -borderwidth 1 -highlightthickness 0 \
1460            -command [itcl::code $this Slice move x]
1461    } {
1462        usual
1463        ignore -borderwidth -highlightthickness
1464    }
1465    # Set the default cutplane value before disabling the scale.
1466    $itk_component(xCutScale) set 50
1467    $itk_component(xCutScale) configure -state disabled
1468    Rappture::Tooltip::for $itk_component(xCutScale) \
1469        "@[itcl::code $this SlicerTip x]"
1470
1471    # Y-value slicer...
1472    itk_component add yCutButton {
1473        Rappture::PushButton $inner.ybutton \
1474            -onimage [Rappture::icon y-cutplane] \
1475            -offimage [Rappture::icon y-cutplane] \
1476            -command [itcl::code $this FixSettings ycutplane] \
1477            -variable [itcl::scope _settings($this-ycutplane)]
1478    }
1479    Rappture::Tooltip::for $itk_component(yCutButton) \
1480        "Toggle the Y cut plane on/off"
1481
1482    itk_component add yCutScale {
1483        ::scale $inner.yval -from 100 -to 0 \
1484            -width 10 -orient vertical -showvalue off -state disabled \
1485            -borderwidth 1 -highlightthickness 0 \
1486            -command [itcl::code $this Slice move y]
1487    } {
1488        usual
1489        ignore -borderwidth -highlightthickness
1490    }
1491    Rappture::Tooltip::for $itk_component(yCutScale) \
1492        "@[itcl::code $this SlicerTip y]"
1493    # Set the default cutplane value before disabling the scale.
1494    $itk_component(yCutScale) set 50
1495    $itk_component(yCutScale) configure -state disabled
1496
1497    # Z-value slicer...
1498    itk_component add zCutButton {
1499        Rappture::PushButton $inner.zbutton \
1500            -onimage [Rappture::icon z-cutplane] \
1501            -offimage [Rappture::icon z-cutplane] \
1502            -command [itcl::code $this FixSettings zcutplane] \
1503            -variable [itcl::scope _settings($this-zcutplane)]
1504    }
1505    Rappture::Tooltip::for $itk_component(zCutButton) \
1506        "Toggle the Z cut plane on/off"
1507
1508    itk_component add zCutScale {
1509        ::scale $inner.zval -from 100 -to 0 \
1510            -width 10 -orient vertical -showvalue off -state disabled \
1511            -borderwidth 1 -highlightthickness 0 \
1512            -command [itcl::code $this Slice move z]
1513    } {
1514        usual
1515        ignore -borderwidth -highlightthickness
1516    }
1517    $itk_component(zCutScale) set 50
1518    $itk_component(zCutScale) configure -state disabled
1519    #$itk_component(zCutScale) configure -state disabled
1520    Rappture::Tooltip::for $itk_component(zCutScale) \
1521        "@[itcl::code $this SlicerTip z]"
1522
1523    blt::table $inner \
1524        1,1 $itk_component(xCutButton) \
1525        1,2 $itk_component(yCutButton) \
1526        1,3 $itk_component(zCutButton) \
1527        0,1 $itk_component(xCutScale) \
1528        0,2 $itk_component(yCutScale) \
1529        0,3 $itk_component(zCutScale)
1530
1531    blt::table configure $inner r0 r1 c* -resize none
1532    blt::table configure $inner r2 c4 -resize expand
1533    blt::table configure $inner c0 -width 2
1534    blt::table configure $inner c1 c2 c3 -padx 2
1535}
1536
1537itcl::body Rappture::VtkViewer::BuildCameraTab {} {
1538    set tab [$itk_component(main) insert end \
1539        -title "Camera Settings" \
1540        -icon [Rappture::icon camera]]
1541    blt::scrollset $tab.ss \
1542        -xscrollbar $tab.ss.xs \
1543        -yscrollbar $tab.ss.ys \
1544        -window $tab.ss.frame
1545    blt::tk::scrollbar $tab.ss.xs               
1546    blt::tk::scrollbar $tab.ss.ys               
1547    pack $tab.ss -fill both -expand yes
1548    set inner [blt::tk::frame $tab.ss.frame]
1549    $inner configure -borderwidth 4
1550
1551    set labels { phi theta psi pan-x pan-y zoom }
1552    set row 0
1553    foreach tag $labels {
1554        label $inner.${tag}label -text $tag -font "Arial 9"
1555        entry $inner.${tag} -font "Arial 9"  -bg white \
1556            -textvariable [itcl::scope _settings($this-$tag)]
1557        bind $inner.${tag} <KeyPress-Return> \
1558            [itcl::code $this camera set ${tag}]
1559        blt::table $inner \
1560            $row,0 $inner.${tag}label -anchor e -pady 2 \
1561            $row,1 $inner.${tag} -anchor w -pady 2
1562        blt::table configure $inner r$row -resize none
1563        incr row
1564    }
1565    blt::table configure $inner c0 c1 -resize none
1566    blt::table configure $inner c2 -resize expand
1567    blt::table configure $inner r$row -resize expand
1568}
1569
1570# ----------------------------------------------------------------------
1571# USAGE: FixSettings <what> ?<value>?
1572#
1573# Used internally to update rendering settings whenever parameters
1574# change in the popup settings panel.  Sends the new settings off
1575# to the back end.
1576# ----------------------------------------------------------------------
1577itcl::body Rappture::VtkViewer::FixSettings {what {value ""}} {
1578    switch -- $what {
1579        light {
1580        }
1581        transp {
1582        }
1583        opacity {
1584            set new [expr $_settings($this-opacity) * 0.01]
1585            foreach dataobj [get] {
1586                foreach comp [$dataobj components] {
1587                    set actor [$dataobj values $comp]
1588                    set prop [$actor GetProperty]
1589                    $prop SetOpacity $new
1590                }
1591            }
1592            $_window Render
1593        }
1594
1595        "wireframe" {
1596            foreach dataobj [get] {
1597                foreach comp [$dataobj components] {
1598                    set actor [$dataobj values $comp]
1599                    set prop [$actor GetProperty]
1600                    if { $_settings($this-wireframe) } {
1601                        $prop SetRepresentationToWireframe
1602                    } else {
1603                        $prop SetRepresentationToSurface
1604                    }
1605                }
1606            }
1607            $_window Render
1608        }
1609        "isosurface" {
1610        }
1611        "edges" {
1612            foreach dataobj [get] {
1613                foreach comp [$dataobj components] {
1614                    set actor [$dataobj values $comp]
1615                    set prop [$actor GetProperty]
1616                    if { $_settings($this-edges) } {
1617                        $prop EdgeVisibilityOn
1618                    } else {
1619                        $prop EdgeVisibilityOff
1620                    }
1621                }
1622            }
1623            $_window Render
1624        }
1625        "axes" {
1626            if { $_settings($this-axes) } {
1627                $_cubeAxesActor VisibilityOn
1628            } else {
1629                $_cubeAxesActor VisibilityOff
1630            }
1631            $_window Render
1632        }
1633        "legend" {
1634            if { $_settings($this-legend) } {
1635                blt::table $itk_component(plotarea) \
1636                    0,0 $itk_component(3dview) -fill both \
1637                    1,0 $itk_component(legend) -fill x
1638                blt::table configure $itk_component(plotarea) r1 -resize none
1639            } else {
1640                blt::table forget $itk_component(legend)
1641            }
1642        }
1643        "volume" {
1644        }
1645        "xcutplane" - "ycutplane" - "zcutplane" {
1646            set axis [string range $what 0 0]
1647            set bool $_settings($this-$what)
1648            if { $bool } {
1649                $itk_component(${axis}CutScale) configure -state normal \
1650                    -troughcolor white
1651            } else {
1652                $itk_component(${axis}CutScale) configure -state disabled \
1653                    -troughcolor grey82
1654            }
1655        }
1656        default {
1657            error "don't know how to fix $what"
1658        }
1659    }
1660}
1661
1662if 0 {
1663    #
1664    # Create slicer controls...
1665    #
1666    itk_component add slicers {
1667        frame $itk_component(controls).slicers
1668    } {
1669        usual
1670        rename -background -controlbackground controlBackground Background
1671    }
1672    pack $itk_component(slicers) -side bottom -padx 4 -pady 4
1673    grid rowconfigure $itk_component(slicers) 1 -weight 1
1674
1675    #
1676    # X-value slicer...
1677    #
1678    itk_component add xslice {
1679        label $itk_component(slicers).xslice \
1680            -borderwidth 1 -relief raised -padx 1 -pady 1 \
1681            -bitmap [Rappture::icon x]
1682    } {
1683        usual
1684        ignore -borderwidth
1685        rename -highlightbackground -controlbackground controlBackground Background
1686    }
1687    bind $itk_component(xslice) <ButtonPress> \
1688        [itcl::code $this Slice axis x toggle]
1689    Rappture::Tooltip::for $itk_component(xslice) \
1690        "Toggle the X cut plane on/off"
1691    grid $itk_component(xslice) -row 0 -column 0 -sticky ew -padx 1
1692
1693    itk_component add xslicer {
1694        ::scale $itk_component(slicers).xval -from 100 -to 0 \
1695            -width 10 -orient vertical -showvalue off -state disabled \
1696            -borderwidth 1 -highlightthickness 0 \
1697            -command [itcl::code $this Slice move x]
1698    } {
1699        usual
1700        ignore -borderwidth
1701        ignore -highlightthickness
1702        rename -highlightbackground -controlbackground controlBackground Background
1703        rename -troughcolor -controldarkbackground controlDarkBackground Background
1704    }
1705    grid $itk_component(xslicer) -row 1 -column 0 -padx 1
1706    Rappture::Tooltip::for $itk_component(xslicer) \
1707        "@[itcl::code $this Slicertip x]"
1708
1709    #
1710    # Y-value slicer...
1711    #
1712    itk_component add yslice {
1713        label $itk_component(slicers).yslice \
1714            -borderwidth 1 -relief raised -padx 1 -pady 1 \
1715            -bitmap [Rappture::icon y]
1716    } {
1717        usual
1718        ignore -borderwidth
1719        rename -highlightbackground -controlbackground controlBackground Background
1720    }
1721    bind $itk_component(yslice) <ButtonPress> \
1722        [itcl::code $this Slice axis y toggle]
1723    Rappture::Tooltip::for $itk_component(yslice) \
1724        "Toggle the Y cut plane on/off"
1725    grid $itk_component(yslice) -row 0 -column 1 -sticky ew -padx 1
1726
1727    itk_component add yslicer {
1728        ::scale $itk_component(slicers).yval -from 100 -to 0 \
1729            -width 10 -orient vertical -showvalue off -state disabled \
1730            -borderwidth 1 -highlightthickness 0 \
1731            -command [itcl::code $this Slice move y]
1732    } {
1733        usual
1734        ignore -borderwidth
1735        ignore -highlightthickness
1736        rename -highlightbackground -controlbackground controlBackground Background
1737        rename -troughcolor -controldarkbackground controlDarkBackground Background
1738    }
1739    grid $itk_component(yslicer) -row 1 -column 1 -padx 1
1740    Rappture::Tooltip::for $itk_component(yslicer) \
1741        "@[itcl::code $this Slicertip y]"
1742
1743    #
1744    # Z-value slicer...
1745    #
1746    itk_component add zslice {
1747        label $itk_component(slicers).zslice \
1748            -borderwidth 1 -relief raised -padx 1 -pady 1 \
1749            -bitmap [Rappture::icon z]
1750    } {
1751        usual
1752        ignore -borderwidth
1753        rename -highlightbackground -controlbackground controlBackground Background
1754    }
1755    grid $itk_component(zslice) -row 0 -column 2 -sticky ew -padx 1
1756    bind $itk_component(zslice) <ButtonPress> \
1757        [itcl::code $this Slice axis z toggle]
1758    Rappture::Tooltip::for $itk_component(zslice) \
1759        "Toggle the Z cut plane on/off"
1760
1761    itk_component add zslicer {
1762        ::scale $itk_component(slicers).zval -from 100 -to 0 \
1763            -width 10 -orient vertical -showvalue off -state disabled \
1764            -borderwidth 1 -highlightthickness 0 \
1765            -command [itcl::code $this Slice move z]
1766    } {
1767        usual
1768        ignore -borderwidth
1769        ignore -highlightthickness
1770        rename -highlightbackground -controlbackground controlBackground Background
1771        rename -troughcolor -controldarkbackground controlDarkBackground Background
1772    }
1773    grid $itk_component(zslicer) -row 1 -column 2 -padx 1
1774    Rappture::Tooltip::for $itk_component(zslicer) \
1775        "@[itcl::code $this Slicertip z]"
1776
1777}
1778
1779itcl::body Rappture::VtkViewer::GetLimits {} {
1780    return [list $_limits(xMin) $_limits(xMax) \
1781                $_limits(yMin) $_limits(yMax) \
1782                $_limits(zMin) $_limits(zMax)]
1783}
1784
1785itcl::body Rappture::VtkViewer::ComputeLimits { args } {
1786    array set _limits {
1787        xMin 0
1788        xMax 1
1789        yMin 0
1790        yMax 1
1791        zMin 0
1792        zMax 1
1793        vMin 0
1794        vMax 1
1795    }
1796    set actors {}
1797    if { [llength $args] > 0 } {
1798        foreach dataobj $args {
1799            foreach comp [$dataobj components] {
1800                lappend actors [$dataobj values $comp]
1801            }
1802        }
1803    } else {
1804        foreach dataobj [get] {
1805            foreach comp [$dataobj components] {
1806                lappend actors [$dataobj values $comp]
1807            }
1808        }
1809    }
1810    if { [llength $actors] == 0 } {
1811        return
1812    }
1813    set actor [lindex $actors 0]
1814    foreach key { xMin xMax yMin yMax zMin zMax} value [$actor GetBounds] {
1815        set _limits($key) $value
1816    }
1817    foreach actor [lrange $actors 1 end] {
1818        foreach { xMin xMax yMin yMax zMin zMax} [$actor GetBounds] break
1819        if { $xMin < $_limits(xMin) } {
1820            set _limits(xMin) $xMin
1821        }
1822        if { $xMax > $_limits(xMax) } {
1823            set _limits(xMax) $xMax
1824        }
1825        if { $yMin < $_limits(yMin) } {
1826            set _limits(yMin) $yMin
1827        }
1828        if { $yMax > $_limits(yMax) } {
1829            set _limits(yMax) $yMax
1830        }
1831        if { $zMin < $_limits(zMin) } {
1832            set _limits(zMin) $zMin
1833        }
1834        if { $zMax > $_limits(zMax) } {
1835            set _limits(zMax) $zMax
1836        }
1837    }
1838    set _limits(vMin) $_limits(zMin)
1839    set _limits(vMax) $_limits(zMax)
1840}
Note: See TracBrowser for help on using the repository browser.