source: branches/blt4/gui/scripts/vtkviewer.tcl @ 2287

Last change on this file since 2287 was 2201, checked in by gah, 13 years ago
File size: 37.5 KB
Line 
1
2# ----------------------------------------------------------------------
3#  COMPONENT: contourresult - contour plot in a ResultSet
4#
5#  This widget is a contour plot for 2D meshes with a scalar value.
6#  It is normally used in the ResultViewer to show results from the
7#  run of a Rappture tool.  Use the "add" and "delete" methods to
8#  control the dataobjs showing on the plot.
9# ======================================================================
10#  AUTHOR:  Michael McLennan, Purdue University
11#  Copyright (c) 2004-2005  Purdue Research Foundation
12#
13#  See the file "license.terms" for information on usage and
14#  redistribution of this file, and for a DISCLAIMER OF ALL WARRANTIES.
15# ======================================================================
16package require Itk
17package require vtk
18package require vtkinteraction
19package require BLT
20#package require Img
21
22option add *VtkViewer.width 4i widgetDefault
23option add *VtkViewer.height 4i widgetDefault
24option add *VtkViewer.foreground black widgetDefault
25option add *VtkViewer.controlBackground gray widgetDefault
26option add *VtkViewer.controlDarkBackground #999999 widgetDefault
27option add *VtkViewer.plotBackground black widgetDefault
28option add *VtkViewer.plotForeground white widgetDefault
29option add *VtkViewer.font \
30    -*-helvetica-medium-r-normal-*-12-* widgetDefault
31
32itcl::class Rappture::VtkViewer {
33    inherit itk::Widget
34
35    itk_option define -plotforeground plotForeground Foreground ""
36    itk_option define -plotbackground plotBackground Background ""
37
38    private variable _dlist ""     ;# list of data objects
39    private variable _dims ""      ;# dimensionality of data objects
40    private variable _obj2color    ;# maps dataobj => plotting color
41    private variable _obj2width    ;# maps dataobj => line width
42    private variable _obj2raise    ;# maps dataobj => raise flag 0/1
43    private variable _dataobj2vtk  ;# maps dataobj => vtk objects
44    private variable _actors       ;# array of actors for each dataobj.
45    private variable _lights       ;# list of lights for each renderer
46    private variable _click        ;# info used for _move operations
47    private variable _limits       ;# autoscale min/max for all axes
48    private variable _view         ;# view params for 3D view
49    private variable _download ""  ;# snapshot for download
50
51    private variable _renderer "";
52    private variable _window "";
53    private variable _interactor "";
54    private variable _style "";
55    private variable _light "";
56    private variable _cubeAxesActor ""
57    private variable _axesActor ""
58    private variable _axesWidget "";
59    private variable _settings
60    constructor {args} {
61        # defined below
62    }
63    destructor {
64        # defined below
65    }
66
67    public method add {dataobj {settings ""}}
68    public method get {}
69    public method delete {args}
70    public method scale {args}
71    public method parameters {title args} {
72        # do nothing
73    }
74    public method download {option args}
75
76    protected method Rebuild {}
77    protected method Clear {}
78    protected method Zoom {option}
79    protected method Move {option x y}
80    protected method _3dView {theta phi}
81    protected method _fixLimits {}
82    protected method _color2rgb {color}
83    protected method SetActorProperties { actor style }
84
85    private method ComputeLimits { args }
86    private method GetLimits {}
87    private method BuildCameraTab {}
88    private method UpdateCameraInfo {}
89    private method BuildViewTab {}
90    private method BuildVolumeTab {}
91    protected method FixSettings {what {value ""}}
92
93}
94
95itk::usual VtkViewer {
96    keep -background -foreground -cursor -font
97    keep -plotbackground -plotforeground
98}
99
100# ----------------------------------------------------------------------
101# CONSTRUCTOR
102# ----------------------------------------------------------------------
103itcl::body Rappture::VtkViewer::constructor {args} {
104    option add hull.width hull.height
105    pack propagate $itk_component(hull) no
106    set _view(theta) 0
107    set _view(phi) 0
108   
109    array set _limits {
110        xMin    0
111        xMax    1
112        yMin    0
113        yMax    1
114        zMin    0
115        zMax    1
116        vMin    0
117        vMax    1
118    }
119
120
121    foreach { key value } {
122        edges           1
123        axes            1
124        smallaxes       0
125        wireframe       0
126    } {
127        set _settings($this-$key) $value
128    }
129    itk_component add main {
130        Rappture::SidebarFrame $itk_interior.main
131    }
132    pack $itk_component(main) -expand yes -fill both
133    set f [$itk_component(main) component frame]
134   
135    itk_component add controls {
136        frame $f.cntls
137    } {
138        usual
139        rename -background -controlbackground controlBackground Background
140    }
141    pack $itk_component(controls) -side right -fill y
142
143    itk_component add zoom {
144        frame $itk_component(controls).zoom
145    } {
146        usual
147        rename -background -controlbackground controlBackground Background
148    }
149    pack $itk_component(zoom) -side top
150   
151    itk_component add reset {
152        button $itk_component(zoom).reset \
153            -borderwidth 1 -padx 1 -pady 1 \
154            -bitmap [Rappture::icon reset] \
155            -command [itcl::code $this Zoom reset]
156    } {
157        usual
158        ignore -borderwidth
159        rename -highlightbackground -controlbackground controlBackground Background
160    }
161    pack $itk_component(reset) -padx 4 -pady 4
162    Rappture::Tooltip::for $itk_component(reset) \
163        "Reset the view to the default zoom level"
164
165    itk_component add zoomin {
166        button $itk_component(zoom).zin \
167            -borderwidth 1 -padx 1 -pady 1 \
168            -bitmap [Rappture::icon zoomin] \
169            -command [itcl::code $this Zoom in]
170    } {
171        usual
172        ignore -borderwidth
173        rename -highlightbackground -controlbackground controlBackground \
174            Background
175    }
176    pack $itk_component(zoomin) -padx 4 -pady 4
177    Rappture::Tooltip::for $itk_component(zoomin) "Zoom in"
178   
179    itk_component add zoomout {
180        button $itk_component(zoom).zout \
181            -borderwidth 1 -padx 1 -pady 1 \
182            -bitmap [Rappture::icon zoomout] \
183            -command [itcl::code $this Zoom out]
184    } {
185        usual
186        ignore -borderwidth
187        rename -highlightbackground -controlbackground controlBackground \
188            Background
189    }
190    pack $itk_component(zoomout) -padx 4 -pady 4
191    Rappture::Tooltip::for $itk_component(zoomout) "Zoom out"
192   
193    #
194    # RENDERING AREA
195    #
196    itk_component add area {
197        frame $f.area
198    }
199    pack $itk_component(area) -expand yes -fill both
200   
201    set _renderer [vtkRenderer $this-Renderer]
202    set _window [vtkRenderWindow $this-RenderWindow]
203    itk_component add plot {
204        vtkTkRenderWidget $itk_component(area).plot -rw $_window \
205            -width 1 -height 1
206    } {
207        # empty
208    }
209    pack $itk_component(plot) -expand yes -fill both
210    $_window AddRenderer $_renderer
211    $_window LineSmoothingOn
212    $_window PolygonSmoothingOn
213   
214    set _interactor [vtkRenderWindowInteractor $this-Interactor]
215    set _style [vtkInteractorStyleTrackballCamera $this-InteractorStyle]
216    $_interactor SetRenderWindow $_window
217    $_interactor SetInteractorStyle $_style
218    $_interactor Initialize
219   
220    set _cubeAxesActor [vtkCubeAxesActor $this-CubeAxesActor]
221    $_cubeAxesActor SetCamera [$_renderer GetActiveCamera]
222    $_renderer AddActor $_cubeAxesActor
223   
224    # Supply small axes guide.
225    set _axesActor [vtkAxesActor $this-AxesActor]
226    set _axesWidget [vtkOrientationMarkerWidget $this-AxesWidget]
227    $_axesWidget SetOrientationMarker $_axesActor
228    $_axesWidget SetInteractor $_interactor
229    $_axesWidget SetEnabled $_settings($this-smallaxes)
230    $_axesWidget SetInteractive 0
231    $_axesWidget SetViewport .7 0 1.0 0.3
232   
233    BuildViewTab
234    BuildCameraTab
235   
236    set v0 0
237    set v1 1
238    set _lookup [vtkLookupTable $this-Lookup]
239    $_lookup SetTableRange $v0 $v1
240    $_lookup SetHueRange 0.66667 0.0
241    $_lookup Build
242   
243    set lightKit [vtkLightKit $this-LightKit]
244    $lightKit AddLightsToRenderer $_renderer
245   
246    #
247    # Create a picture for download snapshots
248    #
249    set _download [image create photo]
250   
251    eval itk_initialize $args
252}
253
254# ----------------------------------------------------------------------
255# DESTRUCTOR
256# ----------------------------------------------------------------------
257itcl::body Rappture::VtkViewer::destructor {} {
258    Clear
259    after cancel [itcl::code $this Rebuild]
260   
261    foreach c [info commands $this-vtk*] {
262        rename $c ""
263    }
264    image delete $_download
265}
266
267# ----------------------------------------------------------------------
268# USAGE: add <dataobj> ?<settings>?
269#
270# Clients use this to add a data object to the plot.  The optional
271# <settings> are used to configure the plot.  Allowed settings are
272# -color, -brightness, -width, -linestyle, and -raise.
273# ----------------------------------------------------------------------
274itcl::body Rappture::VtkViewer::add {dataobj {settings ""}} {
275    array set params {
276        -color auto
277        -width 1
278        -linestyle solid
279        -brightness 0
280        -raise 0
281        -description ""
282        -param ""
283    }
284    foreach {opt val} $settings {
285        if {![info exists params($opt)]} {
286            error "bad setting \"$opt\": should be [join [lsort [array names params]] {, }]"
287        }
288        set params($opt) $val
289    }
290    if {$params(-color) == "auto" || $params(-color) == "autoreset"} {
291        # can't handle -autocolors yet
292        set params(-color) black
293    }
294    foreach comp [$dataobj components] {
295        set actor [$dataobj values $comp]
296        $actor VisibilityOff
297    }
298    set pos [lsearch -exact $dataobj $_dlist]
299    if {$pos < 0} {
300        lappend _dlist $dataobj
301
302        set _obj2color($dataobj) $params(-color)
303        set _obj2width($dataobj) $params(-width)
304        set _obj2raise($dataobj) $params(-raise)
305       
306        after cancel [itcl::code $this Rebuild]
307        after idle [itcl::code $this Rebuild]
308    }
309}
310
311# ----------------------------------------------------------------------
312# USAGE: get
313#
314# Clients use this to query the list of objects being plotted, in
315# order from bottom to top of this result.
316# ----------------------------------------------------------------------
317itcl::body Rappture::VtkViewer::get {} {
318    # put the dataobj list in order according to -raise options
319    set dlist $_dlist
320    foreach obj $dlist {
321        if {[info exists _obj2raise($obj)] && $_obj2raise($obj)} {
322            set i [lsearch -exact $dlist $obj]
323            if {$i >= 0} {
324                set dlist [lreplace $dlist $i $i]
325                lappend dlist $obj
326            }
327        }
328    }
329    return $dlist
330}
331
332# ----------------------------------------------------------------------
333# USAGE: delete ?<dataobj1> <dataobj2> ...?
334#
335# Clients use this to delete a dataobj from the plot.  If no dataobjs
336# are specified, then all dataobjs are deleted.
337# ----------------------------------------------------------------------
338itcl::body Rappture::VtkViewer::delete {args} {
339    if {[llength $args] == 0} {
340        set args $_dlist
341    }
342    puts stderr "deleting $args"
343    # delete all specified dataobjs
344    set changed 0
345    foreach dataobj $args {
346        set i [lsearch -exact $_dlist $dataobj]
347        if {$i >= 0} {
348            set _dlist [lreplace $_dlist $i $i]
349            catch {unset _obj2color($dataobj)}
350            catch {unset _obj2width($dataobj)}
351            catch {unset _obj2raise($dataobj)}
352            if { [info exists _actors($dataobj)] } {
353                foreach actor $_actors($dataobj) {
354                    $actor VisibilityOff
355                }
356            }
357            set changed 1
358        }
359    }
360    # If anything changed, then rebuild the plot
361    if {$changed} {
362        after cancel [itcl::code $this Rebuild]
363        after idle [itcl::code $this Rebuild]
364    }
365}
366
367# ----------------------------------------------------------------------
368# USAGE: scale ?<data1> <data2> ...?
369#
370# Sets the default limits for the overall plot according to the
371# limits of the data for all of the given <data> objects.  This
372# accounts for all objects--even those not showing on the screen.
373# Because of this, the limits are appropriate for all objects as
374# the user scans through data in the ResultSet viewer.
375# ----------------------------------------------------------------------
376itcl::body Rappture::VtkViewer::scale {args} {
377    eval ComputeLimits $args
378    _fixLimits
379}
380
381# ----------------------------------------------------------------------
382# USAGE: download coming
383# USAGE: download controls <downloadCommand>
384# USAGE: download now
385#
386# Clients use this method to create a downloadable representation
387# of the plot.  Returns a list of the form {ext string}, where
388# "ext" is the file extension (indicating the type of data) and
389# "string" is the data itself.
390# ----------------------------------------------------------------------
391itcl::body Rappture::VtkViewer::download {option args} {
392    switch $option {
393        coming {
394            if {[catch {
395                blt::winop snap $itk_component(plotarea) $_download
396            }]} {
397                $_download configure -width 1 -height 1
398                $_download put #000000
399            }
400        }
401        controls {
402            # no controls for this download yet
403            return ""
404        }
405        now {
406            set writer [vtkJPEGWriter $this-vtkJPEGWriter]
407            set large [vtkRenderLargeImage $this-RenderLargeImage]
408            $_axesWidget SetEnabled 0
409            $large SetInput $_renderer
410            $large SetMagnification 4
411            $writer SetInputConnection [$large GetOutputPort]
412
413            $writer SetFileName junk.jpg
414            $writer Write
415            rename $writer ""
416            rename $large ""
417            FixSettings smallaxes
418
419            set img [image create photo -file junk.jpg]
420            set bytes [$img data -format "jpeg -quality 100"]
421            set bytes [Rappture::encoding::decode -as b64 $bytes]
422            image delete $img
423            return [list .jpg $bytes]
424        }
425        default {
426            error "bad option \"$option\": should be coming, controls, now"
427        }
428    }
429}
430
431# ----------------------------------------------------------------------
432# USAGE: Clear
433#
434# Used internally to clear the drawing area and tear down all vtk
435# objects in the current scene.
436# ----------------------------------------------------------------------
437itcl::body Rappture::VtkViewer::Clear {} {
438    # clear out any old constructs
439   
440    foreach ren [array names _lights] {
441        foreach light $_lights($ren) {
442            $ren RemoveLight $light
443            rename $light ""
444        }
445        set _lights($ren) ""
446    }
447    foreach dataobj $_dlist {
448        foreach actor $_actors($dataobj) {
449            $_renderer RemoveActor $actor
450        }
451    }
452    array unset _actors
453    set _dlist ""
454    array unset _dataobj2vtk
455}
456
457# ----------------------------------------------------------------------
458# USAGE: Zoom in
459# USAGE: Zoom out
460# USAGE: Zoom reset
461#
462# Called automatically when the user clicks on one of the zoom
463# controls for this widget.  Changes the zoom for the current view.
464# ----------------------------------------------------------------------
465itcl::body Rappture::VtkViewer::Zoom {option} {
466    set cam [$_renderer GetActiveCamera]
467    switch -- $option {
468        in {
469            $cam Zoom 1.25
470            $_window Render
471        }
472        out {
473            $cam Zoom 0.8
474            $_window Render
475        }
476        reset {
477            $cam SetViewAngle 30
478            $_renderer ResetCamera
479            _3dView 90 -90
480            array set camera {
481                xpos 1.73477e-06 ypos 74.7518 zpos -1.73477e-06
482                xviewup 0 yviewup 0 zviewup 1.0
483                xfocal 0.0 yfocal 0.0 zfocal 0.0
484                angle 30
485            }
486            set dataobj [lindex $_dlist end]
487            if { $dataobj != "" } {
488                array set camera [$dataobj hints camera]
489            }
490            if { [info exists camera(clipmin)] } {
491                $cam SetClippingRange $camera(clipmin) $camera(clipmax)
492            }
493            if { [info exists camera(parallelscale)] } {
494                $cam SetParallelScale $camera(parallelscale)
495            }
496            $cam SetViewAngle $camera(angle)
497            $cam SetFocalPoint $camera(xfocal) $camera(yfocal) $camera(zfocal)
498            $cam SetPosition $camera(xpos) $camera(ypos) $camera(zpos)
499            $cam SetViewUp $camera(xviewup) $camera(yviewup) $camera(zviewup)
500            $cam OrthogonalizeViewUp
501            foreach key [array names camera] {
502                set _settings($this-$key) $camera($key)
503            }
504            $cam ComputeViewPlaneNormal
505            $_renderer ResetCamera
506            $_window Render
507        }
508    }
509}
510
511# ----------------------------------------------------------------------
512# USAGE: Move click <x> <y>
513# USAGE: Move drag <x> <y>
514# USAGE: Move release <x> <y>
515#
516# Called automatically when the user clicks/drags/releases in the
517# plot area.  Moves the plot according to the user's actions.
518# ----------------------------------------------------------------------
519itcl::body Rappture::VtkViewer::Move {option x y} {
520    switch -- $option {
521        click {
522            blt::busy configure $itk_component(area) -cursor fleur
523            set _click(x) $x
524            set _click(y) $y
525            set _click(theta) $_view(theta)
526            set _click(phi) $_view(phi)
527        }
528        drag {
529            if {[array size _click] == 0} {
530                Move click $x $y
531            } else {
532                set w [winfo width $itk_component(plot)]
533                set h [winfo height $itk_component(plot)]
534                set scalex [expr {$_limits(xMax)-$_limits(xMin)}]
535                set scaley [expr {$_limits(yMax)-$_limits(yMin)}]
536                set dx [expr {double($x-$_click(x))/$w*$scalex}]
537                set dy [expr {double($y-$_click(y))/$h*$scaley}]
538
539                if {$_dims == "2D"} {
540                    #
541                    # Shift the contour plot in 2D
542                    #
543                    foreach dataobj $_dlist {
544                        foreach actor $_actors($dataobj) {
545                            foreach {ax ay az} [$actor GetPosition] break
546                            $actor SetPosition [expr {$ax+$dx}] \
547                                [expr {$ay-$dy}] 0
548                        }
549                    }
550                    $_window Render
551                } elseif {$_dims == "3D"} {
552                    #
553                    # Rotate the camera in 3D
554                    #
555                    set theta [expr {$_view(theta) - $dy*180}]
556                    if {$theta < 2} { set theta 2 }
557                    if {$theta > 178} { set theta 178 }
558                    set phi [expr {$_view(phi) - $dx*360}]
559                   
560                    _3dView $theta $phi
561                    $_window Render
562                }
563                set _click(x) $x
564                set _click(y) $y
565            }
566        }
567        release {
568            Move drag $x $y
569            blt::busy configure $itk_component(area) -cursor left_ptr
570            catch {unset _click}
571        }
572        default {
573            error "bad option \"$option\": should be click, drag, release"
574        }
575    }
576    UpdateCameraInfo
577}
578
579
580# ----------------------------------------------------------------------
581# USAGE: _3dView <theta> <phi>
582#
583# Used internally to change the position of the camera for 3D data
584# sets.  Sets the camera according to the angles <theta> (angle from
585# the z-axis) and <phi> (angle from the x-axis in the x-y plane).
586# Both angles are in degrees.
587# ----------------------------------------------------------------------
588itcl::body Rappture::VtkViewer::_3dView {theta phi} {
589    return
590    set deg2rad 0.0174532927778
591    set xn [expr {sin($theta*$deg2rad)*cos($phi*$deg2rad)}]
592    set yn [expr {sin($theta*$deg2rad)*sin($phi*$deg2rad)}]
593    set zn [expr {cos($theta*$deg2rad)}]
594   
595    set xm [expr {0.5*($_limits(xMax)+$_limits(xMin))}]
596    set ym [expr {0.5*($_limits(yMax)+$_limits(yMin))}]
597    set zm [expr {0.5*($_limits(zMax)+$_limits(zMin))}]
598   
599    set cam [$_renderer GetActiveCamera]
600    set zoom [$cam GetViewAngle]
601    $cam SetViewAngle 30
602    $cam SetFocalPoint $xm $ym $zm
603    $cam SetPosition [expr {$xm-$xn}] [expr {$ym-$yn}] [expr {$zm+$zn}]
604    $cam ComputeViewPlaneNormal
605    $cam SetViewUp 0 0 1  ;# z-dir is up
606    $cam OrthogonalizeViewUp
607    $_renderer ResetCamera
608    $cam SetViewAngle $zoom
609   
610    set _view(theta) $theta
611    set _view(phi) $phi
612}
613
614# ----------------------------------------------------------------------
615# USAGE: _fixLimits
616#
617# Used internally to apply automatic limits to the axes for the
618# current plot.
619# ----------------------------------------------------------------------
620itcl::body Rappture::VtkViewer::_fixLimits {} {
621    $_renderer ResetCamera
622    set camera [$_renderer GetActiveCamera]
623    $camera Zoom 1.5
624    $_window Render
625    if 0 {
626        $this-vtkRenderWindow2 Render
627    }
628}
629
630# ----------------------------------------------------------------------
631# USAGE: _color2rgb <color>
632#
633# Used internally to convert a color name to a set of {r g b} values
634# needed for vtk.  Each r/g/b component is scaled in the range 0-1.
635# ----------------------------------------------------------------------
636itcl::body Rappture::VtkViewer::_color2rgb {color} {
637    foreach {r g b} [winfo rgb $itk_component(hull) $color] break
638    set r [expr {$r/65535.0}]
639    set g [expr {$g/65535.0}]
640    set b [expr {$b/65535.0}]
641    return [list $r $g $b]
642}
643
644# ----------------------------------------------------------------------
645# CONFIGURATION OPTION: -plotbackground
646# ----------------------------------------------------------------------
647itcl::configbody Rappture::VtkViewer::plotbackground {
648    foreach {r g b} [_color2rgb $itk_option(-plotbackground)] break
649    $_renderer SetBackground $r $g $b
650    $_window Render
651    if 0 {
652        $this-vtkRenderer2 SetBackground $r $g $b
653        $this-vtkRenderWindow2 Render
654    }
655}
656
657# ----------------------------------------------------------------------
658# CONFIGURATION OPTION: -plotforeground
659# ----------------------------------------------------------------------
660itcl::configbody Rappture::VtkViewer::plotforeground {
661    after cancel [itcl::code $this Rebuild]
662    after idle [itcl::code $this Rebuild]
663}
664
665itcl::body Rappture::VtkViewer::SetActorProperties { actor style } {
666    array set props {
667        -color \#6666FF
668        -edgevisibility yes
669        -edgecolor black
670        -linewidth 1.0
671        -opacity 1.0
672    }
673    # Parse style string.
674    array set props $style
675    set prop [$actor GetProperty]
676    eval $prop SetColor [_color2rgb $props(-color)]
677    if { $props(-edgevisibility) } {
678        $prop EdgeVisibilityOn
679    } else {
680        $prop EdgeVisibilityOff
681    }
682    set _settings($this-edges) $props(-edgevisibility)
683    eval $prop SetEdgeColor [_color2rgb $props(-edgecolor)]
684    $prop SetLineWidth $props(-linewidth)
685    $prop SetOpacity $props(-opacity)
686    set _settings($this-opacity) [expr $props(-opacity) * 100.0]
687}
688
689# ----------------------------------------------------------------------
690# USAGE: Rebuild
691#
692# Called automatically whenever something changes that affects the
693# data in the widget.  Clears any existing data and rebuilds the
694# widget to display new data.
695# ----------------------------------------------------------------------
696itcl::body Rappture::VtkViewer::Rebuild {} {
697    set id 0
698   
699    # determine the dimensionality from the topmost (raised) object
700    puts stderr _dlist=$_dlist
701    set dataobj [lindex $_dlist end]
702    if {$dataobj != ""} {
703        set _dims [lindex [lsort [$dataobj components -dimensions]] end]
704    } else {
705        set _dims "0D"
706    }
707    ComputeLimits
708    $_cubeAxesActor SetCamera [$_renderer GetActiveCamera]
709    eval $_cubeAxesActor SetBounds [GetLimits]
710    foreach dataobj [get] {
711        foreach comp [$dataobj components] {
712            set actor [$dataobj values $comp]
713            $actor VisibilityOff
714        }
715    }
716    if 0 {
717        #
718        # LOOKUP TABLE FOR COLOR CONTOURS
719        #
720        # Use vmin/vmax if possible, otherwise get from data
721        if {$_limits(vMin) == "" || $_limits(vMax) == ""} {
722            set v0 0
723            set v1 1
724            if { [info exists _dataobj2vtk($dataobj)] } {
725                set pd [lindex $_dataobj2vtk($dataobj) 0]
726                if {"" != $pd} {
727                    foreach {v0 v1} [$pd GetScalarRange] break
728                }
729            }
730        } else {
731            set v0 $_limits(vMin)
732            set v1 $_limits(vMax)
733        }
734    }   
735    # scan through all data objects and build the contours
736    foreach dataobj $_dlist {
737        puts stderr "dataobj=$dataobj"
738        foreach comp [$dataobj components] {
739            puts stderr "component=$comp"
740            set tag $dataobj-$comp
741            if { ![info exists _dataobj2vtk($tag)] } {
742                set actor [$dataobj values $comp]
743                set style [$dataobj style $comp]
744                set _dataobj2vtk($tag) $actor
745                puts stderr "adding actor $actor to _dlist=$_dlist"
746                lappend _actors($dataobj) $actor
747                $_renderer AddActor $actor
748                SetActorProperties $actor $style
749                incr id
750            }
751            $_dataobj2vtk($tag) VisibilityOn
752        }
753    }
754    if { [array size _dataobj2vtk] > 0 } {
755        parray _dataobj2vtk
756    }
757    if { [array size _actors] > 0 } {
758        parray _actors
759    }
760    set top [lindex [get] end]
761    if { $top != "" } {
762        foreach axis { x y z } {
763            set title [$top hints ${axis}label]
764            set units [$top hints ${axis}units]
765            set method Set[string toupper $axis]Title
766            set label "$title"
767            if { $units != "" } {
768                append label " ($units)"
769            }       
770            $_cubeAxesActor $method $label
771        }
772    }
773    $_interactor Start
774    if 1 {
775        _fixLimits
776        Zoom reset
777
778    }
779    $_renderer ResetCamera
780    $_renderer Render
781    $_window Render
782    UpdateCameraInfo
783    return
784
785    #
786    # HACK ALERT!  A single ResetCamera doesn't seem to work for
787    #   some contour data.  You have to do it multiple times to
788    #   get to the right zoom factor on data.  I hope 20 times is
789    #   enough.  I hate Vtk sometimes...
790    #
791    for {set i 0} {$i < 20} {incr i} {
792        $_renderer ResetCamera
793        [$_renderer GetActiveCamera] Zoom 1.5
794    }
795    # prevent interactions -- use our own
796    blt::busy hold $itk_component(area) -cursor left_ptr
797    bind $itk_component(area)_Busy <ButtonPress> \
798        [itcl::code $this Move click %x %y]
799    bind $itk_component(area)_Busy <B1-Motion> \
800        [itcl::code $this Move drag %x %y]
801    bind $itk_component(area)_Busy <ButtonRelease> \
802        [itcl::code $this Move release %x %y]
803}
804
805itcl::body Rappture::VtkViewer::BuildViewTab {} {
806
807    set fg [option get $itk_component(hull) font Font]
808    #set bfg [option get $itk_component(hull) boldFont Font]
809
810    set tab [$itk_component(main) insert end \
811        -title "View Settings" \
812        -icon [Rappture::icon wrench]]
813    set inner $tab
814    if 0 {
815    blt::scrollset $tab.ss \
816        -xscrollbar $tab.ss.xs \
817        -yscrollbar $tab.ss.ys \
818        -window $tab.ss.frame
819    pack $tab.ss -fill both -expand yes
820    blt::tk::scrollbar $tab.ss.xs               
821    blt::tk::scrollbar $tab.ss.ys               
822    set inner [blt::tk::frame $tab.ss.frame]
823    $inner configure -borderwidth 4
824    }
825    set ::Rappture::VtkViewer::_settings($this-isosurface) 0
826    checkbutton $inner.isosurface \
827        -text "Isosurface shading" \
828        -variable [itcl::scope _settings($this-isosurface)] \
829        -command [itcl::code $this FixSettings isosurface] \
830        -font "Arial 9"
831
832    checkbutton $inner.axes \
833        -text "Axes" \
834        -variable [itcl::scope _settings($this-axes)] \
835        -command [itcl::code $this FixSettings axes] \
836        -font "Arial 9"
837
838    checkbutton $inner.edges \
839        -text "Edges" \
840        -variable [itcl::scope _settings($this-edges)] \
841        -command [itcl::code $this FixSettings edges] \
842        -font "Arial 9"
843
844    checkbutton $inner.smallaxes \
845        -text "Small Axes" \
846        -variable [itcl::scope _settings($this-smallaxes)] \
847        -command [itcl::code $this FixSettings smallaxes] \
848        -font "Arial 9"
849
850    checkbutton $inner.wireframe \
851        -text "Wireframe" \
852        -variable [itcl::scope _settings($this-wireframe)] \
853        -command [itcl::code $this FixSettings wireframe] \
854        -font "Arial 9"
855
856    blt::table $inner \
857        0,0 $inner.axes  -columnspan 2 -anchor w \
858        1,0 $inner.edges  -columnspan 2 -anchor w \
859        2,0 $inner.wireframe  -columnspan 2 -anchor w \
860        3,0 $inner.smallaxes  -columnspan 2 -anchor w
861
862    blt::table configure $inner r* -resize none
863    blt::table configure $inner r5 -resize expand
864}
865
866itcl::body Rappture::VtkViewer::BuildVolumeTab {} {
867    foreach { key value } {
868        light           40
869        transp          50
870        opacity         1000
871    } {
872        set _settings($this-$key) $value
873    }
874
875    set tab [$itk_component(main) insert end \
876        -title "Volume Settings" \
877        -icon [Rappture::icon volume-on]]
878    set inner $tab
879    if 0 {
880    blt::scrollset $tab.ss \
881        -xscrollbar $tab.ss.xs \
882        -yscrollbar $tab.ss.ys \
883        -window $tab.ss.frame
884    pack $tab.ss -fill both -expand yes
885    blt::tk::scrollbar $tab.ss.xs               
886    blt::tk::scrollbar $tab.ss.ys               
887    set inner [blt::tk::frame $tab.ss.frame]
888    $inner configure -borderwidth 4
889    }
890    set fg [option get $itk_component(hull) font Font]
891    #set bfg [option get $itk_component(hull) boldFont Font]
892
893    checkbutton $inner.vol -text "Show volume" -font $fg \
894        -variable [itcl::scope _settings($this-volume)] \
895        -command [itcl::code $this FixSettings volume]
896    label $inner.shading -text "Shading:" -font $fg
897
898    label $inner.dim -text "Dim" -font $fg
899    ::scale $inner.light -from 0 -to 100 -orient horizontal \
900        -variable [itcl::scope _settings($this-light)] \
901        -width 10 \
902        -showvalue off -command [itcl::code $this FixSettings light]
903    label $inner.bright -text "Bright" -font $fg
904
905    label $inner.fog -text "Fog" -font $fg
906    ::scale $inner.transp -from 0 -to 100 -orient horizontal \
907        -variable [itcl::scope _settings($this-transp)] \
908        -width 10 \
909        -showvalue off -command [itcl::code $this FixSettings transp]
910    label $inner.plastic -text "Plastic" -font $fg
911
912    label $inner.clear -text "Clear" -font $fg
913    ::scale $inner.opacity -from 0 -to 100 -orient horizontal \
914        -variable [itcl::scope _settings($this-opacity)] \
915        -width 10 \
916        -showvalue off -command [itcl::code $this FixSettings opacity]
917    label $inner.opaque -text "Opaque" -font $fg
918
919    blt::table $inner \
920        0,0 $inner.vol -columnspan 4 -anchor w -pady 2 \
921        1,0 $inner.shading -columnspan 4 -anchor w -pady {10 2} \
922        2,0 $inner.dim -anchor e -pady 2 \
923        2,1 $inner.light -columnspan 2 -pady 2 -fill x \
924        2,3 $inner.bright -anchor w -pady 2 \
925        3,0 $inner.fog -anchor e -pady 2 \
926        3,1 $inner.transp -columnspan 2 -pady 2 -fill x \
927        3,3 $inner.plastic -anchor w -pady 2 \
928        4,0 $inner.clear -anchor e -pady 2 \
929        4,1 $inner.opacity -columnspan 2 -pady 2 -fill x\
930        4,3 $inner.opaque -anchor w -pady 2
931
932    blt::table configure $inner c0 c1 c3 r* -resize none
933    blt::table configure $inner r6 -resize expand
934}
935
936itcl::body Rappture::VtkViewer::UpdateCameraInfo {} {
937    set cam [$_renderer GetActiveCamera]
938    foreach key { x y z } \
939            pt  [$cam GetFocalPoint] \
940            up  [$cam GetViewUp] \
941            pos [$cam GetPosition] {
942        set _settings($this-${key}focal) $pt
943        set _settings($this-${key}up) $up
944        set _settings($this-${key}pos) $pos
945    }
946    foreach {min max} [$cam GetClippingRange] break
947    set _settings($this-clipmin) $min
948    set _settings($this-clipmax) $max
949    set _settings($this-parallelscale) [$cam GetParallelScale]
950    set _settings($this-angle) [$cam GetViewAngle]
951    foreach key { xpos ypos zpos xviewup yviewup zviewup
952        xfocal yfocal zfocal angle clipmin clipmax parallelscale
953    } {
954        set out($key) $_settings($this-$key)
955    }
956    puts \"[array get out]\"
957}
958
959itcl::body Rappture::VtkViewer::BuildCameraTab {} {
960    set inner [$itk_component(main) insert end \
961        -title "Camera Settings" \
962        -icon [Rappture::icon camera]]
963    $inner configure -borderwidth 4
964    bind $inner <Map> [itcl::code $this UpdateCameraInfo]
965
966    label $inner.xposl -text "Position"
967    entry $inner.xpos -bg white \
968        -textvariable [itcl::scope _settings($this-xpos)]
969    entry $inner.ypos -bg white \
970        -textvariable [itcl::scope _settings($this-ypos)]
971    entry $inner.zpos -bg white \
972        -textvariable [itcl::scope _settings($this-zpos)]
973    label $inner.xviewupl -text "View Up"
974    entry $inner.xviewup -bg white \
975        -textvariable [itcl::scope _settings($this-xviewup)]
976    entry $inner.yviewup -bg white \
977        -textvariable [itcl::scope _settings($this-yviewup)]
978    entry $inner.zviewup -bg white \
979        -textvariable [itcl::scope _settings($this-zviewup)]
980    label $inner.xfocall -text "Focal Point"
981    entry $inner.xfocal -bg white \
982        -textvariable [itcl::scope _settings($this-xfocal)]
983    entry $inner.yfocal -bg white \
984        -textvariable [itcl::scope _settings($this-yfocal)]
985    entry $inner.zfocal -bg white \
986        -textvariable [itcl::scope _settings($this-zfocal)]
987    label $inner.anglel -text "View Angle"
988    entry $inner.angle -bg white \
989        -textvariable [itcl::scope _settings($this-angle)]
990    label $inner.clipl -text "Clipping Range"
991    entry $inner.clipmin -bg white \
992        -textvariable [itcl::scope _settings($this-clipmin)]
993    entry $inner.clipmax -bg white \
994        -textvariable [itcl::scope _settings($this-clipmax)]
995    label $inner.pscalel -text "Parallel Scale"
996    entry $inner.pscale -bg white \
997        -textvariable [itcl::scope _settings($this-parallelscale)]
998
999    button $inner.refresh -text "Refresh" \
1000        -command [itcl::code $this UpdateCameraInfo]
1001    blt::table $inner \
1002        0,0 $inner.xposl -anchor w -pady 2 \
1003        1,0 $inner.xpos -pady 2 -fill x\
1004        2,0 $inner.ypos -pady 2 -fill x\
1005        3,0 $inner.zpos -pady 2 -fill x\
1006        4,0 $inner.xviewupl -anchor w -pady 2 \
1007        5,0 $inner.xviewup -pady 2 -fill x \
1008        6,0 $inner.yviewup -pady 2 -fill x \
1009        7,0 $inner.zviewup -pady 2 -fill x \
1010        8,0 $inner.xfocall -anchor w -pady 2 \
1011        9,0 $inner.xfocal -pady 2 -fill x \
1012        10,0 $inner.yfocal -pady 2 -fill x \
1013        11,0 $inner.zfocal -pady 2 -fill x \
1014        16,0 $inner.anglel -anchor w -pady 2 \
1015        17,0 $inner.angle -pady 2 -fill x \
1016        18,0 $inner.clipl -anchor w -pady 2 \
1017        19,0 $inner.clipmin -pady 2 -fill x \
1018        20,0 $inner.clipmax -pady 2 -fill x \
1019        21,0 $inner.pscalel -anchor w -pady 2 \
1020        22,0 $inner.pscale -pady 2 -fill x \
1021        23,0 $inner.refresh
1022
1023    blt::table configure $inner r* c* -resize none
1024    blt::table configure $inner c0 -resize expand
1025    blt::table configure $inner r24 -resize expand
1026}
1027
1028# ----------------------------------------------------------------------
1029# USAGE: FixSettings <what> ?<value>?
1030#
1031# Used internally to update rendering settings whenever parameters
1032# change in the popup settings panel.  Sends the new settings off
1033# to the back end.
1034# ----------------------------------------------------------------------
1035itcl::body Rappture::VtkViewer::FixSettings {what {value ""}} {
1036    switch -- $what {
1037        light {
1038        }
1039        transp {
1040        }
1041        opacity {
1042            set new [expr $_settings($this-opacity) * 0.01]
1043            foreach dataobj [get] {
1044                foreach comp [$dataobj components] {
1045                    set actor [$dataobj values $comp]
1046                    set prop [$actor GetProperty]
1047                    $prop SetOpacity $new
1048                }
1049            }
1050            $_window Render
1051        }
1052
1053        "wireframe" {
1054            foreach dataobj [get] {
1055                foreach comp [$dataobj components] {
1056                    set actor [$dataobj values $comp]
1057                    set prop [$actor GetProperty]
1058                    if { $_settings($this-wireframe) } {
1059                        $prop SetRepresentationToWireframe
1060                    } else {
1061                        $prop SetRepresentationToSurface
1062                    }
1063                }
1064            }
1065            $_window Render
1066        }
1067        "isosurface" {
1068        }
1069        "edges" {
1070            foreach dataobj [get] {
1071                foreach comp [$dataobj components] {
1072                    set actor [$dataobj values $comp]
1073                    set prop [$actor GetProperty]
1074                    if { $_settings($this-edges) } {
1075                        $prop EdgeVisibilityOn
1076                    } else {
1077                        $prop EdgeVisibilityOff
1078                    }
1079                }
1080            }
1081            $_window Render
1082        }
1083        "axes" {
1084            if { $_settings($this-axes) } {
1085                $_cubeAxesActor VisibilityOn
1086            } else {
1087                $_cubeAxesActor VisibilityOff
1088            }
1089            $_window Render
1090        }
1091        "smallaxes" {
1092            $_axesWidget SetEnabled $_settings($this-smallaxes)
1093            $_window Render
1094        }
1095        default {
1096            error "don't know how to fix $what"
1097        }
1098    }
1099}
1100
1101itcl::body Rappture::VtkViewer::GetLimits {} {
1102    return [list $_limits(xMin) $_limits(xMax) \
1103                $_limits(yMin) $_limits(yMax) \
1104                $_limits(zMin) $_limits(zMax)]
1105}
1106
1107itcl::body Rappture::VtkViewer::ComputeLimits { args } {
1108    array set _limits {
1109        xMin 0
1110        xMax 1
1111        yMin 0
1112        yMax 1
1113        zMin 0
1114        zMax 1
1115        vMin 0
1116        vMax 1
1117    }
1118    set actors {}
1119    if { [llength $args] > 0 } {
1120        foreach dataobj $args {
1121            foreach comp [$dataobj components] {
1122                lappend actors [$dataobj values $comp]
1123            }
1124        }
1125    } else {
1126        foreach dataobj [get] {
1127            foreach comp [$dataobj components] {
1128                lappend actors [$dataobj values $comp]
1129            }
1130        }
1131    }
1132    if { [llength $actors] == 0 } {
1133        return
1134    }
1135    set actor [lindex $actors 0]
1136    foreach key { xMin xMax yMin yMax zMin zMax} value [$actor GetBounds] {
1137        set _limits($key) $value
1138    }
1139    foreach actor [lrange $actors 1 end] {
1140        foreach { xMin xMax yMin yMax zMin zMax} [$actor GetBounds] break
1141        if { $xMin < $_limits(xMin) } {
1142            set _limits(xMin) $xMin
1143        }
1144        if { $xMax > $_limits(xMax) } {
1145            set _limits(xMax) $xMax
1146        }
1147        if { $yMin < $_limits(yMin) } {
1148            set _limits(yMin) $yMin
1149        }
1150        if { $yMax > $_limits(yMax) } {
1151            set _limits(yMax) $yMax
1152        }
1153        if { $zMin < $_limits(zMin) } {
1154            set _limits(zMin) $zMin
1155        }
1156        if { $zMax > $_limits(zMax) } {
1157            set _limits(zMax) $zMax
1158        }
1159    }
1160    set _limits(vMin) $_limits(zMin)
1161    set _limits(vMax) $_limits(zMax)
1162}
Note: See TracBrowser for help on using the repository browser.