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

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

Major reorganization of the entire package. The config.xml file
is now irrelevant. All the action is in the tool.xml file. The
main program now organizes all input into 1) side-by-side pages,
2) input/result (wizard-style) pages, or 3) a series of wizard-
style pages. The <input> can have <phase> parts representing
the various pages.

Added a new ContourResult? widget based on Swaroop's vtk plotting
code.

Also, added easymesh and showmesh to the "tools" directory.
We need these for Eric Polizzi's code.

File size: 18.9 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
42option add *ContourResult.width 4i widgetDefault
43option add *ContourResult.height 4i widgetDefault
44option add *ContourResult.foreground black widgetDefault
45option add *ContourResult.controlBackground gray widgetDefault
46option add *ContourResult.font \
47    -*-helvetica-medium-r-normal-*-*-120-* widgetDefault
48
49itcl::class Rappture::ContourResult {
50    inherit itk::Widget
51
52    itk_option define -foreground foreground Foreground ""
53    itk_option define -background background Background ""
54
55    constructor {args} { # defined below }
56    destructor { # defined below }
57
58    public method add {dataobj {settings ""}}
59    public method delete {args}
60    public method scale {args}
61
62    protected method _rebuild {}
63    protected method _zoom {option}
64    protected method _move {option x y}
65    protected method _fixLimits {}
66    protected method _color2rgb {color}
67
68    private variable _dlist ""     ;# list of data objects
69    private variable _obj2color    ;# maps dataobj => plotting color
70    private variable _obj2width    ;# maps dataobj => line width
71    private variable _obj2raise    ;# maps dataobj => raise flag 0/1
72    private variable _obj2vtk      ;# maps dataobj => vtk objects
73    private variable _actors       ;# list of actors for each renderer
74    private variable _click        ;# info used for _move operations
75    private variable _xmin ""      ;# autoscale min for x-axis
76    private variable _xmax ""      ;# autoscale max for x-axis
77    private variable _ymin ""      ;# autoscale min for y-axis
78    private variable _ymax ""      ;# autoscale max for y-axis
79    private variable _zmin ""      ;# autoscale min for z-axis
80    private variable _zmax ""      ;# autoscale max for z-axis
81
82    private common _counter 0      ;# used for auto-generated names
83}
84
85itk::usual ContourResult {
86    keep -background -foreground -cursor -font
87}
88
89# ----------------------------------------------------------------------
90# CONSTRUCTOR
91# ----------------------------------------------------------------------
92itcl::body Rappture::ContourResult::constructor {args} {
93    option add hull.width hull.height
94    pack propagate $itk_component(hull) no
95
96    itk_component add controls {
97        frame $itk_interior.cntls
98    } {
99        usual
100        rename -background -controlbackground controlBackground Background
101    }
102    pack $itk_component(controls) -side right -fill y
103
104    itk_component add reset {
105        button $itk_component(controls).reset \
106            -borderwidth 1 -padx 1 -pady 1 \
107            -bitmap ContourResult-reset \
108            -command [itcl::code $this _zoom reset]
109    } {
110        ignore -borderwidth
111        rename -highlightbackground -controlbackground controlBackground Background
112    }
113    pack $itk_component(reset) -padx 4 -pady 4
114    Rappture::Tooltip::for $itk_component(reset) "Reset the view to the default zoom level"
115
116    itk_component add zoomin {
117        button $itk_component(controls).zin \
118            -borderwidth 1 -padx 1 -pady 1 \
119            -bitmap ContourResult-zoomin \
120            -command [itcl::code $this _zoom in]
121    } {
122        ignore -borderwidth
123        rename -highlightbackground -controlbackground controlBackground Background
124    }
125    pack $itk_component(zoomin) -padx 4 -pady 4
126    Rappture::Tooltip::for $itk_component(zoomin) "Zoom in"
127
128    itk_component add zoomout {
129        button $itk_component(controls).zout \
130            -borderwidth 1 -padx 1 -pady 1 \
131            -bitmap ContourResult-zoomout \
132            -command [itcl::code $this _zoom out]
133    } {
134        ignore -borderwidth
135        rename -highlightbackground -controlbackground controlBackground Background
136    }
137    pack $itk_component(zoomout) -padx 4 -pady 4
138    Rappture::Tooltip::for $itk_component(zoomout) "Zoom out"
139
140    itk_component add area {
141        frame $itk_interior.area
142    }
143    pack $itk_component(area) -expand yes -fill both
144
145    vtkRenderer $this-ren
146    vtkRenderWindow $this-renWin
147    $this-renWin AddRenderer $this-ren
148    vtkRenderWindowInteractor $this-iren
149    $this-iren SetRenderWindow $this-renWin
150
151    itk_component add plot {
152        vtkTkRenderWidget $itk_component(area).plot -rw $this-renWin \
153            -width 1 -height 1
154    } {
155    }
156    pack $itk_component(plot) -expand yes -fill both
157
158
159    vtkRenderer $this-ren2
160    vtkRenderWindow $this-renWin2
161    $this-renWin2 AddRenderer $this-ren2
162    vtkRenderWindowInteractor $this-iren2
163    $this-iren2 SetRenderWindow $this-renWin2
164
165    itk_component add legend {
166        vtkTkRenderWidget $itk_component(area).legend -rw $this-renWin2 \
167            -width 1 -height 40
168    } {
169    }
170    pack $itk_component(legend) -side bottom -fill x
171
172    eval itk_initialize $args
173
174    blt::busy hold $itk_component(area) -cursor left_ptr
175    bind $itk_component(area)_Busy <ButtonPress> \
176        [itcl::code $this _move click %x %y]
177    bind $itk_component(area)_Busy <B1-Motion> \
178        [itcl::code $this _move drag %x %y]
179    bind $itk_component(area)_Busy <ButtonRelease> \
180        [itcl::code $this _move release %x %y]
181}
182
183# ----------------------------------------------------------------------
184# DESTRUCTOR
185# ----------------------------------------------------------------------
186itcl::body Rappture::ContourResult::destructor {} {
187    rename $this-renWin ""
188    rename $this-ren ""
189    rename $this-iren ""
190
191    rename $this-renWin2 ""
192    rename $this-ren2 ""
193    rename $this-iren2 ""
194
195    after cancel [itcl::code $this _rebuild]
196}
197
198# ----------------------------------------------------------------------
199# USAGE: add <dataobj> ?<settings>?
200#
201# Clients use this to add a data object to the plot.  The optional
202# <settings> are used to configure the plot.  Allowed settings are
203# -color, -width, and -raise.
204# ----------------------------------------------------------------------
205itcl::body Rappture::ContourResult::add {dataobj {settings ""}} {
206    array set params {
207        -color black
208        -width 1
209        -raise 0
210    }
211    foreach {opt val} $settings {
212        if {![info exists params($opt)]} {
213            error "bad setting \"$opt\": should be [join [lsort [array names params]] {, }]"
214        }
215        set params($opt) $val
216    }
217
218    set pos [lsearch -exact $dataobj $_dlist]
219    if {$pos < 0} {
220        lappend _dlist $dataobj
221        set _obj2color($dataobj) $params(-color)
222        set _obj2width($dataobj) $params(-width)
223        set _obj2raise($dataobj) $params(-raise)
224
225        after cancel [itcl::code $this _rebuild]
226        after idle [itcl::code $this _rebuild]
227    }
228}
229
230# ----------------------------------------------------------------------
231# USAGE: delete ?<dataobj1> <dataobj2> ...?
232#
233# Clients use this to delete a dataobj from the plot.  If no dataobjs
234# are specified, then all dataobjs are deleted.
235# ----------------------------------------------------------------------
236itcl::body Rappture::ContourResult::delete {args} {
237    if {[llength $args] == 0} {
238        set args $_dlist
239    }
240
241    # delete all specified dataobjs
242    set changed 0
243    foreach dataobj $args {
244        set pos [lsearch -exact $_dlist $dataobj]
245        if {$pos >= 0} {
246            set _dlist [lreplace $_dlist $pos $pos]
247            catch {unset _obj2color($dataobj)}
248            catch {unset _obj2width($dataobj)}
249            catch {unset _obj2raise($dataobj)}
250            set changed 1
251        }
252    }
253
254    # if anything changed, then rebuild the plot
255    if {$changed} {
256        after cancel [itcl::code $this _rebuild]
257        after idle [itcl::code $this _rebuild]
258    }
259}
260
261# ----------------------------------------------------------------------
262# USAGE: scale ?<data1> <data2> ...?
263#
264# Sets the default limits for the overall plot according to the
265# limits of the data for all of the given <data> objects.  This
266# accounts for all objects--even those not showing on the screen.
267# Because of this, the limits are appropriate for all objects as
268# the user scans through data in the ResultSet viewer.
269# ----------------------------------------------------------------------
270itcl::body Rappture::ContourResult::scale {args} {
271    set _xmin ""
272    set _xmax ""
273    set _ymin ""
274    set _ymax ""
275    set _zmin ""
276    set _zmax ""
277    foreach obj $args {
278        foreach axis {x y z} {
279            foreach {min max} [$obj limits $axis] break
280            if {"" != $min && "" != $max} {
281                if {"" == [set _${axis}min]} {
282                    set _${axis}min $min
283                    set _${axis}max $max
284                } else {
285                    if {$min < [set _${axis}min]} {
286                        set _${axis}min $min
287                    }
288                    if {$max > [set _${axis}max]} {
289                        set _${axis}max $max
290                    }
291                }
292            }
293        }
294    }
295    _fixLimits
296}
297
298# ----------------------------------------------------------------------
299# USAGE: _rebuild
300#
301# Called automatically whenever something changes that affects the
302# data in the widget.  Clears any existing data and rebuilds the
303# widget to display new data.
304# ----------------------------------------------------------------------
305itcl::body Rappture::ContourResult::_rebuild {} {
306    # clear out any old constructs
307    foreach ren [array names _actors] {
308        foreach actor $_actors($ren) {
309            $ren RemoveActor $actor
310        }
311        set _actors($ren) ""
312    }
313    foreach dataobj [array names _obj2vtk] {
314        foreach cmd $_obj2vtk($dataobj) {
315            rename $cmd ""
316        }
317        set _obj2vtk($dataobj) ""
318    }
319
320    # put the dataobj list in order according to -raise options
321    set dlist $_dlist
322    foreach obj $dlist {
323        if {[info exists _obj2raise($obj)] && $_obj2raise($obj)} {
324            set i [lsearch -exact $dlist $obj]
325            if {$i >= 0} {
326                set dlist [lreplace $dlist $i $i]
327                lappend dlist $obj
328            }
329        }
330    }
331
332    # scan through all data objects and build the contours
333    set _counter 0
334    foreach dataobj $dlist {
335        foreach comp [$dataobj components] {
336            set pd $this-polydata$_counter
337            vtkPolyData $pd
338            $pd SetPoints [$dataobj mesh $comp]
339            [$pd GetPointData] SetScalars [$dataobj values $comp]
340
341            # use _zmin/_zmax if possible, otherwise get from data
342            if {$_zmin == "" || $_zmax == ""} {
343                foreach {z0 z1} [$pd GetScalarRange] break
344            } else {
345                set z0 $_zmin
346                set z1 $_zmax
347            }
348
349            set tr $this-triangles$_counter
350            vtkDelaunay2D $tr
351            $tr SetInput $pd
352            $tr SetTolerance 0.0000000000001
353
354            set lu $this-lookup$_counter
355            vtkLookupTable $lu
356            $lu SetTableRange $z0 $z1
357            $lu SetHueRange 0.66667 0.0
358            $lu Build
359
360            lappend _obj2vtk($dataobj) $pd $tr $lu
361
362            #
363            # Add color contours.
364            #
365            if {$_counter == 0} {
366                set mp $this-mapper$_counter
367                vtkPolyDataMapper $mp
368                $mp SetInput [$tr GetOutput]
369                $mp SetScalarRange $z0 $z1
370                $mp SetLookupTable $lu
371
372                set ac $this-actor$_counter
373                vtkActor $ac
374                $ac SetMapper $mp
375                $ac SetPosition 0 0 0
376                [$ac GetProperty] SetColor 0 0 0
377                $this-ren AddActor $ac
378                lappend _actors($this-ren) $ac
379
380                lappend _obj2vtk($dataobj) $mp $ac
381            }
382
383            #
384            # Add color lines
385            #
386            if {$_counter > 0} {
387                set cf $this-clfilter$_counter
388                vtkContourFilter $cf
389                $cf SetInput [$tr GetOutput]
390                $cf GenerateValues 20 $z0 $z1
391
392                set mp $this-clmapper$_counter
393                vtkPolyDataMapper $mp
394                $mp SetInput [$cf GetOutput]
395                $mp SetScalarRange $z0 $z1
396                $mp SetLookupTable $lu
397
398                set ac $this-clactor$_counter
399                vtkActor $ac
400                $ac SetMapper $mp
401                [$ac GetProperty] SetColor 1 1 1
402                $ac SetPosition 0 0 0
403                $this-ren AddActor $ac
404                lappend _actors($this-ren) $ac
405
406                lappend _obj2vtk($dataobj) $cf $mp $ac
407            }
408
409            #
410            # Add an outline around the data
411            #
412            set olf $this-olfilter$_counter
413            vtkOutlineFilter $olf
414            $olf SetInput [$tr GetOutput]
415
416            set olm $this-olmapper$_counter
417            vtkPolyDataMapper $olm
418            $olm SetInput [$olf GetOutput]
419
420            set ola $this-olactor$_counter
421            vtkActor $ola
422            $ola SetMapper $olm
423            eval [$ola GetProperty] SetColor 0 0 0
424            $this-ren AddActor $ola
425            lappend _actors($this-ren) $ola
426
427            lappend _obj2vtk($dataobj) $olf $olm $ola
428
429            #
430            # Add a legend with the scale.
431            #
432            set lg $this-legend$_counter
433            vtkScalarBarActor $lg
434            $lg SetLookupTable $lu
435            [$lg GetPositionCoordinate] SetCoordinateSystemToNormalizedViewport
436            [$lg GetPositionCoordinate] SetValue 0.1 0.1
437            $lg SetOrientationToHorizontal
438            $lg SetWidth 0.8
439            $lg SetHeight 1.0
440
441            set tp [$lg GetLabelTextProperty]
442            eval $tp SetColor [_color2rgb $itk_option(-foreground)]
443            $tp BoldOff
444            $tp ItalicOff
445            $tp ShadowOff
446            #eval $tp SetShadowColor [_color2rgb gray]
447
448            $this-ren2 AddActor2D $lg
449            lappend _actors($this-ren2) $lg
450            lappend _obj2vtk($dataobj) $lg
451
452            incr _counter
453        }
454    }
455    _fixLimits
456}
457
458# ----------------------------------------------------------------------
459# USAGE: _zoom in
460# USAGE: _zoom out
461# USAGE: _zoom reset
462#
463# Called automatically when the user clicks on one of the zoom
464# controls for this widget.  Changes the zoom for the current view.
465# ----------------------------------------------------------------------
466itcl::body Rappture::ContourResult::_zoom {option} {
467    switch -- $option {
468        in {
469            set camera [$this-ren GetActiveCamera]
470            set zoom [$camera Zoom 1.25]
471            $this-renWin Render
472        }
473        out {
474            set camera [$this-ren GetActiveCamera]
475            set zoom [$camera Zoom 0.8]
476            $this-renWin Render
477        }
478        reset {
479            $this-ren ResetCamera
480            [$this-ren GetActiveCamera] Zoom 1.5
481            $this-renWin Render
482            $this-renWin2 Render
483        }
484    }
485}
486
487# ----------------------------------------------------------------------
488# USAGE: _move click <x> <y>
489# USAGE: _move drag <x> <y>
490# USAGE: _move release <x> <y>
491#
492# Called automatically when the user clicks/drags/releases in the
493# plot area.  Moves the plot according to the user's actions.
494# ----------------------------------------------------------------------
495itcl::body Rappture::ContourResult::_move {option x y} {
496    switch -- $option {
497        click {
498            blt::busy configure $itk_component(area) -cursor fleur
499            set _click(x) $x
500            set _click(y) $y
501        }
502        drag {
503            set w [winfo width $itk_component(plot)]
504            set h [winfo height $itk_component(plot)]
505            set dx [expr {double($x-$_click(x))/$w}]
506            set dy [expr {double($y-$_click(y))/$h}]
507            foreach actor $_actors($this-ren) {
508                foreach {ax ay az} [$actor GetPosition] break
509                $actor SetPosition [expr {$ax+$dx}] [expr {$ay-$dy}] 0
510            }
511            $this-renWin Render
512
513            set _click(x) $x
514            set _click(y) $y
515        }
516        release {
517            _move drag $x $y
518            blt::busy configure $itk_component(area) -cursor left_ptr
519        }
520        default {
521            error "bad option \"$option\": should be click, drag, release"
522        }
523    }
524}
525
526# ----------------------------------------------------------------------
527# USAGE: _fixLimits
528#
529# Used internally to apply automatic limits to the axes for the
530# current plot.
531# ----------------------------------------------------------------------
532itcl::body Rappture::ContourResult::_fixLimits {} {
533    $this-ren ResetCamera
534    [$this-ren GetActiveCamera] Zoom 1.5
535    $this-renWin Render
536    $this-renWin2 Render
537}
538
539# ----------------------------------------------------------------------
540# USAGE: _color2rgb <color>
541#
542# Used internally to convert a color name to a set of {r g b} values
543# needed for vtk.  Each r/g/b component is scaled in the range 0-1.
544# ----------------------------------------------------------------------
545itcl::body Rappture::ContourResult::_color2rgb {color} {
546    foreach {r g b} [winfo rgb $itk_component(hull) $color] break
547    set r [expr {$r/65535.0}]
548    set g [expr {$g/65535.0}]
549    set b [expr {$b/65535.0}]
550    return [list $r $g $b]
551}
552
553# ----------------------------------------------------------------------
554# CONFIGURATION OPTION: -background
555# ----------------------------------------------------------------------
556itcl::configbody Rappture::ContourResult::background {
557    foreach {r g b} [_color2rgb $itk_option(-background)] break
558    $this-ren SetBackground $r $g $b
559    $this-renWin Render
560    $this-ren2 SetBackground $r $g $b
561    $this-renWin2 Render
562}
563
564# ----------------------------------------------------------------------
565# CONFIGURATION OPTION: -foreground
566# ----------------------------------------------------------------------
567itcl::configbody Rappture::ContourResult::foreground {
568    after cancel [itcl::code $this _rebuild]
569    after idle [itcl::code $this _rebuild]
570}
Note: See TracBrowser for help on using the repository browser.