source: trunk/gui/scripts/vtkviewer.tcl @ 2148

Last change on this file since 2148 was 2148, checked in by gah, 14 years ago
File size: 35.4 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 _dataobj2vtk  ;# maps dataobj => vtk objects
44    private variable _actors       ;# array of actors for each dataobj.
45    private variable _lights       ;# list of lights for each renderer
46    private variable _click        ;# info used for _move operations
47    private variable _limits       ;# autoscale min/max for all axes
48    private variable _view         ;# view params for 3D view
49    private variable _download ""  ;# snapshot for download
50
51    private variable _renderer "";
52    private variable _window "";
53    private variable _interactor "";
54    private variable _style "";
55    private variable _light "";
56    private variable _cubeAxesActor ""
57    private variable _axesActor ""
58    private variable _axesWidget "";
59    private variable _settings
60    constructor {args} {
61        # defined below
62    }
63    destructor {
64        # defined below
65    }
66
67    public method add {dataobj {settings ""}}
68    public method get {}
69    public method delete {args}
70    public method scale {args}
71    public method parameters {title args} {
72        # do nothing
73    }
74    public method download {option args}
75
76    protected method Rebuild {}
77    protected method Clear {}
78    protected method Zoom {option}
79    protected method Move {option x y}
80    protected method _3dView {theta phi}
81    protected method _fixLimits {}
82    protected method _color2rgb {color}
83    protected method SetActorProperties { actor style }
84
85    private method ComputeLimits { args }
86    private method GetLimits {}
87    private method BuildCameraTab {}
88    private method UpdateCameraInfo {}
89    private method BuildViewTab {}
90    private method BuildVolumeTab {}
91    protected method FixSettings {what {value ""}}
92
93}
94
95itk::usual VtkViewer {
96    keep -background -foreground -cursor -font
97    keep -plotbackground -plotforeground
98}
99
100# ----------------------------------------------------------------------
101# CONSTRUCTOR
102# ----------------------------------------------------------------------
103itcl::body Rappture::VtkViewer::constructor {args} {
104    option add hull.width hull.height
105    pack propagate $itk_component(hull) no
106    set _view(theta) 0
107    set _view(phi) 0
108   
109    array set _limits {
110        xMin    0
111        xMax    1
112        yMin    0
113        yMax    1
114        zMin    0
115        zMax    1
116        vMin    0
117        vMax    1
118    }
119
120
121    foreach { key value } {
122        edges           1
123        axes            1
124        smallaxes       0
125        wireframe       0
126    } {
127        set _settings($this-$key) $value
128    }
129    itk_component add main {
130        Rappture::SidebarFrame $itk_interior.main
131    }
132    pack $itk_component(main) -expand yes -fill both
133    set f [$itk_component(main) component frame]
134   
135    itk_component add controls {
136        frame $f.cntls
137    } {
138        usual
139        rename -background -controlbackground controlBackground Background
140    }
141    pack $itk_component(controls) -side right -fill y
142
143    itk_component add zoom {
144        frame $itk_component(controls).zoom
145    } {
146        usual
147        rename -background -controlbackground controlBackground Background
148    }
149    pack $itk_component(zoom) -side top
150   
151    itk_component add reset {
152        button $itk_component(zoom).reset \
153            -borderwidth 1 -padx 1 -pady 1 \
154            -bitmap [Rappture::icon reset] \
155            -command [itcl::code $this Zoom reset]
156    } {
157        usual
158        ignore -borderwidth
159        rename -highlightbackground -controlbackground controlBackground Background
160    }
161    pack $itk_component(reset) -padx 4 -pady 4
162    Rappture::Tooltip::for $itk_component(reset) \
163        "Reset the view to the default zoom level"
164
165    itk_component add zoomin {
166        button $itk_component(zoom).zin \
167            -borderwidth 1 -padx 1 -pady 1 \
168            -bitmap [Rappture::icon zoomin] \
169            -command [itcl::code $this Zoom in]
170    } {
171        usual
172        ignore -borderwidth
173        rename -highlightbackground -controlbackground controlBackground \
174            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 \
188            Background
189    }
190    pack $itk_component(zoomout) -padx 4 -pady 4
191    Rappture::Tooltip::for $itk_component(zoomout) "Zoom out"
192   
193    #
194    # RENDERING AREA
195    #
196    itk_component add area {
197        frame $f.area
198    }
199    pack $itk_component(area) -expand yes -fill both
200   
201    set _renderer [vtkRenderer $this-Renderer]
202    set _window [vtkRenderWindow $this-RenderWindow]
203    itk_component add plot {
204        vtkTkRenderWidget $itk_component(area).plot -rw $_window \
205            -width 1 -height 1
206    } {
207        # empty
208    }
209    pack $itk_component(plot) -expand yes -fill both
210    $_window AddRenderer $_renderer
211    $_window LineSmoothingOn
212    $_window PolygonSmoothingOn
213   
214    set _interactor [vtkRenderWindowInteractor $this-Interactor]
215    set _style [vtkInteractorStyleTrackballCamera $this-InteractorStyle]
216    $_interactor SetRenderWindow $_window
217    $_interactor SetInteractorStyle $_style
218    $_interactor Initialize
219   
220    set _cubeAxesActor [vtkCubeAxesActor $this-CubeAxesActor]
221    $_cubeAxesActor SetCamera [$_renderer GetActiveCamera]
222    $_renderer AddActor $_cubeAxesActor
223   
224    # Supply small axes guide.
225    set _axesActor [vtkAxesActor $this-AxesActor]
226    set _axesWidget [vtkOrientationMarkerWidget $this-AxesWidget]
227    $_axesWidget SetOrientationMarker $_axesActor
228    $_axesWidget SetInteractor $_interactor
229    $_axesWidget SetEnabled $_settings($this-smallaxes)
230    $_axesWidget SetInteractive 0
231    $_axesWidget SetViewport .7 0 1.0 0.3
232   
233    BuildViewTab
234    BuildCameraTab
235   
236    set v0 0
237    set v1 1
238    set _lookup [vtkLookupTable $this-Lookup]
239    $_lookup SetTableRange $v0 $v1
240    $_lookup SetHueRange 0.66667 0.0
241    $_lookup Build
242   
243    set lightKit [vtkLightKit $this-LightKit]
244    $lightKit AddLightsToRenderer $_renderer
245   
246    #
247    # Create a picture for download snapshots
248    #
249    set _download [image create photo]
250   
251    eval itk_initialize $args
252}
253
254# ----------------------------------------------------------------------
255# DESTRUCTOR
256# ----------------------------------------------------------------------
257itcl::body Rappture::VtkViewer::destructor {} {
258    Clear
259    after cancel [itcl::code $this Rebuild]
260   
261    foreach c [info commands $this-vtk*] {
262        rename $c ""
263    }
264    image delete $_download
265}
266
267# ----------------------------------------------------------------------
268# USAGE: add <dataobj> ?<settings>?
269#
270# Clients use this to add a data object to the plot.  The optional
271# <settings> are used to configure the plot.  Allowed settings are
272# -color, -brightness, -width, -linestyle, and -raise.
273# ----------------------------------------------------------------------
274itcl::body Rappture::VtkViewer::add {dataobj {settings ""}} {
275    array set params {
276        -color auto
277        -width 1
278        -linestyle solid
279        -brightness 0
280        -raise 0
281        -description ""
282        -param ""
283    }
284    foreach {opt val} $settings {
285        if {![info exists params($opt)]} {
286            error "bad setting \"$opt\": should be [join [lsort [array names params]] {, }]"
287        }
288        set params($opt) $val
289    }
290    if {$params(-color) == "auto" || $params(-color) == "autoreset"} {
291        # can't handle -autocolors yet
292        set params(-color) black
293    }
294    set pos [lsearch -exact $dataobj $_dlist]
295    if {$pos < 0} {
296        lappend _dlist $dataobj
297
298        set _obj2color($dataobj) $params(-color)
299        set _obj2width($dataobj) $params(-width)
300        set _obj2raise($dataobj) $params(-raise)
301       
302        after cancel [itcl::code $this Rebuild]
303        after idle [itcl::code $this Rebuild]
304    }
305}
306
307# ----------------------------------------------------------------------
308# USAGE: get
309#
310# Clients use this to query the list of objects being plotted, in
311# order from bottom to top of this result.
312# ----------------------------------------------------------------------
313itcl::body Rappture::VtkViewer::get {} {
314    # put the dataobj list in order according to -raise options
315    set dlist $_dlist
316    foreach obj $dlist {
317        if {[info exists _obj2raise($obj)] && $_obj2raise($obj)} {
318            set i [lsearch -exact $dlist $obj]
319            if {$i >= 0} {
320                set dlist [lreplace $dlist $i $i]
321                lappend dlist $obj
322            }
323        }
324    }
325    return $dlist
326}
327
328# ----------------------------------------------------------------------
329# USAGE: delete ?<dataobj1> <dataobj2> ...?
330#
331# Clients use this to delete a dataobj from the plot.  If no dataobjs
332# are specified, then all dataobjs are deleted.
333# ----------------------------------------------------------------------
334itcl::body Rappture::VtkViewer::delete {args} {
335    if {[llength $args] == 0} {
336        set args $_dlist
337    }
338
339    # delete all specified dataobjs
340    set changed 0
341    foreach dataobj $args {
342        set i [lsearch -exact $_dlist $dataobj]
343        if {$i >= 0} {
344            set _dlist [lreplace $_dlist $i $i]
345            catch {unset _obj2color($dataobj)}
346            catch {unset _obj2width($dataobj)}
347            catch {unset _obj2raise($dataobj)}
348            foreach actor $_actors($dataobj) {
349                $_renderer RemoveActor $actor
350            }
351            array unset _actors $dataobj
352            array unset _dataobj2vtk $dataobj-*
353            set changed 1
354        }
355    }
356    # If anything changed, then rebuild the plot
357    if {$changed} {
358        after cancel [itcl::code $this Rebuild]
359        after idle [itcl::code $this Rebuild]
360    }
361}
362
363# ----------------------------------------------------------------------
364# USAGE: scale ?<data1> <data2> ...?
365#
366# Sets the default limits for the overall plot according to the
367# limits of the data for all of the given <data> objects.  This
368# accounts for all objects--even those not showing on the screen.
369# Because of this, the limits are appropriate for all objects as
370# the user scans through data in the ResultSet viewer.
371# ----------------------------------------------------------------------
372itcl::body Rappture::VtkViewer::scale {args} {
373    eval ComputeLimits $args
374    _fixLimits
375}
376
377# ----------------------------------------------------------------------
378# USAGE: download coming
379# USAGE: download controls <downloadCommand>
380# USAGE: download now
381#
382# Clients use this method to create a downloadable representation
383# of the plot.  Returns a list of the form {ext string}, where
384# "ext" is the file extension (indicating the type of data) and
385# "string" is the data itself.
386# ----------------------------------------------------------------------
387itcl::body Rappture::VtkViewer::download {option args} {
388    switch $option {
389        coming {
390            if {[catch {
391                blt::winop snap $itk_component(plotarea) $_download
392            }]} {
393                $_download configure -width 1 -height 1
394                $_download put #000000
395            }
396        }
397        controls {
398            # no controls for this download yet
399            return ""
400        }
401        now {
402            set writer [vtkJPEGWriter $this-vtkJPEGWriter]
403            set large [vtkRenderLargeImage $this-RenderLargeImage]
404            $_axesWidget SetEnabled 0
405            $large SetInput $_renderer
406            $large SetMagnification 4
407            $writer SetInputConnection [$large GetOutputPort]
408
409            $writer SetFileName junk.jpg
410            $writer Write
411            rename $writer ""
412            rename $large ""
413            FixSettings smallaxes
414
415            set img [image create photo -file junk.jpg]
416            set bytes [$img data -format "jpeg -quality 100"]
417            set bytes [Rappture::encoding::decode -as b64 $bytes]
418            image delete $img
419            return [list .jpg $bytes]
420        }
421        default {
422            error "bad option \"$option\": should be coming, controls, now"
423        }
424    }
425}
426
427# ----------------------------------------------------------------------
428# USAGE: Clear
429#
430# Used internally to clear the drawing area and tear down all vtk
431# objects in the current scene.
432# ----------------------------------------------------------------------
433itcl::body Rappture::VtkViewer::Clear {} {
434    # clear out any old constructs
435   
436    foreach ren [array names _lights] {
437        foreach light $_lights($ren) {
438            $ren RemoveLight $light
439            rename $light ""
440        }
441        set _lights($ren) ""
442    }
443    foreach dataobj $_dlist {
444        foreach actor $_actors($dataobj) {
445            $_renderer RemoveActor $actor
446        }
447    }
448    array unset _actors
449    set _dlist ""
450    array unset _dataobj2vtk
451}
452
453# ----------------------------------------------------------------------
454# USAGE: Zoom in
455# USAGE: Zoom out
456# USAGE: Zoom reset
457#
458# Called automatically when the user clicks on one of the zoom
459# controls for this widget.  Changes the zoom for the current view.
460# ----------------------------------------------------------------------
461itcl::body Rappture::VtkViewer::Zoom {option} {
462    set cam [$_renderer GetActiveCamera]
463    switch -- $option {
464        in {
465            $cam Zoom 1.25
466            $_window Render
467        }
468        out {
469            $cam Zoom 0.8
470            $_window Render
471        }
472        reset {
473            $cam SetViewAngle 30
474            $_renderer ResetCamera
475            _3dView 90 -90
476            array set camera {
477                xpos 1.73477e-06 ypos 74.7518 zpos -1.73477e-06
478                xviewup 5.38569e-16 yviewup 2.32071e-08 zviewup 1.0
479                xfocal 0.0 yfocal 0.0 zfocal 0.0
480            }
481            set dataobj [lindex $_dlist end]
482            if { $dataobj != "" } {
483                array set camera [$dataobj hints camera]
484            }
485            $cam SetFocalPoint $camera(xfocal) $camera(yfocal) $camera(zfocal)
486            $cam SetPosition $camera(xpos) $camera(ypos) $camera(zpos)
487            $cam SetViewUp $camera(xviewup) $camera(yviewup) $camera(zviewup)
488            foreach key [array names camera] {
489                set _settings($this-$key) $camera($key)
490            }
491            $_window Render
492        }
493    }
494}
495
496# ----------------------------------------------------------------------
497# USAGE: Move click <x> <y>
498# USAGE: Move drag <x> <y>
499# USAGE: Move release <x> <y>
500#
501# Called automatically when the user clicks/drags/releases in the
502# plot area.  Moves the plot according to the user's actions.
503# ----------------------------------------------------------------------
504itcl::body Rappture::VtkViewer::Move {option x y} {
505    switch -- $option {
506        click {
507            blt::busy configure $itk_component(area) -cursor fleur
508            set _click(x) $x
509            set _click(y) $y
510            set _click(theta) $_view(theta)
511            set _click(phi) $_view(phi)
512        }
513        drag {
514            if {[array size _click] == 0} {
515                Move click $x $y
516            } else {
517                set w [winfo width $itk_component(plot)]
518                set h [winfo height $itk_component(plot)]
519                set scalex [expr {$_limits(xMax)-$_limits(xMin)}]
520                set scaley [expr {$_limits(yMax)-$_limits(yMin)}]
521                set dx [expr {double($x-$_click(x))/$w*$scalex}]
522                set dy [expr {double($y-$_click(y))/$h*$scaley}]
523
524                if {$_dims == "2D"} {
525                    #
526                    # Shift the contour plot in 2D
527                    #
528                    foreach dataobj $_dlist {
529                        foreach actor $_actors($dataobj) {
530                            foreach {ax ay az} [$actor GetPosition] break
531                            $actor SetPosition [expr {$ax+$dx}] \
532                                [expr {$ay-$dy}] 0
533                        }
534                    }
535                    $_window Render
536                } elseif {$_dims == "3D"} {
537                    #
538                    # Rotate the camera in 3D
539                    #
540                    set theta [expr {$_view(theta) - $dy*180}]
541                    if {$theta < 2} { set theta 2 }
542                    if {$theta > 178} { set theta 178 }
543                    set phi [expr {$_view(phi) - $dx*360}]
544                   
545                    _3dView $theta $phi
546                    $_window Render
547                }
548                set _click(x) $x
549                set _click(y) $y
550            }
551        }
552        release {
553            Move drag $x $y
554            blt::busy configure $itk_component(area) -cursor left_ptr
555            catch {unset _click}
556        }
557        default {
558            error "bad option \"$option\": should be click, drag, release"
559        }
560    }
561    UpdateCameraInfo
562}
563
564
565# ----------------------------------------------------------------------
566# USAGE: _3dView <theta> <phi>
567#
568# Used internally to change the position of the camera for 3D data
569# sets.  Sets the camera according to the angles <theta> (angle from
570# the z-axis) and <phi> (angle from the x-axis in the x-y plane).
571# Both angles are in degrees.
572# ----------------------------------------------------------------------
573itcl::body Rappture::VtkViewer::_3dView {theta phi} {
574    set deg2rad 0.0174532927778
575    set xn [expr {sin($theta*$deg2rad)*cos($phi*$deg2rad)}]
576    set yn [expr {sin($theta*$deg2rad)*sin($phi*$deg2rad)}]
577    set zn [expr {cos($theta*$deg2rad)}]
578   
579    set xm [expr {0.5*($_limits(xMax)+$_limits(xMin))}]
580    set ym [expr {0.5*($_limits(yMax)+$_limits(yMin))}]
581    set zm [expr {0.5*($_limits(zMax)+$_limits(zMin))}]
582   
583    set cam [$_renderer GetActiveCamera]
584    set zoom [$cam GetViewAngle]
585    $cam SetViewAngle 30
586    $cam SetFocalPoint $xm $ym $zm
587    $cam SetPosition [expr {$xm-$xn}] [expr {$ym-$yn}] [expr {$zm+$zn}]
588    $cam ComputeViewPlaneNormal
589    $cam SetViewUp 0 0 1  ;# z-dir is up
590    $cam OrthogonalizeViewUp
591    $_renderer ResetCamera
592    $cam SetViewAngle $zoom
593   
594    set _view(theta) $theta
595    set _view(phi) $phi
596}
597
598# ----------------------------------------------------------------------
599# USAGE: _fixLimits
600#
601# Used internally to apply automatic limits to the axes for the
602# current plot.
603# ----------------------------------------------------------------------
604itcl::body Rappture::VtkViewer::_fixLimits {} {
605    $_renderer ResetCamera
606    set camera [$_renderer GetActiveCamera]
607    $camera Zoom 1.5
608    $_window Render
609    if 0 {
610        $this-vtkRenderWindow2 Render
611    }
612}
613
614# ----------------------------------------------------------------------
615# USAGE: _color2rgb <color>
616#
617# Used internally to convert a color name to a set of {r g b} values
618# needed for vtk.  Each r/g/b component is scaled in the range 0-1.
619# ----------------------------------------------------------------------
620itcl::body Rappture::VtkViewer::_color2rgb {color} {
621    foreach {r g b} [winfo rgb $itk_component(hull) $color] break
622    set r [expr {$r/65535.0}]
623    set g [expr {$g/65535.0}]
624    set b [expr {$b/65535.0}]
625    return [list $r $g $b]
626}
627
628# ----------------------------------------------------------------------
629# CONFIGURATION OPTION: -plotbackground
630# ----------------------------------------------------------------------
631itcl::configbody Rappture::VtkViewer::plotbackground {
632    foreach {r g b} [_color2rgb $itk_option(-plotbackground)] break
633    $_renderer SetBackground $r $g $b
634    $_window Render
635    if 0 {
636        $this-vtkRenderer2 SetBackground $r $g $b
637        $this-vtkRenderWindow2 Render
638    }
639}
640
641# ----------------------------------------------------------------------
642# CONFIGURATION OPTION: -plotforeground
643# ----------------------------------------------------------------------
644itcl::configbody Rappture::VtkViewer::plotforeground {
645    after cancel [itcl::code $this Rebuild]
646    after idle [itcl::code $this Rebuild]
647}
648
649itcl::body Rappture::VtkViewer::SetActorProperties { actor style } {
650    array set props {
651        -color \#6666FF
652        -edgevisibility yes
653        -edgecolor black
654        -linewidth 1.0
655        -opacity 1.0
656    }
657    # Parse style string.
658    array set props $style
659    set prop [$actor GetProperty]
660    eval $prop SetColor [_color2rgb $props(-color)]
661    if { $props(-edgevisibility) } {
662        $prop EdgeVisibilityOn
663    } else {
664        $prop EdgeVisibilityOff
665    }
666    set _settings($this-edges) $props(-edgevisibility)
667    eval $prop SetEdgeColor [_color2rgb $props(-edgecolor)]
668    $prop SetLineWidth $props(-linewidth)
669    $prop SetOpacity $props(-opacity)
670    set _settings($this-opacity) [expr $props(-opacity) * 100.0]
671}
672
673# ----------------------------------------------------------------------
674# USAGE: Rebuild
675#
676# Called automatically whenever something changes that affects the
677# data in the widget.  Clears any existing data and rebuilds the
678# widget to display new data.
679# ----------------------------------------------------------------------
680itcl::body Rappture::VtkViewer::Rebuild {} {
681    set id 0
682   
683    # determine the dimensionality from the topmost (raised) object
684    set dlist [get]
685    set dataobj [lindex $dlist end]
686    if {$dataobj != ""} {
687        set _dims [lindex [lsort [$dataobj components -dimensions]] end]
688    } else {
689        set _dims "0D"
690    }
691    ComputeLimits
692    $_cubeAxesActor SetCamera [$_renderer GetActiveCamera]
693    eval $_cubeAxesActor SetBounds [GetLimits]
694   
695    if 1 {
696        #
697        # LOOKUP TABLE FOR COLOR CONTOURS
698        #
699        # Use vmin/vmax if possible, otherwise get from data
700        if {$_limits(vMin) == "" || $_limits(vMax) == ""} {
701            set v0 0
702            set v1 1
703            if { [info exists _dataobj2vtk($dataobj)] } {
704                set pd [lindex $_dataobj2vtk($dataobj) 0]
705                if {"" != $pd} {
706                    foreach {v0 v1} [$pd GetScalarRange] break
707                }
708            }
709        } else {
710            set v0 $_limits(vMin)
711            set v1 $_limits(vMax)
712        }
713    }   
714    # scan through all data objects and build the contours
715    set firstobj 1
716    foreach dataobj $_dlist {
717        foreach comp [$dataobj components] {
718            set tag $dataobj-$comp
719            if { ![info exists _dataobj2vtk($tag)] } {
720                set actor [$dataobj values $comp]
721                set style [$dataobj style $comp]
722                set _dataobj2vtk($tag) $actor
723                lappend _actors($dataobj) $actor
724                $_renderer AddActor $actor
725                SetActorProperties $actor $style
726                incr id
727            }
728        }
729        set firstobj 0
730    }
731    set top [lindex [get] end]
732    if { $top != "" } {
733        foreach axis { x y z } {
734            set title [$top hints ${axis}label]
735            set units [$top hints ${axis}units]
736            set method Set[string toupper $axis]Title
737            set label "$title"
738            if { $units != "" } {
739                append label " ($units)"
740            }       
741            $_cubeAxesActor $method $label
742        }
743    }
744    if 1 {
745        _fixLimits
746        Zoom reset
747
748    }
749    $_interactor Start
750    $_window Render
751    return
752
753    #
754    # HACK ALERT!  A single ResetCamera doesn't seem to work for
755    #   some contour data.  You have to do it multiple times to
756    #   get to the right zoom factor on data.  I hope 20 times is
757    #   enough.  I hate Vtk sometimes...
758    #
759    for {set i 0} {$i < 20} {incr i} {
760        $_renderer ResetCamera
761        [$_renderer GetActiveCamera] Zoom 1.5
762    }
763    # prevent interactions -- use our own
764    blt::busy hold $itk_component(area) -cursor left_ptr
765    bind $itk_component(area)_Busy <ButtonPress> \
766        [itcl::code $this Move click %x %y]
767    bind $itk_component(area)_Busy <B1-Motion> \
768        [itcl::code $this Move drag %x %y]
769    bind $itk_component(area)_Busy <ButtonRelease> \
770        [itcl::code $this Move release %x %y]
771}
772
773itcl::body Rappture::VtkViewer::BuildViewTab {} {
774
775    set fg [option get $itk_component(hull) font Font]
776    #set bfg [option get $itk_component(hull) boldFont Font]
777
778    set tab [$itk_component(main) insert end \
779        -title "View Settings" \
780        -icon [Rappture::icon wrench]]
781    set inner $tab
782    if 0 {
783    blt::scrollset $tab.ss \
784        -xscrollbar $tab.ss.xs \
785        -yscrollbar $tab.ss.ys \
786        -window $tab.ss.frame
787    pack $tab.ss -fill both -expand yes
788    blt::tk::scrollbar $tab.ss.xs               
789    blt::tk::scrollbar $tab.ss.ys               
790    set inner [blt::tk::frame $tab.ss.frame]
791    $inner configure -borderwidth 4
792    }
793    set ::Rappture::VtkViewer::_settings($this-isosurface) 0
794    checkbutton $inner.isosurface \
795        -text "Isosurface shading" \
796        -variable [itcl::scope _settings($this-isosurface)] \
797        -command [itcl::code $this FixSettings isosurface] \
798        -font "Arial 9"
799
800    checkbutton $inner.axes \
801        -text "Axes" \
802        -variable [itcl::scope _settings($this-axes)] \
803        -command [itcl::code $this FixSettings axes] \
804        -font "Arial 9"
805
806    checkbutton $inner.edges \
807        -text "Edges" \
808        -variable [itcl::scope _settings($this-edges)] \
809        -command [itcl::code $this FixSettings edges] \
810        -font "Arial 9"
811
812    checkbutton $inner.smallaxes \
813        -text "Small Axes" \
814        -variable [itcl::scope _settings($this-smallaxes)] \
815        -command [itcl::code $this FixSettings smallaxes] \
816        -font "Arial 9"
817
818    checkbutton $inner.wireframe \
819        -text "Wireframe" \
820        -variable [itcl::scope _settings($this-wireframe)] \
821        -command [itcl::code $this FixSettings wireframe] \
822        -font "Arial 9"
823
824    blt::table $inner \
825        0,0 $inner.axes  -columnspan 2 -anchor w \
826        1,0 $inner.edges  -columnspan 2 -anchor w \
827        2,0 $inner.wireframe  -columnspan 2 -anchor w \
828        3,0 $inner.smallaxes  -columnspan 2 -anchor w
829
830    blt::table configure $inner r* -resize none
831    blt::table configure $inner r5 -resize expand
832}
833
834itcl::body Rappture::VtkViewer::BuildVolumeTab {} {
835    foreach { key value } {
836        light           40
837        transp          50
838        opacity         1000
839    } {
840        set _settings($this-$key) $value
841    }
842
843    set tab [$itk_component(main) insert end \
844        -title "Volume Settings" \
845        -icon [Rappture::icon volume-on]]
846    set inner $tab
847    if 0 {
848    blt::scrollset $tab.ss \
849        -xscrollbar $tab.ss.xs \
850        -yscrollbar $tab.ss.ys \
851        -window $tab.ss.frame
852    pack $tab.ss -fill both -expand yes
853    blt::tk::scrollbar $tab.ss.xs               
854    blt::tk::scrollbar $tab.ss.ys               
855    set inner [blt::tk::frame $tab.ss.frame]
856    $inner configure -borderwidth 4
857    }
858    set fg [option get $itk_component(hull) font Font]
859    #set bfg [option get $itk_component(hull) boldFont Font]
860
861    checkbutton $inner.vol -text "Show volume" -font $fg \
862        -variable [itcl::scope _settings($this-volume)] \
863        -command [itcl::code $this FixSettings volume]
864    label $inner.shading -text "Shading:" -font $fg
865
866    label $inner.dim -text "Dim" -font $fg
867    ::scale $inner.light -from 0 -to 100 -orient horizontal \
868        -variable [itcl::scope _settings($this-light)] \
869        -width 10 \
870        -showvalue off -command [itcl::code $this FixSettings light]
871    label $inner.bright -text "Bright" -font $fg
872
873    label $inner.fog -text "Fog" -font $fg
874    ::scale $inner.transp -from 0 -to 100 -orient horizontal \
875        -variable [itcl::scope _settings($this-transp)] \
876        -width 10 \
877        -showvalue off -command [itcl::code $this FixSettings transp]
878    label $inner.plastic -text "Plastic" -font $fg
879
880    label $inner.clear -text "Clear" -font $fg
881    ::scale $inner.opacity -from 0 -to 100 -orient horizontal \
882        -variable [itcl::scope _settings($this-opacity)] \
883        -width 10 \
884        -showvalue off -command [itcl::code $this FixSettings opacity]
885    label $inner.opaque -text "Opaque" -font $fg
886
887    blt::table $inner \
888        0,0 $inner.vol -columnspan 4 -anchor w -pady 2 \
889        1,0 $inner.shading -columnspan 4 -anchor w -pady {10 2} \
890        2,0 $inner.dim -anchor e -pady 2 \
891        2,1 $inner.light -columnspan 2 -pady 2 -fill x \
892        2,3 $inner.bright -anchor w -pady 2 \
893        3,0 $inner.fog -anchor e -pady 2 \
894        3,1 $inner.transp -columnspan 2 -pady 2 -fill x \
895        3,3 $inner.plastic -anchor w -pady 2 \
896        4,0 $inner.clear -anchor e -pady 2 \
897        4,1 $inner.opacity -columnspan 2 -pady 2 -fill x\
898        4,3 $inner.opaque -anchor w -pady 2
899
900    blt::table configure $inner c0 c1 c3 r* -resize none
901    blt::table configure $inner r6 -resize expand
902}
903
904itcl::body Rappture::VtkViewer::UpdateCameraInfo {} {
905    set cam [$_renderer GetActiveCamera]
906    foreach key { x y z } \
907            pt  [$cam GetFocalPoint] \
908            up  [$cam GetViewUp] \
909            pos [$cam GetPosition] {
910        set _settings($this-${key}focal) $pt
911        set _settings($this-${key}up) $up
912        set _settings($this-${key}pos) $pos
913    }
914}
915
916itcl::body Rappture::VtkViewer::BuildCameraTab {} {
917    set inner [$itk_component(main) insert end \
918        -title "Camera Settings" \
919        -icon [Rappture::icon camera]]
920    $inner configure -borderwidth 4
921    bind $inner <Map> [itcl::code $this UpdateCameraInfo]
922
923    label $inner.xposl -text "Position"
924    entry $inner.xpos -bg white \
925        -textvariable [itcl::scope _settings($this-xpos)]
926    entry $inner.ypos -bg white \
927        -textvariable [itcl::scope _settings($this-ypos)]
928    entry $inner.zpos -bg white \
929        -textvariable [itcl::scope _settings($this-zpos)]
930    label $inner.xviewupl -text "View Up"
931    entry $inner.xviewup -bg white \
932        -textvariable [itcl::scope _settings($this-xviewup)]
933    entry $inner.yviewup -bg white \
934        -textvariable [itcl::scope _settings($this-yviewup)]
935    entry $inner.zviewup -bg white \
936        -textvariable [itcl::scope _settings($this-zviewup)]
937    label $inner.xfocall -text "Focal Point"
938    entry $inner.xfocal -bg white \
939        -textvariable [itcl::scope _settings($this-xfocal)]
940    entry $inner.yfocal -bg white \
941        -textvariable [itcl::scope _settings($this-yfocal)]
942    entry $inner.zfocal -bg white \
943        -textvariable [itcl::scope _settings($this-zfocal)]
944
945    button $inner.refresh -text "Refresh" \
946        -command [itcl::code $this UpdateCameraInfo]
947    blt::table $inner \
948        0,0 $inner.xposl -anchor w -pady 2 \
949        1,0 $inner.xpos -pady 2 -fill x\
950        2,0 $inner.ypos -pady 2 -fill x\
951        3,0 $inner.zpos -pady 2 -fill x\
952        4,0 $inner.xviewupl -anchor w -pady 2 \
953        5,0 $inner.xviewup -pady 2 -fill x \
954        6,0 $inner.yviewup -pady 2 -fill x \
955        7,0 $inner.zviewup -pady 2 -fill x \
956        8,0 $inner.xfocall -anchor w -pady 2 \
957        9,0 $inner.xfocal -pady 2 -fill x \
958        10,0 $inner.yfocal -pady 2 -fill x \
959        11,0 $inner.zfocal -pady 2 -fill x \
960        12,0 $inner.refresh
961
962    blt::table configure $inner r* c* -resize none
963    blt::table configure $inner c0 -resize expand
964    blt::table configure $inner r13 -resize expand
965}
966
967# ----------------------------------------------------------------------
968# USAGE: FixSettings <what> ?<value>?
969#
970# Used internally to update rendering settings whenever parameters
971# change in the popup settings panel.  Sends the new settings off
972# to the back end.
973# ----------------------------------------------------------------------
974itcl::body Rappture::VtkViewer::FixSettings {what {value ""}} {
975    switch -- $what {
976        light {
977        }
978        transp {
979        }
980        opacity {
981            set new [expr $_settings($this-opacity) * 0.01]
982            foreach dataobj [get] {
983                foreach comp [$dataobj components] {
984                    set actor [$dataobj values $comp]
985                    set prop [$actor GetProperty]
986                    $prop SetOpacity $new
987                }
988            }
989            $_window Render
990        }
991
992        "wireframe" {
993            foreach dataobj [get] {
994                foreach comp [$dataobj components] {
995                    set actor [$dataobj values $comp]
996                    set prop [$actor GetProperty]
997                    if { $_settings($this-wireframe) } {
998                        $prop SetRepresentationToWireframe
999                    } else {
1000                        $prop SetRepresentationToSurface
1001                    }
1002                }
1003            }
1004            $_window Render
1005        }
1006        "isosurface" {
1007        }
1008        "edges" {
1009            foreach dataobj [get] {
1010                foreach comp [$dataobj components] {
1011                    set actor [$dataobj values $comp]
1012                    set prop [$actor GetProperty]
1013                    if { $_settings($this-edges) } {
1014                        $prop EdgeVisibilityOn
1015                    } else {
1016                        $prop EdgeVisibilityOff
1017                    }
1018                }
1019            }
1020            $_window Render
1021        }
1022        "axes" {
1023            if { $_settings($this-axes) } {
1024                $_cubeAxesActor VisibilityOn
1025            } else {
1026                $_cubeAxesActor VisibilityOff
1027            }
1028            $_window Render
1029        }
1030        "smallaxes" {
1031            $_axesWidget SetEnabled $_settings($this-smallaxes)
1032            $_window Render
1033        }
1034        default {
1035            error "don't know how to fix $what"
1036        }
1037    }
1038}
1039
1040itcl::body Rappture::VtkViewer::GetLimits {} {
1041    return [list $_limits(xMin) $_limits(xMax) \
1042                $_limits(yMin) $_limits(yMax) \
1043                $_limits(zMin) $_limits(zMax)]
1044}
1045
1046itcl::body Rappture::VtkViewer::ComputeLimits { args } {
1047    array set _limits {
1048        xMin 0
1049        xMax 1
1050        yMin 0
1051        yMax 1
1052        zMin 0
1053        zMax 1
1054        vMin 0
1055        vMax 1
1056    }
1057    set actors {}
1058    if { [llength $args] > 0 } {
1059        foreach dataobj $args {
1060            foreach comp [$dataobj components] {
1061                lappend actors [$dataobj values $comp]
1062            }
1063        }
1064    } else {
1065        foreach dataobj [get] {
1066            foreach comp [$dataobj components] {
1067                lappend actors [$dataobj values $comp]
1068            }
1069        }
1070    }
1071    if { [llength $actors] == 0 } {
1072        return
1073    }
1074    set actor [lindex $actors 0]
1075    foreach key { xMin xMax yMin yMax zMin zMax} value [$actor GetBounds] {
1076        set _limits($key) $value
1077    }
1078    foreach actor [lrange $actors 1 end] {
1079        foreach { xMin xMax yMin yMax zMin zMax} [$actor GetBounds] break
1080        if { $xMin < $_limits(xMin) } {
1081            set _limits(xMin) $xMin
1082        }
1083        if { $xMax > $_limits(xMax) } {
1084            set _limits(xMax) $xMax
1085        }
1086        if { $yMin < $_limits(yMin) } {
1087            set _limits(yMin) $yMin
1088        }
1089        if { $yMax > $_limits(yMax) } {
1090            set _limits(yMax) $yMax
1091        }
1092        if { $zMin < $_limits(zMin) } {
1093            set _limits(zMin) $zMin
1094        }
1095        if { $zMax > $_limits(zMax) } {
1096            set _limits(zMax) $zMax
1097        }
1098    }
1099    set _limits(vMin) $_limits(zMin)
1100    set _limits(vMax) $_limits(zMax)
1101}
Note: See TracBrowser for help on using the repository browser.