source: trunk/gui/scripts/contourresult.tcl @ 16

Last change on this file since 16 was 16, checked in by mmc, 19 years ago

Added support for contour plots of 3D data sets.

File size: 30.1 KB
Line 
1# ----------------------------------------------------------------------
2#  COMPONENT: contourresult - contour plot in a ResultSet
3#
4#  This widget is a contour plot for 2D meshes with a scalar value.
5#  It is normally used in the ResultViewer to show results from the
6#  run of a Rappture tool.  Use the "add" and "delete" methods to
7#  control the dataobjs showing on the plot.
8# ======================================================================
9#  AUTHOR:  Michael McLennan, Purdue University
10#  Copyright (c) 2004-2005
11#  Purdue Research Foundation, West Lafayette, IN
12# ======================================================================
13package require Itk
14package require vtk
15package require vtkinteraction
16package require BLT
17
18blt::bitmap define ContourResult-reset {
19#define reset_width 12
20#define reset_height 12
21static unsigned char reset_bits[] = {
22   0x00, 0x00, 0x00, 0x00, 0xfc, 0x03, 0x04, 0x02, 0x04, 0x02, 0x04, 0x02,
23   0x04, 0x02, 0x04, 0x02, 0x04, 0x02, 0xfc, 0x03, 0x00, 0x00, 0x00, 0x00};
24}
25
26blt::bitmap define ContourResult-zoomin {
27#define zoomin_width 12
28#define zoomin_height 12
29static unsigned char zoomin_bits[] = {
30   0x7c, 0x00, 0x82, 0x00, 0x11, 0x01, 0x11, 0x01, 0x7d, 0x01, 0x11, 0x01,
31   0x11, 0x01, 0x82, 0x03, 0xfc, 0x07, 0x80, 0x0f, 0x00, 0x0f, 0x00, 0x06};
32}
33
34blt::bitmap define ContourResult-zoomout {
35#define zoomout_width 12
36#define zoomout_height 12
37static unsigned char zoomout_bits[] = {
38   0x7c, 0x00, 0x82, 0x00, 0x01, 0x01, 0x01, 0x01, 0x7d, 0x01, 0x01, 0x01,
39   0x01, 0x01, 0x82, 0x03, 0xfc, 0x07, 0x80, 0x0f, 0x00, 0x0f, 0x00, 0x06};
40}
41
42blt::bitmap define ContourResult-xslice {
43#define x_width 12
44#define x_height 12
45static unsigned char x_bits[] = {
46   0x00, 0x00, 0x00, 0x00, 0x9c, 0x03, 0x98, 0x01, 0xf0, 0x00, 0x60, 0x00,
47   0x60, 0x00, 0xf0, 0x00, 0x98, 0x01, 0x9c, 0x03, 0x00, 0x00, 0x00, 0x00};
48}
49
50blt::bitmap define ContourResult-yslice {
51#define y_width 12
52#define y_height 12
53static unsigned char y_bits[] = {
54   0x00, 0x00, 0x00, 0x00, 0x0e, 0x07, 0x0c, 0x03, 0x98, 0x01, 0xf0, 0x00,
55   0x60, 0x00, 0x60, 0x00, 0x60, 0x00, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x00};
56}
57blt::bitmap define ContourResult-zslice {
58#define z_width 12
59#define z_height 12
60static unsigned char z_bits[] = {
61   0x00, 0x00, 0x00, 0x00, 0xfc, 0x03, 0x84, 0x03, 0xc0, 0x01, 0xe0, 0x00,
62   0x70, 0x00, 0x38, 0x00, 0x1c, 0x02, 0xfc, 0x03, 0x00, 0x00, 0x00, 0x00};
63}
64
65option add *ContourResult.width 4i widgetDefault
66option add *ContourResult.height 4i widgetDefault
67option add *ContourResult.foreground black widgetDefault
68option add *ContourResult.controlBackground gray widgetDefault
69option add *ContourResult.controlDarkBackground #999999 widgetDefault
70option add *ContourResult.font \
71    -*-helvetica-medium-r-normal-*-*-120-* widgetDefault
72
73itcl::class Rappture::ContourResult {
74    inherit itk::Widget
75
76    itk_option define -foreground foreground Foreground ""
77    itk_option define -background background Background ""
78
79    constructor {args} { # defined below }
80    destructor { # defined below }
81
82    public method add {dataobj {settings ""}}
83    public method get {}
84    public method delete {args}
85    public method scale {args}
86
87    protected method _rebuild {}
88    protected method _zoom {option}
89    protected method _move {option x y}
90    protected method _slice {option args}
91    protected method _fixLimits {}
92    protected method _color2rgb {color}
93
94    private variable _dlist ""     ;# list of data objects
95    private variable _obj2color    ;# maps dataobj => plotting color
96    private variable _obj2width    ;# maps dataobj => line width
97    private variable _obj2raise    ;# maps dataobj => raise flag 0/1
98    private variable _obj2vtk      ;# maps dataobj => vtk objects
99    private variable _actors       ;# list of actors for each renderer
100    private variable _click        ;# info used for _move operations
101    private variable _slicer       ;# vtk transform used for 3D slice plane
102    private variable _limits       ;# autoscale min/max for all axes
103
104    private common _counter 0      ;# used for auto-generated names
105}
106
107itk::usual ContourResult {
108    keep -background -foreground -cursor -font
109}
110
111# ----------------------------------------------------------------------
112# CONSTRUCTOR
113# ----------------------------------------------------------------------
114itcl::body Rappture::ContourResult::constructor {args} {
115    option add hull.width hull.height
116    pack propagate $itk_component(hull) no
117
118    set _slicer(axis) ""
119    set _slicer(xform) ""
120    set _slicer(readout) ""
121
122    itk_component add controls {
123        frame $itk_interior.cntls
124    } {
125        usual
126        rename -background -controlbackground controlBackground Background
127    }
128    pack $itk_component(controls) -side right -fill y
129
130    itk_component add reset {
131        button $itk_component(controls).reset \
132            -borderwidth 1 -padx 1 -pady 1 \
133            -bitmap ContourResult-reset \
134            -command [itcl::code $this _zoom reset]
135    } {
136        usual
137        ignore -borderwidth
138        rename -highlightbackground -controlbackground controlBackground Background
139    }
140    pack $itk_component(reset) -padx 4 -pady 4
141    Rappture::Tooltip::for $itk_component(reset) "Reset the view to the default zoom level"
142
143    itk_component add zoomin {
144        button $itk_component(controls).zin \
145            -borderwidth 1 -padx 1 -pady 1 \
146            -bitmap ContourResult-zoomin \
147            -command [itcl::code $this _zoom in]
148    } {
149        usual
150        ignore -borderwidth
151        rename -highlightbackground -controlbackground controlBackground Background
152    }
153    pack $itk_component(zoomin) -padx 4 -pady 4
154    Rappture::Tooltip::for $itk_component(zoomin) "Zoom in"
155
156    itk_component add zoomout {
157        button $itk_component(controls).zout \
158            -borderwidth 1 -padx 1 -pady 1 \
159            -bitmap ContourResult-zoomout \
160            -command [itcl::code $this _zoom out]
161    } {
162        usual
163        ignore -borderwidth
164        rename -highlightbackground -controlbackground controlBackground Background
165    }
166    pack $itk_component(zoomout) -padx 4 -pady 4
167    Rappture::Tooltip::for $itk_component(zoomout) "Zoom out"
168
169    itk_component add xslice {
170        label $itk_component(controls).xslice \
171            -borderwidth 1 -relief raised -padx 1 -pady 1 \
172            -bitmap ContourResult-xslice
173    } {
174        usual
175        ignore -borderwidth
176        rename -highlightbackground -controlbackground controlBackground Background
177    }
178    bind $itk_component(xslice) <ButtonPress> \
179        [itcl::code $this _slice axis x]
180    Rappture::Tooltip::for $itk_component(xslice) "Slice along x-axis"
181
182    itk_component add yslice {
183        label $itk_component(controls).yslice \
184            -borderwidth 1 -relief raised -padx 1 -pady 1 \
185            -bitmap ContourResult-yslice
186    } {
187        usual
188        ignore -borderwidth
189        rename -highlightbackground -controlbackground controlBackground Background
190    }
191    bind $itk_component(yslice) <ButtonPress> \
192        [itcl::code $this _slice axis y]
193    Rappture::Tooltip::for $itk_component(yslice) "Slice along y-axis"
194
195    itk_component add zslice {
196        label $itk_component(controls).zslice \
197            -borderwidth 1 -relief raised -padx 1 -pady 1 \
198            -bitmap ContourResult-zslice
199    } {
200        usual
201        ignore -borderwidth
202        rename -highlightbackground -controlbackground controlBackground Background
203    }
204    bind $itk_component(zslice) <ButtonPress> \
205        [itcl::code $this _slice axis z]
206    Rappture::Tooltip::for $itk_component(zslice) "Slice along z-axis"
207
208    itk_component add slicer {
209        ::scale $itk_component(controls).slicer -from 100 -to 0 \
210            -width 10 -orient vertical -showvalue off \
211            -borderwidth 1 -highlightthickness 0 \
212            -command [itcl::code $this _slice move]
213    } {
214        usual
215        ignore -borderwidth
216        ignore -highlightthickness
217        rename -highlightbackground -controlbackground controlBackground Background
218        rename -troughcolor -controldarkbackground controlDarkBackground Background
219    }
220    pack $itk_component(slicer) -side bottom -padx 4 -pady 4
221    Rappture::Tooltip::for $itk_component(slicer) "Move the cut plane"
222
223    #
224    # RENDERING AREA
225    #
226    itk_component add area {
227        frame $itk_interior.area
228    }
229    pack $itk_component(area) -expand yes -fill both
230
231    vtkRenderer $this-ren
232    vtkRenderWindow $this-renWin
233    $this-renWin AddRenderer $this-ren
234    vtkRenderWindowInteractor $this-iren
235    $this-iren SetRenderWindow $this-renWin
236
237    itk_component add plot {
238        vtkTkRenderWidget $itk_component(area).plot -rw $this-renWin \
239            -width 1 -height 1
240    } {
241    }
242    pack $itk_component(plot) -expand yes -fill both
243
244
245    vtkRenderer $this-ren2
246    vtkRenderWindow $this-renWin2
247    $this-renWin2 AddRenderer $this-ren2
248    vtkRenderWindowInteractor $this-iren2
249    $this-iren2 SetRenderWindow $this-renWin2
250
251    itk_component add legend {
252        vtkTkRenderWidget $itk_component(area).legend -rw $this-renWin2 \
253            -width 1 -height 40
254    } {
255    }
256    pack $itk_component(legend) -side bottom -fill x
257
258    eval itk_initialize $args
259}
260
261# ----------------------------------------------------------------------
262# DESTRUCTOR
263# ----------------------------------------------------------------------
264itcl::body Rappture::ContourResult::destructor {} {
265    rename $this-renWin ""
266    rename $this-ren ""
267    rename $this-iren ""
268
269    rename $this-renWin2 ""
270    rename $this-ren2 ""
271    rename $this-iren2 ""
272
273    after cancel [itcl::code $this _rebuild]
274}
275
276# ----------------------------------------------------------------------
277# USAGE: add <dataobj> ?<settings>?
278#
279# Clients use this to add a data object to the plot.  The optional
280# <settings> are used to configure the plot.  Allowed settings are
281# -color, -brightness, -width, -linestyle, and -raise.
282# ----------------------------------------------------------------------
283itcl::body Rappture::ContourResult::add {dataobj {settings ""}} {
284    array set params {
285        -color black
286        -width 1
287        -linestyle solid
288        -brightness 0
289        -raise 0
290    }
291    foreach {opt val} $settings {
292        if {![info exists params($opt)]} {
293            error "bad setting \"$opt\": should be [join [lsort [array names params]] {, }]"
294        }
295        set params($opt) $val
296    }
297
298    set pos [lsearch -exact $dataobj $_dlist]
299    if {$pos < 0} {
300        lappend _dlist $dataobj
301        set _obj2color($dataobj) $params(-color)
302        set _obj2width($dataobj) $params(-width)
303        set _obj2raise($dataobj) $params(-raise)
304
305        after cancel [itcl::code $this _rebuild]
306        after idle [itcl::code $this _rebuild]
307    }
308}
309
310# ----------------------------------------------------------------------
311# USAGE: get
312#
313# Clients use this to query the list of objects being plotted, in
314# order from bottom to top of this result.
315# ----------------------------------------------------------------------
316itcl::body Rappture::ContourResult::get {} {
317    # put the dataobj list in order according to -raise options
318    set dlist $_dlist
319    foreach obj $dlist {
320        if {[info exists _obj2raise($obj)] && $_obj2raise($obj)} {
321            set i [lsearch -exact $dlist $obj]
322            if {$i >= 0} {
323                set dlist [lreplace $dlist $i $i]
324                lappend dlist $obj
325            }
326        }
327    }
328    return $dlist
329}
330
331# ----------------------------------------------------------------------
332# USAGE: delete ?<dataobj1> <dataobj2> ...?
333#
334# Clients use this to delete a dataobj from the plot.  If no dataobjs
335# are specified, then all dataobjs are deleted.
336# ----------------------------------------------------------------------
337itcl::body Rappture::ContourResult::delete {args} {
338    if {[llength $args] == 0} {
339        set args $_dlist
340    }
341
342    # delete all specified dataobjs
343    set changed 0
344    foreach dataobj $args {
345        set pos [lsearch -exact $_dlist $dataobj]
346        if {$pos >= 0} {
347            set _dlist [lreplace $_dlist $pos $pos]
348            catch {unset _obj2color($dataobj)}
349            catch {unset _obj2width($dataobj)}
350            catch {unset _obj2raise($dataobj)}
351            set changed 1
352        }
353    }
354
355    # if anything changed, then rebuild the plot
356    if {$changed} {
357        after cancel [itcl::code $this _rebuild]
358        after idle [itcl::code $this _rebuild]
359    }
360}
361
362# ----------------------------------------------------------------------
363# USAGE: scale ?<data1> <data2> ...?
364#
365# Sets the default limits for the overall plot according to the
366# limits of the data for all of the given <data> objects.  This
367# accounts for all objects--even those not showing on the screen.
368# Because of this, the limits are appropriate for all objects as
369# the user scans through data in the ResultSet viewer.
370# ----------------------------------------------------------------------
371itcl::body Rappture::ContourResult::scale {args} {
372    foreach val {xmin xmax ymin ymax zmin zmax vmin vmax} {
373        set _limits($val) ""
374    }
375    foreach obj $args {
376        foreach axis {x y z v} {
377            foreach {min max} [$obj limits $axis] break
378            if {"" != $min && "" != $max} {
379                if {"" == $_limits(${axis}min)} {
380                    set _limits(${axis}min) $min
381                    set _limits(${axis}max) $max
382                } else {
383                    if {$min < $_limits(${axis}min)} {
384                        set _limits(${axis}min) $min
385                    }
386                    if {$max > $_limits(${axis}max)} {
387                        set _limits(${axis}max) $max
388                    }
389                }
390            }
391        }
392    }
393    _fixLimits
394}
395
396# ----------------------------------------------------------------------
397# USAGE: _rebuild
398#
399# Called automatically whenever something changes that affects the
400# data in the widget.  Clears any existing data and rebuilds the
401# widget to display new data.
402# ----------------------------------------------------------------------
403itcl::body Rappture::ContourResult::_rebuild {} {
404    # clear out any old constructs
405    foreach ren [array names _actors] {
406        foreach actor $_actors($ren) {
407            $ren RemoveActor $actor
408        }
409        set _actors($ren) ""
410    }
411    foreach dataobj [array names _obj2vtk] {
412        foreach cmd $_obj2vtk($dataobj) {
413            rename $cmd ""
414        }
415        set _obj2vtk($dataobj) ""
416    }
417    set _slicer(axis) ""
418    set _slicer(xform) ""
419    set _slicer(readout) ""
420
421    # determine the dimensionality from the topmost (raised) object
422    set dlist [get]
423    set dataobj [lindex $dlist end]
424    if {$dataobj != ""} {
425        set dims [$dataobj components -dimensions]
426    } else {
427        set dims "0D"
428    }
429
430    # scan through all data objects and build the contours
431    set _counter 0
432    foreach dataobj [get] {
433        foreach comp [$dataobj components] {
434            set pd $this-polydata$_counter
435            vtkPolyData $pd
436            $pd SetPoints [$dataobj mesh $comp]
437            [$pd GetPointData] SetScalars [$dataobj values $comp]
438
439            # use vmin/vmax if possible, otherwise get from data
440            if {$_limits(vmin) == "" || $_limits(vmax) == ""} {
441                foreach {v0 v1} [$pd GetScalarRange] break
442            } else {
443                set v0 $_limits(vmin)
444                set v1 $_limits(vmax)
445            }
446
447            set tr $this-triangles$_counter
448            vtkDelaunay$dims $tr
449            $tr SetInput $pd
450            $tr SetTolerance 0.0000000000001
451
452            set lu $this-lookup$_counter
453            vtkLookupTable $lu
454            $lu SetTableRange $v0 $v1
455            $lu SetHueRange 0.66667 0.0
456            $lu Build
457
458            lappend _obj2vtk($dataobj) $pd $tr $lu
459
460            #
461            # Add color contours.
462            #
463            if {$_counter == 0} {
464                if {$dims == "3D"} {
465                    pack $itk_component(slicer) -side bottom -padx 4 -pady 4
466                    pack $itk_component(zslice) -side bottom -padx 4 -pady 4
467                    pack $itk_component(yslice) -side bottom -padx 4 -pady 4
468                    pack $itk_component(xslice) -side bottom -padx 4 -pady 4
469
470                    #
471                    # 3D CUT PLANE
472                    #
473                    set pl $this-cutplane$_counter
474                    vtkPlaneSource $pl
475                    $pl SetResolution 50 50
476
477                    set xf $this-cpxform$_counter
478                    vtkTransform $xf
479                    set _slicer(xform) $xf
480                    _slice axis "z"
481
482                    set pdf $this-cpfilter$_counter
483                    vtkTransformPolyDataFilter $pdf
484                    $pdf SetInput [$pl GetOutput]
485                    $pdf SetTransform $xf
486
487                    set pb $this-cpprobe$_counter
488                    vtkProbeFilter $pb
489                    $pb SetInput [$pdf GetOutput]
490                    $pb SetSource [$tr GetOutput]
491
492                    lappend _obj2vtk($dataobj) $pl $xf $pdf $pb
493
494                    set mp $this-mapper$_counter
495                    vtkPolyDataMapper $mp
496                    $mp SetInput [$pb GetOutput]
497                    $mp SetScalarRange $v0 $v1
498                    $mp SetLookupTable $lu
499
500                    set ac $this-actor$_counter
501                    vtkActor $ac
502                    $ac SetMapper $mp
503                    $ac SetPosition 0 0 0
504                    [$ac GetProperty] SetColor 0 0 0
505                    $this-ren AddActor $ac
506                    lappend _actors($this-ren) $ac
507
508                    lappend _obj2vtk($dataobj) $mp $ac
509
510                    set olf $this-3dolfilter$_counter
511                    vtkOutlineFilter $olf
512                    $olf SetInput [$tr GetOutput]
513
514                    set olm $this-3dolmapper$_counter
515                    vtkPolyDataMapper $olm
516                    $olm SetInput [$olf GetOutput]
517
518                    set ola $this-3dolactor$_counter
519                    vtkActor $ola
520                    $ola SetMapper $olm
521                    eval [$ola GetProperty] SetColor 0 0 0
522                    $this-ren AddActor $ola
523                    lappend _actors($this-ren) $ola
524
525                    lappend _obj2vtk($dataobj) $olf $olm $ola
526
527                    #
528                    # CUT PLANE READOUT
529                    #
530                    set tx $this-text$_counter
531                    vtkTextMapper $tx
532                    set tp [$tx GetTextProperty]
533                    eval $tp SetColor [_color2rgb $itk_option(-foreground)]
534                    $tp SetVerticalJustificationToTop
535                    set _slicer(readout) $tx
536
537                    set txa $this-texta$_counter
538                    vtkActor2D $txa
539                    $txa SetMapper $tx
540                    [$txa GetPositionCoordinate] \
541                        SetCoordinateSystemToNormalizedDisplay
542                    [$txa GetPositionCoordinate] SetValue 0.02 0.98
543
544                    $this-ren AddActor $txa
545                    lappend _actors($this-ren) $txa
546
547                    lappend _obj2vtk($dataobj) $tx $txa
548                } else {
549                    pack forget $itk_component(xslice)
550                    pack forget $itk_component(yslice)
551                    pack forget $itk_component(zslice)
552                    pack forget $itk_component(slicer)
553
554                    set mp $this-mapper$_counter
555                    vtkPolyDataMapper $mp
556                    $mp SetInput [$tr GetOutput]
557                    $mp SetScalarRange $v0 $v1
558                    $mp SetLookupTable $lu
559
560                    set ac $this-actor$_counter
561                    vtkActor $ac
562                    $ac SetMapper $mp
563                    $ac SetPosition 0 0 0
564                    [$ac GetProperty] SetColor 0 0 0
565                    $this-ren AddActor $ac
566                    lappend _actors($this-ren) $ac
567
568                    lappend _obj2vtk($dataobj) $mp $ac
569                }
570            }
571
572            #
573            # Add color lines
574            #
575            if {$_counter > 0} {
576                set cf $this-clfilter$_counter
577                vtkContourFilter $cf
578                $cf SetInput [$tr GetOutput]
579                $cf GenerateValues 20 $v0 $v1
580
581                set mp $this-clmapper$_counter
582                vtkPolyDataMapper $mp
583                $mp SetInput [$cf GetOutput]
584                $mp SetScalarRange $v0 $v1
585                $mp SetLookupTable $lu
586
587                set ac $this-clactor$_counter
588                vtkActor $ac
589                $ac SetMapper $mp
590                [$ac GetProperty] SetColor 1 1 1
591                $ac SetPosition 0 0 0
592                $this-ren AddActor $ac
593                lappend _actors($this-ren) $ac
594
595                lappend _obj2vtk($dataobj) $cf $mp $ac
596            }
597
598            #
599            # Add an outline around the data
600            #
601            set olf $this-olfilter$_counter
602            vtkOutlineFilter $olf
603            $olf SetInput [$tr GetOutput]
604
605            set olm $this-olmapper$_counter
606            vtkPolyDataMapper $olm
607            $olm SetInput [$olf GetOutput]
608
609            set ola $this-olactor$_counter
610            vtkActor $ola
611            $ola SetMapper $olm
612            eval [$ola GetProperty] SetColor 0 0 0
613            $this-ren AddActor $ola
614            lappend _actors($this-ren) $ola
615
616            lappend _obj2vtk($dataobj) $olf $olm $ola
617
618            #
619            # Add a legend with the scale.
620            #
621            set lg $this-legend$_counter
622            vtkScalarBarActor $lg
623            $lg SetLookupTable $lu
624            [$lg GetPositionCoordinate] SetCoordinateSystemToNormalizedViewport
625            [$lg GetPositionCoordinate] SetValue 0.1 0.1
626            $lg SetOrientationToHorizontal
627            $lg SetWidth 0.8
628            $lg SetHeight 1.0
629
630            set tp [$lg GetLabelTextProperty]
631            eval $tp SetColor [_color2rgb $itk_option(-foreground)]
632            $tp BoldOff
633            $tp ItalicOff
634            $tp ShadowOff
635            #eval $tp SetShadowColor [_color2rgb gray]
636
637            $this-ren2 AddActor2D $lg
638            lappend _actors($this-ren2) $lg
639            lappend _obj2vtk($dataobj) $lg
640
641            incr _counter
642        }
643    }
644    _fixLimits
645    _zoom reset
646
647    if {$dims == "3D"} {
648        # allow interactions in 3D
649        catch {blt::busy release $itk_component(area)}
650    } else {
651        # prevent interactions in 2D
652        blt::busy hold $itk_component(area) -cursor left_ptr
653        bind $itk_component(area)_Busy <ButtonPress> \
654            [itcl::code $this _move click %x %y]
655        bind $itk_component(area)_Busy <B1-Motion> \
656            [itcl::code $this _move drag %x %y]
657        bind $itk_component(area)_Busy <ButtonRelease> \
658            [itcl::code $this _move release %x %y]
659    }
660}
661
662# ----------------------------------------------------------------------
663# USAGE: _zoom in
664# USAGE: _zoom out
665# USAGE: _zoom reset
666#
667# Called automatically when the user clicks on one of the zoom
668# controls for this widget.  Changes the zoom for the current view.
669# ----------------------------------------------------------------------
670itcl::body Rappture::ContourResult::_zoom {option} {
671    switch -- $option {
672        in {
673            set camera [$this-ren GetActiveCamera]
674            set zoom [$camera Zoom 1.25]
675            $this-renWin Render
676        }
677        out {
678            set camera [$this-ren GetActiveCamera]
679            set zoom [$camera Zoom 0.8]
680            $this-renWin Render
681        }
682        reset {
683            $this-ren ResetCamera
684            [$this-ren GetActiveCamera] Zoom 1.5
685            $this-renWin Render
686            $this-renWin2 Render
687        }
688    }
689}
690
691# ----------------------------------------------------------------------
692# USAGE: _move click <x> <y>
693# USAGE: _move drag <x> <y>
694# USAGE: _move release <x> <y>
695#
696# Called automatically when the user clicks/drags/releases in the
697# plot area.  Moves the plot according to the user's actions.
698# ----------------------------------------------------------------------
699itcl::body Rappture::ContourResult::_move {option x y} {
700    switch -- $option {
701        click {
702            blt::busy configure $itk_component(area) -cursor fleur
703            set _click(x) $x
704            set _click(y) $y
705        }
706        drag {
707            if {[array size _click] == 0} {
708                _move click $x $y
709            } else {
710                set w [winfo width $itk_component(plot)]
711                set h [winfo height $itk_component(plot)]
712                set dx [expr {double($x-$_click(x))/$w}]
713                set dy [expr {double($y-$_click(y))/$h}]
714                foreach actor $_actors($this-ren) {
715                    foreach {ax ay az} [$actor GetPosition] break
716                    $actor SetPosition [expr {$ax+$dx}] [expr {$ay-$dy}] 0
717                }
718                $this-renWin Render
719
720                set _click(x) $x
721                set _click(y) $y
722            }
723        }
724        release {
725            _move drag $x $y
726            blt::busy configure $itk_component(area) -cursor left_ptr
727            catch {unset _click}
728        }
729        default {
730            error "bad option \"$option\": should be click, drag, release"
731        }
732    }
733}
734
735# ----------------------------------------------------------------------
736# USAGE: _slice axis x|y|z
737# USAGE: _slice move <newval>
738#
739# Called automatically when the user drags the slider to move the
740# cut plane that slices 3D data.  Gets the current value from the
741# slider and moves the cut plane to the appropriate point in the
742# data set.
743# ----------------------------------------------------------------------
744itcl::body Rappture::ContourResult::_slice {option args} {
745    if {$_slicer(xform) == ""} {
746        # no slicer? then bail out!
747        return
748    }
749    switch -- $option {
750        axis {
751            if {[llength $args] != 1} {
752                error "wrong # args: should be \"_slice axis xyz\""
753            }
754            set axis [lindex $args 0]
755
756            set _slicer(axis) $axis
757            $itk_component(slicer) set 50
758            _slice move 50
759            $this-renWin Render
760
761            foreach a {x y z} {
762                $itk_component(${a}slice) configure -relief raised
763            }
764            $itk_component(${axis}slice) configure -relief sunken
765        }
766        move {
767            if {[llength $args] != 1} {
768                error "wrong # args: should be \"_slice move newval\""
769            }
770            set newval [lindex $args 0]
771
772            switch -- $_slicer(axis) {
773                x {
774                    # Rotate 90 around x-axis -- switch y/z scales
775                    # limit z-motion according to y-scale
776                    set min ymin; set max ymax
777                    # switch scales for y/z
778                    set sx [expr {$_limits(xmax)-$_limits(xmin)}]
779                    set sy [expr {$_limits(zmax)-$_limits(zmin)}]
780                    set sz [expr {$_limits(ymax)-$_limits(ymin)}]
781                }
782                y {
783                    # Rotate 90 around x-axis -- switch x/z scales
784                    # limit z-motion according to x-scale
785                    set min xmin; set max xmax
786                    # switch scales for x/z
787                    set sx [expr {$_limits(zmax)-$_limits(zmin)}]
788                    set sy [expr {$_limits(ymax)-$_limits(ymin)}]
789                    set sz [expr {$_limits(xmax)-$_limits(xmin)}]
790                }
791                z {
792                    # No rotation -- treat z-axis normally
793                    set min zmin; set max zmax
794                    set sx [expr {$_limits(xmax)-$_limits(xmin)}]
795                    set sy [expr {$_limits(ymax)-$_limits(ymin)}]
796                    set sz [expr {$_limits(zmax)-$_limits(zmin)}]
797                }
798            }
799
800            set zval [expr {0.01*($newval-50)
801                *($_limits($max)-$_limits($min))
802                  + 0.5*($_limits($max)+$_limits($min))}]
803
804            $_slicer(xform) Identity
805            switch -- $_slicer(axis) {
806                x { $_slicer(xform) RotateX 90 }
807                y { $_slicer(xform) RotateY 90 }
808                z { # all set }
809                default { error "bad axis \"$axis\": should be x, y, z" }
810            }
811            $_slicer(xform) Translate 0 0 $zval
812            $_slicer(xform) Scale $sx $sy $sz
813
814            # show the current value in the readout
815            if {$_slicer(readout) != ""} {
816                set a $_slicer(axis)
817                set newval [expr {0.01*($newval-50)
818                    *($_limits(${a}max)-$_limits(${a}min))
819                      + 0.5*($_limits(${a}max)+$_limits(${a}min))}]
820                $_slicer(readout) SetInput "$a = $newval"
821            }
822
823            $this-renWin Render
824        }
825        default {
826            error "bad option \"$option\": should be axis or move"
827        }
828    }
829}
830
831# ----------------------------------------------------------------------
832# USAGE: _fixLimits
833#
834# Used internally to apply automatic limits to the axes for the
835# current plot.
836# ----------------------------------------------------------------------
837itcl::body Rappture::ContourResult::_fixLimits {} {
838    $this-ren ResetCamera
839    [$this-ren GetActiveCamera] Zoom 1.5
840    $this-renWin Render
841    $this-renWin2 Render
842}
843
844# ----------------------------------------------------------------------
845# USAGE: _color2rgb <color>
846#
847# Used internally to convert a color name to a set of {r g b} values
848# needed for vtk.  Each r/g/b component is scaled in the range 0-1.
849# ----------------------------------------------------------------------
850itcl::body Rappture::ContourResult::_color2rgb {color} {
851    foreach {r g b} [winfo rgb $itk_component(hull) $color] break
852    set r [expr {$r/65535.0}]
853    set g [expr {$g/65535.0}]
854    set b [expr {$b/65535.0}]
855    return [list $r $g $b]
856}
857
858# ----------------------------------------------------------------------
859# CONFIGURATION OPTION: -background
860# ----------------------------------------------------------------------
861itcl::configbody Rappture::ContourResult::background {
862    foreach {r g b} [_color2rgb $itk_option(-background)] break
863    $this-ren SetBackground $r $g $b
864    $this-renWin Render
865    $this-ren2 SetBackground $r $g $b
866    $this-renWin2 Render
867}
868
869# ----------------------------------------------------------------------
870# CONFIGURATION OPTION: -foreground
871# ----------------------------------------------------------------------
872itcl::configbody Rappture::ContourResult::foreground {
873    after cancel [itcl::code $this _rebuild]
874    after idle [itcl::code $this _rebuild]
875}
Note: See TracBrowser for help on using the repository browser.