source: trunk/gui/scripts/vtkstreamlinesviewer.tcl @ 2604

Last change on this file since 2604 was 2604, checked in by gah, 13 years ago
File size: 84.2 KB
Line 
1
2# ----------------------------------------------------------------------
3#  COMPONENT: vtkviewer - Vtk drawing object viewer
4#
5#  It connects to the Vtk server running on a rendering farm,
6#  transmits data, and displays the results.
7# ======================================================================
8#  AUTHOR:  Michael McLennan, Purdue University
9#  Copyright (c) 2004-2005  Purdue Research Foundation
10#
11#  See the file "license.terms" for information on usage and
12#  redistribution of this file, and for a DISCLAIMER OF ALL WARRANTIES.
13# ======================================================================
14package require Itk
15package require BLT
16#package require Img
17package require vtk
18
19option add *VtkStreamlinesViewer.width 4i widgetDefault
20option add *VtkStreamlinesViewer*cursor crosshair widgetDefault
21option add *VtkStreamlinesViewer.height 4i widgetDefault
22option add *VtkStreamlinesViewer.foreground black widgetDefault
23option add *VtkStreamlinesViewer.controlBackground gray widgetDefault
24option add *VtkStreamlinesViewer.controlDarkBackground #999999 widgetDefault
25option add *VtkStreamlinesViewer.plotBackground black widgetDefault
26option add *VtkStreamlinesViewer.plotForeground white widgetDefault
27option add *VtkStreamlinesViewer.font \
28    -*-helvetica-medium-r-normal-*-12-* widgetDefault
29
30# must use this name -- plugs into Rappture::resources::load
31proc VtkStreamlinesViewer_init_resources {} {
32    Rappture::resources::register \
33        vtkvis_server Rappture::VtkStreamlinesViewer::SetServerList
34}
35
36itcl::class Rappture::VtkStreamlinesViewer {
37    inherit Rappture::VisViewer
38
39    itk_option define -plotforeground plotForeground Foreground ""
40    itk_option define -plotbackground plotBackground Background ""
41
42    constructor { hostlist args } {
43        Rappture::VisViewer::constructor $hostlist
44    } {
45        # defined below
46    }
47    destructor {
48        # defined below
49    }
50    public proc SetServerList { namelist } {
51        Rappture::VisViewer::SetServerList "vtkvis" $namelist
52    }
53    public method add {dataobj {settings ""}}
54    public method camera {option args}
55    public method delete {args}
56    public method disconnect {}
57    public method download {option args}
58    public method get {args}
59    public method isconnected {}
60    public method limits { colormap }
61    public method sendto { string }
62    public method parameters {title args} {
63        # do nothing
64    }
65    public method scale {args}
66
67    protected method Connect {}
68    protected method CurrentDatasets {args}
69    protected method Disconnect {}
70    protected method DoResize {}
71    protected method DoReseed {}
72    protected method DoRotate {}
73    protected method AdjustSetting {what {value ""}}
74    protected method InitSettings { args  }
75    protected method Pan {option x y}
76    protected method Pick {x y}
77    protected method Rebuild {}
78    protected method ReceiveDataset { args }
79    protected method ReceiveImage { args }
80    protected method ReceiveLegend { colormap title vmin vmax size }
81    protected method Rotate {option x y}
82    protected method SendCmd {string}
83    protected method Zoom {option}
84
85    # The following methods are only used by this class.
86    private method BuildAxisTab {}
87    private method BuildCameraTab {}
88    private method BuildColormap { name colors }
89    private method BuildCutplaneTab {}
90    private method BuildDownloadPopup { widget command }
91    private method BuildStreamsTab {}
92    private method BuildVolumeTab {}
93    private method ConvertToVtkData { dataobj comp }
94    private method DrawLegend { title }
95    private method EnterLegend { x y }
96    private method EventuallyResize { w h }
97    private method EventuallyReseed { numPoints }
98    private method EventuallyRotate { q }
99    private method EventuallySetCutplane { axis args }
100    private method GetImage { args }
101    private method GetVtkData { args }
102    private method IsValidObject { dataobj }
103    private method LeaveLegend {}
104    private method MotionLegend { x y }
105    private method PanCamera {}
106    private method RequestLegend {}
107    private method SetColormap { dataobj comp }
108    private method ChangeColormap { dataobj comp color }
109    private method ColorsToColormap { color }
110    private method SetLegendTip { x y }
111    private method SetObjectStyle { dataobj comp }
112    private method Slice {option args}
113
114    private variable _arcball ""
115    private variable _outbuf       ;    # buffer for outgoing commands
116
117    private variable _dlist ""     ;    # list of data objects
118    private variable _allDataObjs
119    private variable _obj2datasets
120    private variable _obj2ovride   ;    # maps dataobj => style override
121    private variable _datasets     ;    # contains all the dataobj-component
122                                   ;    # datasets in the server
123    private variable _colormaps    ;    # contains all the colormaps
124                                   ;    # in the server.
125    private variable _dataset2style    ;# maps dataobj-component to transfunc
126
127    private variable _click        ;    # info used for rotate operations
128    private variable _limits       ;    # autoscale min/max for all axes
129    private variable _view         ;    # view params for 3D view
130    private variable _settings
131    private variable _style;            # Array of current component styles.
132    private variable _initialStyle;     # Array of initial component styles.
133    private variable _reset 1;          # indicates if camera needs to be reset
134                                        # to starting position.
135
136    private variable _first ""     ;    # This is the topmost dataset.
137    private variable _start 0
138    private variable _buffering 0
139    private variable _title ""
140    private variable _seeds
141
142    common _downloadPopup;              # download options from popup
143    private common _hardcopy
144    private variable _width 0
145    private variable _height 0
146    private variable _resizePending 0
147    private variable _reseedPending 0
148    private variable _rotatePending 0
149    private variable _cutplanePending 0
150    private variable _outline
151    private variable _vectorFields
152    private variable _scalarFields
153    private variable _fields
154    private variable _currentField
155    private variable _numSeeds 200
156    private variable _colorMode "vmag";#  Mode of colormap (vmag or scalar)
157}
158
159itk::usual VtkStreamlinesViewer {
160    keep -background -foreground -cursor -font
161    keep -plotbackground -plotforeground
162}
163
164# ----------------------------------------------------------------------
165# CONSTRUCTOR
166# ----------------------------------------------------------------------
167itcl::body Rappture::VtkStreamlinesViewer::constructor {hostlist args} {
168    # Rebuild event
169    $_dispatcher register !rebuild
170    $_dispatcher dispatch $this !rebuild "[itcl::code $this Rebuild]; list"
171
172    # Resize event
173    $_dispatcher register !resize
174    $_dispatcher dispatch $this !resize "[itcl::code $this DoResize]; list"
175
176    # Reseed event
177    $_dispatcher register !reseed
178    $_dispatcher dispatch $this !reseed "[itcl::code $this DoReseed]; list"
179
180    # Rotate event
181    $_dispatcher register !rotate
182    $_dispatcher dispatch $this !rotate "[itcl::code $this DoRotate]; list"
183
184    # X-Cutplane event
185    $_dispatcher register !xcutplane
186    $_dispatcher dispatch $this !xcutplane \
187        "[itcl::code $this AdjustSetting cutplane-xposition]; list"
188
189    # Y-Cutplane event
190    $_dispatcher register !ycutplane
191    $_dispatcher dispatch $this !ycutplane \
192        "[itcl::code $this AdjustSetting cutplane-yposition]; list"
193
194    # Z-Cutplane event
195    $_dispatcher register !zcutplane
196    $_dispatcher dispatch $this !zcutplane \
197        "[itcl::code $this AdjustSetting cutplane-zposition]; list"
198
199    #
200    # Populate parser with commands handle incoming requests
201    #
202    $_parser alias image [itcl::code $this ReceiveImage]
203    $_parser alias dataset [itcl::code $this ReceiveDataset]
204    $_parser alias legend [itcl::code $this ReceiveLegend]
205
206    array set _outline {
207        id -1
208        afterId -1
209        x1 -1
210        y1 -1
211        x2 -1
212        y2 -1
213    }
214    # Initialize the view to some default parameters.
215    array set _view {
216        qw              1
217        qx              0
218        qy              0
219        qz              0
220        zoom            1.0
221        xpan            0
222        ypan            0
223        ortho           0
224    }
225    set _arcball [blt::arcball create 100 100]
226    set q [list $_view(qw) $_view(qx) $_view(qy) $_view(qz)]
227    $_arcball quaternion $q
228
229    set _limits(zmin) 0.0
230    set _limits(zmax) 1.0
231
232    array set _settings [subst {
233        axis-xgrid              0
234        axis-ygrid              0
235        axis-zgrid              0
236        axis-xcutplane          0
237        axis-ycutplane          0
238        axis-zcutplane          0
239        axis-xposition          0
240        axis-yposition          0
241        axis-zposition          0
242        axis-visible            1
243        axis-labels             1
244        cutplane-edges          0
245        cutplane-xvisible       0
246        cutplane-yvisible       0
247        cutplane-zvisible       0
248        cutplane-xposition      50
249        cutplane-yposition      50
250        cutplane-zposition      50
251        cutplane-visible        1
252        cutplane-wireframe      0
253        cutplane-opacity        100
254        volume-edges            0
255        volume-lighting         1
256        volume-opacity          40
257        volume-visible          1
258        volume-wireframe        0
259        streamlines-seeds       0
260        streamlines-visible     1
261        streamlines-opacity     100
262        streamlines-numpoints   200
263        streamlines-lighting    1
264        streamlines-scale       1
265        legend-visible          1
266    }]
267
268    itk_component add view {
269        canvas $itk_component(plotarea).view \
270            -highlightthickness 0 -borderwidth 0
271    } {
272        usual
273        ignore -highlightthickness -borderwidth  -background
274    }
275
276    set c $itk_component(view)
277    bind $c <Configure> [itcl::code $this EventuallyResize %w %h]
278    bind $c <4> [itcl::code $this Zoom in 0.25]
279    bind $c <5> [itcl::code $this Zoom out 0.25]
280    bind $c <KeyPress-Left>  [list %W xview scroll 10 units]
281    bind $c <KeyPress-Right> [list %W xview scroll -10 units]
282    bind $c <KeyPress-Up>    [list %W yview scroll 10 units]
283    bind $c <KeyPress-Down>  [list %W yview scroll -10 units]
284    bind $c <Enter> "focus %W"
285
286    # Fix the scrollregion in case we go off screen
287    $c configure -scrollregion [$c bbox all]
288
289    set _map(id) [$c create image 0 0 -anchor nw -image $_image(plot)]
290    set _map(cwidth) -1
291    set _map(cheight) -1
292    set _map(zoom) 1.0
293    set _map(original) ""
294
295    set f [$itk_component(main) component controls]
296    itk_component add reset {
297        button $f.reset -borderwidth 1 -padx 1 -pady 1 \
298            -highlightthickness 0 \
299            -image [Rappture::icon reset-view] \
300            -command [itcl::code $this Zoom reset]
301    } {
302        usual
303        ignore -highlightthickness
304    }
305    pack $itk_component(reset) -side top -padx 2 -pady 2
306    Rappture::Tooltip::for $itk_component(reset) "Reset the view to the default zoom level"
307
308    itk_component add zoomin {
309        button $f.zin -borderwidth 1 -padx 1 -pady 1 \
310            -highlightthickness 0 \
311            -image [Rappture::icon zoom-in] \
312            -command [itcl::code $this Zoom in]
313    } {
314        usual
315        ignore -highlightthickness
316    }
317    pack $itk_component(zoomin) -side top -padx 2 -pady 2
318    Rappture::Tooltip::for $itk_component(zoomin) "Zoom in"
319
320    itk_component add zoomout {
321        button $f.zout -borderwidth 1 -padx 1 -pady 1 \
322            -highlightthickness 0 \
323            -image [Rappture::icon zoom-out] \
324            -command [itcl::code $this Zoom out]
325    } {
326        usual
327        ignore -highlightthickness
328    }
329    pack $itk_component(zoomout) -side top -padx 2 -pady 2
330    Rappture::Tooltip::for $itk_component(zoomout) "Zoom out"
331
332    itk_component add volume {
333        Rappture::PushButton $f.volume \
334            -onimage [Rappture::icon volume-on] \
335            -offimage [Rappture::icon volume-off] \
336            -variable [itcl::scope _settings(volume-visible)] \
337            -command [itcl::code $this AdjustSetting volume-visible]
338    }
339    $itk_component(volume) select
340    Rappture::Tooltip::for $itk_component(volume) \
341        "Don't display the volume"
342    pack $itk_component(volume) -padx 2 -pady 2
343
344    itk_component add streamlines {
345        Rappture::PushButton $f.streamlines \
346            -onimage [Rappture::icon streamlines-on] \
347            -offimage [Rappture::icon streamlines-off] \
348            -variable [itcl::scope _settings(streamlines-visible)] \
349            -command [itcl::code $this AdjustSetting streamlines-visible] \
350    }
351    $itk_component(streamlines) select
352    Rappture::Tooltip::for $itk_component(streamlines) \
353        "Toggle the streamlines on/off"
354    pack $itk_component(streamlines) -padx 2 -pady 2
355
356    if { [catch {
357        BuildVolumeTab
358        BuildStreamsTab
359        BuildCutplaneTab
360        BuildAxisTab
361        BuildCameraTab
362    } errs] != 0 } {
363        puts stderr errs=$errs
364    }
365    # Legend
366
367    set _image(legend) [image create photo]
368    itk_component add legend {
369        canvas $itk_component(plotarea).legend -width 50 -highlightthickness 0
370    } {
371        usual
372        ignore -highlightthickness
373        rename -background -plotbackground plotBackground Background
374    }
375
376    # Hack around the Tk panewindow.  The problem is that the requested
377    # size of the 3d view isn't set until an image is retrieved from
378    # the server.  So the panewindow uses the tiny size.
379    set w 10000
380    pack forget $itk_component(view)
381    blt::table $itk_component(plotarea) \
382        0,0 $itk_component(view) -fill both -reqwidth $w
383    blt::table configure $itk_component(plotarea) c1 -resize none
384
385    # Bindings for rotation via mouse
386    bind $itk_component(view) <ButtonPress-1> \
387        [itcl::code $this Rotate click %x %y]
388    bind $itk_component(view) <B1-Motion> \
389        [itcl::code $this Rotate drag %x %y]
390    bind $itk_component(view) <ButtonRelease-1> \
391        [itcl::code $this Rotate release %x %y]
392    bind $itk_component(view) <Configure> \
393        [itcl::code $this EventuallyResize %w %h]
394
395    if 0 {
396    bind $itk_component(view) <Configure> \
397        [itcl::code $this EventuallyResize %w %h]
398    }
399    # Bindings for panning via mouse
400    bind $itk_component(view) <ButtonPress-2> \
401        [itcl::code $this Pan click %x %y]
402    bind $itk_component(view) <B2-Motion> \
403        [itcl::code $this Pan drag %x %y]
404    bind $itk_component(view) <ButtonRelease-2> \
405        [itcl::code $this Pan release %x %y]
406
407    bind $itk_component(view) <ButtonRelease-3> \
408        [itcl::code $this Pick %x %y]
409
410    # Bindings for panning via keyboard
411    bind $itk_component(view) <KeyPress-Left> \
412        [itcl::code $this Pan set -10 0]
413    bind $itk_component(view) <KeyPress-Right> \
414        [itcl::code $this Pan set 10 0]
415    bind $itk_component(view) <KeyPress-Up> \
416        [itcl::code $this Pan set 0 -10]
417    bind $itk_component(view) <KeyPress-Down> \
418        [itcl::code $this Pan set 0 10]
419    bind $itk_component(view) <Shift-KeyPress-Left> \
420        [itcl::code $this Pan set -2 0]
421    bind $itk_component(view) <Shift-KeyPress-Right> \
422        [itcl::code $this Pan set 2 0]
423    bind $itk_component(view) <Shift-KeyPress-Up> \
424        [itcl::code $this Pan set 0 -2]
425    bind $itk_component(view) <Shift-KeyPress-Down> \
426        [itcl::code $this Pan set 0 2]
427
428    # Bindings for zoom via keyboard
429    bind $itk_component(view) <KeyPress-Prior> \
430        [itcl::code $this Zoom out]
431    bind $itk_component(view) <KeyPress-Next> \
432        [itcl::code $this Zoom in]
433
434    bind $itk_component(view) <Enter> "focus $itk_component(view)"
435
436    if {[string equal "x11" [tk windowingsystem]]} {
437        # Bindings for zoom via mouse
438        bind $itk_component(view) <4> [itcl::code $this Zoom out]
439        bind $itk_component(view) <5> [itcl::code $this Zoom in]
440    }
441
442    set _image(download) [image create photo]
443
444    eval itk_initialize $args
445    Connect
446    update
447}
448
449# ----------------------------------------------------------------------
450# DESTRUCTOR
451# ----------------------------------------------------------------------
452itcl::body Rappture::VtkStreamlinesViewer::destructor {} {
453    Disconnect
454    $_dispatcher cancel !rebuild
455    $_dispatcher cancel !resize
456    $_dispatcher cancel !reseed
457    $_dispatcher cancel !rotate
458    $_dispatcher cancel !xcutplane
459    $_dispatcher cancel !ycutplane
460    $_dispatcher cancel !zcutplane
461    image delete $_image(plot)
462    image delete $_image(download)
463    catch { blt::arcball destroy $_arcball }
464}
465
466itcl::body Rappture::VtkStreamlinesViewer::DoResize {} {
467    if { $_width < 2 } {
468        set _width 500
469    }
470    if { $_height < 2 } {
471        set _height 500
472    }
473    set _start [clock clicks -milliseconds]
474    SendCmd "screen size $_width $_height"
475    RequestLegend
476
477    #SendCmd "imgflush"
478
479    # Must reset camera to have object scaling to take effect.
480    #SendCmd "camera reset"
481    #SendCmd "camera zoom $_view(zoom)"
482    set _resizePending 0
483}
484
485itcl::body Rappture::VtkStreamlinesViewer::DoRotate {} {
486    set q [list $_view(qw) $_view(qx) $_view(qy) $_view(qz)]
487    SendCmd "camera orient $q"
488    set _rotatePending 0
489}
490
491itcl::body Rappture::VtkStreamlinesViewer::DoReseed {} {
492    foreach dataset [CurrentDatasets -visible] {
493        foreach {dataobj comp} [split $dataset -] break
494        # This command works for either random or fmesh seeds
495        SendCmd "streamlines seed numpts $_numSeeds $dataset"
496    }
497    set _reseedPending 0
498}
499
500itcl::body Rappture::VtkStreamlinesViewer::EventuallyResize { w h } {
501    set _width $w
502    set _height $h
503    $_arcball resize $w $h
504    if { !$_resizePending } {
505        set _resizePending 1
506        $_dispatcher event -after 400 !resize
507    }
508}
509
510itcl::body Rappture::VtkStreamlinesViewer::EventuallyReseed { numPoints } {
511    set _numSeeds $numPoints
512    if { !$_reseedPending } {
513        set _reseedPending 1
514        $_dispatcher event -after 600 !reseed
515    }
516}
517
518set rotate_delay 100
519
520itcl::body Rappture::VtkStreamlinesViewer::EventuallyRotate { q } {
521    foreach { _view(qw) _view(qx) _view(qy) _view(qz) } $q break
522    if { !$_rotatePending } {
523        set _rotatePending 1
524        global rotate_delay
525        $_dispatcher event -after $rotate_delay !rotate
526    }
527}
528
529itcl::body Rappture::VtkStreamlinesViewer::EventuallySetCutplane { axis args } {
530    if { !$_cutplanePending } {
531        set _cutplanePending 1
532        $_dispatcher event -after 100 !${axis}cutplane
533    }
534}
535
536# ----------------------------------------------------------------------
537# USAGE: add <dataobj> ?<settings>?
538#
539# Clients use this to add a data object to the plot.  The optional
540# <settings> are used to configure the plot.  Allowed settings are
541# -color, -brightness, -width, -linestyle, and -raise.
542# ----------------------------------------------------------------------
543itcl::body Rappture::VtkStreamlinesViewer::add {dataobj {settings ""}} {
544    array set params {
545        -color auto
546        -width 1
547        -linestyle solid
548        -brightness 0
549        -raise 0
550        -description ""
551        -param ""
552        -type ""
553    }
554    array set params $settings
555    set params(-description) ""
556    set params(-param) ""
557    foreach {opt val} $settings {
558        if {![info exists params($opt)]} {
559            error "bad setting \"$opt\": should be [join [lsort [array names params]] {, }]"
560        }
561        set params($opt) $val
562    }
563    if {$params(-color) == "auto" || $params(-color) == "autoreset"} {
564        # can't handle -autocolors yet
565        set params(-color) black
566    }
567    set pos [lsearch -exact $dataobj $_dlist]
568    if {$pos < 0} {
569        lappend _dlist $dataobj
570    }
571    set _allDataObjs($dataobj) 1
572    set _obj2ovride($dataobj-color) $params(-color)
573    set _obj2ovride($dataobj-width) $params(-width)
574    set _obj2ovride($dataobj-raise) $params(-raise)
575    $_dispatcher event -idle !rebuild
576}
577
578
579# ----------------------------------------------------------------------
580# USAGE: delete ?<dataobj1> <dataobj2> ...?
581#
582#       Clients use this to delete a dataobj from the plot.  If no dataobjs
583#       are specified, then all dataobjs are deleted.  No data objects are
584#       deleted.  They are only removed from the display list.
585#
586# ----------------------------------------------------------------------
587itcl::body Rappture::VtkStreamlinesViewer::delete {args} {
588    if { [llength $args] == 0} {
589        set args $_dlist
590    }
591    # Delete all specified dataobjs
592    set changed 0
593    foreach dataobj $args {
594        set pos [lsearch -exact $_dlist $dataobj]
595        if { $pos < 0 } {
596            continue;                   # Don't know anything about it.
597        }
598        # Remove it from the dataobj list.
599        set _dlist [lreplace $_dlist $pos $pos]
600        foreach comp [$dataobj components] {
601            SendCmd "dataset visible 0 $dataobj-$comp"
602        }
603        array unset _obj2ovride $dataobj-*
604        array unset _settings $dataobj-*
605        # Append to the end of the dataobj list.
606        lappend _dlist $dataobj
607        set changed 1
608    }
609    # If anything changed, then rebuild the plot
610    if { $changed } {
611        $_dispatcher event -idle !rebuild
612    }
613}
614
615# ----------------------------------------------------------------------
616# USAGE: get ?-objects?
617# USAGE: get ?-visible?
618# USAGE: get ?-image view?
619#
620# Clients use this to query the list of objects being plotted, in
621# order from bottom to top of this result.  The optional "-image"
622# flag can also request the internal images being shown.
623# ----------------------------------------------------------------------
624itcl::body Rappture::VtkStreamlinesViewer::get {args} {
625    if {[llength $args] == 0} {
626        set args "-objects"
627    }
628
629    set op [lindex $args 0]
630    switch -- $op {
631        "-objects" {
632            # put the dataobj list in order according to -raise options
633            set dlist {}
634            foreach dataobj $_dlist {
635                if { ![IsValidObject $dataobj] } {
636                    continue
637                }
638                if {[info exists _obj2ovride($dataobj-raise)] &&
639                    $_obj2ovride($dataobj-raise)} {
640                    set dlist [linsert $dlist 0 $dataobj]
641                } else {
642                    lappend dlist $dataobj
643                }
644            }
645            return $dlist
646        }
647        "-visible" {
648            set dlist {}
649            foreach dataobj $_dlist {
650                if { ![IsValidObject $dataobj] } {
651                    continue
652                }
653                if { ![info exists _obj2ovride($dataobj-raise)] } {
654                    # No setting indicates that the object isn't visible.
655                    continue
656                }
657                # Otherwise use the -raise parameter to put the object to
658                # the front of the list.
659                if { $_obj2ovride($dataobj-raise) } {
660                    set dlist [linsert $dlist 0 $dataobj]
661                } else {
662                    lappend dlist $dataobj
663                }
664            }
665            return $dlist
666        }           
667        -image {
668            if {[llength $args] != 2} {
669                error "wrong # args: should be \"get -image view\""
670            }
671            switch -- [lindex $args end] {
672                view {
673                    return $_image(plot)
674                }
675                default {
676                    error "bad image name \"[lindex $args end]\": should be view"
677                }
678            }
679        }
680        default {
681            error "bad option \"$op\": should be -objects or -image"
682        }
683    }
684}
685
686# ----------------------------------------------------------------------
687# USAGE: scale ?<data1> <data2> ...?
688#
689# Sets the default limits for the overall plot according to the
690# limits of the data for all of the given <data> objects.  This
691# accounts for all objects--even those not showing on the screen.
692# Because of this, the limits are appropriate for all objects as
693# the user scans through data in the ResultSet viewer.
694# ----------------------------------------------------------------------
695itcl::body Rappture::VtkStreamlinesViewer::scale {args} {
696    array unset _limits
697    foreach dataobj $args {
698        set string [limits $dataobj]
699        if { $string == "" } {
700            continue
701        }
702        array set bounds $string
703        if {![info exists _limits(xmin)] || $_limits(xmin) > $bounds(xmin)} {
704            set _limits(xmin) $bounds(xmin)
705        }
706        if {![info exists _limits(xmax)] || $_limits(xmax) < $bounds(xmax)} {
707            set _limits(xmax) $bounds(xmax)
708        }
709
710        if {![info exists _limits(ymin)] || $_limits(ymin) > $bounds(ymin)} {
711            set _limits(ymin) $bounds(ymin)
712        }
713        if {![info exists _limits(ymax)] || $_limits(ymax) < $bounds(ymax)} {
714            set _limits(ymax) $bounds(ymax)
715        }
716
717        if {![info exists _limits(zmin)] || $_limits(zmin) > $bounds(zmin)} {
718            set _limits(zmin) $bounds(zmin)
719        }
720        if {![info exists _limits(zmax)] || $_limits(zmax) < $bounds(zmax)} {
721            set _limits(zmax) $bounds(zmax)
722        }
723    }
724}
725
726# ----------------------------------------------------------------------
727# USAGE: download coming
728# USAGE: download controls <downloadCommand>
729# USAGE: download now
730#
731# Clients use this method to create a downloadable representation
732# of the plot.  Returns a list of the form {ext string}, where
733# "ext" is the file extension (indicating the type of data) and
734# "string" is the data itself.
735# ----------------------------------------------------------------------
736itcl::body Rappture::VtkStreamlinesViewer::download {option args} {
737    switch $option {
738        coming {
739            if {[catch {
740                blt::winop snap $itk_component(plotarea) $_image(download)
741            }]} {
742                $_image(download) configure -width 1 -height 1
743                $_image(download) put #000000
744            }
745        }
746        controls {
747            set popup .vtkviewerdownload
748            if { ![winfo exists .vtkviewerdownload] } {
749                set inner [BuildDownloadPopup $popup [lindex $args 0]]
750            } else {
751                set inner [$popup component inner]
752            }
753            set _downloadPopup(image_controls) $inner.image_frame
754            set num [llength [get]]
755            set num [expr {($num == 1) ? "1 result" : "$num results"}]
756            set word [Rappture::filexfer::label downloadWord]
757            $inner.summary configure -text "$word $num in the following format:"
758            update idletasks            ;# Fix initial sizes
759            return $popup
760        }
761        now {
762            set popup .vtkviewerdownload
763            if {[winfo exists .vtkviewerdownload]} {
764                $popup deactivate
765            }
766            switch -- $_downloadPopup(format) {
767                "image" {
768                    return [$this GetImage [lindex $args 0]]
769                }
770                "vtk" {
771                    return [$this GetVtkData [lindex $args 0]]
772                }
773            }
774            return ""
775        }
776        default {
777            error "bad option \"$option\": should be coming, controls, now"
778        }
779    }
780}
781
782# ----------------------------------------------------------------------
783# USAGE: Connect ?<host:port>,<host:port>...?
784#
785# Clients use this method to establish a connection to a new
786# server, or to reestablish a connection to the previous server.
787# Any existing connection is automatically closed.
788# ----------------------------------------------------------------------
789itcl::body Rappture::VtkStreamlinesViewer::Connect {} {
790    set _hosts [GetServerList "vtkvis"]
791    if { "" == $_hosts } {
792        return 0
793    }
794    set result [VisViewer::Connect $_hosts]
795    if { $result } {
796        set w [winfo width $itk_component(view)]
797        set h [winfo height $itk_component(view)]
798        EventuallyResize $w $h
799    }
800    return $result
801}
802
803#
804# isconnected --
805#
806#       Indicates if we are currently connected to the visualization server.
807#
808itcl::body Rappture::VtkStreamlinesViewer::isconnected {} {
809    return [VisViewer::IsConnected]
810}
811
812#
813# disconnect --
814#
815itcl::body Rappture::VtkStreamlinesViewer::disconnect {} {
816    Disconnect
817    set _reset 1
818}
819
820#
821# Disconnect --
822#
823#       Clients use this method to disconnect from the current rendering
824#       server.
825#
826itcl::body Rappture::VtkStreamlinesViewer::Disconnect {} {
827    VisViewer::Disconnect
828
829    # disconnected -- no more data sitting on server
830    set _outbuf ""
831    array unset _datasets
832    array unset _data
833    array unset _colormaps
834}
835
836#
837# sendto --
838#
839itcl::body Rappture::VtkStreamlinesViewer::sendto { bytes } {
840    SendBytes "$bytes\n"
841}
842
843#
844# SendCmd
845#
846#       Send commands off to the rendering server.  If we're currently
847#       sending data objects to the server, buffer the commands to be
848#       sent later.
849#
850itcl::body Rappture::VtkStreamlinesViewer::SendCmd {string} {
851    if { $_buffering } {
852        append _outbuf $string "\n"
853    } else {
854        SendBytes "$string\n"
855    }
856}
857
858# ----------------------------------------------------------------------
859# USAGE: ReceiveImage -bytes <size> -type <type> -token <token>
860#
861# Invoked automatically whenever the "image" command comes in from
862# the rendering server.  Indicates that binary image data with the
863# specified <size> will follow.
864# ----------------------------------------------------------------------
865itcl::body Rappture::VtkStreamlinesViewer::ReceiveImage { args } {
866    array set info {
867        -token "???"
868        -bytes 0
869        -type image
870    }
871    array set info $args
872    set bytes [ReceiveBytes $info(-bytes)]
873    if { $info(-type) == "image" } {
874        if 0 {
875            set f [open "last.ppm" "w"]
876            puts $f $bytes
877            close $f
878        }
879        $_image(plot) configure -data $bytes
880        set time [clock seconds]
881        set date [clock format $time]
882        #puts stderr "$date: received image [image width $_image(plot)]x[image height $_image(plot)] image>"       
883        if { $_start > 0 } {
884            set finish [clock clicks -milliseconds]
885            #puts stderr "round trip time [expr $finish -$_start] milliseconds"
886            set _start 0
887        }
888    } elseif { $info(type) == "print" } {
889        set tag $this-print-$info(-token)
890        set _hardcopy($tag) $bytes
891    }
892}
893
894#
895# ReceiveDataset --
896#
897itcl::body Rappture::VtkStreamlinesViewer::ReceiveDataset { args } {
898    if { ![isconnected] } {
899        return
900    }
901    set option [lindex $args 0]
902    switch -- $option {
903        "scalar" {
904            set option [lindex $args 1]
905            switch -- $option {
906                "world" {
907                    foreach { x y z value tag } [lrange $args 2 end] break
908                }
909                "pixel" {
910                    foreach { x y value tag } [lrange $args 2 end] break
911                }
912            }
913        }
914        "vector" {
915            set option [lindex $args 1]
916            switch -- $option {
917                "world" {
918                    foreach { x y z vx vy vz tag } [lrange $args 2 end] break
919                }
920                "pixel" {
921                    foreach { x y vx vy vz tag } [lrange $args 2 end] break
922                }
923            }
924        }
925        "names" {
926            foreach { name } [lindex $args 1] {
927                #puts stderr "Dataset: $name"
928            }
929        }
930        default {
931            error "unknown dataset option \"$option\" from server"
932        }
933    }
934}
935
936# ----------------------------------------------------------------------
937# USAGE: Rebuild
938#
939# Called automatically whenever something changes that affects the
940# data in the widget.  Clears any existing data and rebuilds the
941# widget to display new data.
942# ----------------------------------------------------------------------
943itcl::body Rappture::VtkStreamlinesViewer::Rebuild {} {
944    update
945    set w [winfo width $itk_component(view)]
946    set h [winfo height $itk_component(view)]
947    if { $w < 2 || $h < 2 } {
948        $_dispatcher event -idle !rebuild
949        return
950    }
951
952    # Turn on buffering of commands to the server.  We don't want to
953    # be preempted by a server disconnect/reconnect (which automatically
954    # generates a new call to Rebuild).   
955    set _buffering 1
956
957    set _width $w
958    set _height $h
959    $_arcball resize $w $h
960    DoResize
961    #
962    # Reset the camera and other view parameters
963    #
964    set q [list $_view(qw) $_view(qx) $_view(qy) $_view(qz)]
965    $_arcball quaternion $q
966    if {$_view(ortho)} {
967        SendCmd "camera mode ortho"
968    } else {
969        SendCmd "camera mode persp"
970    }
971    DoRotate
972    PanCamera
973    set _first ""
974    InitSettings axis-xgrid axis-ygrid axis-zgrid axis-mode \
975        axis-visible axis-labels
976
977    SendCmd "imgflush"
978
979    set _limits(zmin) ""
980    set _limits(zmax) ""
981    set _first ""
982    foreach dataobj [get -objects] {
983        if { [info exists _obj2ovride($dataobj-raise)] &&  $_first == "" } {
984            set _first $dataobj
985        }
986        set _obj2datasets($dataobj) ""
987        foreach comp [$dataobj components] {
988            set tag $dataobj-$comp
989            if { ![info exists _datasets($tag)] } {
990                set bytes [$dataobj blob $comp]
991                set length [string length $bytes]
992                append _outbuf "dataset add $tag data follows $length\n"
993                append _outbuf $bytes
994                set _datasets($tag) 1
995                SetObjectStyle $dataobj $comp
996            }
997            lappend _obj2datasets($dataobj) $tag
998            if { [info exists _obj2ovride($dataobj-raise)] } {
999                SendCmd "dataset visible 1 $tag"
1000            } else {
1001                SendCmd "dataset visible 0 $tag"
1002            }
1003        }
1004    }
1005    if {"" != $_first} {
1006        set location [$_first hints camera]
1007        if { $location != "" } {
1008            array set view $location
1009        }
1010
1011        foreach axis { x y z } {
1012            set label [$_first hints ${axis}label]
1013            if { $label != "" } {
1014                SendCmd "axis name $axis $label"
1015            }
1016            set units [$_first hints ${axis}units]
1017            if { $units != "" } {
1018                SendCmd "axis units $axis $units"
1019            }
1020        }
1021    }
1022    array unset _scalarFields
1023    array set _scalarFields [$_first hints scalars]
1024    array unset _vectorFields
1025    array set _vectorFields [$_first hints vectors]
1026    set _currentField [$_first hints default]
1027    $itk_component(field) choices delete 0 end
1028    array unset _fields
1029    foreach name [array names _vectorFields] {
1030        set value $_vectorFields($name)
1031        $itk_component(field) choices insert end "$value" "$name"
1032        set _fields($value) $name
1033    }
1034    foreach name [array names _scalarFields] {
1035        set value $_scalarFields($name)
1036        $itk_component(field) choices insert end "$value" "$name"
1037        set _fields($value) $name
1038    }
1039    $itk_component(field) value $_currentField
1040
1041    InitSettings streamlines-seeds streamlines-visible streamlines-opacity \
1042        streamlines-numpoints streamlines-lighting streamlines-palette \
1043        volume-edges volume-lighting volume-opacity volume-visible \
1044        volume-wireframe \
1045        cutplane-xvisible cutplane-yvisible cutplane-zvisible \
1046        cutplane-xposition cutplane-yposition cutplane-zposition
1047
1048    if { $_reset || $_first == "" } {
1049        Zoom reset
1050        set _reset 0
1051    }
1052       
1053    set _buffering 0;                        # Turn off buffering.
1054
1055    # Actually write the commands to the server socket.  If it fails, we don't
1056    # care.  We're finished here.
1057    blt::busy hold $itk_component(hull)
1058    SendBytes $_outbuf;                       
1059    blt::busy release $itk_component(hull)
1060    set _outbuf "";                        # Clear the buffer.               
1061}
1062
1063# ----------------------------------------------------------------------
1064# USAGE: CurrentDatasets ?-all -visible? ?dataobjs?
1065#
1066# Returns a list of server IDs for the current datasets being displayed.  This
1067# is normally a single ID, but it might be a list of IDs if the current data
1068# object has multiple components.
1069# ----------------------------------------------------------------------
1070itcl::body Rappture::VtkStreamlinesViewer::CurrentDatasets {args} {
1071    set flag [lindex $args 0]
1072    switch -- $flag {
1073        "-all" {
1074            if { [llength $args] > 1 } {
1075                error "CurrentDatasets: can't specify dataobj after \"-all\""
1076            }
1077            set dlist [get -objects]
1078        }
1079        "-visible" {
1080            if { [llength $args] > 1 } {
1081                set dlist {}
1082                set args [lrange $args 1 end]
1083                foreach dataobj $args {
1084                    if { [info exists _obj2ovride($dataobj-raise)] } {
1085                        lappend dlist $dataobj
1086                    }
1087                }
1088            } else {
1089                set dlist [get -visible]
1090            }
1091        }           
1092        default {
1093            set dlist $args
1094        }
1095    }
1096    set rlist ""
1097    foreach dataobj $dlist {
1098        foreach comp [$dataobj components] {
1099            set tag $dataobj-$comp
1100            if { [info exists _datasets($tag)] && $_datasets($tag) } {
1101                lappend rlist $tag
1102            }
1103        }
1104    }
1105    return $rlist
1106}
1107
1108# ----------------------------------------------------------------------
1109# USAGE: Zoom in
1110# USAGE: Zoom out
1111# USAGE: Zoom reset
1112#
1113# Called automatically when the user clicks on one of the zoom
1114# controls for this widget.  Changes the zoom for the current view.
1115# ----------------------------------------------------------------------
1116itcl::body Rappture::VtkStreamlinesViewer::Zoom {option} {
1117    switch -- $option {
1118        "in" {
1119            set _view(zoom) [expr {$_view(zoom)*1.25}]
1120            SendCmd "camera zoom $_view(zoom)"
1121        }
1122        "out" {
1123            set _view(zoom) [expr {$_view(zoom)*0.8}]
1124            SendCmd "camera zoom $_view(zoom)"
1125        }
1126        "reset" {
1127            array set _view {
1128                qw      1
1129                qx      0
1130                qy      0
1131                qz      0
1132                zoom    1.0
1133                xpan   0
1134                ypan   0
1135            }
1136            SendCmd "camera reset all"
1137            if { $_first != "" } {
1138                set location [$_first hints camera]
1139                if { $location != "" } {
1140                    array set _view $location
1141                }
1142            }
1143            set q [list $_view(qw) $_view(qx) $_view(qy) $_view(qz)]
1144            $_arcball quaternion $q
1145            DoRotate
1146        }
1147    }
1148}
1149
1150itcl::body Rappture::VtkStreamlinesViewer::PanCamera {} {
1151    set x $_view(xpan)
1152    set y $_view(ypan)
1153    SendCmd "camera pan $x $y"
1154}
1155
1156
1157# ----------------------------------------------------------------------
1158# USAGE: Rotate click <x> <y>
1159# USAGE: Rotate drag <x> <y>
1160# USAGE: Rotate release <x> <y>
1161#
1162# Called automatically when the user clicks/drags/releases in the
1163# plot area.  Moves the plot according to the user's actions.
1164# ----------------------------------------------------------------------
1165itcl::body Rappture::VtkStreamlinesViewer::Rotate {option x y} {
1166    switch -- $option {
1167        "click" {
1168            $itk_component(view) configure -cursor fleur
1169            set _click(x) $x
1170            set _click(y) $y
1171        }
1172        "drag" {
1173            if {[array size _click] == 0} {
1174                Rotate click $x $y
1175            } else {
1176                set w [winfo width $itk_component(view)]
1177                set h [winfo height $itk_component(view)]
1178                if {$w <= 0 || $h <= 0} {
1179                    return
1180                }
1181
1182                if {[catch {
1183                    # this fails sometimes for no apparent reason
1184                    set dx [expr {double($x-$_click(x))/$w}]
1185                    set dy [expr {double($y-$_click(y))/$h}]
1186                }]} {
1187                    return
1188                }
1189                if { $dx == 0 && $dy == 0 } {
1190                    return
1191                }
1192                set q [$_arcball rotate $x $y $_click(x) $_click(y)]
1193                EventuallyRotate $q
1194                set _click(x) $x
1195                set _click(y) $y
1196            }
1197        }
1198        "release" {
1199            Rotate drag $x $y
1200            $itk_component(view) configure -cursor ""
1201            catch {unset _click}
1202        }
1203        default {
1204            error "bad option \"$option\": should be click, drag, release"
1205        }
1206    }
1207}
1208
1209itcl::body Rappture::VtkStreamlinesViewer::Pick {x y} {
1210    foreach tag [CurrentDatasets -visible] {
1211        SendCmd "dataset getscalar pixel $x $y $tag"
1212    }
1213}
1214
1215# ----------------------------------------------------------------------
1216# USAGE: $this Pan click x y
1217#        $this Pan drag x y
1218#        $this Pan release x y
1219#
1220# Called automatically when the user clicks on one of the zoom
1221# controls for this widget.  Changes the zoom for the current view.
1222# ----------------------------------------------------------------------
1223itcl::body Rappture::VtkStreamlinesViewer::Pan {option x y} {
1224    switch -- $option {
1225        "set" {
1226            set w [winfo width $itk_component(view)]
1227            set h [winfo height $itk_component(view)]
1228            set x [expr $x / double($w)]
1229            set y [expr $y / double($h)]
1230            set _view(xpan) [expr $_view(xpan) + $x]
1231            set _view(ypan) [expr $_view(ypan) + $y]
1232            PanCamera
1233            return
1234        }
1235        "click" {
1236            set _click(x) $x
1237            set _click(y) $y
1238            $itk_component(view) configure -cursor hand1
1239        }
1240        "drag" {
1241            if { ![info exists _click(x)] } {
1242                set _click(x) $x
1243            }
1244            if { ![info exists _click(y)] } {
1245                set _click(y) $y
1246            }
1247            set w [winfo width $itk_component(view)]
1248            set h [winfo height $itk_component(view)]
1249            set dx [expr ($_click(x) - $x)/double($w)]
1250            set dy [expr ($_click(y) - $y)/double($h)]
1251            set _click(x) $x
1252            set _click(y) $y
1253            set _view(xpan) [expr $_view(xpan) - $dx]
1254            set _view(ypan) [expr $_view(ypan) - $dy]
1255            PanCamera
1256        }
1257        "release" {
1258            Pan drag $x $y
1259            $itk_component(view) configure -cursor ""
1260        }
1261        default {
1262            error "unknown option \"$option\": should set, click, drag, or release"
1263        }
1264    }
1265}
1266
1267# ----------------------------------------------------------------------
1268# USAGE: InitSettings <what> ?<value>?
1269#
1270# Used internally to update rendering settings whenever parameters
1271# change in the popup settings panel.  Sends the new settings off
1272# to the back end.
1273# ----------------------------------------------------------------------
1274itcl::body Rappture::VtkStreamlinesViewer::InitSettings { args } {
1275    foreach spec $args {
1276        if { [info exists _settings($_first-$spec)] } {
1277            # Reset global setting with dataobj specific setting
1278            set _settings($spec) $_settings($_first-$spec)
1279        }
1280        AdjustSetting $spec
1281    }
1282}
1283
1284#
1285# AdjustSetting --
1286#
1287#       Changes/updates a specific setting in the widget.  There are
1288#       usually user-setable option.  Commands are sent to the render
1289#       server.
1290#
1291itcl::body Rappture::VtkStreamlinesViewer::AdjustSetting {what {value ""}} {
1292    if { ![isconnected] } {
1293        return
1294    }
1295    switch -- $what {
1296        "volume-opacity" {
1297            set val $_settings(volume-opacity)
1298            set sval [expr { 0.01 * double($val) }]
1299            foreach dataset [CurrentDatasets -visible] {
1300                SendCmd "polydata opacity $sval $dataset"
1301            }
1302        }
1303        "volume-wireframe" {
1304            set bool $_settings(volume-wireframe)
1305            foreach dataset [CurrentDatasets -visible] {
1306                SendCmd "polydata wireframe $bool $dataset"
1307            }
1308        }
1309        "volume-visible" {
1310            set bool $_settings(volume-visible)
1311            foreach dataset [CurrentDatasets -visible] {
1312                SendCmd "polydata visible $bool $dataset"
1313            }
1314            if { $bool } {
1315                Rappture::Tooltip::for $itk_component(volume) \
1316                    "Hide the volume"
1317            } else {
1318                Rappture::Tooltip::for $itk_component(volume) \
1319                    "Show the volume"
1320            }
1321        }
1322        "volume-lighting" {
1323            set bool $_settings(volume-lighting)
1324            foreach dataset [CurrentDatasets -visible] {
1325                SendCmd "polydata lighting $bool $dataset"
1326            }
1327        }
1328        "volume-edges" {
1329            set bool $_settings(volume-edges)
1330            foreach dataset [CurrentDatasets -visible] {
1331                SendCmd "polydata edges $bool $dataset"
1332            }
1333        }
1334        "axis-visible" {
1335            set bool $_settings(axis-visible)
1336            SendCmd "axis visible all $bool"
1337        }
1338        "axis-labels" {
1339            set bool $_settings(axis-labels)
1340            SendCmd "axis labels all $bool"
1341        }
1342        "axis-xgrid" - "axis-ygrid" - "axis-zgrid" {
1343            set axis [string range $what 5 5]
1344            set bool $_settings($what)
1345            SendCmd "axis grid $axis $bool"
1346        }
1347        "axis-mode" {
1348            set mode [$itk_component(axismode) value]
1349            set mode [$itk_component(axismode) translate $mode]
1350            set _settings($what) $mode
1351            SendCmd "axis flymode $mode"
1352        }
1353        "cutplane-edges" {
1354            set bool $_settings($what)
1355            foreach dataset [CurrentDatasets -visible] {
1356                SendCmd "cutplane edges $bool $dataset"
1357            }
1358        }
1359        "cutplane-visible" {
1360            set bool $_settings($what)
1361            foreach dataset [CurrentDatasets -visible] {
1362                SendCmd "cutplane visible $bool $dataset"
1363            }
1364        }
1365        "cutplane-wireframe" {
1366            set bool $_settings($what)
1367            foreach dataset [CurrentDatasets -visible] {
1368                SendCmd "cutplane wireframe $bool $dataset"
1369            }
1370        }
1371        "cutplane-lighting" {
1372            set bool $_settings($what)
1373            foreach dataset [CurrentDatasets -visible] {
1374                SendCmd "cutplane lighting $bool $dataset"
1375            }
1376        }
1377        "cutplane-opacity" {
1378            set val $_settings($what)
1379            set sval [expr { 0.01 * double($val) }]
1380            foreach dataset [CurrentDatasets -visible] {
1381                SendCmd "cutplane opacity $sval $dataset"
1382            }
1383        }
1384        "cutplane-xvisible" - "cutplane-yvisible" - "cutplane-zvisible" {
1385            set axis [string range $what 9 9]
1386            set bool $_settings($what)
1387            if { $bool } {
1388                $itk_component(${axis}CutScale) configure -state normal \
1389                    -troughcolor white
1390            } else {
1391                $itk_component(${axis}CutScale) configure -state disabled \
1392                    -troughcolor grey82
1393            }
1394            SendCmd "cutplane axis $axis $bool"
1395            SendCmd "cutplane colormode $_colorMode"
1396        }
1397        "cutplane-xposition" - "cutplane-yposition" - "cutplane-zposition" {
1398            set axis [string range $what 9 9]
1399            set pos [expr $_settings($what) * 0.01]
1400            SendCmd "cutplane slice ${axis} ${pos}"
1401            set _cutplanePending 0
1402        }
1403        "streamlines-seeds" {
1404            set bool $_settings($what)
1405            foreach dataset [CurrentDatasets -visible] {
1406                SendCmd "streamlines seed visible $bool $dataset"
1407            }
1408        }
1409        "streamlines-numpoints" {
1410            set density $_settings($what)
1411            EventuallyReseed $density
1412        }
1413        "streamlines-visible" {
1414            set bool $_settings($what)
1415            foreach dataset [CurrentDatasets -visible] {
1416                SendCmd "streamlines visible $bool $dataset"
1417            }
1418            if { $bool } {
1419                Rappture::Tooltip::for $itk_component(streamlines) \
1420                    "Hide the streamlines"
1421            } else {
1422                Rappture::Tooltip::for $itk_component(streamlines) \
1423                    "Show the streamlines"
1424            }
1425        }
1426        "streamlines-mode" {
1427            set mode [$itk_component(streammode) value]
1428            set _settings(streamlines-mode) $mode
1429            foreach dataset [CurrentDatasets -visible] {
1430                switch -- $mode {
1431                    "lines" {
1432                        SendCmd "streamlines lines $dataset"
1433                    }
1434                    "ribbons" {
1435                        SendCmd "streamlines ribbons 3 0 $dataset"
1436                    }
1437                    "tubes" {
1438                        SendCmd "streamlines tubes 5 3 $dataset"
1439                    }
1440                }
1441            }
1442        }
1443        "streamlines-palette" {
1444            set palette [$itk_component(palette) value]
1445            set _settings(streamlines-palette) $palette
1446            foreach dataset [CurrentDatasets -visible $_first] {
1447                foreach {dataobj comp} [split $dataset -] break
1448                ChangeColormap $dataobj $comp $palette
1449            }
1450            RequestLegend
1451        }
1452        "streamlines-opacity" {
1453            set val $_settings(streamlines-opacity)
1454            set sval [expr { 0.01 * double($val) }]
1455            foreach dataset [CurrentDatasets -visible $_first] {
1456                SendCmd "streamlines opacity $sval $dataset"
1457            }
1458        }
1459        "streamlines-scale" {
1460            set val $_settings(streamlines-scale)
1461            set sval [expr { 0.01 * double($val) }]
1462            foreach dataset [CurrentDatasets -visible $_first] {
1463                SendCmd "streamlines scale $sval $sval $sval $dataset"
1464            }
1465        }
1466        "streamlines-lighting" {
1467            set bool $_settings(streamlines-lighting)
1468            foreach dataset [CurrentDatasets -visible $_first] {
1469                SendCmd "streamlines lighting $bool"
1470            }
1471        }
1472        "streamlines-field" {
1473            set new [$itk_component(field) value]
1474            set value [$itk_component(axismode) translate $new]
1475            puts stderr "streamlines-field old field=$_currentField new field = $new value=$value"
1476            set _settings(streamlines-field) $value
1477            if { [info exists _scalarFields($new)] } {
1478                set name $_scalarFields($new)
1479                set _colorMode scalar
1480                set fieldType scalar
1481                set _currentField $new
1482            } elseif { [info exists _vectorFields($new)] } {
1483                set name $_vectorFields($new)
1484                set _colorMode vmag
1485                set fieldType vector
1486                set _currentField $new
1487            } else {
1488                puts stderr "unknown field \"$new\""
1489                return
1490            }
1491            foreach dataset [CurrentDatasets -visible] {
1492                puts stderr "dataset ${fieldType} ${name} $dataset"
1493                puts stderr "streamlines colormode $_colorMode $dataset"
1494                puts stderr "cutplane colormode $_colorMode $dataset"
1495                SendCmd "dataset ${fieldType} ${name} $dataset"
1496                SendCmd "streamlines colormode $_colorMode $dataset"
1497                SendCmd "cutplane colormode $_colorMode $dataset"
1498            }
1499            RequestLegend
1500        }
1501        default {
1502            error "don't know how to fix $what"
1503        }
1504    }
1505}
1506
1507#
1508# RequestLegend --
1509#
1510#       Request a new legend from the server.  The size of the legend
1511#       is determined from the height of the canvas.  It will be rotated
1512#       to be vertical when drawn.
1513#
1514itcl::body Rappture::VtkStreamlinesViewer::RequestLegend {} {
1515    set font "Arial 8"
1516    set lineht [font metrics $font -linespace]
1517    set c $itk_component(legend)
1518    set w 12
1519    set h [expr {$_height - 3 * ($lineht + 2)}]
1520    if { $h < 1} {
1521        return
1522    }
1523    # Set the legend on the first streamlines dataset.
1524    foreach dataset [CurrentDatasets -visible $_first] {
1525        foreach {dataobj comp} [split $dataset -] break
1526        if { [info exists _dataset2style($dataset)] } {
1527            SendCmd "legend $_dataset2style($dataset) $_colorMode {} $w $h 0"
1528            break;
1529        }
1530    }
1531}
1532
1533#
1534# ChangeColormap --
1535#
1536itcl::body Rappture::VtkStreamlinesViewer::ChangeColormap {dataobj comp color} {
1537    set tag $dataobj-$comp
1538    if { ![info exist _style($tag)] } {
1539        error "no initial colormap"
1540    }
1541    array set style $_style($tag)
1542    set style(-color) $color
1543    set _style($tag) [array get style]
1544    SetColormap $dataobj $comp
1545}
1546
1547#
1548# SetColormap --
1549#
1550itcl::body Rappture::VtkStreamlinesViewer::SetColormap { dataobj comp } {
1551    array set style {
1552        -color BGYOR
1553        -levels 6
1554        -opacity 1.0
1555    }
1556    set tag $dataobj-$comp
1557    if { ![info exists _initialStyle($tag)] } {
1558        # Save the initial component style.
1559        set _initialStyle($tag) [$dataobj style $comp]
1560    }
1561
1562    # Override defaults with initial style defined in xml.
1563    array set style $_initialStyle($tag)
1564
1565    if { ![info exists _style($tag)] } {
1566        set _style($tag) [array get style]
1567    }
1568    # Override initial style with current style.
1569    array set style $_style($tag)
1570
1571    set name "$style(-color):$style(-levels):$style(-opacity)"
1572    if { ![info exists _colormaps($name)] } {
1573        BuildColormap $name [array get style]
1574        set _colormaps($name) 1
1575    }
1576    if { ![info exists _dataset2style($tag)] ||
1577         $_dataset2style($tag) != $name } {
1578        SendCmd "streamlines colormap $name $tag"
1579        SendCmd "cutplane colormap $name $tag"
1580        set _dataset2style($tag) $name
1581    }
1582}
1583
1584itcl::body Rappture::VtkStreamlinesViewer::ColorsToColormap { colors } {
1585    switch -- $colors {
1586        "grey-to-blue" {
1587            return {
1588                0.0                      0.200 0.200 0.200
1589                0.14285714285714285      0.400 0.400 0.400
1590                0.2857142857142857       0.600 0.600 0.600
1591                0.42857142857142855      0.900 0.900 0.900
1592                0.5714285714285714       0.800 1.000 1.000
1593                0.7142857142857143       0.600 1.000 1.000
1594                0.8571428571428571       0.400 0.900 1.000
1595                1.0                      0.000 0.600 0.800
1596            }
1597        }
1598        "blue-to-grey" {
1599            return {
1600                0.0                     0.000 0.600 0.800
1601                0.14285714285714285     0.400 0.900 1.000
1602                0.2857142857142857      0.600 1.000 1.000
1603                0.42857142857142855     0.800 1.000 1.000
1604                0.5714285714285714      0.900 0.900 0.900
1605                0.7142857142857143      0.600 0.600 0.600
1606                0.8571428571428571      0.400 0.400 0.400
1607                1.0                     0.200 0.200 0.200
1608            }
1609        }
1610        "blue" {
1611            return {
1612                0.0                     0.900 1.000 1.000
1613                0.1111111111111111      0.800 0.983 1.000
1614                0.2222222222222222      0.700 0.950 1.000
1615                0.3333333333333333      0.600 0.900 1.000
1616                0.4444444444444444      0.500 0.833 1.000
1617                0.5555555555555556      0.400 0.750 1.000
1618                0.6666666666666666      0.300 0.650 1.000
1619                0.7777777777777778      0.200 0.533 1.000
1620                0.8888888888888888      0.100 0.400 1.000
1621                1.0                     0.000 0.250 1.000
1622            }
1623        }
1624        "brown-to-blue" {
1625            return {
1626                0.0                             0.200   0.100   0.000
1627                0.09090909090909091             0.400   0.187   0.000
1628                0.18181818181818182             0.600   0.379   0.210
1629                0.2727272727272727              0.800   0.608   0.480
1630                0.36363636363636365             0.850   0.688   0.595
1631                0.45454545454545453             0.950   0.855   0.808
1632                0.5454545454545454              0.800   0.993   1.000
1633                0.6363636363636364              0.600   0.973   1.000
1634                0.7272727272727273              0.400   0.940   1.000
1635                0.8181818181818182              0.200   0.893   1.000
1636                0.9090909090909091              0.000   0.667   0.800
1637                1.0                             0.000   0.480   0.600
1638            }
1639        }
1640        "blue-to-brown" {
1641            return {
1642                0.0                             0.000   0.480   0.600
1643                0.09090909090909091             0.000   0.667   0.800
1644                0.18181818181818182             0.200   0.893   1.000
1645                0.2727272727272727              0.400   0.940   1.000
1646                0.36363636363636365             0.600   0.973   1.000
1647                0.45454545454545453             0.800   0.993   1.000
1648                0.5454545454545454              0.950   0.855   0.808
1649                0.6363636363636364              0.850   0.688   0.595
1650                0.7272727272727273              0.800   0.608   0.480
1651                0.8181818181818182              0.600   0.379   0.210
1652                0.9090909090909091              0.400   0.187   0.000
1653                1.0                             0.200   0.100   0.000
1654            }
1655        }
1656        "blue-to-orange" {
1657            return {
1658                0.0                             0.000   0.167   1.000
1659                0.09090909090909091             0.100   0.400   1.000
1660                0.18181818181818182             0.200   0.600   1.000
1661                0.2727272727272727              0.400   0.800   1.000
1662                0.36363636363636365             0.600   0.933   1.000
1663                0.45454545454545453             0.800   1.000   1.000
1664                0.5454545454545454              1.000   1.000   0.800
1665                0.6363636363636364              1.000   0.933   0.600
1666                0.7272727272727273              1.000   0.800   0.400
1667                0.8181818181818182              1.000   0.600   0.200
1668                0.9090909090909091              1.000   0.400   0.100
1669                1.0                             1.000   0.167   0.000
1670            }
1671        }
1672        "orange-to-blue" {
1673            return {
1674                0.0                             1.000   0.167   0.000
1675                0.09090909090909091             1.000   0.400   0.100
1676                0.18181818181818182             1.000   0.600   0.200
1677                0.2727272727272727              1.000   0.800   0.400
1678                0.36363636363636365             1.000   0.933   0.600
1679                0.45454545454545453             1.000   1.000   0.800
1680                0.5454545454545454              0.800   1.000   1.000
1681                0.6363636363636364              0.600   0.933   1.000
1682                0.7272727272727273              0.400   0.800   1.000
1683                0.8181818181818182              0.200   0.600   1.000
1684                0.9090909090909091              0.100   0.400   1.000
1685                1.0                             0.000   0.167   1.000
1686            }
1687        }
1688        "rainbow" {
1689            set clist {
1690                "#EE82EE"
1691                "#4B0082"
1692                "blue"
1693                "#008000"
1694                "yellow"
1695                "#FFA500"
1696                "red"
1697            }
1698        }
1699        "BGYOR" {
1700            set clist {
1701                "blue"
1702                "#008000"
1703                "yellow"
1704                "#FFA500"
1705                "red"
1706            }
1707        }
1708        "ROYGB" {
1709            set clist {
1710                "red"
1711                "#FFA500"
1712                "yellow"
1713                "#008000"
1714                "blue"
1715            }
1716        }
1717        "RYGCB" {
1718            set clist {
1719                "red"
1720                "yellow"
1721                "green"
1722                "cyan"
1723                "blue"
1724            }
1725        }
1726        "BCGYR" {
1727            set clist {
1728                "blue"
1729                "cyan"
1730                "green"
1731                "yellow"
1732                "red"
1733            }
1734        }
1735        "spectral" {
1736            return {
1737                0.0 0.150 0.300 1.000
1738                0.1 0.250 0.630 1.000
1739                0.2 0.450 0.850 1.000
1740                0.3 0.670 0.970 1.000
1741                0.4 0.880 1.000 1.000
1742                0.5 1.000 1.000 0.750
1743                0.6 1.000 0.880 0.600
1744                0.7 1.000 0.680 0.450
1745                0.8 0.970 0.430 0.370
1746                0.9 0.850 0.150 0.196
1747                1.0 0.650 0.000 0.130
1748            }
1749        }
1750        "green-to-magenta" {
1751            return {
1752                0.0 0.000 0.316 0.000
1753                0.06666666666666667 0.000 0.526 0.000
1754                0.13333333333333333 0.000 0.737 0.000
1755                0.2 0.000 0.947 0.000
1756                0.26666666666666666 0.316 1.000 0.316
1757                0.3333333333333333 0.526 1.000 0.526
1758                0.4 0.737 1.000 0.737
1759                0.4666666666666667 1.000 1.000 1.000
1760                0.5333333333333333 1.000 0.947 1.000
1761                0.6 1.000 0.737 1.000
1762                0.6666666666666666 1.000 0.526 1.000
1763                0.7333333333333333 1.000 0.316 1.000
1764                0.8 0.947 0.000 0.947
1765                0.8666666666666667 0.737 0.000 0.737
1766                0.9333333333333333 0.526 0.000 0.526
1767                1.0 0.316 0.000 0.316
1768            }
1769        }
1770        "greyscale" {
1771            return {
1772                0.0 0.0 0.0 0.0 1.0 1.0 1.0 1.0
1773            }
1774        }
1775        "nanohub" {
1776            set clist "white yellow green cyan blue magenta"
1777        }
1778        default {
1779            set clist $colors
1780        }
1781    }
1782    set cmap {}
1783    for {set i 0} {$i < [llength $clist]} {incr i} {
1784        set x [expr {double($i)/([llength $clist]-1)}]
1785        set color [lindex $clist $i]
1786        append cmap "$x [Color2RGB $color] "
1787    }
1788    return $cmap
1789}
1790
1791#
1792# BuildColormap --
1793#
1794itcl::body Rappture::VtkStreamlinesViewer::BuildColormap { name styles } {
1795    array set style $styles
1796    set cmap [ColorsToColormap $style(-color)]
1797    if { [llength $cmap] == 0 } {
1798        set cmap "0.0 0.0 0.0 0.0 1.0 1.0 1.0 1.0"
1799    }
1800    if { ![info exists _settings(volume-opacity)] } {
1801        set _settings(volume-opacity) $style(-opacity)
1802    }
1803    set max $_settings(volume-opacity)
1804
1805    set wmap "0.0 1.0 1.0 1.0"
1806    SendCmd "colormap add $name { $cmap } { $wmap }"
1807}
1808
1809# ----------------------------------------------------------------------
1810# CONFIGURATION OPTION: -plotbackground
1811# ----------------------------------------------------------------------
1812itcl::configbody Rappture::VtkStreamlinesViewer::plotbackground {
1813    if { [isconnected] } {
1814        foreach {r g b} [Color2RGB $itk_option(-plotbackground)] break
1815        SendCmd "screen bgcolor $r $g $b"
1816    }
1817}
1818
1819# ----------------------------------------------------------------------
1820# CONFIGURATION OPTION: -plotforeground
1821# ----------------------------------------------------------------------
1822itcl::configbody Rappture::VtkStreamlinesViewer::plotforeground {
1823    if { [isconnected] } {
1824        foreach {r g b} [Color2RGB $itk_option(-plotforeground)] break
1825        #fix this!
1826        #SendCmd "color background $r $g $b"
1827    }
1828}
1829
1830itcl::body Rappture::VtkStreamlinesViewer::limits { dataobj } {
1831    return
1832    array unset _limits $dataobj-*
1833    foreach comp [$dataobj components] {
1834        set tag $dataobj-$comp
1835        if { ![info exists _limits($tag)] } {
1836            set data [$dataobj blob $comp]
1837            set tmpfile file[pid].vtk
1838            set f [open "$tmpfile" "w"]
1839            fconfigure $f -translation binary
1840            puts $f $data
1841            close $f
1842            set reader [vtkDataSetReader $tag-xvtkDataSetReader]
1843            $reader SetFileName $tmpfile
1844            $reader ReadAllScalarsOn
1845            $reader ReadAllVectorsOn
1846            $reader ReadAllFieldsOn
1847            $reader Update
1848            set output [$reader GetOutput]
1849            set _limits($tag) [$output GetBounds]
1850            set pointData [$output GetPointData]
1851            puts stderr "\#scalars=[$reader GetNumberOfScalarsInFile]"
1852            puts stderr "\#fielddata=[$reader GetNumberOfFieldDataInFile]"
1853            puts stderr "fielddataname=[$reader GetFieldDataNameInFile 0]"
1854            set fieldData [$output GetFieldData]
1855            set pointData [$output GetPointData]
1856            puts stderr "field \#arrays=[$fieldData GetNumberOfArrays]"
1857            for { set i 0 } { $i < [$fieldData GetNumberOfArrays] } { incr i } {
1858                puts stderr [$fieldData GetArrayName $i]
1859            }
1860            puts stderr "point \#arrays=[$pointData GetNumberOfArrays]"
1861            for { set i 0 } { $i < [$pointData GetNumberOfArrays] } { incr i } {
1862                set name [$pointData GetArrayName $i]
1863                if { ![info exists _fields($name)] } {
1864                    $itk_component(field) choices insert end "$name" "$name"
1865                    set _fields($name) 1
1866                }
1867            }
1868            puts stderr "field \#components=[$fieldData GetNumberOfComponents]"
1869            puts stderr "point \#components=[$pointData GetNumberOfComponents]"
1870            puts stderr "field \#tuples=[$fieldData GetNumberOfTuples]"
1871            puts stderr "point \#tuples=[$pointData GetNumberOfTuples]"
1872            puts stderr "point \#scalars=[$pointData GetScalars]"
1873            puts stderr vectors=[$pointData GetVectors]
1874            rename $output ""
1875            rename $reader ""
1876            file delete $tmpfile
1877        }
1878        foreach { xMin xMax yMin yMax zMin zMax} $_limits($tag) break
1879        if {![info exists limits(xmin)] || $limits(xmin) > $xMin} {
1880            set limits(xmin) $xMin
1881        }
1882        if {![info exists limits(xmax)] || $limits(xmax) < $xMax} {
1883            set limits(xmax) $xMax
1884        }
1885        if {![info exists limits(ymin)] || $limits(ymin) > $yMin} {
1886            set limits(ymin) $xMin
1887        }
1888        if {![info exists limits(ymax)] || $limits(ymax) < $yMax} {
1889            set limits(ymax) $yMax
1890        }
1891        if {![info exists limits(zmin)] || $limits(zmin) > $zMin} {
1892            set limits(zmin) $zMin
1893        }
1894        if {![info exists limits(zmax)] || $limits(zmax) < $zMax} {
1895            set limits(zmax) $zMax
1896        }
1897    }
1898    return [array get limits]
1899}
1900
1901itcl::body Rappture::VtkStreamlinesViewer::BuildVolumeTab {} {
1902
1903    set fg [option get $itk_component(hull) font Font]
1904    #set bfg [option get $itk_component(hull) boldFont Font]
1905
1906    set inner [$itk_component(main) insert end \
1907        -title "Volume Settings" \
1908        -icon [Rappture::icon volume-on]]
1909    $inner configure -borderwidth 4
1910
1911    checkbutton $inner.volume \
1912        -text "Show Volume" \
1913        -variable [itcl::scope _settings(volume-visible)] \
1914        -command [itcl::code $this AdjustSetting volume-visible] \
1915        -font "Arial 9"
1916
1917    checkbutton $inner.wireframe \
1918        -text "Show Wireframe" \
1919        -variable [itcl::scope _settings(volume-wireframe)] \
1920        -command [itcl::code $this AdjustSetting volume-wireframe] \
1921        -font "Arial 9"
1922
1923    checkbutton $inner.lighting \
1924        -text "Enable Lighting" \
1925        -variable [itcl::scope _settings(volume-lighting)] \
1926        -command [itcl::code $this AdjustSetting volume-lighting] \
1927        -font "Arial 9"
1928
1929    checkbutton $inner.edges \
1930        -text "Show Edges" \
1931        -variable [itcl::scope _settings(volume-edges)] \
1932        -command [itcl::code $this AdjustSetting volume-edges] \
1933        -font "Arial 9"
1934
1935    label $inner.opacity_l -text "Opacity" -font "Arial 9"
1936    ::scale $inner.opacity -from 0 -to 100 -orient horizontal \
1937        -variable [itcl::scope _settings(volume-opacity)] \
1938        -width 10 \
1939        -showvalue off \
1940        -command [itcl::code $this AdjustSetting volume-opacity]
1941
1942    blt::table $inner \
1943        0,0 $inner.volume    -anchor w -pady 2 \
1944        1,0 $inner.wireframe -anchor w -pady 2 \
1945        2,0 $inner.lighting  -anchor w -pady 2 \
1946        3,0 $inner.edges     -anchor w -pady 2 \
1947        4,0 $inner.opacity_l -anchor w -pady 2 \
1948        5,0 $inner.opacity   -fill x   -pady 2
1949
1950    blt::table configure $inner r* c* -resize none
1951    blt::table configure $inner r6 c1 -resize expand
1952}
1953
1954
1955itcl::body Rappture::VtkStreamlinesViewer::BuildStreamsTab {} {
1956
1957    set fg [option get $itk_component(hull) font Font]
1958    #set bfg [option get $itk_component(hull) boldFont Font]
1959
1960    set inner [$itk_component(main) insert end \
1961        -title "Streams Settings" \
1962        -icon [Rappture::icon streamlines-on]]
1963    $inner configure -borderwidth 4
1964
1965    checkbutton $inner.streamlines \
1966        -text "Show Streamlines" \
1967        -variable [itcl::scope _settings(streamlines-visible)] \
1968        -command [itcl::code $this AdjustSetting streamlines-visible] \
1969        -font "Arial 9"
1970   
1971    checkbutton $inner.lighting \
1972        -text "Enable Lighting" \
1973        -variable [itcl::scope _settings(streamlines-lighting)] \
1974        -command [itcl::code $this AdjustSetting streamlines-lighting] \
1975        -font "Arial 9"
1976
1977    checkbutton $inner.seeds \
1978        -text "Show Seeds" \
1979        -variable [itcl::scope _settings(streamlines-seeds)] \
1980        -command [itcl::code $this AdjustSetting streamlines-seeds] \
1981        -font "Arial 9"
1982
1983    label $inner.mode_l -text "Mode" -font "Arial 9"
1984    itk_component add streammode {
1985        Rappture::Combobox $inner.mode -width 10 -editable no
1986    }
1987    $inner.mode choices insert end \
1988        "lines"    "lines" \
1989        "ribbons"   "ribbons" \
1990        "tubes"     "tubes"
1991    $itk_component(streammode) value "lines"
1992    bind $inner.mode <<Value>> [itcl::code $this AdjustSetting streamlines-mode]
1993
1994    label $inner.opacity_l -text "Opacity" -font "Arial 9"
1995    ::scale $inner.opacity -from 0 -to 100 -orient horizontal \
1996        -variable [itcl::scope _settings(streamlines-opacity)] \
1997        -width 10 \
1998        -showvalue off \
1999        -command [itcl::code $this AdjustSetting streamlines-opacity]
2000
2001    label $inner.density_l -text "Number of Seeds" -font "Arial 9"
2002    ::scale $inner.density -from 1 -to 1000 -orient horizontal \
2003        -variable [itcl::scope _settings(streamlines-numpoints)] \
2004        -width 10 \
2005        -showvalue on \
2006        -command [itcl::code $this AdjustSetting streamlines-numpoints]
2007
2008    label $inner.scale_l -text "Scale" -font "Arial 9"
2009    ::scale $inner.scale -from 1 -to 100 -orient horizontal \
2010        -variable [itcl::scope _settings(streamlines-scale)] \
2011        -width 10 \
2012        -showvalue off \
2013        -command [itcl::code $this AdjustSetting streamlines-scale]
2014
2015    label $inner.field_l -text "Field" -font "Arial 9"
2016    itk_component add field {
2017        Rappture::Combobox $inner.field -width 10 -editable no
2018    }
2019    bind $inner.field <<Value>> \
2020        [itcl::code $this AdjustSetting streamlines-field]
2021
2022    label $inner.palette_l -text "Palette" -font "Arial 9"
2023    itk_component add palette {
2024        Rappture::Combobox $inner.palette -width 10 -editable no
2025    }
2026    $inner.palette choices insert end \
2027        "BCGYR"              "BCGYR"            \
2028        "BGYOR"              "BGYOR"            \
2029        "blue"               "blue"             \
2030        "blue-to-brown"      "blue-to-brown"    \
2031        "blue-to-orange"     "blue-to-orange"   \
2032        "blue-to-grey"       "blue-to-grey"     \
2033        "green-to-magenta"   "green-to-magenta" \
2034        "greyscale"          "greyscale"        \
2035        "nanohub"            "nanohub"          \
2036        "rainbow"            "rainbow"          \
2037        "spectral"           "spectral"         \
2038        "ROYGB"              "ROYGB"            \
2039        "RYGCB"              "RYGCB"            \
2040        "brown-to-blue"      "brown-to-blue"    \
2041        "grey-to-blue"       "grey-to-blue"     \
2042        "orange-to-blue"     "orange-to-blue"   
2043
2044    $itk_component(palette) value "BCGYR"
2045    bind $inner.palette <<Value>> \
2046        [itcl::code $this AdjustSetting streamlines-palette]
2047
2048    blt::table $inner \
2049        0,0 $inner.streamlines -anchor w -pady 2 -cspan 2 \
2050        1,0 $inner.lighting    -anchor w -pady 2 -cspan 2 \
2051        2,0 $inner.seeds       -anchor w -pady 2 -cspan 2 \
2052        3,0 $inner.density_l   -anchor w -pady 2 -cspan 2 \
2053        4,0 $inner.density     -fill x   -pady 2 -cspan 2 \
2054        5,0 $inner.mode_l      -anchor w -pady 2  \
2055        5,1 $inner.mode        -anchor w -pady 2  \
2056        6,0 $inner.opacity_l   -anchor w -pady 2 -cspan 2 \
2057        7,0 $inner.opacity     -fill x   -pady 2 -cspan 2 \
2058        8,0 $inner.field_l     -anchor w -pady 2  \
2059        8,1 $inner.field       -anchor w -pady 2  \
2060        9,0 $inner.palette_l   -anchor w -pady 2  \
2061        9,1 $inner.palette     -anchor w -pady 2  \
2062       
2063
2064    blt::table configure $inner r* c* -resize none
2065    blt::table configure $inner r10 c1 c2 -resize expand
2066}
2067
2068itcl::body Rappture::VtkStreamlinesViewer::BuildAxisTab {} {
2069
2070    set fg [option get $itk_component(hull) font Font]
2071    #set bfg [option get $itk_component(hull) boldFont Font]
2072
2073    set inner [$itk_component(main) insert end \
2074        -title "Axis Settings" \
2075        -icon [Rappture::icon axis1]]
2076    $inner configure -borderwidth 4
2077
2078    checkbutton $inner.visible \
2079        -text "Show Axes" \
2080        -variable [itcl::scope _settings(axis-visible)] \
2081        -command [itcl::code $this AdjustSetting axis-visible] \
2082        -font "Arial 9"
2083
2084    checkbutton $inner.labels \
2085        -text "Show Axis Labels" \
2086        -variable [itcl::scope _settings(axis-labels)] \
2087        -command [itcl::code $this AdjustSetting axis-labels] \
2088        -font "Arial 9"
2089
2090    checkbutton $inner.gridx \
2091        -text "Show X Grid" \
2092        -variable [itcl::scope _settings(axis-xgrid)] \
2093        -command [itcl::code $this AdjustSetting axis-xgrid] \
2094        -font "Arial 9"
2095    checkbutton $inner.gridy \
2096        -text "Show Y Grid" \
2097        -variable [itcl::scope _settings(axis-ygrid)] \
2098        -command [itcl::code $this AdjustSetting axis-ygrid] \
2099        -font "Arial 9"
2100    checkbutton $inner.gridz \
2101        -text "Show Z Grid" \
2102        -variable [itcl::scope _settings(axis-zgrid)] \
2103        -command [itcl::code $this AdjustSetting axis-zgrid] \
2104        -font "Arial 9"
2105
2106    label $inner.mode_l -text "Mode" -font "Arial 9"
2107
2108    itk_component add axismode {
2109        Rappture::Combobox $inner.mode -width 10 -editable no
2110    }
2111    $inner.mode choices insert end \
2112        "static_triad"    "static" \
2113        "closest_triad"   "closest" \
2114        "furthest_triad"  "furthest" \
2115        "outer_edges"     "outer"         
2116    $itk_component(axismode) value "static"
2117    bind $inner.mode <<Value>> [itcl::code $this AdjustSetting axis-mode]
2118
2119    blt::table $inner \
2120        0,0 $inner.visible -anchor w -cspan 2 \
2121        1,0 $inner.labels  -anchor w -cspan 2 \
2122        2,0 $inner.gridx   -anchor w -cspan 2 \
2123        3,0 $inner.gridy   -anchor w -cspan 2 \
2124        4,0 $inner.gridz   -anchor w -cspan 2 \
2125        5,0 $inner.mode_l  -anchor w -cspan 2 -padx { 2 0 } \
2126        6,0 $inner.mode    -fill x   -cspan 2
2127
2128    blt::table configure $inner r* c* -resize none
2129    blt::table configure $inner r7 c1 -resize expand
2130}
2131
2132
2133itcl::body Rappture::VtkStreamlinesViewer::BuildCameraTab {} {
2134    set inner [$itk_component(main) insert end \
2135        -title "Camera Settings" \
2136        -icon [Rappture::icon camera]]
2137    $inner configure -borderwidth 4
2138
2139    set labels { qx qy qz qw xpan ypan zoom }
2140    set row 0
2141    foreach tag $labels {
2142        label $inner.${tag}label -text $tag -font "Arial 9"
2143        entry $inner.${tag} -font "Arial 9"  -bg white \
2144            -textvariable [itcl::scope _view($tag)]
2145        bind $inner.${tag} <KeyPress-Return> \
2146            [itcl::code $this camera set ${tag}]
2147        blt::table $inner \
2148            $row,0 $inner.${tag}label -anchor e -pady 2 \
2149            $row,1 $inner.${tag} -anchor w -pady 2
2150        blt::table configure $inner r$row -resize none
2151        incr row
2152    }
2153    checkbutton $inner.ortho \
2154        -text "Orthographic Projection" \
2155        -variable [itcl::scope _view(ortho)] \
2156        -command [itcl::code $this camera set ortho] \
2157        -font "Arial 9"
2158    blt::table $inner \
2159            $row,0 $inner.ortho -columnspan 2 -anchor w -pady 2
2160    blt::table configure $inner r$row -resize none
2161    incr row
2162
2163    blt::table configure $inner c0 c1 -resize none
2164    blt::table configure $inner c2 -resize expand
2165    blt::table configure $inner r$row -resize expand
2166}
2167
2168itcl::body Rappture::VtkStreamlinesViewer::BuildCutplaneTab {} {
2169
2170    set fg [option get $itk_component(hull) font Font]
2171   
2172    set inner [$itk_component(main) insert end \
2173        -title "Cutplane Settings" \
2174        -icon [Rappture::icon cutbutton]]
2175
2176    $inner configure -borderwidth 4
2177
2178    checkbutton $inner.visible \
2179        -text "Show Cutplanes" \
2180        -variable [itcl::scope _settings(cutplane-visible)] \
2181        -command [itcl::code $this AdjustSetting cutplane-visible] \
2182        -font "Arial 9"
2183
2184    checkbutton $inner.wireframe \
2185        -text "Show Wireframe" \
2186        -variable [itcl::scope _settings(cutplane-wireframe)] \
2187        -command [itcl::code $this AdjustSetting cutplane-wireframe] \
2188        -font "Arial 9"
2189
2190    checkbutton $inner.lighting \
2191        -text "Enable Lighting" \
2192        -variable [itcl::scope _settings(cutplane-lighting)] \
2193        -command [itcl::code $this AdjustSetting cutplane-lighting] \
2194        -font "Arial 9"
2195
2196    checkbutton $inner.edges \
2197        -text "Show Edges" \
2198        -variable [itcl::scope _settings(cutplane-edges)] \
2199        -command [itcl::code $this AdjustSetting cutplane-edges] \
2200        -font "Arial 9"
2201
2202    label $inner.opacity_l -text "Opacity" -font "Arial 9"
2203    ::scale $inner.opacity -from 0 -to 100 -orient horizontal \
2204        -variable [itcl::scope _settings(cutplane-opacity)] \
2205        -width 10 \
2206        -showvalue off \
2207        -command [itcl::code $this AdjustSetting cutplane-opacity]
2208    $inner.opacity set $_settings(cutplane-opacity)
2209
2210    # X-value slicer...
2211    itk_component add xCutButton {
2212        Rappture::PushButton $inner.xbutton \
2213            -onimage [Rappture::icon x-cutplane] \
2214            -offimage [Rappture::icon x-cutplane] \
2215            -command [itcl::code $this AdjustSetting cutplane-xvisible] \
2216            -variable [itcl::scope _settings(cutplane-xvisible)]
2217    }
2218    Rappture::Tooltip::for $itk_component(xCutButton) \
2219        "Toggle the X-axis cutplane on/off"
2220
2221    itk_component add xCutScale {
2222        ::scale $inner.xval -from 100 -to 1 \
2223            -width 10 -orient vertical -showvalue yes \
2224            -borderwidth 1 -highlightthickness 0 \
2225            -command [itcl::code $this EventuallySetCutplane x] \
2226            -variable [itcl::scope _settings(cutplane-xposition)]
2227    } {
2228        usual
2229        ignore -borderwidth -highlightthickness
2230    }
2231    # Set the default cutplane value before disabling the scale.
2232    $itk_component(xCutScale) set 50
2233    $itk_component(xCutScale) configure -state disabled
2234    Rappture::Tooltip::for $itk_component(xCutScale) \
2235        "@[itcl::code $this Slice tooltip x]"
2236
2237    # Y-value slicer...
2238    itk_component add yCutButton {
2239        Rappture::PushButton $inner.ybutton \
2240            -onimage [Rappture::icon y-cutplane] \
2241            -offimage [Rappture::icon y-cutplane] \
2242            -command [itcl::code $this AdjustSetting cutplane-yvisible] \
2243            -variable [itcl::scope _settings(cutplane-yvisible)]
2244    }
2245    Rappture::Tooltip::for $itk_component(yCutButton) \
2246        "Toggle the Y-axis cutplane on/off"
2247
2248    itk_component add yCutScale {
2249        ::scale $inner.yval -from 100 -to 1 \
2250            -width 10 -orient vertical -showvalue yes \
2251            -borderwidth 1 -highlightthickness 0 \
2252            -command [itcl::code $this EventuallySetCutplane y] \
2253            -variable [itcl::scope _settings(cutplane-yposition)]
2254    } {
2255        usual
2256        ignore -borderwidth -highlightthickness
2257    }
2258    Rappture::Tooltip::for $itk_component(yCutScale) \
2259        "@[itcl::code $this Slice tooltip y]"
2260    # Set the default cutplane value before disabling the scale.
2261    $itk_component(yCutScale) set 50
2262    $itk_component(yCutScale) configure -state disabled
2263
2264    # Z-value slicer...
2265    itk_component add zCutButton {
2266        Rappture::PushButton $inner.zbutton \
2267            -onimage [Rappture::icon z-cutplane] \
2268            -offimage [Rappture::icon z-cutplane] \
2269            -command [itcl::code $this AdjustSetting cutplane-zvisible] \
2270            -variable [itcl::scope _settings(cutplane-zvisible)]
2271    }
2272    Rappture::Tooltip::for $itk_component(zCutButton) \
2273        "Toggle the Z-axis cutplane on/off"
2274
2275    itk_component add zCutScale {
2276        ::scale $inner.zval -from 100 -to 1 \
2277            -width 10 -orient vertical -showvalue yes \
2278            -borderwidth 1 -highlightthickness 0 \
2279            -command [itcl::code $this EventuallySetCutplane z] \
2280            -variable [itcl::scope _settings(cutplane-zposition)]
2281    } {
2282        usual
2283        ignore -borderwidth -highlightthickness
2284    }
2285    $itk_component(zCutScale) set 50
2286    $itk_component(zCutScale) configure -state disabled
2287    #$itk_component(zCutScale) configure -state disabled
2288    Rappture::Tooltip::for $itk_component(zCutScale) \
2289        "@[itcl::code $this Slice tooltip z]"
2290
2291    blt::table $inner \
2292        0,0 $inner.visible              -anchor w -pady 2 -cspan 4 \
2293        1,0 $inner.lighting             -anchor w -pady 2 -cspan 4 \
2294        2,0 $inner.wireframe            -anchor w -pady 2 -cspan 4 \
2295        3,0 $inner.edges                -anchor w -pady 2 -cspan 4 \
2296        4,0 $inner.opacity_l            -anchor w -pady 2 -cspan 3 \
2297        5,0 $inner.opacity              -fill x   -pady 2 -cspan 3 \
2298        6,0 $itk_component(xCutButton)  -anchor e -padx 2 -pady 2 \
2299        7,0 $itk_component(xCutScale)   -fill y \
2300        6,1 $itk_component(yCutButton)  -anchor e -padx 2 -pady 2 \
2301        7,1 $itk_component(yCutScale)   -fill y \
2302        6,2 $itk_component(zCutButton)  -anchor e -padx 2 -pady 2 \
2303        7,2 $itk_component(zCutScale)   -fill y \
2304
2305    blt::table configure $inner r* c* -resize none
2306    blt::table configure $inner r7 c3 -resize expand
2307}
2308
2309
2310
2311#
2312#  camera --
2313#
2314itcl::body Rappture::VtkStreamlinesViewer::camera {option args} {
2315    switch -- $option {
2316        "show" {
2317            puts [array get _view]
2318        }
2319        "set" {
2320            set who [lindex $args 0]
2321            set x $_view($who)
2322            set code [catch { string is double $x } result]
2323            if { $code != 0 || !$result } {
2324                return
2325            }
2326            switch -- $who {
2327                "ortho" {
2328                    if {$_view(ortho)} {
2329                        SendCmd "camera mode ortho"
2330                    } else {
2331                        SendCmd "camera mode persp"
2332                    }
2333                }
2334                "xpan" - "ypan" {
2335                    PanCamera
2336                }
2337                "qx" - "qy" - "qz" - "qw" {
2338                    set q [list $_view(qw) $_view(qx) $_view(qy) $_view(qz)]
2339                    $_arcball quaternion $q
2340                    EventuallyRotate $q
2341                }
2342                "zoom" {
2343                    SendCmd "camera zoom $_view(zoom)"
2344                }
2345            }
2346        }
2347    }
2348}
2349
2350itcl::body Rappture::VtkStreamlinesViewer::ConvertToVtkData { dataobj comp } {
2351    foreach { x1 x2 xN y1 y2 yN } [$dataobj mesh $comp] break
2352    set values [$dataobj values $comp]
2353    append out "# vtk DataFile Version 2.0 \n"
2354    append out "Test data \n"
2355    append out "ASCII \n"
2356    append out "DATASET STRUCTURED_POINTS \n"
2357    append out "DIMENSIONS $xN $yN 1 \n"
2358    append out "ORIGIN 0 0 0 \n"
2359    append out "SPACING 1 1 1 \n"
2360    append out "POINT_DATA [expr $xN * $yN] \n"
2361    append out "SCALARS field float 1 \n"
2362    append out "LOOKUP_TABLE default \n"
2363    append out [join $values "\n"]
2364    append out "\n"
2365    return $out
2366}
2367
2368
2369itcl::body Rappture::VtkStreamlinesViewer::GetVtkData { args } {
2370    set bytes ""
2371    foreach dataobj [get] {
2372        foreach comp [$dataobj components] {
2373            set tag $dataobj-$comp
2374            #set contents [ConvertToVtkData $dataobj $comp]
2375            set contents [$dataobj blob $comp]
2376            append bytes "$contents\n\n"
2377        }
2378    }
2379    return [list .vtk $bytes]
2380}
2381
2382itcl::body Rappture::VtkStreamlinesViewer::GetImage { args } {
2383    if { [image width $_image(download)] > 0 &&
2384         [image height $_image(download)] > 0 } {
2385        set bytes [$_image(download) data -format "jpeg -quality 100"]
2386        set bytes [Rappture::encoding::decode -as b64 $bytes]
2387        return [list .jpg $bytes]
2388    }
2389    return ""
2390}
2391
2392itcl::body Rappture::VtkStreamlinesViewer::BuildDownloadPopup { popup command } {
2393    Rappture::Balloon $popup \
2394        -title "[Rappture::filexfer::label downloadWord] as..."
2395    set inner [$popup component inner]
2396    label $inner.summary -text "" -anchor w
2397    radiobutton $inner.vtk_button -text "VTK data file" \
2398        -variable [itcl::scope _downloadPopup(format)] \
2399        -font "Helvetica 9 " \
2400        -value vtk 
2401    Rappture::Tooltip::for $inner.vtk_button "Save as VTK data file."
2402    radiobutton $inner.image_button -text "Image File" \
2403        -variable [itcl::scope _downloadPopup(format)] \
2404        -value image
2405    Rappture::Tooltip::for $inner.image_button \
2406        "Save as digital image."
2407
2408    button $inner.ok -text "Save" \
2409        -highlightthickness 0 -pady 2 -padx 3 \
2410        -command $command \
2411        -compound left \
2412        -image [Rappture::icon download]
2413
2414    button $inner.cancel -text "Cancel" \
2415        -highlightthickness 0 -pady 2 -padx 3 \
2416        -command [list $popup deactivate] \
2417        -compound left \
2418        -image [Rappture::icon cancel]
2419
2420    blt::table $inner \
2421        0,0 $inner.summary -cspan 2  \
2422        1,0 $inner.vtk_button -anchor w -cspan 2 -padx { 4 0 } \
2423        2,0 $inner.image_button -anchor w -cspan 2 -padx { 4 0 } \
2424        4,1 $inner.cancel -width .9i -fill y \
2425        4,0 $inner.ok -padx 2 -width .9i -fill y
2426    blt::table configure $inner r3 -height 4
2427    blt::table configure $inner r4 -pady 4
2428    raise $inner.image_button
2429    $inner.vtk_button invoke
2430    return $inner
2431}
2432
2433itcl::body Rappture::VtkStreamlinesViewer::SetObjectStyle { dataobj comp } {
2434    # Parse style string.
2435    set tag $dataobj-$comp
2436    set style [$dataobj style $comp]
2437    array set settings {
2438        -color \#808080
2439        -edges 0
2440        -edgecolor black
2441        -linewidth 1.0
2442        -opacity 0.4
2443        -wireframe 0
2444        -lighting 1
2445        -seeds 1
2446        -seedcolor white
2447        -visible 1
2448    }
2449    if { $dataobj != $_first } {
2450        set settings(-opacity) 1
2451    }
2452    array set settings $style
2453    SendCmd "streamlines add $tag"
2454    SendCmd "streamlines seed visible off $tag"
2455    set seeds [$dataobj hints seeds]
2456    if { $seeds != "" && ![info exists _seeds($dataobj)] } {
2457        set length [string length $seeds]
2458        SendCmd "streamlines seed fmesh 200 data follows $length $tag"
2459        SendCmd "$seeds"
2460        set _seeds($dataobj) 1
2461    }
2462    SendCmd "cutplane add $tag"
2463    SendCmd "cutplane colormode $_colorMode $tag"
2464    SendCmd "cutplane edges 0 $tag"
2465    SendCmd "cutplane wireframe 0 $tag"
2466    SendCmd "cutplane lighting 1 $tag"
2467    SendCmd "cutplane linewidth 1 $tag"
2468    #SendCmd "cutplane linecolor 1 1 1 $tag"
2469    #SendCmd "cutplane visible $tag"
2470    foreach axis { x y z } {
2471        SendCmd "cutplane slice $axis 1.0 $tag"
2472        SendCmd "cutplane axis $axis 0 $tag"
2473    }
2474
2475    SendCmd "polydata add $tag"
2476    SendCmd "polydata edges $settings(-edges) $tag"
2477    set _settings(volume-edges) $settings(-edges)
2478    SendCmd "polydata color [Color2RGB $settings(-color)] $tag"
2479    SendCmd "polydata lighting $settings(-lighting) $tag"
2480    set _settings(volume-lighting) $settings(-lighting)
2481    SendCmd "polydata linecolor [Color2RGB $settings(-edgecolor)] $tag"
2482    SendCmd "polydata linewidth $settings(-linewidth) $tag"
2483    SendCmd "polydata opacity $settings(-opacity) $tag"
2484    set _settings(volume-opacity) $settings(-opacity)
2485    SendCmd "polydata wireframe $settings(-wireframe) $tag"
2486    set _settings(volume-wireframe) $settings(-wireframe)
2487    set _settings(volume-opacity) [expr $settings(-opacity) * 100.0]
2488    SetColormap $dataobj $comp
2489}
2490
2491itcl::body Rappture::VtkStreamlinesViewer::IsValidObject { dataobj } {
2492    if {[catch {$dataobj isa Rappture::Field} valid] != 0 || !$valid} {
2493        return 0
2494    }
2495    return 1
2496}
2497
2498# ----------------------------------------------------------------------
2499# USAGE: ReceiveLegend <colormap> <title> <vmin> <vmax> <size>
2500#
2501# Invoked automatically whenever the "legend" command comes in from
2502# the rendering server.  Indicates that binary image data with the
2503# specified <size> will follow.
2504# ----------------------------------------------------------------------
2505itcl::body Rappture::VtkStreamlinesViewer::ReceiveLegend { colormap title vmin vmax size } {
2506    #puts stderr "ReceiveLegend colormap=$colormap title=$title range=$vmin,$vmax size=$size"
2507    set _limits(vmin) $vmin
2508    set _limits(vmax) $vmax
2509    set _title $title
2510    if { [IsConnected] } {
2511        set bytes [ReceiveBytes $size]
2512        if { ![info exists _image(legend)] } {
2513            set _image(legend) [image create photo]
2514        }
2515        $_image(legend) configure -data $bytes
2516        #puts stderr "read $size bytes for [image width $_image(legend)]x[image height $_image(legend)] legend>"
2517        DrawLegend $_currentField
2518    }
2519}
2520
2521#
2522# DrawLegend --
2523#
2524#       Draws the legend in it's own canvas which resides to the right
2525#       of the contour plot area.
2526#
2527itcl::body Rappture::VtkStreamlinesViewer::DrawLegend { title } {
2528    set c $itk_component(view)
2529    set w [winfo width $c]
2530    set h [winfo height $c]
2531    set font "Arial 8"
2532    set lineht [font metrics $font -linespace]
2533   
2534    regsub {\(mag\)} $title "" title
2535    if { [info exists _fields($title)] } {
2536        set title $_fields($title)
2537    }
2538    if { $_settings(legend-visible) } {
2539        set x [expr $w - 2]
2540        if { [$c find withtag "legend"] == "" } {
2541            set y 2
2542            $c create text $x $y \
2543                -anchor ne \
2544                -fill $itk_option(-plotforeground) -tags "title legend" \
2545                -font $font
2546            incr y $lineht
2547            $c create text $x $y \
2548                -anchor ne \
2549                -fill $itk_option(-plotforeground) -tags "vmax legend" \
2550                -font $font
2551            incr y $lineht
2552            $c create image $x $y \
2553                -anchor ne \
2554                -image $_image(legend) -tags "colormap legend"
2555            $c create text $x [expr {$h-2}] \
2556                -anchor se \
2557                -fill $itk_option(-plotforeground) -tags "vmin legend" \
2558                -font $font
2559            #$c bind colormap <Enter> [itcl::code $this EnterLegend %x %y]
2560            $c bind colormap <Leave> [itcl::code $this LeaveLegend]
2561            $c bind colormap <Motion> [itcl::code $this MotionLegend %x %y]
2562        }
2563        # Reset the item coordinates according the current size of the plot.
2564        $c itemconfigure title -text $title
2565        if { $_limits(vmin) != "" } {
2566            $c itemconfigure vmin -text [format %g $_limits(vmin)]
2567        }
2568        if { $_limits(vmax) != "" } {
2569            $c itemconfigure vmax -text [format %g $_limits(vmax)]
2570        }
2571        set y 2
2572        $c coords title $x $y
2573        incr y $lineht
2574        $c coords vmax $x $y
2575        incr y $lineht
2576        $c coords colormap $x $y
2577        $c coords vmin $x [expr {$h - 2}]
2578    }
2579}
2580
2581#
2582# EnterLegend --
2583#
2584itcl::body Rappture::VtkStreamlinesViewer::EnterLegend { x y } {
2585    SetLegendTip $x $y
2586}
2587
2588#
2589# MotionLegend --
2590#
2591itcl::body Rappture::VtkStreamlinesViewer::MotionLegend { x y } {
2592    Rappture::Tooltip::tooltip cancel
2593    set c $itk_component(view)
2594    SetLegendTip $x $y
2595}
2596
2597#
2598# LeaveLegend --
2599#
2600itcl::body Rappture::VtkStreamlinesViewer::LeaveLegend { } {
2601    Rappture::Tooltip::tooltip cancel
2602    .rappturetooltip configure -icon ""
2603}
2604
2605#
2606# SetLegendTip --
2607#
2608itcl::body Rappture::VtkStreamlinesViewer::SetLegendTip { x y } {
2609    set c $itk_component(view)
2610    set w [winfo width $c]
2611    set h [winfo height $c]
2612    set font "Arial 8"
2613    set lineht [font metrics $font -linespace]
2614   
2615    set imgHeight [image height $_image(legend)]
2616    set coords [$c coords colormap]
2617    set imgX [expr $w - [image width $_image(legend)] - 2]
2618    set imgY [expr $y - 2 * ($lineht + 2)]
2619
2620    # Make a swatch of the selected color
2621    if { [catch { $_image(legend) get 10 $imgY } pixel] != 0 } {
2622        #puts stderr "out of range: $imgY"
2623        return
2624    }
2625    if { ![info exists _image(swatch)] } {
2626        set _image(swatch) [image create photo -width 24 -height 24]
2627    }
2628    set color [eval format "\#%02x%02x%02x" $pixel]
2629    $_image(swatch) put black  -to 0 0 23 23
2630    $_image(swatch) put $color -to 1 1 22 22
2631    .rappturetooltip configure -icon $_image(swatch)
2632
2633    # Compute the value of the point
2634    set t [expr 1.0 - (double($imgY) / double($imgHeight-1))]
2635    set value [expr $t * ($_limits(vmax) - $_limits(vmin)) + $_limits(vmin)]
2636    set tipx [expr $x + 15]
2637    set tipy [expr $y - 5]
2638    Rappture::Tooltip::text $c "$_title $value"
2639    Rappture::Tooltip::tooltip show $c +$tipx,+$tipy   
2640}
2641
2642
2643# ----------------------------------------------------------------------
2644# USAGE: Slice move x|y|z <newval>
2645#
2646# Called automatically when the user drags the slider to move the
2647# cut plane that slices 3D data.  Gets the current value from the
2648# slider and moves the cut plane to the appropriate point in the
2649# data set.
2650# ----------------------------------------------------------------------
2651itcl::body Rappture::VtkStreamlinesViewer::Slice {option args} {
2652    switch -- $option {
2653        "move" {
2654            set axis [lindex $args 0]
2655            set oldval $_settings(axis-${axis}position)
2656            set newval [lindex $args 1]
2657            if {[llength $args] != 2} {
2658                error "wrong # args: should be \"Slice move x|y|z newval\""
2659            }
2660            set newpos [expr {0.01*$newval}]
2661            SendCmd "cutplane slice $axis $newpos"
2662        }
2663        "tooltip" {
2664            set axis [lindex $args 0]
2665            set val [$itk_component(${axis}CutScale) get]
2666            return "Move the [string toupper $axis] cut plane.\nCurrently:  $axis = $val%"
2667        }
2668        default {
2669            error "bad option \"$option\": should be axis, move, or tooltip"
2670        }
2671    }
2672}
2673
2674proc name { mesg } {
2675    SendBytes $mesg
2676}
2677
2678
2679 
Note: See TracBrowser for help on using the repository browser.