source: branches/1.6/gui/scripts/vtkstreamlinesviewer.tcl @ 6212

Last change on this file since 6212 was 6212, checked in by ldelgass, 9 years ago

merge viewer cleanups from trunk

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