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

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