Changeset 6675


Ignore:
Timestamp:
Jan 23, 2017 11:29:05 AM (7 years ago)
Author:
ldelgass
Message:

Revert volume viewer changes to release branch versions

Location:
trunk/gui/scripts
Files:
4 edited

Legend:

Unmodified
Added
Removed
  • trunk/gui/scripts/flowvisviewer.tcl

    r6360 r6675  
    6161    public method get {args}
    6262    public method isconnected {}
    63     public method limits { cname }
     63    public method limits { tf }
    6464    public method overMarker { m x }
    6565    public method parameters {title args} {
     
    129129    private variable _dlist "";         # list of data objects
    130130    private variable _obj2ovride;       # maps dataobj => style override
    131     private variable _datasets;         # maps dataobj-component
     131    private variable _serverDatasets;   # contains all the dataobj-component
    132132                                        # to volumes in the server
     133    private variable _recvdDatasets;    # list of data objs to send to server
    133134    private variable _dataset2style;    # maps dataobj-component to transfunc
    134135    private variable _style2datasets;   # maps tf back to list of
     
    225226    $_arcball quaternion [ViewToQuaternion]
    226227
     228    set _limits(vmin) 0.0
     229    set _limits(vmax) 1.0
     230
    227231    array set _settings [subst {
    228         -ambient                60
    229232        -arrows                 0
    230233        -axesvisible            0
     
    233236        -currenttime            0
    234237        -cutplanesvisible       0
    235         -diffuse                40
    236238        -duration               1:00
    237239        -gridvisible            0
     
    239241        -legendvisible          1
    240242        -lic                    1
     243        -light                  40
    241244        -light2side             1
    242245        -loop                   0
     
    249252        -qy                     $_view(-qy)
    250253        -qz                     $_view(-qz)
    251         -specularexponent       90
    252         -specularlevel          30
    253254        -speed                  500
    254255        -step                   0
     
    496497    $itk_component(speed) value 1
    497498    bind $itk_component(speed) <<Value>> [itcl::code $this flow speed]
    498 
    499499
    500500    blt::table $itk_component(flowcontrols) \
     
    739739            set _limits($cname) $limits(v)
    740740        }
    741         foreach axis {x y z} {
     741        foreach axis {x y z v} {
    742742            foreach { min max } [$dataobj limits $axis] break
    743743            if {"" != $min && "" != $max} {
    744                 if { ![info exists _limits($axis)] } {
    745                     set _limits($axis) [list $min $max]
     744                if { ![info exists _limits(${axis}min)] } {
     745                    set _limits(${axis}min) $min
     746                    set _limits(${axis}max) $max
    746747                    continue
    747748                }
    748                 foreach {amin amax} $_limits($axis) break
    749                 if {$min < $amin} {
    750                     set amin $min
     749                if {$min < $_limits(${axis}min)} {
     750                    set _limits(${axis}min) $min
    751751                }
    752                 if {$max > $amax} {
    753                     set amax $max
     752                if {$max > $_limits(${axis}max)} {
     753                    set _limits(${axis}max) $max
    754754                }
    755                 set _limits($axis) [list $amin $amax]
    756755            }
    757756        }
     
    897896
    898897    # disconnected -- no more data sitting on server
    899     array unset _datasets
     898    array unset _serverDatasets
    900899}
    901900
     
    993992    # Display the markers used by the current transfer function.
    994993    set tf $_dataset2style($tag)
    995     foreach {min max} [limits $tf] break
    996     $c itemconfigure vmin -text [format %g $min]
     994    array set limits [limits $tf]
     995    $c itemconfigure vmin -text [format %g $limits(vmin)]
    997996    $c coords vmin $lx $ly
    998997
    999     $c itemconfigure vmax -text [format %g $max]
     998    $c itemconfigure vmax -text [format %g $limits(vmax)]
    1000999    $c coords vmax [expr {$w-$lx}] $ly
    10011000
     
    10431042# The procedure is the response from the render server to each "data
    10441043# follows" command.  The server sends back a "data" command invoked our
    1045 # the slave interpreter.  The purpose was to collect the min/max of the
    1046 # volume sent to the render server.  This is no longer needed since we
    1047 # already know the limits.
     1044# the slave interpreter.  The purpose is to collect the min/max of the
     1045# volume sent to the render server.  Since the client (flowvisviewer)
     1046# doesn't parse 3D data formats, we rely on the server (nanovis) to
     1047# tell us what the limits are.  Once we've received the limits to all
     1048# the data we've sent (tracked by _recvdDatasets) we can then determine
     1049# what the transfer functions are for these volumes.
     1050#
     1051#
     1052#       Note: There is a considerable tradeoff in having the server report
     1053#             back what the data limits are.  It means that much of the code
     1054#             having to do with transfer-functions has to wait for the data
     1055#             to come back, since the isomarkers are calculated based upon
     1056#             the data limits.  The client code is much messier because of
     1057#             this.  The alternative is to parse any of the 3D formats on the
     1058#             client side.
    10481059#
    10491060itcl::body Rappture::FlowvisViewer::ReceiveData { args } {
     
    10561067
    10571068    set tag $info(tag)
    1058     set _limits($tag) [list $info(min) $info(max)]
     1069    set parts [split $tag -]
     1070
     1071    #
     1072    # Volumes don't exist until we're told about them.
     1073    #
     1074    set dataobj [lindex $parts 0]
     1075    set _serverDatasets($tag) 0
     1076    set _limits($tag-min)  $info(min);  # Minimum value of the volume.
     1077    set _limits($tag-max)  $info(max);  # Maximum value of the volume.
     1078
     1079    unset _recvdDatasets($tag)
     1080    if { [array size _recvdDatasets] == 0 } {
     1081        updateTransferFunctions
     1082    }
    10591083}
    10601084
     
    10991123    }
    11001124    set _first ""
    1101     foreach dataobj [get -objects] {
    1102         if { [info exists _obj2ovride($dataobj-raise)] &&  $_first == "" } {
    1103             set _first $dataobj
    1104         }
     1125    foreach dataobj [get] {
    11051126        foreach cname [$dataobj components] {
    11061127            set tag $dataobj-$cname
    1107             if { ![info exists _datasets($tag)] } {
    1108                 if { [$dataobj type] == "dx" } {
    1109                     set data [$dataobj blob $cname]
    1110                 } else {
    1111                     set data [$dataobj vtkdata $cname]
     1128            if {[$dataobj type] == "dx"} {
     1129                set data [$dataobj blob $cname]
     1130            } else {
     1131                set data [$dataobj vtkdata $cname]
     1132            }
     1133            set nbytes [string length $data]
     1134            if { $_reportClientInfo }  {
     1135                set info {}
     1136                lappend info "tool_id"       [$dataobj hints toolid]
     1137                lappend info "tool_name"     [$dataobj hints toolname]
     1138                lappend info "tool_title"    [$dataobj hints tooltitle]
     1139                lappend info "tool_command"  [$dataobj hints toolcommand]
     1140                lappend info "tool_revision" [$dataobj hints toolrevision]
     1141                lappend info "dataset_label" [$dataobj hints label]
     1142                lappend info "dataset_size"  $nbytes
     1143                lappend info "dataset_tag"   $tag
     1144                SendCmd "clientinfo [list $info]"
     1145            }
     1146            set numComponents [$dataobj numComponents $cname]
     1147            # I have a field. Is a vector field or a volume field?
     1148            if { $numComponents == 1 } {
     1149                SendCmd "volume data follows $nbytes $tag"
     1150            } else {
     1151                if {[SendFlowCmd $dataobj $cname $nbytes $numComponents] < 0} {
     1152                    continue
    11121153                }
    1113                 set nbytes [string length $data]
    1114                 if { $_reportClientInfo }  {
    1115                     set info {}
    1116                     lappend info "tool_id"       [$dataobj hints toolid]
    1117                     lappend info "tool_name"     [$dataobj hints toolname]
    1118                     lappend info "tool_title"    [$dataobj hints tooltitle]
    1119                     lappend info "tool_command"  [$dataobj hints toolcommand]
    1120                     lappend info "tool_revision" [$dataobj hints toolrevision]
    1121                     lappend info "dataset_label" [$dataobj hints label]
    1122                     lappend info "dataset_size"  $nbytes
    1123                     lappend info "dataset_tag"   $tag
    1124                     SendCmd "clientinfo [list $info]"
    1125                 }
    1126                 set numComponents [$dataobj numComponents $cname]
    1127                 # I have a field. Is a vector field or a volume field?
    1128                 if { $numComponents == 1 } {
    1129                     SendCmd "volume data follows $nbytes $tag"
    1130                 } else {
    1131                     if {[SendFlowCmd $dataobj $cname $nbytes $numComponents] < 0} {
    1132                         continue
    1133                     }
    1134                 }
    1135                 SendData $data
    1136                 set _datasets($tag) 1
    1137                 NameTransferFunction $dataobj $cname
    1138             }
    1139         }
    1140     }
     1154            }
     1155            SendData $data
     1156            NameTransferFunction $dataobj $cname
     1157            set _recvdDatasets($tag) 1
     1158        }
     1159    }
     1160
     1161    set _first [lindex [get] 0]
    11411162
    11421163    # Turn off cutplanes for all volumes
     
    11451166    }
    11461167
    1147     InitSettings -volume -outlinevisible -cutplanesvisible \
     1168    # Reset the camera and other view parameters
     1169    InitSettings -opacity -light2side -isosurfaceshading \
     1170        -light \
     1171        -volume -outlinevisible -cutplanesvisible \
    11481172        -xcutplanevisible -ycutplanevisible -zcutplanevisible \
    11491173        -xcutplaneposition -ycutplaneposition -zcutplaneposition
    11501174
    1151     if { $_reset } {
    1152         InitSettings -opacity -light2side -isosurfaceshading \
    1153             -ambient -diffuse -specularlevel -specularexponent
    1154 
    1155         #
    1156         # Reset the camera and other view parameters
    1157         #
    1158         if {"" != $_first} {
    1159             set axis [$_first hints updir]
    1160             if { "" != $axis } {
    1161                 SendCmd "up $axis"
    1162             }
    1163             set location [$_first hints camera]
    1164             if { $location != "" } {
    1165                 array set _view $location
    1166             }
    1167         }
    1168         set _settings(-qw)    $_view(-qw)
    1169         set _settings(-qx)    $_view(-qx)
    1170         set _settings(-qy)    $_view(-qy)
    1171         set _settings(-qz)    $_view(-qz)
    1172         set _settings(-xpan)  $_view(-xpan)
    1173         set _settings(-ypan)  $_view(-ypan)
    1174         set _settings(-zoom)  $_view(-zoom)
    1175 
    1176         set q [ViewToQuaternion]
    1177         $_arcball quaternion $q
    1178         SendCmd "camera orient $q"
    1179         SendCmd "camera reset"
    1180         PanCamera
    1181         SendCmd "camera zoom $_view(-zoom)"
     1175    # nothing to send -- activate the proper volume
     1176    if {"" != $_first} {
     1177        set axis [$_first hints updir]
     1178        if {"" != $axis} {
     1179            SendCmd "up $axis"
     1180        }
     1181        set location [$_first hints camera]
     1182        if { $location != "" } {
     1183            array set _view $location
     1184        }
     1185    }
     1186    set _settings(-qw)    $_view(-qw)
     1187    set _settings(-qx)    $_view(-qx)
     1188    set _settings(-qy)    $_view(-qy)
     1189    set _settings(-qz)    $_view(-qz)
     1190    set _settings(-xpan)  $_view(-xpan)
     1191    set _settings(-ypan)  $_view(-ypan)
     1192    set _settings(-zoom)  $_view(-zoom)
     1193
     1194    set q [ViewToQuaternion]
     1195    $_arcball quaternion $q
     1196    SendCmd "camera orient $q"
     1197    SendCmd "camera reset"
     1198    PanCamera
     1199    SendCmd "camera zoom $_view(-zoom)"
     1200
     1201    foreach dataobj [get] {
     1202        foreach cname [$dataobj components] {
     1203            NameTransferFunction $dataobj $cname
     1204        }
    11821205        set _reset 0
    11831206    }
    11841207
     1208    # nothing to send -- activate the proper ivol
     1209    set _first [lindex [get] 0]
    11851210    if {"" != $_first} {
     1211        set axis [$_first hints updir]
     1212        if {"" != $axis} {
     1213            SendCmd "up $axis"
     1214        }
     1215        set location [$_first hints camera]
     1216        if { $location != "" } {
     1217            array set _view $location
     1218        }
    11861219        set cname [lindex [$_first components] 0]
    11871220        set _activeTf [lindex $_dataset2style($_first-$cname) 0]
    1188         # Make sure we display the proper transfer function in the legend.
    1189         updateTransferFunctions
    1190     }
     1221    }
     1222
     1223    # sync the state of slicers
     1224    set vols [CurrentDatasets -cutplanes]
     1225    foreach axis {x y z} {
     1226        set pos [expr {0.01*$_settings(-${axis}cutplaneposition)}]
     1227        SendCmd "cutplane position $pos $axis $vols"
     1228    }
     1229    SendCmd "volume data state $_settings(-volume)"
     1230    EventuallyRedrawLegend
    11911231
    11921232    # Actually write the commands to the server socket.  If it fails, we don't
     
    12051245# ----------------------------------------------------------------------
    12061246itcl::body Rappture::FlowvisViewer::CurrentDatasets {{what -all}} {
    1207     set rlist ""
     1247    return ""
    12081248    if { $_first == "" } {
    12091249        return
    12101250    }
    1211     foreach cname [$_first components] {
    1212         set tag $_first-$cname
    1213         if { [info exists _datasets($tag)] && $_datasets($tag) } {
     1251    foreach tag [array names _serverDatasets *-*] {
     1252        if {[string match $_first-* $tag]} {
    12141253            array set style {
    12151254                -cutplanes 1
    12161255            }
    1217             array set style [lindex [$_first components -style $cname] 0]
    1218             if { $what != "-cutplanes" || $style(-cutplanes) } {
    1219                 lappend rlist $tag
     1256            foreach {dataobj cname} [split $tag -] break
     1257            array set style [lindex [$dataobj components -style $cname] 0]
     1258            if {$what != "-cutplanes" || $style(-cutplanes)} {
     1259                lappend rlist $_serverDatasets($tag)
    12201260            }
    12211261        }
     
    14051445    }
    14061446    switch -- $what {
    1407         "-ambient" {
    1408             if { $_first != "" } {
    1409                 set comp [lindex [$_first components] 0]
    1410                 set tag $_first-$comp
    1411                 set val $_settings($what)
    1412                 set val [expr {0.01*$val}]
    1413                 SendCmd "$tag configure -ambient $val"
    1414             }
    1415         }
    14161447        "-axesvisible" {
    14171448            SendCmd "axis visible $_settings($what)"
     
    14421473            set tag [lindex $datasets 0]
    14431474            SendCmd "cutplane visible $bool $tag"
    1444         }
    1445         "-diffuse" {
    1446             if { $_first != "" } {
    1447                 set comp [lindex [$_first components] 0]
    1448                 set tag $_first-$comp
    1449                 set val $_settings($what)
    1450                 set val [expr {0.01*$val}]
    1451                 SendCmd "$tag configure -diffuse $val"
    1452             }
    14531475        }
    14541476        "-gridvisible" {
     
    14741496            }
    14751497        }
     1498        "-light" {
     1499            if { $_first != "" } {
     1500                set comp [lindex [$_first components] 0]
     1501                set tag $_first-$comp
     1502                set diffuse [expr {0.01*$_settings($what)}]
     1503                set ambient [expr {1.0 - $diffuse}]
     1504                set specularLevel 0.3
     1505                set specularExp 90.0
     1506                SendCmd "$tag configure -ambient $ambient -diffuse $diffuse -specularLevel $specularLevel -specularExp $specularExp"
     1507            }
     1508        }
    14761509        "-light2side" {
    14771510            if { $_first != "" } {
     
    14951528                set tag $_first-$comp
    14961529                SendCmd "$tag configure -outline $_settings($what)"
    1497             }
    1498         }
    1499         "-specularlevel" {
    1500             if { $_first != "" } {
    1501                 set comp [lindex [$_first components] 0]
    1502                 set tag $_first-$comp
    1503                 set val $_settings($what)
    1504                 set val [expr {0.01*$val}]
    1505                 SendCmd "$tag configure -specularLevel $val"
    1506             }
    1507         }
    1508         "-specularexponent" {
    1509             if { $_first != "" } {
    1510                 set comp [lindex [$_first components] 0]
    1511                 set tag $_first-$comp
    1512                 set val $_settings($what)
    1513                 SendCmd "$tag configure -specularExp $val"
    15141530            }
    15151531        }
     
    16011617    }
    16021618    array set style [lindex [$dataobj components -style $cname] 0]
     1619    set tf "$style(-color):$style(-levels)"
    16031620    # Some tools erroneously set -opacity to 1 in style, so
    16041621    # override the requested opacity for now
    16051622    set style(-opacity) 0.5
    16061623    set _settings(-opacity) [expr $style(-opacity) * 100]
    1607     set _dataset2style($dataobj-$cname) $cname
    1608     lappend _style2datasets($cname) $dataobj $cname
    1609     return $cname
     1624    set _dataset2style($dataobj-$cname) $tf
     1625    lappend _style2datasets($tf) $dataobj $cname
     1626    return $tf
    16101627}
    16111628
     
    18881905}
    18891906
    1890 itcl::body Rappture::FlowvisViewer::limits { cname } {
    1891     if { ![info exists _limits($cname)] } {
    1892         puts stderr "no limits for cname=($cname)"
    1893         return [list 0.0 1.0]
    1894     }
    1895     return $_limits($cname)
     1907itcl::body Rappture::FlowvisViewer::limits { tf } {
     1908    set _limits(vmin) 0.0
     1909    set _limits(vmax) 1.0
     1910    if { ![info exists _style2datasets($tf)] } {
     1911        puts stderr "no _style2datasets for tf=($tf)"
     1912        return [array get _limits]
     1913    }
     1914    set min ""; set max ""
     1915    foreach {dataobj comp} $_style2datasets($tf) {
     1916        set tag $dataobj-$comp
     1917        if { ![info exists _serverDatasets($tag)] } {
     1918            puts stderr "$tag not in _serverDatasets?"
     1919            continue
     1920        }
     1921        if { ![info exists _limits($tag-min)] } {
     1922            puts stderr "$tag no min?"
     1923            continue
     1924        }
     1925        if { $min == "" || $min > $_limits($tag-min) } {
     1926            set min $_limits($tag-min)
     1927        }
     1928        if { $max == "" || $max < $_limits($tag-max) } {
     1929            set max $_limits($tag-max)
     1930        }
     1931    }
     1932    if { $min != "" } {
     1933        set _limits(vmin) $min
     1934    }
     1935    if { $max != "" } {
     1936        set _limits(vmax) $max
     1937    }
     1938    return [array get _limits]
    18961939}
    18971940
     
    19972040        -command [itcl::code $this AdjustSetting -light2side]
    19982041
    1999     label $inner.ambient_l -text "Ambient" -font $fg
    2000     ::scale $inner.ambient -from 0 -to 100 -orient horizontal \
    2001         -variable [itcl::scope _settings(-ambient)] \
     2042    label $inner.dim -text "Glow" -font $fg
     2043    ::scale $inner.light -from 0 -to 100 -orient horizontal \
     2044        -variable [itcl::scope _settings(-light)] \
    20022045        -width 10 \
    2003         -showvalue off -command [itcl::code $this AdjustSetting -ambient]
    2004 
    2005     label $inner.diffuse_l -text "Diffuse" -font $fg
    2006     ::scale $inner.diffuse -from 0 -to 100 -orient horizontal \
    2007         -variable [itcl::scope _settings(-diffuse)] \
    2008         -width 10 \
    2009         -showvalue off -command [itcl::code $this AdjustSetting -diffuse]
    2010 
    2011     label $inner.specularLevel_l -text "Specular" -font $fg
    2012     ::scale $inner.specularLevel -from 0 -to 100 -orient horizontal \
    2013         -variable [itcl::scope _settings(-specularlevel)] \
    2014         -width 10 \
    2015         -showvalue off -command [itcl::code $this AdjustSetting -specularlevel]
    2016 
    2017     label $inner.specularExponent_l -text "Shininess" -font $fg
    2018     ::scale $inner.specularExponent -from 10 -to 128 -orient horizontal \
    2019         -variable [itcl::scope _settings(-specularexponent)] \
    2020         -width 10 \
    2021         -showvalue off -command [itcl::code $this AdjustSetting -specularexponent]
     2046        -showvalue off -command [itcl::code $this AdjustSetting -light]
     2047    label $inner.bright -text "Surface" -font $fg
    20222048
    20232049    # Opacity
     
    20442070        Rappture::Combobox $inner.colormap -width 10 -editable no
    20452071    }
     2072
    20462073    $inner.colormap choices insert end [GetColormapList -includeNone]
    20472074    bind $inner.colormap <<Value>> \
     
    20542081        1,0 $inner.lighting_l -cspan 4 -anchor w -pady {10 2} \
    20552082        2,0 $inner.light2side -cspan 4 -anchor w -pady 2 \
    2056         3,0 $inner.ambient_l -anchor e -pady 2 \
    2057         3,1 $inner.ambient -cspan 3 -pady 2 -fill x \
    2058         4,0 $inner.diffuse_l -anchor e -pady 2 \
    2059         4,1 $inner.diffuse -cspan 3 -pady 2 -fill x \
    2060         5,0 $inner.specularLevel_l -anchor e -pady 2 \
    2061         5,1 $inner.specularLevel -cspan 3 -pady 2 -fill x \
    2062         6,0 $inner.specularExponent_l -anchor e -pady 2 \
    2063         6,1 $inner.specularExponent -cspan 3 -pady 2 -fill x \
    2064         7,0 $inner.opacity_l -anchor e -pady 2 \
    2065         7,1 $inner.opacity -cspan 3 -pady 2 -fill x \
    2066         8,0 $inner.thin -anchor e -pady 2 \
    2067         8,1 $inner.thickness -cspan 2 -pady 2 -fill x \
    2068         8,3 $inner.thick -anchor w -pady 2
     2083        3,0 $inner.dim -anchor e -pady 2 \
     2084        3,1 $inner.light -cspan 2 -pady 2 -fill x \
     2085        3,3 $inner.bright -anchor w -pady 2 \
     2086        4,0 $inner.opacity_l -anchor e -pady 2 \
     2087        4,1 $inner.opacity -cspan 3 -pady 2 -fill x \
     2088        5,0 $inner.thin -anchor e -pady 2 \
     2089        5,1 $inner.thickness -cspan 2 -pady 2 -fill x \
     2090        5,3 $inner.thick -anchor w -pady 2
    20692091
    20702092    blt::table configure $inner c0 c1 c3 r* -resize none
    2071     blt::table configure $inner r9 -resize expand
     2093    blt::table configure $inner r6 -resize expand
    20722094}
    20732095
     
    29452967    set list ""
    29462968    foreach tag $_volcomponents($cname) {
    2947         if { ![info exists _datasets($tag)] } {
     2969        if { ![info exists _serverDatasets($tag)] } {
    29482970            continue
    29492971        }
  • trunk/gui/scripts/isomarker.tcl

    r5639 r6675  
    125125
    126126itcl::body Rappture::IsoMarker::relval { {x "-get"} } {
    127     foreach {min max} [$_nvobj limits $_tf] break
     127    array set limits [$_nvobj limits $_tf]
     128    set min $limits(vmin)
     129    set max $limits(vmax)
    128130    if { $x == "-get" } {
    129131        if { $max == $min } {
  • trunk/gui/scripts/nanovisviewer.tcl

    r6360 r6675  
    6060    public method get {args}
    6161    public method isconnected {}
     62    public method limits { tf }
     63    public method overMarker { m x }
    6264    public method parameters {title args} {
    6365        # do nothing
    6466    }
     67    public method removeDuplicateMarker { m x }
    6568    public method scale {args}
    6669    public method updateTransferFunctions {}
    6770
    6871    # The following methods are only used by this class.
    69     private method AddNewMarker { x y }
     72    private method AddIsoMarker { x y }
    7073    private method AdjustSetting {what {value ""}}
    7174    private method BuildCameraTab {}
     
    7376    private method BuildDownloadPopup { widget command }
    7477    private method BuildViewTab {}
    75     private method BuildVolumeComponents {}
    7678    private method BuildVolumeTab {}
    77     private method ComputeAlphamap { cname }
    78     private method ComputeTransferFunction { cname }
     79    private method ComputeTransferFunction { tf }
    7980    private method Connect {}
    8081    private method CurrentDatasets {{what -all}}
    8182    private method Disconnect {}
    8283    private method DoResize {}
    83     private method DrawLegend { cname }
     84    private method DrawLegend { tf }
    8485    private method EventuallyRedrawLegend { }
    8586    private method EventuallyResize { w h }
    8687    private method FixLegend {}
    87     private method GetColormap { cname color }
    88     private method GetDatasetsWithComponent { cname }
    8988    private method GetImage { args }
    9089    private method GetVtkData { args }
    91     private method HideAllMarkers {}
    92     private method InitComponentSettings { cname }
    9390    private method InitSettings { args }
    9491    private method NameTransferFunction { dataobj comp }
    9592    private method Pan {option x y}
    9693    private method PanCamera {}
    97     private method ParseLevelsOption { cname levels }
    98     private method ParseMarkersOption { cname markers }
     94    private method ParseLevelsOption { tf levels }
     95    private method ParseMarkersOption { tf markers }
    9996    private method QuaternionToView { q } {
    10097        foreach { _view(-qw) _view(-qx) _view(-qy) _view(-qz) } $q break
     
    104101    private method ReceiveImage { args }
    105102    private method ReceiveLegend { tf vmin vmax size }
    106     private method RemoveMarker { x y }
    107     private method ResetColormap { cname color }
     103    private method ResetColormap { color }
    108104    private method Rotate {option x y}
    109105    private method SendTransferFunctions {}
    110     private method SetObjectStyle { dataobj cname }
    111106    private method SetOrientation { side }
    112107    private method Slice {option args}
    113108    private method SlicerTip {axis}
    114     private method SwitchComponent { cname }
    115109    private method ViewToQuaternion {} {
    116110        return [list $_view(-qw) $_view(-qx) $_view(-qy) $_view(-qz)]
     
    121115    private variable _dlist "";         # list of data objects
    122116    private variable _obj2ovride;       # maps dataobj => style override
    123     private variable _datasets;         # maps dataobj-component
     117    private variable _serverDatasets;   # contains all the dataobj-component
    124118                                        # to volumes in the server
     119    private variable _recvdDatasets;    # list of data objs to send to server
     120    private variable _dataset2style;    # maps dataobj-component to transfunc
     121    private variable _style2datasets;   # maps tf back to list of
     122                                        # dataobj-components using the tf.
    125123
    126124    private variable _reset 1;          # Connection to server has been reset.
     
    128126    private variable _limits;           # Autoscale min/max for all axes
    129127    private variable _view;             # View params for 3D view
    130     private variable _parsedFunction
    131     private variable _transferFunctionEditors
     128    private variable _isomarkers;       # array of isosurface level values 0..1
     129    # Array of transfer functions in server.  If 0 the transfer has been
     130    # defined but not loaded.  If 1 the transfer function has been named
     131    # and loaded.
     132    private variable _activeTfs
    132133    private variable _settings
    133134    private variable _first "";         # This is the topmost volume.
    134     private variable _current "";       # Currently selected component
    135     private variable _volcomponents;    # Maps component name to list of
    136                                         # dataobj-component tags
    137     private variable _componentsList;   # List of components found
    138     private variable _cname2transferFunction
    139     private variable _cname2defaultcolormap
    140135    private variable _width 0
    141136    private variable _height 0
     
    198193    $_arcball quaternion [ViewToQuaternion]
    199194
     195    set _limits(vmin) 0.0
     196    set _limits(vmax) 1.0
     197
    200198    array set _settings [subst {
    201         -ambient                60
    202199        -axesvisible            1
    203200        -background             black
    204         -colormap               "default"
     201        -colormap               "BCGYR"
    205202        -cutplanesvisible       0
    206         -diffuse                40
    207203        -gridvisible            0
    208204        -isosurfaceshading      0
    209205        -legendvisible          1
     206        -light                  40
    210207        -light2side             1
    211208        -opacity                50
     
    215212        -qy                     $_view(-qy)
    216213        -qz                     $_view(-qz)
    217         -specularexponent       90
    218         -specularlevel          30
    219214        -thickness              350
    220215        -volume                 1
    221         -volumevisible          1
    222216        -xcutplaneposition      50
    223         -xcutplanevisible       1
     217        -xcutplanevisible       0
    224218        -xpan                   $_view(-xpan)
    225219        -ycutplaneposition      50
    226         -ycutplanevisible       1
     220        -ycutplanevisible       0
    227221        -ypan                   $_view(-ypan)
    228222        -zcutplaneposition      50
    229         -zcutplanevisible       1
     223        -zcutplanevisible       0
    230224        -zoom                   $_view(-zoom)
    231225    }]
     
    299293    Rappture::Tooltip::for $itk_component(cutplane) \
    300294        "Show/Hide cutplanes"
    301     pack $itk_component(cutplane) -padx 2 -pady 2
     295    #pack $itk_component(cutplane) -padx 2 -pady 2
    302296
    303297    if { [catch {
     
    322316    bind $itk_component(legend) <Configure> \
    323317        [itcl::code $this EventuallyRedrawLegend]
    324     bind $itk_component(legend) <KeyPress-Delete> \
    325         [itcl::code $this RemoveMarker %x %y]
    326     bind $itk_component(legend) <Enter> \
    327         [list focus $itk_component(legend)]
    328318
    329319    # Hack around the Tk panewindow.  The problem is that the requested
     
    344334    bind $itk_component(view) <ButtonRelease-1> \
    345335        [itcl::code $this Rotate release %x %y]
    346 
    347336    bind $itk_component(view) <Configure> \
    348337        [itcl::code $this EventuallyResize %w %h]
     
    404393    image delete $_image(legend)
    405394    image delete $_image(download)
    406     foreach cname [array names _transferFunctionEditors] {
    407         itcl::delete object $_transferFunctionEditors($cname)
    408     }
    409395    catch { blt::arcball destroy $_arcball }
    410396    array unset _settings
     
    536522# ----------------------------------------------------------------------
    537523itcl::body Rappture::NanovisViewer::scale {args} {
    538     array set style {
    539         -color    BCGYR
    540         -levels   6
    541         -markers  ""
    542     }
    543     array unset _limits
    544     array unset _volcomponents
     524    foreach val {xmin xmax ymin ymax zmin zmax vmin vmax} {
     525        set _limits($val) ""
     526    }
    545527    foreach dataobj $args {
    546528        if { ![$dataobj isvalid] } {
    547529            continue;                     # Object doesn't contain valid data.
    548530        }
    549         foreach cname [$dataobj components] {
    550             if { ![info exists _volcomponents($cname)] } {
    551                 lappend _componentsList $cname
    552                 array set style [lindex [$dataobj components -style $cname] 0]
    553                 set cmap [ColorsToColormap $style(-color)]
    554                 set _cname2defaultcolormap($cname) $cmap
    555                 set _settings($cname-colormap) $style(-color)
    556             }
    557             lappend _volcomponents($cname) $dataobj-$cname
    558             array unset limits
    559             array set limits [$dataobj valueLimits $cname]
    560             set _limits($cname) $limits(v)
    561         }
    562         foreach axis {x y z} {
     531        foreach axis {x y z v} {
    563532            foreach { min max } [$dataobj limits $axis] break
    564533            if {"" != $min && "" != $max} {
    565                 if { ![info exists _limits($axis)] } {
    566                     set _limits($axis) [list $min $max]
    567                     continue
     534                if {"" == $_limits(${axis}min)} {
     535                    set _limits(${axis}min) $min
     536                    set _limits(${axis}max) $max
     537                } else {
     538                    if {$min < $_limits(${axis}min)} {
     539                        set _limits(${axis}min) $min
     540                    }
     541                    if {$max > $_limits(${axis}max)} {
     542                        set _limits(${axis}max) $max
     543                    }
    568544                }
    569                 foreach {amin amax} $_limits($axis) break
    570                 if {$min < $amin} {
    571                     set amin $min
    572                 }
    573                 if {$max > $amax} {
    574                     set amax $max
    575                 }
    576                 set _limits($axis) [list $amin $amax]
    577             }
    578         }
    579     }
    580     BuildVolumeComponents
     545            }
     546        }
     547    }
    581548}
    582549
     
    712679
    713680    # disconnected -- no more data sitting on server
    714     array unset _datasets
     681    array unset _serverDatasets
    715682}
    716683
     
    719686# ----------------------------------------------------------------------
    720687itcl::body Rappture::NanovisViewer::SendTransferFunctions {} {
    721     foreach cname [array names _volcomponents] {
    722         ComputeTransferFunction $cname
     688    if { $_first == "" } {
     689        puts stderr "first not set"
     690        return
     691    }
     692    # Ensure that the global thickness setting (in the slider
     693    # settings widget) is used for the active transfer-function.  Update
     694    # the value in the _settings variable.
     695    # Scale values between 0.00001 and 0.01000
     696    set thickness [expr {double($_settings(-thickness)) * 0.0001}]
     697
     698    foreach tag [CurrentDatasets] {
     699        if { ![info exists _serverDatasets($tag)] || !$_serverDatasets($tag) } {
     700            # The volume hasn't reached the server yet.  How did we get
     701            # here?
     702            puts stderr "Don't have $tag in _serverDatasets"
     703            continue
     704        }
     705        if { ![info exists _dataset2style($tag)] } {
     706            puts stderr "don't have style for volume $tag"
     707            continue;                        # How does this happen?
     708        }
     709        set tf $_dataset2style($tag)
     710        set _settings($tf-thickness) $thickness
     711        ComputeTransferFunction $tf
     712        # FIXME: Need to the send information as to what transfer functions
     713        #        to update so that we only update the transfer function
     714        #        as necessary.  Right now, all transfer functions are
     715        #        updated. This makes moving the isomarker slider chunky.
     716        if { ![info exists _activeTfs($tf)] || !$_activeTfs($tf) } {
     717            set _activeTfs($tf) 1
     718        }
     719        SendCmd "volume shading transfunc $tf $tag"
    723720    }
    724721    FixLegend
     
    758755# DrawLegend --
    759756#
    760 itcl::body Rappture::NanovisViewer::DrawLegend { cname } {
     757itcl::body Rappture::NanovisViewer::DrawLegend { tf } {
    761758    set c $itk_component(legend)
    762759    set w [winfo width $c]
     
    774771            -fill $itk_option(-plotforeground) -tags "title text"
    775772        $c lower colorbar
    776         $c bind colorbar <ButtonRelease-1> [itcl::code $this AddNewMarker %x %y]
     773        $c bind colorbar <ButtonRelease-1> [itcl::code $this AddIsoMarker %x %y]
    777774    }
    778775
    779776    # Display the markers used by the current transfer function.
    780     HideAllMarkers
    781     if {$cname == "" || ![info exists _transferFunctionEditors($cname)]} {
    782         return
    783     }
    784     $_transferFunctionEditors($cname) showMarkers $_limits($cname)
    785 
    786     foreach {min max} $_limits($cname) break
    787     $c itemconfigure vmin -text [format %g $min]
     777    array set limits [limits $tf]
     778    $c itemconfigure vmin -text [format %g $limits(min)]
    788779    $c coords vmin $lx $ly
    789780
    790     $c itemconfigure vmax -text [format %g $max]
     781    $c itemconfigure vmax -text [format %g $limits(max)]
    791782    $c coords vmax [expr {$w-$lx}] $ly
    792783
     
    801792    $c itemconfigure title -text $title
    802793    $c coords title [expr {$w/2}] $ly
     794
     795    if { [info exists _isomarkers($tf)] } {
     796        # The "visible" isomarker method below implicitly calls "absval".
     797        # It uses the screen position of the marker to compute the absolute
     798        # value.  So make sure the window size has been computed before
     799        # calling "visible".
     800        update idletasks
     801        update
     802        foreach m $_isomarkers($tf) {
     803            $m visible yes
     804        }
     805    }
     806
     807    # The colormap may have changed. Resync the slicers with the colormap.
     808    set datasets [CurrentDatasets -cutplanes]
     809    SendCmd "volume data state $_settings(-volume) $datasets"
     810
     811    # Adjust the cutplane for only the first component in the topmost volume
     812    # (i.e. the first volume designated in the field).
     813    set tag [lindex $datasets 0]
     814    foreach axis {x y z} {
     815        # Turn off cutplanes for all volumes
     816        SendCmd "cutplane state 0 $axis"
     817        if { $_settings(-${axis}cutplanevisible) } {
     818            # Turn on cutplane for this particular volume and set the position
     819            SendCmd "cutplane state 1 $axis $tag"
     820            set pos [expr {0.01*$_settings(-${axis}cutplaneposition)}]
     821            SendCmd "cutplane position $pos $axis $tag"
     822        }
     823    }
    803824}
    804825
     
    812833# active transfer function is displayed.
    813834#
    814 itcl::body Rappture::NanovisViewer::ReceiveLegend { cname vmin vmax size } {
     835itcl::body Rappture::NanovisViewer::ReceiveLegend { tf vmin vmax size } {
    815836    if { ![isconnected] } {
    816837        return
     
    820841    ReceiveEcho <<line "<read $size bytes for [image width $_image(legend)]x[image height $_image(legend)] legend>"
    821842
    822     DrawLegend $_current
     843    DrawLegend $tf
    823844}
    824845
     
    828849# The procedure is the response from the render server to each "data
    829850# follows" command.  The server sends back a "data" command invoked our
    830 # the slave interpreter.  The purpose was to collect the min/max of the
    831 # volume sent to the render server.  This is no longer needed since we
    832 # already know the limits.
     851# the slave interpreter.  The purpose is to collect the min/max of the
     852# volume sent to the render server.  Since the client (nanovisviewer)
     853# doesn't parse 3D data formats, we rely on the server (nanovis) to
     854# tell us what the limits are.  Once we've received the limits to all
     855# the data we've sent (tracked by _recvdDatasets) we can then determine
     856# what the transfer functions are for these volumes.
     857#
     858#
     859#       Note: There is a considerable tradeoff in having the server report
     860#             back what the data limits are.  It means that much of the code
     861#             having to do with transfer-functions has to wait for the data
     862#             to come back, since the isomarkers are calculated based upon
     863#             the data limits.  The client code is much messier because of
     864#             this.  The alternative is to parse any of the 3D formats on the
     865#             client side.
    833866#
    834867itcl::body Rappture::NanovisViewer::ReceiveData { args } {
     
    841874
    842875    set tag $info(tag)
    843     set _limits($tag) [list $info(min) $info(max)]
     876    set parts [split $tag -]
     877
     878    #
     879    # Volumes don't exist until we're told about them.
     880    #
     881    set dataobj [lindex $parts 0]
     882    set _serverDatasets($tag) 1
     883    if { $_settings(-volume) && $dataobj == $_first } {
     884        SendCmd "volume state 1 $tag"
     885    }
     886    set _limits($tag-min)  $info(min);  # Minimum value of the volume.
     887    set _limits($tag-max)  $info(max);  # Maximum value of the volume.
     888    set _limits(vmin)      $info(vmin); # Overall minimum value.
     889    set _limits(vmax)      $info(vmax); # Overall maximum value.
     890
     891    unset _recvdDatasets($tag)
     892    if { [array size _recvdDatasets] == 0 } {
     893        # The active transfer function is by default the first component of
     894        # the first data object.  This assumes that the data is always
     895        # successfully transferred.
     896        updateTransferFunctions
     897    }
    844898}
    845899
     
    865919    StartBufferingCommands
    866920
     921    # Hide all the isomarkers. Can't remove them. Have to remember the
     922    # settings since the user may have created/deleted/moved markers.
     923
     924    # The "visible" isomarker method below implicitly calls "absval".  It
     925    # uses the screen position of the marker to compute the absolute value.
     926    # So make sure the window size has been computed before calling
     927    # "visible".
     928    update idletasks
     929    update
     930    foreach tf [array names _isomarkers] {
     931        foreach m $_isomarkers($tf) {
     932            $m visible no
     933        }
     934    }
     935
    867936    if { $_width != $w || $_height != $h || $_reset } {
    868937        set _width $w
     
    874943        InitSettings -background -axesvisible -gridvisible
    875944    }
    876     set _first ""
    877     SendCmd "volume state 0"
    878     foreach dataobj [get -objects] {
    879         if { [info exists _obj2ovride($dataobj-raise)] &&  $_first == "" } {
    880             set _first $dataobj
    881         }
     945    foreach dataobj [get] {
    882946        foreach cname [$dataobj components] {
    883947            set tag $dataobj-$cname
    884             if { ![info exists _datasets($tag)] } {
     948            if { ![info exists _serverDatasets($tag)] } {
     949                # Send the data as one huge base64-encoded mess -- yuck!
    885950                if { [$dataobj type] == "dx" } {
    886951                    set data [$dataobj blob $cname]
     
    909974                SendCmd "volume data follows $nbytes $tag"
    910975                SendData $data
    911                 set _datasets($tag) 1
    912                 SetObjectStyle $dataobj $cname
    913             }
    914             if { [info exists _obj2ovride($dataobj-raise)] } {
    915                 SendCmd "volume state 1 $tag"
    916             }
    917         }
    918     }
    919 
    920     # Turn off cutplanes for all volumes
    921     foreach axis {x y z} {
    922         SendCmd "cutplane state 0 $axis"
    923     }
    924 
    925     InitSettings -outlinevisible -cutplanesvisible \
    926         -xcutplanevisible -ycutplanevisible -zcutplanevisible \
    927         -xcutplaneposition -ycutplaneposition -zcutplaneposition
    928 
     976                set _recvdDatasets($tag) 1
     977                set _serverDatasets($tag) 0
     978            }
     979            NameTransferFunction $dataobj $cname
     980        }
     981    }
     982    set _first [lindex [get] 0]
     983    # Outline seems to need to be reset every update.
     984    InitSettings -outlinevisible ;#-cutplanesvisible
    929985    if { $_reset } {
    930         InitSettings -opacity -light2side -isosurfaceshading \
    931             -ambient -diffuse -specularlevel -specularexponent \
    932             -current
    933 
    934986        #
    935987        # Reset the camera and other view parameters
    936988        #
    937         if {"" != $_first} {
    938             set axis [$_first hints updir]
    939             if { "" != $axis } {
    940                 SendCmd "up $axis"
    941             }
    942             set location [$_first hints camera]
    943             if { $location != "" } {
    944                 array set _view $location
    945             }
    946         }
    947989        set _settings(-qw)    $_view(-qw)
    948990        set _settings(-qx)    $_view(-qx)
     
    9591001        PanCamera
    9601002        SendCmd "camera zoom $_view(-zoom)"
     1003
     1004        # Turn off cutplanes for all volumes
     1005        foreach axis {x y z} {
     1006            SendCmd "cutplane state 0 $axis"
     1007        }
     1008
     1009        InitSettings -opacity -light2side -isosurfaceshading \
     1010            -light \
     1011            -xcutplanevisible -ycutplanevisible -zcutplanevisible
     1012
     1013        if {"" != $_first} {
     1014            set axis [$_first hints updir]
     1015            if { "" != $axis } {
     1016                SendCmd "up $axis"
     1017            }
     1018            set location [$_first hints camera]
     1019            if { $location != "" } {
     1020                array set _view $location
     1021            }
     1022        }
    9611023        set _reset 0
    9621024    }
    9631025
     1026    # nothing to send -- activate the proper ivol
     1027    SendCmd "volume state 0"
    9641028    if {"" != $_first} {
    965         # Make sure we display the proper transfer function in the legend.
    966         updateTransferFunctions
    967     }
    968 
     1029        set datasets [array names _serverDatasets $_first-*]
     1030        if { $datasets != "" } {
     1031            SendCmd "volume state 1 $datasets"
     1032        }
     1033        # If the first volume already exists on the server, then make sure
     1034        # we display the proper transfer function in the legend.
     1035        set cname [lindex [$_first components] 0]
     1036        if { [info exists _serverDatasets($_first-$cname)] } {
     1037            updateTransferFunctions
     1038        }
     1039    }
    9691040    # Actually write the commands to the server socket.  If it fails, we don't
    9701041    # care.  We're finished here.
     
    9881059    foreach cname [$_first components] {
    9891060        set tag $_first-$cname
    990         if { [info exists _datasets($tag)] && $_datasets($tag) } {
     1061        if { [info exists _serverDatasets($tag)] && $_serverDatasets($tag) } {
    9911062            array set style {
    9921063                -cutplanes 1
     
    11821253    }
    11831254    switch -- $what {
    1184         "-ambient" {
    1185             # Other parts of the code use the ambient setting to
    1186             # tell if the component settings have been initialized
    1187             if { ![info exists _settings($_current${what})] } {
    1188                 InitComponentSettings $_current
    1189             }
    1190             set _settings($_current${what}) $_settings($what)
    1191             set val $_settings($what)
    1192             set val [expr {0.01*$val}]
    1193             foreach tag [GetDatasetsWithComponent $_current] {
    1194                 SendCmd "volume shading ambient $val $tag"
    1195             }
    1196         }
    11971255        "-axesvisible" {
    11981256            SendCmd "axis visible $_settings($what)"
     
    12071265            configure -plotbackground $bgcolor \
    12081266                -plotforeground $fgcolors($bgcolor)
    1209             DrawLegend $_current
     1267            #DrawLegend $_current
    12101268        }
    12111269        "-colormap" {
    12121270            set color [$itk_component(colormap) value]
    12131271            set _settings($what) $color
    1214             set _settings($_current${what}) $color
    1215             ResetColormap $_current $color
    1216         }
    1217         "-current" {
    1218             set cname [$itk_component(volcomponents) value]
    1219             SwitchComponent $cname
     1272            # Only set the colormap on the first volume. Ignore the others.
     1273            #ResetColormap $color
    12201274        }
    12211275        "-cutplanesvisible" {
     
    12261280            SendCmd "cutplane visible $bool $tag"
    12271281        }
    1228         "-diffuse" {
    1229             set _settings($_current${what}) $_settings($what)
    1230             set val $_settings($what)
    1231             set val [expr {0.01*$val}]
    1232             foreach tag [GetDatasetsWithComponent $_current] {
    1233                 SendCmd "volume shading diffuse $val $tag"
    1234             }
    1235         }
    12361282        "-gridvisible" {
    12371283            SendCmd "grid visible $_settings($what)"
     
    12391285        "-isosurfaceshading" {
    12401286            set val $_settings($what)
    1241             foreach tag [GetDatasetsWithComponent $_current] {
    1242                 SendCmd "volume shading isosurface $val $tag"
    1243             }
     1287            SendCmd "volume shading isosurface $val"
    12441288        }
    12451289        "-legendvisible" {
     
    12531297            }
    12541298        }
     1299        "-light" {
     1300            set val $_settings($what)
     1301            set diffuse [expr {0.01*$val}]
     1302            set ambient [expr {1.0-$diffuse}]
     1303            set specularLevel 0.3
     1304            set specularExp 90.0
     1305            SendCmd "volume shading ambient $ambient"
     1306            SendCmd "volume shading diffuse $diffuse"
     1307            SendCmd "volume shading specularLevel $specularLevel"
     1308            SendCmd "volume shading specularExp $specularExp"
     1309        }
    12551310        "-light2side" {
    1256             set _settings($_current${what}) $_settings($what)
    12571311            set val $_settings($what)
    1258             foreach tag [GetDatasetsWithComponent $_current] {
    1259                 SendCmd "volume shading light2side $val $tag"
    1260             }
     1312            SendCmd "volume shading light2side $val"
    12611313        }
    12621314        "-opacity" {
    1263             set _settings($_current${what}) $_settings($what)
    12641315            set val $_settings($what)
    12651316            set sval [expr { 0.01 * double($val) }]
    1266             foreach tag [GetDatasetsWithComponent $_current] {
    1267                 SendCmd "volume shading opacity $sval $tag"
    1268             }
    1269         }
    1270         "-outlinecolor" {
    1271             set rgb [Color2RGB $_settings($what)]
    1272             SendCmd "volume outline color $rgb"
     1317            SendCmd "volume shading opacity $sval"
    12731318        }
    12741319        "-outlinevisible" {
    12751320            SendCmd "volume outline state $_settings($what)"
    12761321        }
    1277         "-specularexponent" {
    1278             set _settings($_current${what}) $_settings($what)
    1279             set val $_settings($what)
    1280             foreach tag [GetDatasetsWithComponent $_current] {
    1281                 SendCmd "volume shading specularExp $val $tag"
    1282             }
    1283         }
    1284         "-specularlevel" {
    1285             set _settings($_current${what}) $_settings($what)
    1286             set val $_settings($what)
    1287             set val [expr {0.01*$val}]
    1288             foreach tag [GetDatasetsWithComponent $_current] {
    1289                 SendCmd "volume shading specularLevel $val $tag"
    1290             }
    1291         }
    12921322        "-thickness" {
    1293             set val $_settings($what)
    1294             set _settings($_current${what}) $val
    1295             updateTransferFunctions
     1323            if { [array names _activeTfs] > 0 } {
     1324                set val $_settings($what)
     1325                # Scale values between 0.00001 and 0.01000
     1326                set sval [expr {0.0001*double($val)}]
     1327                foreach tf [array names _activeTfs] {
     1328                    set _settings($tf${what}) $sval
     1329                    set _activeTfs($tf) 0
     1330                }
     1331                updateTransferFunctions
     1332            }
    12961333        }
    12971334        "-volume" {
    1298             # This is the global volume visibility control.  It controls the
    1299             # visibility of all the volumes.  Whenever it's changed, you have
    1300             # to synchronize each of the local controls (see below) with this.
    1301             set datasets [CurrentDatasets]
    1302             set bool $_settings($what)
    1303             SendCmd "volume data state $bool $datasets"
    1304             foreach cname $_componentsList {
    1305                 set _settings($cname-volumevisible) $bool
    1306             }
    1307             set _settings(-volumevisible) $bool
    1308         }
    1309         "-volumevisible" {
    1310             # This is the component specific control.  It changes the
    1311             # visibility of only the current component.
    1312             set _settings($_current${what}) $_settings($what)
    1313             foreach tag [GetDatasetsWithComponent $_current] {
    1314                 SendCmd "volume data state $_settings($what) $tag"
    1315             }
     1335            set datasets [CurrentDatasets -cutplanes]
     1336            SendCmd "volume data state $_settings($what) $datasets"
    13161337        }
    13171338        "-xcutplaneposition" - "-ycutplaneposition" - "-zcutplaneposition" {
     
    13561377    set w [expr {$_width-20}]
    13571378    set h [expr {[winfo height $itk_component(legend)]-20-$lineht}]
    1358     if {$w > 0 && $h > 0 && $_first != "" } {
    1359         if { [info exists _cname2transferFunction($_current)] } {
    1360             SendCmd "legend $_current $w $h"
     1379    if {$w > 0 && $h > 0 && [array names _activeTfs] > 0 && $_first != "" } {
     1380        set tag [lindex [CurrentDatasets] 0]
     1381        if { [info exists _dataset2style($tag)] } {
     1382            SendCmd "legend $_dataset2style($tag) $w $h"
    13611383        }
    13621384    }
     
    13721394# server parses the 3D data and sends back the limits via ReceiveData.]
    13731395#
     1396#       FIXME: The current way we generate transfer-function names completely
     1397#              ignores the -markers option.  The problem is that we are forced
     1398#              to compute the name from an increasing complex set of values:
     1399#              color, levels, markers.
     1400#
    13741401itcl::body Rappture::NanovisViewer::NameTransferFunction { dataobj cname } {
    13751402    array set style {
    13761403        -color BCGYR
    13771404        -levels 6
    1378         -markers ""
    13791405    }
    13801406    set tag $dataobj-$cname
    13811407    array set style [lindex [$dataobj components -style $cname] 0]
    1382     if { ![info exists _cname2transferFunction($cname)] } {
    1383         # Get the colormap right now, since it doesn't change with marker
    1384         # changes.
    1385         set cmap [ColorsToColormap $style(-color)]
    1386         set amap [list 0.0 0.0 1.0 1.0]
    1387         set _cname2transferFunction($cname) [list $cmap $amap]
    1388         SendCmd [list transfunc define $cname $cmap $amap]
    1389     }
    1390     SendCmd "volume shading transfunc $cname $tag"
    1391     if { ![info exists _transferFunctionEditors($cname)] } {
    1392         set _transferFunctionEditors($cname) \
    1393             [Rappture::TransferFunctionEditor ::\#auto $itk_component(legend) \
    1394                  $cname \
    1395                  -command [itcl::code $this updateTransferFunctions]]
    1396     }
    1397     return $cname
     1408    set tf "$style(-color):$style(-levels)"
     1409    set _dataset2style($tag) $tf
     1410    lappend _style2datasets($tf) $tag
     1411    return $tf
    13981412}
    13991413
     
    14071421# the alpha map of the transfer function.
    14081422#
    1409 itcl::body Rappture::NanovisViewer::ComputeTransferFunction { cname } {
    1410     foreach {cmap amap} $_cname2transferFunction($cname) break
     1423itcl::body Rappture::NanovisViewer::ComputeTransferFunction { tf } {
     1424    array set style {
     1425        -color BCGYR
     1426        -levels 6
     1427    }
     1428
     1429    foreach {dataobj cname} [split [lindex $_style2datasets($tf) 0] -] break
     1430    array set style [lindex [$dataobj components -style $cname] 0]
    14111431
    14121432    # We have to parse the style attributes for a volume using this
     
    14161436    # of the volumes (the first in the list) using the transfer-function as a
    14171437    # reference.
    1418     if { ![info exists _parsedFunction($cname)] } {
    1419         array set style {
    1420             -color BCGYR
    1421             -levels 6
    1422             -markers ""
    1423         }
    1424         # Accumulate the style from all the datasets using it.
    1425         foreach tag [GetDatasetsWithComponent $cname] {
    1426             foreach {dataobj cname} [split [lindex $tag 0] -] break
    1427             array set style [lindex [$dataobj components -style $cname] 0]
    1428         }
    1429         eval $_transferFunctionEditors($cname) limits $_limits($cname)
     1438    #
     1439    # FIXME: The current way we generate transfer-function names completely
     1440    #        ignores the -markers option.  The problem is that we are forced
     1441    #        to compute the name from an increasing complex set of values:
     1442    #        color, levels, markers.
     1443    if { ![info exists _isomarkers($tf)] } {
    14301444        # Have to defer creation of isomarkers until we have data limits
    14311445        if { [info exists style(-markers)] &&
    14321446             [llength $style(-markers)] > 0 } {
    1433             ParseMarkersOption $cname $style(-markers)
     1447            ParseMarkersOption $tf $style(-markers)
    14341448        } else {
    1435             ParseLevelsOption $cname $style(-levels)
    1436         }
    1437 
    1438     }
    1439     set amap [ComputeAlphamap $cname]
    1440     set _cname2transferFunction($cname) [list $cmap $amap]
    1441     SendCmd [list transfunc define $cname $cmap $amap]
    1442 }
    1443 
    1444 itcl::body Rappture::NanovisViewer::AddNewMarker { x y } {
    1445     if { ![info exists _transferFunctionEditors($_current)] } {
    1446         continue
    1447     }
    1448     # Add a new marker to the current transfer function
    1449     $_transferFunctionEditors($_current) newMarker $x $y normal
    1450     $itk_component(legend) itemconfigure labels -fill $itk_option(-plotforeground)
    1451 }
    1452 
    1453 itcl::body Rappture::NanovisViewer::RemoveMarker { x y } {
    1454     if { ![info exists _transferFunctionEditors($_current)] } {
    1455         continue
    1456     }
    1457     # Add a new marker to the current transfer function
    1458     $_transferFunctionEditors($_current) deleteMarker $x $y
     1449            ParseLevelsOption $tf $style(-levels)
     1450        }
     1451    }
     1452    set cmap [ColorsToColormap $style(-color)]
     1453
     1454    # Transfer function should be normalized with [0,1] range
     1455    # The volume shading opacity setting is used to scale opacity
     1456    # in the volume shader.
     1457    set max 1.0
     1458
     1459    set isovalues {}
     1460    foreach m $_isomarkers($tf) {
     1461        lappend isovalues [$m relval]
     1462    }
     1463    # Sort the isovalues
     1464    set isovalues [lsort -real $isovalues]
     1465
     1466    if { ![info exists _settings($tf-thickness)]} {
     1467        set _settings($tf-thickness) 0.005
     1468    }
     1469    set delta $_settings($tf-thickness)
     1470
     1471    set first [lindex $isovalues 0]
     1472    set last [lindex $isovalues end]
     1473    set amap ""
     1474    if { $first == "" || $first != 0.0 } {
     1475        lappend amap 0.0 0.0
     1476    }
     1477    foreach x $isovalues {
     1478        set x1 [expr {$x-$delta-0.00001}]
     1479        set x2 [expr {$x-$delta}]
     1480        set x3 [expr {$x+$delta}]
     1481        set x4 [expr {$x+$delta+0.00001}]
     1482        if { $x1 < 0.0 } {
     1483            set x1 0.0
     1484        } elseif { $x1 > 1.0 } {
     1485            set x1 1.0
     1486        }
     1487        if { $x2 < 0.0 } {
     1488            set x2 0.0
     1489        } elseif { $x2 > 1.0 } {
     1490            set x2 1.0
     1491        }
     1492        if { $x3 < 0.0 } {
     1493            set x3 0.0
     1494        } elseif { $x3 > 1.0 } {
     1495            set x3 1.0
     1496        }
     1497        if { $x4 < 0.0 } {
     1498            set x4 0.0
     1499        } elseif { $x4 > 1.0 } {
     1500            set x4 1.0
     1501        }
     1502        # add spikes in the middle
     1503        lappend amap $x1 0.0
     1504        lappend amap $x2 $max
     1505        lappend amap $x3 $max
     1506        lappend amap $x4 0.0
     1507    }
     1508    if { $last == "" || $last != 1.0 } {
     1509        lappend amap 1.0 0.0
     1510    }
     1511    SendCmd "transfunc define $tf { $cmap } { $amap }"
    14591512}
    14601513
     
    15081561# marker is a relative value from 0.0 to 1.0.
    15091562#
    1510 itcl::body Rappture::NanovisViewer::ParseLevelsOption { cname levels } {
     1563itcl::body Rappture::NanovisViewer::ParseLevelsOption { tf levels } {
    15111564    set c $itk_component(legend)
    1512     set list {}
    15131565    regsub -all "," $levels " " levels
    15141566    if {[string is int $levels]} {
    15151567        for {set i 1} { $i <= $levels } {incr i} {
    1516             lappend list [expr {double($i)/($levels+1)}]
     1568            set x [expr {double($i)/($levels+1)}]
     1569            set m [Rappture::IsoMarker \#auto $c $this $tf]
     1570            $itk_component(legend) itemconfigure labels -fill $itk_option(-plotforeground)
     1571            $m relval $x
     1572            lappend _isomarkers($tf) $m
    15171573        }
    15181574    } else {
    15191575        foreach x $levels {
    1520             lappend list $x
    1521         }
    1522     }
    1523     set _parsedFunction($cname) 1
    1524     $_transferFunctionEditors($cname) addMarkers $list
    1525     $itk_component(legend) itemconfigure labels -fill $itk_option(-plotforeground)
     1576            set m [Rappture::IsoMarker \#auto $c $this $tf]
     1577            $itk_component(legend) itemconfigure labels -fill $itk_option(-plotforeground)
     1578            $m relval $x
     1579            lappend _isomarkers($tf) $m
     1580        }
     1581    }
    15261582}
    15271583
     
    15381594#       not be seen.
    15391595#
    1540 itcl::body Rappture::NanovisViewer::ParseMarkersOption { cname markers } {
     1596itcl::body Rappture::NanovisViewer::ParseMarkersOption { tf markers } {
    15411597    set c $itk_component(legend)
    1542     set list {}
    1543     foreach { min max } $_limits($cname) break
    15441598    regsub -all "," $markers " " markers
    15451599    foreach marker $markers {
    15461600        set n [scan $marker "%g%s" value suffix]
    15471601        if { $n == 2 && $suffix == "%" } {
    1548             # $n% : Set relative value (0..1).
    1549             lappend list [expr {$value * 0.01}]
     1602            # ${n}% : Set relative value.
     1603            set value [expr {$value * 0.01}]
     1604            set m [Rappture::IsoMarker \#auto $c $this $tf]
     1605            $itk_component(legend) itemconfigure labels -fill $itk_option(-plotforeground)
     1606            $m relval $value
     1607            lappend _isomarkers($tf) $m
    15501608        } else {
    1551             # $n : absolute value, compute relative
    1552             lappend list [expr {(double($value)-$min)/($max-$min)}]
    1553         }
    1554     }
    1555     set _parsedFunction($cname) 1
    1556     $_transferFunctionEditors($cname) addMarkers $list
    1557     $itk_component(legend) itemconfigure labels -fill $itk_option(-plotforeground)
     1609            # ${n} : Set absolute value.
     1610            set m [Rappture::IsoMarker \#auto $c $this $tf]
     1611            $itk_component(legend) itemconfigure labels -fill $itk_option(-plotforeground)
     1612            $m absval $value
     1613            lappend _isomarkers($tf) $m
     1614        }
     1615    }
    15581616}
    15591617
    15601618itcl::body Rappture::NanovisViewer::updateTransferFunctions {} {
    15611619    $_dispatcher event -idle !send_transfunc
     1620}
     1621
     1622itcl::body Rappture::NanovisViewer::AddIsoMarker { x y } {
     1623    if { $_first == "" } {
     1624        error "active transfer function isn't set"
     1625    }
     1626    set tag [lindex [CurrentDatasets] 0]
     1627    set tf $_dataset2style($tag)
     1628    set c $itk_component(legend)
     1629    set m [Rappture::IsoMarker \#auto $c $this $tf]
     1630    $itk_component(legend) itemconfigure labels -fill $itk_option(-plotforeground)
     1631    set w [winfo width $c]
     1632    $m relval [expr {double($x-10)/($w-20)}]
     1633    lappend _isomarkers($tf) $m
     1634    updateTransferFunctions
     1635    return 1
     1636}
     1637
     1638itcl::body Rappture::NanovisViewer::removeDuplicateMarker { marker x } {
     1639    set tf [$marker transferfunc]
     1640    set bool 0
     1641    if { [info exists _isomarkers($tf)] } {
     1642        set list {}
     1643        set marker [namespace tail $marker]
     1644        foreach m $_isomarkers($tf) {
     1645            set sx [$m screenpos]
     1646            if { $m != $marker } {
     1647                if { $x >= ($sx-3) && $x <= ($sx+3) } {
     1648                    $marker relval [$m relval]
     1649                    itcl::delete object $m
     1650                    bell
     1651                    set bool 1
     1652                    continue
     1653                }
     1654            }
     1655            lappend list $m
     1656        }
     1657        set _isomarkers($tf) $list
     1658        updateTransferFunctions
     1659    }
     1660    return $bool
     1661}
     1662
     1663itcl::body Rappture::NanovisViewer::overMarker { marker x } {
     1664    set tf [$marker transferfunc]
     1665    if { [info exists _isomarkers($tf)] } {
     1666        set marker [namespace tail $marker]
     1667        foreach m $_isomarkers($tf) {
     1668            set sx [$m screenpos]
     1669            if { $m != $marker } {
     1670                set bool [expr { $x >= ($sx-3) && $x <= ($sx+3) }]
     1671                $m activate $bool
     1672            }
     1673        }
     1674    }
     1675    return ""
     1676}
     1677
     1678itcl::body Rappture::NanovisViewer::limits { tf } {
     1679    set _limits(min) 0.0
     1680    set _limits(max) 1.0
     1681    if { ![info exists _style2datasets($tf)] } {
     1682        return [array get _limits]
     1683    }
     1684    set min ""; set max ""
     1685    foreach tag $_style2datasets($tf) {
     1686        if { ![info exists _serverDatasets($tag)] } {
     1687            continue
     1688        }
     1689        if { ![info exists _limits($tag-min)] } {
     1690            continue
     1691        }
     1692        if { $min == "" || $min > $_limits($tag-min) } {
     1693            set min $_limits($tag-min)
     1694        }
     1695        if { $max == "" || $max < $_limits($tag-max) } {
     1696            set max $_limits($tag-max)
     1697        }
     1698    }
     1699    if { $min != "" } {
     1700        set _limits(min) $min
     1701    }
     1702    if { $max != "" } {
     1703        set _limits(max) $max
     1704    }
     1705    return [array get _limits]
    15621706}
    15631707
     
    16361780    #set bfg [option get $itk_component(hull) boldFont Font]
    16371781
    1638     label $inner.lighting_l \
    1639         -text "Lighting / Material Properties" \
    1640         -font "Arial 9 bold"
     1782    checkbutton $inner.vol -text "Show volume" -font $fg \
     1783        -variable [itcl::scope _settings(-volume)] \
     1784        -command [itcl::code $this AdjustSetting -volume]
     1785    label $inner.shading -text "Shading:" -font $fg
    16411786
    16421787    checkbutton $inner.isosurface -text "Isosurface shading" -font $fg \
     
    16481793        -command [itcl::code $this AdjustSetting -light2side]
    16491794
    1650     checkbutton $inner.visibility -text "Visible" -font $fg \
    1651         -variable [itcl::scope _settings(-volumevisible)] \
    1652         -command [itcl::code $this AdjustSetting -volumevisible]
    1653 
    1654     label $inner.ambient_l -text "Ambient" -font $fg
    1655     ::scale $inner.ambient -from 0 -to 100 -orient horizontal \
    1656         -variable [itcl::scope _settings(-ambient)] \
    1657         -showvalue off -command [itcl::code $this AdjustSetting -ambient] \
    1658         -troughcolor grey92
    1659 
    1660     label $inner.diffuse_l -text "Diffuse" -font $fg
    1661     ::scale $inner.diffuse -from 0 -to 100 -orient horizontal \
    1662         -variable [itcl::scope _settings(-diffuse)] \
    1663         -showvalue off -command [itcl::code $this AdjustSetting -diffuse] \
    1664         -troughcolor grey92
    1665 
    1666     label $inner.specularLevel_l -text "Specular" -font $fg
    1667     ::scale $inner.specularLevel -from 0 -to 100 -orient horizontal \
    1668         -variable [itcl::scope _settings(-specularlevel)] \
    1669         -showvalue off \
    1670         -command [itcl::code $this AdjustSetting -specularlevel] \
    1671         -troughcolor grey92
    1672 
    1673     label $inner.specularExponent_l -text "Shininess" -font $fg
    1674     ::scale $inner.specularExponent -from 10 -to 128 -orient horizontal \
    1675         -variable [itcl::scope _settings(-specularexponent)] \
    1676         -showvalue off \
    1677         -command [itcl::code $this AdjustSetting -specularexponent] \
    1678         -troughcolor grey92
     1795    label $inner.dim -text "Glow" -font $fg
     1796    ::scale $inner.light -from 0 -to 100 -orient horizontal \
     1797        -variable [itcl::scope _settings(-light)] \
     1798        -width 10 \
     1799        -showvalue off -command [itcl::code $this AdjustSetting -light]
     1800    label $inner.bright -text "Surface" -font $fg
    16791801
    16801802    # Opacity
    1681     label $inner.opacity_l -text "Opacity" -font $fg
     1803    label $inner.clear -text "Clear" -font $fg
    16821804    ::scale $inner.opacity -from 0 -to 100 -orient horizontal \
    16831805        -variable [itcl::scope _settings(-opacity)] \
    1684         -showvalue off -command [itcl::code $this AdjustSetting -opacity] \
    1685         -troughcolor grey92
    1686 
    1687     label $inner.transferfunction_l \
    1688         -text "Transfer Function" -font "Arial 9 bold"
     1806        -width 10 \
     1807        -showvalue off -command [itcl::code $this AdjustSetting -opacity]
     1808    label $inner.opaque -text "Opaque" -font $fg
    16891809
    16901810    # Tooth thickness
     
    16921812    ::scale $inner.thickness -from 0 -to 1000 -orient horizontal \
    16931813        -variable [itcl::scope _settings(-thickness)] \
    1694         -showvalue off -command [itcl::code $this AdjustSetting -thickness] \
    1695         -troughcolor grey92
     1814        -width 10 \
     1815        -showvalue off -command [itcl::code $this AdjustSetting -thickness]
    16961816    label $inner.thick -text "Thick" -font $fg
    16971817
    16981818    # Colormap
    1699     label $inner.colormap_l -text "Colormap" -font $fg
     1819    label $inner.colormap_l -text "Colormap" -font "Arial 9"
    17001820    itk_component add colormap {
    17011821        Rappture::Combobox $inner.colormap -width 10 -editable no
    17021822    }
    17031823
    1704     $inner.colormap choices insert end [GetColormapList -includeDefault -includeNone]
     1824    $inner.colormap choices insert end [GetColormapList -includeNone]
     1825    $itk_component(colormap) value "BCGYR"
    17051826    bind $inner.colormap <<Value>> \
    17061827        [itcl::code $this AdjustSetting -colormap]
    1707     $itk_component(colormap) value "default"
    1708     set _settings(-colormap) "default"
    1709 
    1710     # Component
    1711     label $inner.volcomponents_l -text "Component" -font $fg
    1712     itk_component add volcomponents {
    1713         Rappture::Combobox $inner.volcomponents -editable no
    1714     }
    1715     bind $inner.volcomponents <<Value>> \
    1716         [itcl::code $this AdjustSetting -current]
    17171828
    17181829    blt::table $inner \
    1719         0,0 $inner.volcomponents_l -anchor e -cspan 2 \
    1720         0,2 $inner.volcomponents -cspan 3 -fill x \
    1721         1,1 $inner.lighting_l -anchor w -cspan 4 \
    1722         2,1 $inner.ambient_l -anchor e \
    1723         2,2 $inner.ambient -cspan 3 -fill x \
    1724         3,1 $inner.diffuse_l -anchor e \
    1725         3,2 $inner.diffuse -cspan 3 -fill x \
    1726         4,1 $inner.specularLevel_l -anchor e \
    1727         4,2 $inner.specularLevel -cspan 3 -fill x \
    1728         5,1 $inner.specularExponent_l -anchor e \
    1729         5,2 $inner.specularExponent -cspan 3 -fill x \
    1730         6,1 $inner.light2side -cspan 3 -anchor w \
    1731         7,1 $inner.visibility -cspan 3 -anchor w \
    1732         8,1 $inner.transferfunction_l -anchor w -cspan 4 \
    1733         9,1 $inner.opacity_l -anchor e \
    1734         9,2 $inner.opacity -cspan 3 -fill x \
    1735         10,1 $inner.colormap_l -anchor e \
    1736         10,2 $inner.colormap -padx 2 -cspan 3 -fill x \
    1737         11,1 $inner.thin -anchor e \
    1738         11,2 $inner.thickness -cspan 2 -fill x \
    1739         11,4 $inner.thick -anchor w
    1740 
    1741     blt::table configure $inner c* r* -resize none
    1742     blt::table configure $inner r* -pady { 2 0 }
    1743     blt::table configure $inner c2 c3 r12 -resize expand
    1744     blt::table configure $inner c0 -width .1i
     1830        0,0 $inner.vol -cspan 4 -anchor w -pady 2 \
     1831        1,0 $inner.shading -cspan 4 -anchor w -pady {10 2} \
     1832        2,0 $inner.light2side -cspan 4 -anchor w -pady 2 \
     1833        3,0 $inner.dim -anchor e -pady 2 \
     1834        3,1 $inner.light -cspan 2 -pady 2 -fill x \
     1835        3,3 $inner.bright -anchor w -pady 2 \
     1836        4,0 $inner.clear -anchor e -pady 2 \
     1837        4,1 $inner.opacity -cspan 2 -pady 2 -fill x \
     1838        4,3 $inner.opaque -anchor w -pady 2 \
     1839        5,0 $inner.thin -anchor e -pady 2 \
     1840        5,1 $inner.thickness -cspan 2 -pady 2 -fill x\
     1841        5,3 $inner.thick -anchor w -pady 2
     1842
     1843    blt::table configure $inner c0 c1 c3 r* -resize none
     1844    blt::table configure $inner r6 -resize expand
    17451845}
    17461846
     
    17671867    Rappture::Tooltip::for $itk_component(xCutButton) \
    17681868        "Toggle the X cut plane on/off"
    1769     $itk_component(xCutButton) select
     1869    #$itk_component(xCutButton) select
    17701870
    17711871    itk_component add xCutScale {
     
    17951895    Rappture::Tooltip::for $itk_component(yCutButton) \
    17961896        "Toggle the Y cut plane on/off"
    1797     $itk_component(yCutButton) select
     1897    #$itk_component(yCutButton) select
    17981898
    17991899    itk_component add yCutScale {
     
    18231923    Rappture::Tooltip::for $itk_component(zCutButton) \
    18241924        "Toggle the Z cut plane on/off"
    1825     $itk_component(zCutButton) select
     1925    #$itk_component(zCutButton) select
    18261926
    18271927    itk_component add zCutScale {
     
    18411941
    18421942    blt::table $inner \
    1843         0,1 $inner.visible -anchor w -pady 2 -cspan 4 \
    1844         1,1 $itk_component(xCutScale) \
    1845         1,2 $itk_component(yCutScale) \
    1846         1,3 $itk_component(zCutScale) \
    1847         2,1 $itk_component(xCutButton) \
    1848         2,2 $itk_component(yCutButton) \
    1849         2,3 $itk_component(zCutButton)
     1943        0,1 $itk_component(xCutScale) \
     1944        0,2 $itk_component(yCutScale) \
     1945        0,3 $itk_component(zCutScale) \
     1946        1,1 $itk_component(xCutButton) \
     1947        1,2 $itk_component(yCutButton) \
     1948        1,3 $itk_component(zCutButton)
     1949
     1950    #    0,1 $inner.visible -anchor w -pady 2 -cspan 4 \
    18501951
    18511952    blt::table configure $inner r0 r1 r2 c* -resize none
     
    19982099    # VTK file.  To download all components/results, we would need
    19992100    # to put them in an archive (e.g. zip or tar file)
    2000     if { $_first != "" && $_current != "" } {
    2001         set bytes [$_first vtkdata $_current]
     2101    if { $_first != ""} {
     2102        set cname [lindex [$_first components] 0]
     2103        set bytes [$_first vtkdata $cname]
    20022104        return [list .vtk $bytes]
    20032105    }
     
    20832185    set _settings(-zoom) $_view(-zoom)
    20842186}
    2085 
    2086 #
    2087 # InitComponentSettings --
    2088 #
    2089 # Initializes the volume settings for a specific component. This should
    2090 # match what's used as global settings above. This is called the first
    2091 # time we try to switch to a given component in SwitchComponent below.
    2092 #
    2093 itcl::body Rappture::NanovisViewer::InitComponentSettings { cname } {
    2094     foreach {key value} {
    2095         -ambient           60
    2096         -colormap          "default"
    2097         -diffuse           40
    2098         -light2side        1
    2099         -opacity           50
    2100         -specularexponent  90
    2101         -specularlevel     30
    2102         -thickness         350
    2103         -volumevisible     1
    2104     } {
    2105         set _settings($cname${key}) $value
    2106     }
    2107 }
    2108 
    2109 #
    2110 # SwitchComponent --
    2111 #
    2112 # This is called when the current component is changed by the dropdown
    2113 # menu in the volume tab.  It synchronizes the global volume settings
    2114 # with the settings of the new current component.
    2115 #
    2116 itcl::body Rappture::NanovisViewer::SwitchComponent { cname } {
    2117     if { ![info exists _settings($cname-ambient)] } {
    2118         InitComponentSettings $cname
    2119     }
    2120     # _settings variables change widgets, except for colormap
    2121     set _settings(-ambient)          $_settings($cname-ambient)
    2122     set _settings(-colormap)         $_settings($cname-colormap)
    2123     set _settings(-diffuse)          $_settings($cname-diffuse)
    2124     set _settings(-light2side)       $_settings($cname-light2side)
    2125     set _settings(-opacity)          $_settings($cname-opacity)
    2126     set _settings(-specularexponent) $_settings($cname-specularexponent)
    2127     set _settings(-specularlevel)    $_settings($cname-specularlevel)
    2128     set _settings(-thickness)        $_settings($cname-thickness)
    2129     set _settings(-volumevisible)    $_settings($cname-volumevisible)
    2130     $itk_component(colormap) value   $_settings($cname-colormap)
    2131     set _current $cname;                # Reset the current component
    2132 }
    2133 
    2134 #
    2135 # BuildVolumeComponents --
    2136 #
    2137 # This is called from the "scale" method which is called when a new
    2138 # dataset is added or deleted.  It repopulates the dropdown menu of
    2139 # volume component names.  It sets the current component to the first
    2140 # component in the list (of components found).  Finally, if there is
    2141 # only one component, don't display the label or the combobox in the
    2142 # volume settings tab.
    2143 #
    2144 itcl::body Rappture::NanovisViewer::BuildVolumeComponents {} {
    2145     $itk_component(volcomponents) choices delete 0 end
    2146     foreach name $_componentsList {
    2147         $itk_component(volcomponents) choices insert end $name $name
    2148     }
    2149     set _current [lindex $_componentsList 0]
    2150     $itk_component(volcomponents) value $_current
    2151     set parent [winfo parent $itk_component(volcomponents)]
    2152     if { [llength $_componentsList] <= 1 } {
    2153         # Unpack the components label and dropdown if there's only one
    2154         # component.
    2155         blt::table forget $parent.volcomponents_l $parent.volcomponents
    2156     } else {
    2157         # Pack the components label and dropdown into the table there's
    2158         # more than one component to select.
    2159         blt::table $parent \
    2160             0,0 $parent.volcomponents_l -anchor e -cspan 2 \
    2161             0,2 $parent.volcomponents -cspan 3 -fill x
    2162     }
    2163 }
    2164 
    2165 #
    2166 # GetDatasetsWithComponents --
    2167 #
    2168 # Returns a list of all the datasets (known by the combination of their
    2169 # data object and component name) that match the given component name.
    2170 # For example, this is used where we want to change the settings of
    2171 # volumes that have the current component.
    2172 #
    2173 itcl::body Rappture::NanovisViewer::GetDatasetsWithComponent { cname } {
    2174     if { ![info exists _volcomponents($cname)] } {
    2175         return ""
    2176     }
    2177     set list ""
    2178     foreach tag $_volcomponents($cname) {
    2179         if { ![info exists _datasets($tag)] } {
    2180             continue
    2181         }
    2182         lappend list $tag
    2183     }
    2184     return $list
    2185 }
    2186 
    2187 #
    2188 # HideAllMarkers --
    2189 #
    2190 # Hide all the markers in all the transfer functions.  Can't simply
    2191 # delete and recreate markers from the <style> since the user may have
    2192 # created, deleted, or moved markers.
    2193 #
    2194 itcl::body Rappture::NanovisViewer::HideAllMarkers {} {
    2195     foreach cname [array names _transferFunctionEditors] {
    2196         $_transferFunctionEditors($cname) hideMarkers
    2197     }
    2198 }
    2199 
    2200 itcl::body Rappture::NanovisViewer::GetColormap { cname color } {
    2201     if { $color == "default" } {
    2202         return $_cname2defaultcolormap($cname)
    2203     }
    2204     return [ColorsToColormap $color]
    2205 }
    2206 
    2207 itcl::body Rappture::NanovisViewer::ResetColormap { cname color } {
    2208     # Get the current transfer function
    2209     if { ![info exists _cname2transferFunction($cname)] } {
    2210         return
    2211     }
    2212     foreach { cmap amap } $_cname2transferFunction($cname) break
    2213     set cmap [GetColormap $cname $color]
    2214     set _cname2transferFunction($cname) [list $cmap $amap]
    2215     SendCmd [list transfunc define $cname $cmap $amap]
    2216     EventuallyRedrawLegend
    2217 }
    2218 
    2219 itcl::body Rappture::NanovisViewer::ComputeAlphamap { cname } {
    2220     if { ![info exists _transferFunctionEditors($cname)] } {
    2221         return [list 0.0 0.0 1.0 1.0]
    2222     }
    2223     if { ![info exists _settings($cname-ambient)] } {
    2224         InitComponentSettings $cname
    2225     }
    2226 
    2227     set isovalues [$_transferFunctionEditors($cname) values]
    2228 
    2229     # Transfer function should be normalized with [0,1] range
    2230     # The volume shading opacity setting is used to scale opacity
    2231     # in the volume shader.
    2232     set max 1.0
    2233 
    2234     # Use the component-wise thickness setting from the slider
    2235     # settings widget
    2236     # Scale values between 0.00001 and 0.01000
    2237     set delta [expr {double($_settings($cname-thickness)) * 0.0001}]
    2238 
    2239     set first [lindex $isovalues 0]
    2240     set last [lindex $isovalues end]
    2241     set amap ""
    2242     if { $first == "" || $first != 0.0 } {
    2243         lappend amap 0.0 0.0
    2244     }
    2245     foreach x $isovalues {
    2246         set x1 [expr {$x-$delta-0.00001}]
    2247         set x2 [expr {$x-$delta}]
    2248         set x3 [expr {$x+$delta}]
    2249         set x4 [expr {$x+$delta+0.00001}]
    2250         if { $x1 < 0.0 } {
    2251             set x1 0.0
    2252         } elseif { $x1 > 1.0 } {
    2253             set x1 1.0
    2254         }
    2255         if { $x2 < 0.0 } {
    2256             set x2 0.0
    2257         } elseif { $x2 > 1.0 } {
    2258             set x2 1.0
    2259         }
    2260         if { $x3 < 0.0 } {
    2261             set x3 0.0
    2262         } elseif { $x3 > 1.0 } {
    2263             set x3 1.0
    2264         }
    2265         if { $x4 < 0.0 } {
    2266             set x4 0.0
    2267         } elseif { $x4 > 1.0 } {
    2268             set x4 1.0
    2269         }
    2270         # add spikes in the middle
    2271         lappend amap $x1 0.0
    2272         lappend amap $x2 $max
    2273         lappend amap $x3 $max
    2274         lappend amap $x4 0.0
    2275     }
    2276     if { $last == "" || $last != 1.0 } {
    2277         lappend amap 1.0 0.0
    2278     }
    2279     return $amap
    2280 }
    2281 
    2282 itcl::body Rappture::NanovisViewer::SetObjectStyle { dataobj cname } {
    2283     array set style {
    2284         -opacity 0.5
    2285     }
    2286     array set style [lindex [$dataobj components -style $cname] 0]
    2287     # Some tools erroneously set -opacity to 1 in style, so
    2288     # override the requested opacity for now
    2289     set style(-opacity) 0.5
    2290     set _settings($cname-opacity) [expr $style(-opacity) * 100.0]
    2291     set tag $dataobj-$cname
    2292     SendCmd "volume shading opacity $style(-opacity) $tag"
    2293     NameTransferFunction $dataobj $cname
    2294 }
  • trunk/gui/scripts/vtkvolumeviewer.tcl

    r6377 r6675  
    6262    }
    6363    public method scale {args}
    64     public method updateTransferFunctions {}
    6564
    6665    # The following methods are only used by this class.
    67     private method AddNewMarker { x y }
    6866    private method AdjustSetting {what {value ""}}
    6967    private method BuildAxisTab {}
    7068    private method BuildCameraTab {}
     69    private method BuildColormap { name colors }
    7170    private method BuildCutplanesTab {}
    7271    private method BuildDownloadPopup { widget command }
    7372    private method BuildViewTab {}
    74     private method BuildVolumeComponents {}
    7573    private method BuildVolumeTab {}
    76     private method ComputeAlphamap { cname }
    77     private method ComputeTransferFunction { cname }
     74    private method ChangeColormap { dataobj comp color }
    7875    private method Connect {}
    7976    private method CurrentDatasets {args}
     
    8784    private method EventuallyRotate { q }
    8885    private method EventuallySetCutplane { axis args }
    89     private method GetColormap { cname color }
    9086    private method GetDatasetsWithComponent { cname }
    9187    private method GetImage { args }
    9288    private method GetVtkData { args }
    93     private method HideAllMarkers {}
    94     private method InitComponentSettings { cname }
    9589    private method InitSettings { args }
    9690    private method IsValidObject { dataobj }
     
    10094    private method Pan {option x y}
    10195    private method PanCamera {}
    102     private method ParseLevelsOption { cname levels }
    103     private method ParseMarkersOption { cname markers }
    10496    private method Pick {x y}
    10597    private method QuaternionToView { q } {
     
    110102    private method ReceiveImage { args }
    111103    private method ReceiveLegend { colormap title min max size }
    112     private method RemoveMarker { x y }
    113104    private method RequestLegend {}
    114     private method ResetColormap { cname color }
    115105    private method Rotate {option x y}
    116     private method SendTransferFunctions {}
     106    private method SetColormap { dataobj comp }
    117107    private method SetCurrentFieldName { dataobj }
    118     private method SetInitialTransferFunction { dataobj cname }
    119108    private method SetLegendTip { x y }
    120109    private method SetObjectStyle { dataobj cname }
    121110    private method SetOrientation { side }
    122111    private method Slice {option args}
    123     private method SwitchComponent { cname }
    124112    private method ViewToQuaternion {} {
    125113        return [list $_view(-qw) $_view(-qx) $_view(-qy) $_view(-qz)]
     
    127115    private method Zoom {option}
    128116
    129     private variable _alphamap
    130117    private variable _arcball ""
    131118    private variable _dlist "";         # list of data objects
     
    141128    private variable _limits;           # Autoscale min/max for all axes
    142129    private variable _view;             # View params for 3D view
    143     private variable _parsedFunction
    144     private variable _transferFunctionEditors
    145130    private variable _settings
     131    private variable _style;            # Array of current component styles.
     132    private variable _initialStyle;     # Array of initial component styles.
    146133
    147134    private variable _start 0
     
    155142
    156143    private variable _first "";         # This is the topmost dataset.
    157     private variable _current "";       # Currently selected component
    158144    private variable _volcomponents;    # Maps component name to list of
    159145                                        # dataobj-component tags
    160146    private variable _componentsList;   # List of components found
    161     private variable _cname2transferFunction
    162     private variable _cname2defaultcolormap
    163147
    164148    private variable _width 0
     
    245229        -axismode               "static"
    246230        -background             black
    247         -color                  "default"
     231        -color                  BCGYR
    248232        -cutplanelighting       1
    249233        -cutplaneopacity        100
    250234        -cutplanesvisible       0
    251235        -legendvisible          1
    252         -volumeambient          40
    253         -volumeblendmode        composite
    254         -volumediffuse          60
    255236        -volumelighting         1
     237        -volumematerial         80
    256238        -volumeopacity          50
    257239        -volumeoutline          0
    258240        -volumequality          80
    259         -volumespecularexponent 90
    260         -volumespecularlevel    30
    261         -volumethickness        350
    262241        -volumevisible          1
    263242        -xcutplaneposition      50
     
    374353    set _image(legend) [image create photo]
    375354    itk_component add legend {
    376         canvas $itk_component(plotarea).legend -height 50 -highlightthickness 0
     355        canvas $itk_component(plotarea).legend -width 50 -highlightthickness 0
    377356    } {
    378357        usual
     
    380359        rename -background -plotbackground plotBackground Background
    381360    }
    382     bind $itk_component(legend) <KeyPress-Delete> \
    383         [itcl::code $this RemoveMarker %x %y]
    384     bind $itk_component(legend) <Enter> \
    385         [list focus $itk_component(legend)]
    386361
    387362    # Hack around the Tk panewindow.  The problem is that the requested
     
    391366    pack forget $itk_component(view)
    392367    blt::table $itk_component(plotarea) \
    393         0,0 $itk_component(view) -fill both -reqwidth $w \
    394         1,0 $itk_component(legend) -fill x
    395     blt::table configure $itk_component(plotarea) r1 -resize none
     368        0,0 $itk_component(view) -fill both -reqwidth $w
     369    blt::table configure $itk_component(plotarea) c1 -resize none
    396370
    397371    # Bindings for rotation via mouse
     
    729703        }
    730704    }
    731     BuildVolumeComponents
    732     updateTransferFunctions
    733705}
    734706
     
    872844    array unset _colormaps
    873845    array unset _dataset2style
    874 
    875     array unset _parsedFunction
    876     array unset _cname2transferFunction
    877846
    878847    set _resizePending 0
     
    10681037    InitSettings -color \
    10691038        -volumevisible \
    1070         -volumeambient -volumediffuse -volumespecularlevel \
    1071         -volumespecularexponent -volumeblendmode -volumethickness \
     1039        -volumematerial \
    10721040        -volumelighting -volumeopacity -volumequality -volumeoutline \
    10731041        -cutplanesvisible \
     
    13491317            set color [$itk_component(colormap) value]
    13501318            set _settings($what) $color
    1351             set _settings($_current${what}) $color
    1352             ResetColormap $_current $color
    1353         }
    1354         "-current" {
    1355             set cname [$itk_component(volcomponents) value]
    1356             SwitchComponent $cname
     1319            foreach dataset [CurrentDatasets -visible $_first] {
     1320                foreach {dataobj comp} [split $dataset -] break
     1321                ChangeColormap $dataobj $comp $color
     1322            }
     1323            EventuallyRequestLegend
    13571324        }
    13581325        "-cutplanelighting" {
     
    14161383        }
    14171384        "-legendvisible" {
    1418             set bool $_settings($what)
    1419             if { $bool } {
    1420                 blt::table $itk_component(plotarea) \
    1421                     1,0 $itk_component(legend) -fill x
    1422             } else {
    1423                 blt::table forget $itk_component(legend)
    1424             }
    1425         }
    1426         "-volumeambient" {
    1427             # Other parts of the code use the -volumeambient setting to
    1428             # tell if the component settings have been initialized
    1429             if { ![info exists _settings($_current${what})] } {
    1430                 InitComponentSettings $_current
    1431             }
     1385            DrawLegend
     1386        }
     1387        "-volumematerial" {
    14321388            set val $_settings($what)
    1433             set _settings($_current${what}) $val
    1434             set ambient [expr {0.01*$val}]
    1435             foreach tag [GetDatasetsWithComponent $_current] {
    1436                 SendCmd "volume shading ambient $ambient $tag"
    1437             }
    1438         }
    1439         "-volumeblendmode" {
    1440             set val [$itk_component(blendmode) value]
    1441             set mode [$itk_component(blendmode) translate $val]
    1442             set _settings($what) $mode
    1443             set _settings($_current${what}) $mode
    1444             foreach tag [GetDatasetsWithComponent $_current] {
    1445                 SendCmd "volume blendmode $mode $tag"
    1446             }
    1447         }
    1448         "-volumediffuse" {
    1449             set val $_settings($what)
    1450             set _settings($_current${what}) $val
    14511389            set diffuse [expr {0.01*$val}]
    1452             foreach tag [GetDatasetsWithComponent $_current] {
     1390            set specular [expr {0.01*$val}]
     1391            #set power [expr {sqrt(160*$val+1.0)}]
     1392            set power [expr {$val+1.0}]
     1393            foreach tag [CurrentDatasets -visible] {
    14531394                SendCmd "volume shading diffuse $diffuse $tag"
     1395                SendCmd "volume shading specular $specular $power $tag"
    14541396            }
    14551397        }
    14561398        "-volumelighting" {
    14571399            set bool $_settings($what)
    1458             set _settings($_current${what}) $bool
    1459             foreach tag [GetDatasetsWithComponent $_current] {
     1400            foreach tag [CurrentDatasets -visible] {
    14601401                SendCmd "volume lighting $bool $tag"
    14611402            }
     
    14631404        "-volumeopacity" {
    14641405            set val $_settings($what)
    1465             set _settings($_current${what}) $val
    14661406            set val [expr {0.01*$val}]
    1467             foreach tag [GetDatasetsWithComponent $_current] {
     1407            foreach tag [CurrentDatasets -visible] {
    14681408                SendCmd "volume opacity $val $tag"
    14691409            }
     
    14721412            set bool $_settings($what)
    14731413            SendCmd "outline visible 0"
    1474             foreach tag [GetDatasetsWithComponent $_current] {
     1414            foreach tag [CurrentDatasets -visible] {
    14751415                SendCmd "outline visible $bool $tag"
    14761416            }
     
    14781418        "-volumequality" {
    14791419            set val $_settings($what)
    1480             set _settings($_current${what}) $val
    14811420            set val [expr {0.01*$val}]
    1482             foreach tag [GetDatasetsWithComponent $_current] {
     1421            foreach tag [CurrentDatasets -visible] {
    14831422                SendCmd "volume quality $val $tag"
    14841423            }
    1485         }
    1486         "-volumespecularlevel" - "-volumespecularexponent" {
    1487             set val $_settings($what)
    1488             set _settings($_current${what}) $val
    1489             set level [expr {0.01*$val}]
    1490             set exp $_settings($what)
    1491             foreach tag [GetDatasetsWithComponent $_current] {
    1492                 SendCmd "volume shading specular $level $exp $tag"
    1493             }
    1494         }
    1495         "-volumethickness" {
    1496             set _settings($_current${what}) $_settings($what)
    1497             updateTransferFunctions
    14981424        }
    14991425        "-volumevisible" {
    15001426            set bool $_settings($what)
    1501             set _settings($_current${what}) $bool
    1502             # Only the data objects in the array _obj2ovride(*-raise) are
    1503             # in the working set and can be displayed on screen. The global
    1504             # volume control determines whether they are visible.
    1505             #
    1506             # Note: The use of the current component is a hold over from
    1507             #       nanovis.  If we can't display more than one volume,
    1508             #       we don't have to limit the effects to a specific
    1509             #       component.
    1510             foreach tag [GetDatasetsWithComponent $_current] {
    1511                 foreach {dataobj cname} [split $tag -] break
    1512                 if { [info exists _obj2ovride($dataobj-raise)] } {
    1513                     SendCmd "volume visible $bool $tag"
    1514                 }
     1427            foreach tag [CurrentDatasets -visible] {
     1428                SendCmd "volume visible $bool $tag"
    15151429            }
    15161430            if { $bool } {
     
    15641478    set _legendPending 0
    15651479    set font "Arial 8"
    1566     set lineht [font metrics $itk_option(-font) -linespace]
    1567     set c $itk_component(legend)
    1568     set w [winfo width $c]
    1569     set h [winfo height $c]
    1570     set h [expr {$h-$lineht-20}]
    1571     set w [expr {$w-20}]
     1480    set lineht [font metrics $font -linespace]
     1481    set w 12
     1482    set h [expr {$_height - 3 * ($lineht + 2)}]
     1483    if { $h < 1 } {
     1484        return
     1485    }
    15721486    # Set the legend on the first dataset.
    15731487    foreach dataset [CurrentDatasets -visible $_first] {
     
    15791493        }
    15801494    }
     1495}
     1496
     1497#
     1498# ChangeColormap --
     1499#
     1500itcl::body Rappture::VtkVolumeViewer::ChangeColormap {dataobj comp color} {
     1501    set tag $dataobj-$comp
     1502    if { ![info exist _style($tag)] } {
     1503        error "no initial colormap"
     1504    }
     1505    array set style $_style($tag)
     1506    set style(-color) $color
     1507    set _style($tag) [array get style]
     1508    SetColormap $dataobj $comp
     1509}
     1510
     1511#
     1512# SetColormap --
     1513#
     1514itcl::body Rappture::VtkVolumeViewer::SetColormap { dataobj comp } {
     1515    array set style {
     1516        -color BCGYR
     1517        -levels 6
     1518    }
     1519    set tag $dataobj-$comp
     1520    if { ![info exists _initialStyle($tag)] } {
     1521        # Save the initial component style.
     1522        set _initialStyle($tag) [$dataobj style $comp]
     1523    }
     1524
     1525    # Override defaults with initial style defined in xml.
     1526    array set style $_initialStyle($tag)
     1527
     1528    if { ![info exists _style($tag)] } {
     1529        set _style($tag) [array get style]
     1530    }
     1531    # Override initial style with current style.
     1532    array set style $_style($tag)
     1533
     1534    set name "$style(-color):$style(-levels)"
     1535    if { ![info exists _colormaps($name)] } {
     1536        BuildColormap $name [array get style]
     1537        set _colormaps($name) 1
     1538    }
     1539    if { ![info exists _dataset2style($tag)] ||
     1540         $_dataset2style($tag) != $name } {
     1541        SendCmd "volume colormap $name $tag"
     1542        SendCmd "$_cutplaneCmd colormap $name-opaque $tag"
     1543        set _dataset2style($tag) $name
     1544    }
     1545}
     1546
     1547#
     1548# BuildColormap --
     1549#
     1550# Alpha map is in the format: normalized_value opacity midpoint sharpness
     1551#
     1552itcl::body Rappture::VtkVolumeViewer::BuildColormap { name styles } {
     1553    array set style $styles
     1554    set cmap [ColorsToColormap $style(-color)]
     1555    if { [llength $cmap] == 0 } {
     1556        set cmap "0.0 0.0 0.0 0.0 1.0 1.0 1.0 1.0"
     1557    }
     1558
     1559    set amap "0.0 0.0 0.5 0.0 1.0 1.0 0.5 0.0"
     1560    set opaqueAmap "0.0 1.0 1.0 1.0"
     1561    SendCmd [list colormap define $name $cmap -spline $amap]
     1562    SendCmd [list colormap define $name-opaque $cmap $opaqueAmap]
    15811563}
    15821564
     
    16751657    $inner configure -borderwidth 4
    16761658
    1677     label $inner.volcomponents_l -text "Component" -font $font
    1678     itk_component add volcomponents {
    1679         Rappture::Combobox $inner.volcomponents -editable 0
    1680     }
    1681     bind $inner.volcomponents <<Value>> \
    1682         [itcl::code $this AdjustSetting -current]
    1683 
    16841659    checkbutton $inner.visibility \
    16851660        -text "Visible" \
     
    16881663        -command [itcl::code $this AdjustSetting -volumevisible]
    16891664
    1690     label $inner.lighting_l \
    1691         -text "Lighting / Material Properties" \
    1692         -font $bfont
    1693 
    16941665    checkbutton $inner.lighting \
    16951666        -text "Enable Lighting" \
     
    16981669        -command [itcl::code $this AdjustSetting -volumelighting]
    16991670
    1700     label $inner.ambient_l \
    1701         -text "Ambient" \
    1702         -font $font
    1703     ::scale $inner.ambient -from 0 -to 100 -orient horizontal \
    1704         -variable [itcl::scope _settings(-volumeambient)] \
     1671    label $inner.dim_l -text "Dim" -font $font
     1672    ::scale $inner.material -from 0 -to 100 -orient horizontal \
     1673        -variable [itcl::scope _settings(-volumematerial)] \
    17051674        -showvalue off \
    1706         -command [itcl::code $this AdjustSetting -volumeambient] \
    1707         -troughcolor grey92
    1708 
    1709     label $inner.diffuse_l -text "Diffuse" -font $font
    1710     ::scale $inner.diffuse -from 0 -to 100 -orient horizontal \
    1711         -variable [itcl::scope _settings(-volumediffuse)] \
    1712         -showvalue off \
    1713         -command [itcl::code $this AdjustSetting -volumediffuse] \
    1714         -troughcolor grey92
    1715 
    1716     label $inner.specularLevel_l -text "Specular" -font $font
    1717     ::scale $inner.specularLevel -from 0 -to 100 -orient horizontal \
    1718         -variable [itcl::scope _settings(-volumespecularlevel)] \
    1719         -showvalue off \
    1720         -command [itcl::code $this AdjustSetting -volumespecularlevel] \
    1721         -troughcolor grey92
    1722 
    1723     label $inner.specularExponent_l -text "Shininess" -font $font
    1724     ::scale $inner.specularExponent -from 10 -to 128 -orient horizontal \
    1725         -variable [itcl::scope _settings(-volumespecularexponent)] \
    1726         -showvalue off \
    1727         -command [itcl::code $this AdjustSetting -volumespecularexponent] \
    1728         -troughcolor grey92
     1675        -command [itcl::code $this AdjustSetting -volumematerial]
     1676    label $inner.bright_l -text "Bright" -font $font
    17291677
    17301678    label $inner.opacity_l -text "Opacity" -font $font
     
    17321680        -variable [itcl::scope _settings(-volumeopacity)] \
    17331681        -showvalue off \
    1734         -command [itcl::code $this AdjustSetting -volumeopacity] \
    1735         -troughcolor grey92
     1682        -command [itcl::code $this AdjustSetting -volumeopacity]
    17361683
    17371684    label $inner.quality_l -text "Quality" -font $font
     
    17391686        -variable [itcl::scope _settings(-volumequality)] \
    17401687        -showvalue off \
    1741         -command [itcl::code $this AdjustSetting -volumequality] \
    1742         -troughcolor grey92
     1688        -command [itcl::code $this AdjustSetting -volumequality]
    17431689
    17441690    label $inner.field_l -text "Field" -font $font
     
    17491695        [itcl::code $this AdjustSetting -field]
    17501696
    1751     label $inner.transferfunction_l \
    1752         -text "Transfer Function" -font $bfont
    1753 
    1754     label $inner.thin -text "Thin" -font $font
    1755     ::scale $inner.thickness -from 0 -to 1000 -orient horizontal \
    1756         -variable [itcl::scope _settings(-volumethickness)] \
    1757         -showvalue off \
    1758         -command [itcl::code $this AdjustSetting -volumethickness] \
    1759         -troughcolor grey92
    1760 
    1761     label $inner.thick -text "Thick" -font $font
    1762     $inner.thickness set $_settings(-volumethickness)
    1763 
    17641697    label $inner.colormap_l -text "Colormap" -font $font
    17651698    itk_component add colormap {
    1766         Rappture::Combobox $inner.colormap -width 10 -editable 0
    1767     }
    1768     $inner.colormap choices insert end [GetColormapList -includeDefault]
    1769 
     1699        Rappture::Combobox $inner.colormap -editable 0
     1700    }
     1701    $inner.colormap choices insert end [GetColormapList]
    17701702    bind $inner.colormap <<Value>> \
    17711703        [itcl::code $this AdjustSetting -color]
    17721704    $itk_component(colormap) value $_settings(-color)
    17731705
    1774     label $inner.blendmode_l -text "Blend Mode" -font $font
    1775     itk_component add blendmode {
    1776         Rappture::Combobox $inner.blendmode -editable 0
    1777     }
    1778     $inner.blendmode choices insert end \
    1779         "composite"     "Composite"         \
    1780         "max_intensity" "Maximum Intensity" \
    1781         "additive"      "Additive"
    1782 
    1783     $itk_component(blendmode) value \
    1784         "[$itk_component(blendmode) label $_settings(-volumeblendmode)]"
    1785     bind $inner.blendmode <<Value>> \
    1786         [itcl::code $this AdjustSetting -volumeblendmode]
    1787 
    17881706    blt::table $inner \
    1789         0,0 $inner.volcomponents_l -anchor e -cspan 2 \
    1790         0,2 $inner.volcomponents -cspan 3 -fill x \
    1791         1,0 $inner.field_l -anchor e -cspan 2  \
    1792         1,2 $inner.field -cspan 3 -fill x \
    1793         2,0 $inner.lighting_l -anchor w -cspan 4 \
    1794         3,1 $inner.lighting -anchor w -cspan 3 \
    1795         4,1 $inner.ambient_l -anchor e \
    1796         4,2 $inner.ambient -cspan 3 -fill x \
    1797         5,1 $inner.diffuse_l -anchor e \
    1798         5,2 $inner.diffuse -cspan 3 -fill x \
    1799         6,1 $inner.specularLevel_l -anchor e \
    1800         6,2 $inner.specularLevel -cspan 3 -fill x \
    1801         7,1 $inner.specularExponent_l -anchor e \
    1802         7,2 $inner.specularExponent -cspan 3 -fill x \
    1803         8,1 $inner.visibility -anchor w -cspan 3 \
    1804         9,1 $inner.quality_l -anchor e \
    1805         9,2 $inner.quality -cspan 3 -fill x \
    1806         10,0 $inner.transferfunction_l -anchor w -cspan 4 \
    1807         11,1 $inner.opacity_l -anchor e \
    1808         11,2 $inner.opacity -cspan 3 -fill x \
    1809         12,1 $inner.colormap_l -anchor e \
    1810         12,2 $inner.colormap -padx 2 -cspan 3 -fill x \
    1811         13,1 $inner.blendmode_l -anchor e \
    1812         13,2 $inner.blendmode -padx 2 -cspan 3 -fill x \
    1813         14,1 $inner.thin -anchor e \
    1814         14,2 $inner.thickness -cspan 2 -fill x \
    1815         14,4 $inner.thick -anchor w
    1816 
    1817     blt::table configure $inner r* c* -resize none
    1818     blt::table configure $inner r* -pady { 2 0 }
    1819     blt::table configure $inner c2 c3 r15 -resize expand
    1820     blt::table configure $inner c0 -width .1i
     1707        0,0 $inner.field_l -anchor w -pady 2 \
     1708        0,1 $inner.field -fill x -pady 2 -cspan 3 \
     1709        1,0 $inner.visibility -anchor w -pady 2 -cspan 4 \
     1710        2,0 $inner.lighting -anchor w -pady 2 -cspan 4 \
     1711        3,0 $inner.dim_l -anchor e -pady 2 \
     1712        3,1 $inner.material -fill x -pady 2 -cspan 2 \
     1713        3,3 $inner.bright_l -anchor w -pady 2 \
     1714        4,0 $inner.opacity_l -anchor w -pady 2 -cspan 4 \
     1715        5,0 $inner.opacity -fill x -pady 2 -cspan 4 \
     1716        6,0 $inner.quality_l -anchor w -pady 2 -cspan 4 \
     1717        7,0 $inner.quality -fill x -pady 2 -cspan 4 \
     1718        8,0 $inner.colormap_l -anchor w -pady 2 \
     1719        8,1 $inner.colormap -fill x -pady 2 -cspan 3
     1720
     1721    blt::table configure $inner r* c0 c1 c3 -resize none
     1722    blt::table configure $inner r9 c2 -resize expand
    18211723}
    18221724
     
    21832085    }
    21842086    array set style [$dataobj style $cname]
    2185     set _settings($cname-volumelighting) $style(-lighting)
    2186     set _settings($cname-volumeopacity) [expr $style(-opacity) * 100]
    2187     set _settings($cname-volumeoutline) $style(-outline)
    2188     set _settings($cname-volumevisible) $style(-visible)
     2087    set _settings(-volumelighting) $style(-lighting)
     2088    set _settings(-volumeopacity) [expr $style(-opacity) * 100.0]
     2089    set _settings(-volumeoutline) $style(-outline)
     2090    set _settings(-volumevisible) $style(-visible)
    21892091
    21902092    $itk_component(colormap) value $style(-color)
     
    22022104    SendCmd "volume opacity $style(-opacity) $tag"
    22032105    SendCmd "volume visible $style(-visible) $tag"
    2204 
    2205     SetInitialTransferFunction $dataobj $cname
    2206     SendCmd "volume colormap $cname $tag"
    2207     SendCmd "$_cutplaneCmd colormap $cname-opaque $tag"
     2106    SetColormap $dataobj $cname
    22082107}
    22092108
     
    22402139#
    22412140itcl::body Rappture::VtkVolumeViewer::DrawLegend {} {
    2242     if { $_current == "" } {
    2243         set _current "component"
    2244     }
    2245     set cname $_current
    2246     set c $itk_component(legend)
     2141    set fname $_curFldName
     2142    set c $itk_component(view)
    22472143    set w [winfo width $c]
    22482144    set h [winfo height $c]
    2249     set lx 10
    2250     set ly [expr {$h - 1}]
    2251     if {"" == [$c find withtag colorbar]} {
    2252         $c create image 10 10 -anchor nw \
    2253             -image $_image(legend) -tags colorbar
    2254         $c create text $lx $ly -anchor sw \
    2255             -fill $itk_option(-plotforeground) -tags "limits text vmin"
    2256         $c create text [expr {$w-$lx}] $ly -anchor se \
    2257             -fill $itk_option(-plotforeground) -tags "limits text vmax"
    2258         $c create text [expr {$w/2}] $ly -anchor s \
    2259             -fill $itk_option(-plotforeground) -tags "limits text title"
    2260         $c lower colorbar
    2261         $c bind colorbar <ButtonRelease-1> [itcl::code $this AddNewMarker %x %y]
    2262     }
    2263 
    2264     # Display the markers used by the current transfer function.
    2265     HideAllMarkers
    2266     if { [info exists _transferFunctionEditors($cname)] } {
    2267         $_transferFunctionEditors($cname) showMarkers $_limits($cname)
    2268     }
    2269 
    2270     foreach {min max} $_limits($cname) break
    2271     $c itemconfigure vmin -text [format %g $min]
    2272     $c coords vmin $lx $ly
    2273 
    2274     $c itemconfigure vmax -text [format %g $max]
    2275     $c coords vmax [expr {$w-$lx}] $ly
    2276 
    2277     set title ""
    2278     if { $_first != "" } {
    2279         set title [$_first hints label]
    2280         set units [$_first hints units]
     2145    set font "Arial 8"
     2146    set lineht [font metrics $font -linespace]
     2147
     2148    if { !$_settings(-legendvisible) } {
     2149        $c delete legend
     2150        return
     2151    }
     2152
     2153    if { [info exists _fields($fname)] } {
     2154        foreach { title units } $_fields($fname) break
    22812155        if { $units != "" } {
    2282             set title "$title ($units)"
    2283         }
    2284     }
     2156            set title [format "%s (%s)" $title $units]
     2157        }
     2158    } else {
     2159        set title $fname
     2160    }
     2161
     2162    set x [expr $w - 2]
     2163    if { [$c find withtag "legend"] == "" } {
     2164        set y 2
     2165        $c create text $x $y \
     2166            -anchor ne \
     2167            -fill $itk_option(-plotforeground) -tags "title legend" \
     2168            -font $font
     2169        incr y $lineht
     2170        $c create text $x $y \
     2171            -anchor ne \
     2172            -fill $itk_option(-plotforeground) -tags "vmax legend" \
     2173            -font $font
     2174        incr y $lineht
     2175        $c create image $x $y \
     2176            -anchor ne \
     2177            -image $_image(legend) -tags "colormap legend"
     2178        $c create text $x [expr {$h-2}] \
     2179            -anchor se \
     2180            -fill $itk_option(-plotforeground) -tags "vmin legend" \
     2181            -font $font
     2182        #$c bind colormap <Enter> [itcl::code $this EnterLegend %x %y]
     2183        $c bind colormap <Leave> [itcl::code $this LeaveLegend]
     2184        $c bind colormap <Motion> [itcl::code $this MotionLegend %x %y]
     2185    }
     2186    $c bind title <ButtonPress> [itcl::code $this LegendTitleAction post]
     2187    $c bind title <Enter> [itcl::code $this LegendTitleAction enter]
     2188    $c bind title <Leave> [itcl::code $this LegendTitleAction leave]
     2189    # Reset the item coordinates according the current size of the plot.
    22852190    $c itemconfigure title -text $title
    2286     $c coords title [expr {$w/2}] $ly
     2191    if { [info exists _limits($_curFldName)] } {
     2192        foreach { vmin vmax } $_limits($_curFldName) break
     2193        $c itemconfigure vmin -text [format %g $vmin]
     2194        $c itemconfigure vmax -text [format %g $vmax]
     2195    }
     2196    set y 2
     2197    $c coords title $x $y
     2198    incr y $lineht
     2199    $c coords vmax $x $y
     2200    incr y $lineht
     2201    $c coords colormap $x $y
     2202    $c coords vmin $x [expr {$h - 2}]
    22872203}
    22882204
     
    24302346}
    24312347
    2432 #
    2433 # The -levels option takes a single value that represents the number
    2434 # of evenly distributed markers based on the current data range. Each
    2435 # marker is a relative value from 0.0 to 1.0.
    2436 #
    2437 itcl::body Rappture::VtkVolumeViewer::ParseLevelsOption { cname levels } {
    2438     set c $itk_component(legend)
    2439     set list {}
    2440     regsub -all "," $levels " " levels
    2441     if {[string is int $levels]} {
    2442         for {set i 1} { $i <= $levels } {incr i} {
    2443             lappend list [expr {double($i)/($levels+1)}]
    2444         }
    2445     } else {
    2446         foreach x $levels {
    2447             lappend list $x
    2448         }
    2449     }
    2450     set _parsedFunction($cname) 1
    2451     $_transferFunctionEditors($cname) addMarkers $list
    2452 }
    2453 
    2454 #
    2455 # The -markers option takes a list of zero or more values (the values
    2456 # may be separated either by spaces or commas) that have the following
    2457 # format:
    2458 #
    2459 #   N%  Percent of current total data range.  Converted to
    2460 #       to a relative value between 0.0 and 1.0.
    2461 #   N   Absolute value of marker.  If the marker is outside of
    2462 #       the current range, it will be displayed on the outer
    2463 #       edge of the legends, but it range it represents will
    2464 #       not be seen.
    2465 #
    2466 itcl::body Rappture::VtkVolumeViewer::ParseMarkersOption { cname markers } {
    2467     set c $itk_component(legend)
    2468     set list {}
    2469     foreach { min max } $_limits($cname) break
    2470     regsub -all "," $markers " " markers
    2471     foreach marker $markers {
    2472         set n [scan $marker "%g%s" value suffix]
    2473         if { $n == 2 && $suffix == "%" } {
    2474             # $n% : Set relative value (0..1).
    2475             lappend list [expr {$value * 0.01}]
    2476         } else {
    2477             # $n : absolute value, compute relative
    2478             lappend list [expr {(double($value)-$min)/($max-$min)}]
    2479         }
    2480     }
    2481     set _parsedFunction($cname) 1
    2482     $_transferFunctionEditors($cname) addMarkers $list
    2483 }
    2484 
    2485 #
    2486 # SetInitialTransferFunction --
    2487 #
    2488 # Creates a transfer function name based on the <style> settings in the
    2489 # library run.xml file. This placeholder will be used later to create
    2490 # and send the actual transfer function once the data info has been sent
    2491 # to us by the render server. [We won't know the volume limits until the
    2492 # server parses the 3D data and sends back the limits via ReceiveData.]
    2493 #
    2494 itcl::body Rappture::VtkVolumeViewer::SetInitialTransferFunction { dataobj cname } {
    2495     set tag $dataobj-$cname
    2496     if { ![info exists _cname2transferFunction($cname)] } {
    2497         ComputeTransferFunction $cname
    2498     }
    2499     set _dataset2style($tag) $cname
    2500 
    2501     return $cname
    2502 }
    2503 
    2504 #
    2505 # ComputeTransferFunction --
    2506 #
    2507 # Computes and sends the transfer function to the render server.  It's
    2508 # assumed that the volume data limits are known and that the global
    2509 # transfer-functions slider values have been set up.  Both parts are
    2510 # needed to compute the relative value (location) of the marker, and
    2511 # the alpha map of the transfer function.
    2512 #
    2513 itcl::body Rappture::VtkVolumeViewer::ComputeTransferFunction { cname } {
    2514 
    2515     if { ![info exists _transferFunctionEditors($cname)] } {
    2516         set _transferFunctionEditors($cname) \
    2517             [Rappture::TransferFunctionEditor ::\#auto $itk_component(legend) \
    2518                  $cname \
    2519                  -command [itcl::code $this updateTransferFunctions]]
    2520     }
    2521 
    2522     # We have to parse the style attributes for a volume using this
    2523     # transfer-function *once*.  This sets up the initial isomarkers for the
    2524     # transfer function.  The user may add/delete markers, so we have to
    2525     # maintain a list of markers for each transfer-function.  We use the one
    2526     # of the volumes (the first in the list) using the transfer-function as a
    2527     # reference.
    2528     if { ![info exists _parsedFunction($cname)] ||
    2529          ![info exists _cname2transferFunction($cname)] } {
    2530         array set style {
    2531             -color BCGYR
    2532             -levels 6
    2533         }
    2534         # Accumulate the style from all the datasets using it.
    2535         foreach tag [GetDatasetsWithComponent $cname] {
    2536             foreach {dataobj cname} [split [lindex $tag 0] -] break
    2537             set option [lindex [$dataobj components -style $cname] 0]
    2538             array set style $option
    2539         }
    2540         set _settings($cname-color) $style(-color)
    2541         set cmap [ColorsToColormap $style(-color)]
    2542         set _cname2defaultcolormap($cname) $cmap
    2543         if { [info exists _transferFunctionEditors($cname)] } {
    2544             eval $_transferFunctionEditors($cname) limits $_limits($cname)
    2545         }
    2546         # Don't enable the -alphamap style until we have a proper UI
    2547         # to allow editing the transfer function
    2548         array unset style -alphamap
    2549         if { [info exists style(-alphamap)] &&
    2550              $style(-alphamap) != "" } {
    2551             set _alphamap($cname) $style(-alphamap)
    2552             set _parsedFuntion($cname) 1
    2553         } else {
    2554             if { [info exists style(-markers)] &&
    2555                  [llength $style(-markers)] > 0 } {
    2556                 ParseMarkersOption $cname $style(-markers)
    2557             } else {
    2558                 ParseLevelsOption $cname $style(-levels)
    2559             }
    2560         }
    2561     } else {
    2562         foreach {cmap amap} $_cname2transferFunction($cname) break
    2563     }
    2564     if { ![info exists _alphamap($cname)] } {
    2565         set amap [ComputeAlphamap $cname]
    2566     } else {
    2567         set amap $_alphamap($cname)
    2568     }
    2569     # We don't need to use a spline for the opaque map
    2570     set opaqueAmap "0.0 1.0 1.0 1.0"
    2571     set _cname2transferFunction($cname) [list $cmap $amap]
    2572     SendCmd [list colormap define $cname $cmap -spline $amap]
    2573     SendCmd [list colormap define $cname-opaque $cmap $opaqueAmap]
    2574 }
    2575 
    2576 #
    2577 # ResetColormap --
    2578 #
    2579 # Changes only the colormap portion of the transfer function.
    2580 #
    2581 itcl::body Rappture::VtkVolumeViewer::ResetColormap { cname color } {
    2582     # Get the current transfer function
    2583     if { ![info exists _cname2transferFunction($cname)] } {
    2584         return
    2585     }
    2586     foreach { cmap amap } $_cname2transferFunction($cname) break
    2587     set cmap [GetColormap $cname $color]
    2588     set _cname2transferFunction($cname) [list $cmap $amap]
    2589     set opaqueAmap "0.0 1.0 1.0 1.0"
    2590     SendCmd [list colormap define $cname $cmap -spline $amap]
    2591     SendCmd [list colormap define $cname-opaque $cmap $opaqueAmap]
    2592     EventuallyRequestLegend
    2593 }
    2594 
    2595 # ----------------------------------------------------------------------
    2596 # USAGE: updateTransferFunctions
    2597 #
    2598 # This is called by the transfer function editor whenever the
    2599 # transfer function definition changes.
    2600 # ----------------------------------------------------------------------
    2601 itcl::body Rappture::VtkVolumeViewer::updateTransferFunctions {} {
    2602     foreach cname [array names _volcomponents] {
    2603         ComputeTransferFunction $cname
    2604     }
    2605     EventuallyRequestLegend
    2606 }
    2607 
    2608 itcl::body Rappture::VtkVolumeViewer::AddNewMarker { x y } {
    2609     if { ![info exists _transferFunctionEditors($_current)] } {
    2610         continue
    2611     }
    2612     # Add a new marker to the current transfer function
    2613     $_transferFunctionEditors($_current) newMarker $x $y normal
    2614 }
    2615 
    2616 itcl::body Rappture::VtkVolumeViewer::RemoveMarker { x y } {
    2617     if { ![info exists _transferFunctionEditors($_current)] } {
    2618         continue
    2619     }
    2620     # Add a new marker to the current transfer function
    2621     $_transferFunctionEditors($_current) deleteMarker $x $y
    2622 }
    2623 
    26242348itcl::body Rappture::VtkVolumeViewer::SetOrientation { side } {
    26252349    array set positions {
     
    26442368
    26452369#
    2646 # InitComponentSettings --
    2647 #
    2648 # Initializes the volume settings for a specific component. This
    2649 # should match what's used as global settings above. This
    2650 # is called the first time we try to switch to a given component
    2651 # in SwitchComponent below.
    2652 #
    2653 itcl::body Rappture::VtkVolumeViewer::InitComponentSettings { cname } {
    2654     array set _settings [subst {
    2655         $cname-color                    default
    2656         $cname-volumeambient            40
    2657         $cname-volumeblendmode          composite
    2658         $cname-volumediffuse            60
    2659         $cname-volumelight2side         1
    2660         $cname-volumelighting           1
    2661         $cname-volumeopacity            50
    2662         $cname-volumeoutline            0
    2663         $cname-volumequality            80
    2664         $cname-volumespecularexponent   90
    2665         $cname-volumespecularlevel      30
    2666         $cname-volumethickness          350
    2667         $cname-volumevisible            1
    2668     }]
    2669 }
    2670 
    2671 #
    2672 # SwitchComponent --
    2673 #
    2674 # This is called when the current component is changed by the
    2675 # dropdown menu in the volume tab.  It synchronizes the global
    2676 # volume settings with the settings of the new current component.
    2677 #
    2678 itcl::body Rappture::VtkVolumeViewer::SwitchComponent { cname } {
    2679     if { ![info exists _settings(${cname}-volumeambient)] } {
    2680         InitComponentSettings $cname
    2681     }
    2682     # _settings variables change widgets, except for colormap
    2683     foreach name {
    2684         -volumeambient
    2685         -volumeblendmode
    2686         -volumediffuse
    2687         -volumelight2side
    2688         -volumelighting
    2689         -volumeopacity
    2690         -volumeoutline
    2691         -volumequality
    2692         -volumespecularexponent
    2693         -volumespecularlevel
    2694         -volumethickness
    2695         -volumevisible
    2696     } {
    2697         set _settings($name) $_settings(${cname}${name})
    2698     }
    2699     $itk_component(colormap) value        $_settings($cname-color)
    2700     set _current $cname;                # Reset the current component
    2701 }
    2702 
    2703 #
    2704 # Alpha map is in the format: normalized_value opacity midpoint sharpness
    2705 #
    2706 itcl::body Rappture::VtkVolumeViewer::ComputeAlphamap { cname } {
    2707     if { ![info exists _transferFunctionEditors($cname)] } {
    2708         return [list 0.0 0.0 0.5 0.0 1.0 1.0 0.5 0.0]
    2709     }
    2710     if { ![info exists _settings($cname-volumeambient)] } {
    2711         InitComponentSettings $cname
    2712     }
    2713 
    2714     set isovalues [$_transferFunctionEditors($cname) values]
    2715 
    2716     # Currently using volume opacity to scale opacity in
    2717     # the volume shader. The transfer function always sets full
    2718     # opacity
    2719     set max 1.0;
    2720 
    2721     # Use the component-wise thickness setting from the slider
    2722     # settings widget
    2723     # Scale values between 0.00001 and 0.01000
    2724     set delta [expr {double($_settings($cname-volumethickness)) * 0.0001}]
    2725     set first [lindex $isovalues 0]
    2726     set last [lindex $isovalues end]
    2727     set amap ""
    2728     if { $first == "" || $first != 0.0 } {
    2729         lappend amap 0.0 0.0 0.5 0.0
    2730     }
    2731     foreach x $isovalues {
    2732         set x1 [expr {$x-$delta-0.00001}]
    2733         set x2 [expr {$x-$delta}]
    2734         set x3 [expr {$x+$delta}]
    2735         set x4 [expr {$x+$delta+0.00001}]
    2736         if { $x1 < 0.0 } {
    2737             set x1 0.0
    2738         } elseif { $x1 > 1.0 } {
    2739             set x1 1.0
    2740         }
    2741         if { $x2 < 0.0 } {
    2742             set x2 0.0
    2743         } elseif { $x2 > 1.0 } {
    2744             set x2 1.0
    2745         }
    2746         if { $x3 < 0.0 } {
    2747             set x3 0.0
    2748         } elseif { $x3 > 1.0 } {
    2749             set x3 1.0
    2750         }
    2751         if { $x4 < 0.0 } {
    2752             set x4 0.0
    2753         } elseif { $x4 > 1.0 } {
    2754             set x4 1.0
    2755         }
    2756         # add spikes in the middle
    2757         lappend amap $x1 0.0 0.5 0.0
    2758         lappend amap $x2 $max 0.5 0.0
    2759         lappend amap $x3 $max 0.5 0.0
    2760         lappend amap $x4 0.0 0.5 0.0
    2761     }
    2762     if { $last == "" || $last != 1.0 } {
    2763         lappend amap 1.0 0.0 0.5 0.0
    2764     }
    2765     return $amap
    2766 }
    2767 
    2768 #
    2769 # HideAllMarkers --
    2770 #
    2771 # Hide all the markers in all the transfer functions.  Can't simply
    2772 # delete and recreate markers from the <style> since the user may
    2773 # have create, deleted, or moved markers.
    2774 #
    2775 itcl::body Rappture::VtkVolumeViewer::HideAllMarkers {} {
    2776     foreach cname [array names _transferFunctionEditors] {
    2777         $_transferFunctionEditors($cname) hideMarkers
    2778     }
    2779 }
    2780 
    2781 #
    27822370# GetDatasetsWithComponent --
    27832371#
     
    27922380    }
    27932381    return $_volcomponents($cname)
    2794 }
    2795 
    2796 #
    2797 # BuildVolumeComponents --
    2798 #
    2799 # This is called from the "scale" method which is called when a
    2800 # new dataset is added or deleted.  It repopulates the dropdown
    2801 # menu of volume component names.  It sets the current component
    2802 # to the first component in the list (of components found).
    2803 # Finally, if there is only one component, don't display the
    2804 # label or the combobox in the volume settings tab.
    2805 #
    2806 itcl::body Rappture::VtkVolumeViewer::BuildVolumeComponents {} {
    2807     $itk_component(volcomponents) choices delete 0 end
    2808     foreach name $_componentsList {
    2809         $itk_component(volcomponents) choices insert end $name $name
    2810     }
    2811     set _current [lindex $_componentsList 0]
    2812     $itk_component(volcomponents) value $_current
    2813     set parent [winfo parent $itk_component(volcomponents)]
    2814     if { [llength $_componentsList] <= 1 } {
    2815         # Unpack the components label and dropdown if there's only one
    2816         # component.
    2817         catch {blt::table forget $parent.volcomponents_l $parent.volcomponents}
    2818     } else {
    2819         # Pack the components label and dropdown into the table there's
    2820         # more than one component to select.
    2821         blt::table $parent \
    2822             0,0 $parent.volcomponents_l -anchor e -cspan 2 \
    2823             0,2 $parent.volcomponents -cspan 3 -fill x
    2824     }
    2825 }
    2826 
    2827 itcl::body Rappture::VtkVolumeViewer::GetColormap { cname color } {
    2828     if { $color == "default" } {
    2829         return $_cname2defaultcolormap($cname)
    2830     }
    2831     return [ColorsToColormap $color]
    28322382}
    28332383
Note: See TracChangeset for help on using the changeset viewer.