Changeset 6675
- Timestamp:
- Jan 23, 2017 11:29:05 AM (6 years ago)
- Location:
- trunk/gui/scripts
- Files:
-
- 4 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/gui/scripts/flowvisviewer.tcl
r6360 r6675 61 61 public method get {args} 62 62 public method isconnected {} 63 public method limits { cname}63 public method limits { tf } 64 64 public method overMarker { m x } 65 65 public method parameters {title args} { … … 129 129 private variable _dlist ""; # list of data objects 130 130 private variable _obj2ovride; # maps dataobj => style override 131 private variable _ datasets; # mapsdataobj-component131 private variable _serverDatasets; # contains all the dataobj-component 132 132 # to volumes in the server 133 private variable _recvdDatasets; # list of data objs to send to server 133 134 private variable _dataset2style; # maps dataobj-component to transfunc 134 135 private variable _style2datasets; # maps tf back to list of … … 225 226 $_arcball quaternion [ViewToQuaternion] 226 227 228 set _limits(vmin) 0.0 229 set _limits(vmax) 1.0 230 227 231 array set _settings [subst { 228 -ambient 60229 232 -arrows 0 230 233 -axesvisible 0 … … 233 236 -currenttime 0 234 237 -cutplanesvisible 0 235 -diffuse 40236 238 -duration 1:00 237 239 -gridvisible 0 … … 239 241 -legendvisible 1 240 242 -lic 1 243 -light 40 241 244 -light2side 1 242 245 -loop 0 … … 249 252 -qy $_view(-qy) 250 253 -qz $_view(-qz) 251 -specularexponent 90252 -specularlevel 30253 254 -speed 500 254 255 -step 0 … … 496 497 $itk_component(speed) value 1 497 498 bind $itk_component(speed) <<Value>> [itcl::code $this flow speed] 498 499 499 500 500 blt::table $itk_component(flowcontrols) \ … … 739 739 set _limits($cname) $limits(v) 740 740 } 741 foreach axis {x y z } {741 foreach axis {x y z v} { 742 742 foreach { min max } [$dataobj limits $axis] break 743 743 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 746 747 continue 747 748 } 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 751 751 } 752 if {$max > $ amax} {753 set amax$max752 if {$max > $_limits(${axis}max)} { 753 set _limits(${axis}max) $max 754 754 } 755 set _limits($axis) [list $amin $amax]756 755 } 757 756 } … … 897 896 898 897 # disconnected -- no more data sitting on server 899 array unset _ datasets898 array unset _serverDatasets 900 899 } 901 900 … … 993 992 # Display the markers used by the current transfer function. 994 993 set tf $_dataset2style($tag) 995 foreach {min max} [limits $tf] break996 $c itemconfigure vmin -text [format %g $ min]994 array set limits [limits $tf] 995 $c itemconfigure vmin -text [format %g $limits(vmin)] 997 996 $c coords vmin $lx $ly 998 997 999 $c itemconfigure vmax -text [format %g $ max]998 $c itemconfigure vmax -text [format %g $limits(vmax)] 1000 999 $c coords vmax [expr {$w-$lx}] $ly 1001 1000 … … 1043 1042 # The procedure is the response from the render server to each "data 1044 1043 # 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. 1048 1059 # 1049 1060 itcl::body Rappture::FlowvisViewer::ReceiveData { args } { … … 1056 1067 1057 1068 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 } 1059 1083 } 1060 1084 … … 1099 1123 } 1100 1124 set _first "" 1101 foreach dataobj [get -objects] { 1102 if { [info exists _obj2ovride($dataobj-raise)] && $_first == "" } { 1103 set _first $dataobj 1104 } 1125 foreach dataobj [get] { 1105 1126 foreach cname [$dataobj components] { 1106 1127 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 1112 1153 } 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] 1141 1162 1142 1163 # Turn off cutplanes for all volumes … … 1145 1166 } 1146 1167 1147 InitSettings -volume -outlinevisible -cutplanesvisible \ 1168 # Reset the camera and other view parameters 1169 InitSettings -opacity -light2side -isosurfaceshading \ 1170 -light \ 1171 -volume -outlinevisible -cutplanesvisible \ 1148 1172 -xcutplanevisible -ycutplanevisible -zcutplanevisible \ 1149 1173 -xcutplaneposition -ycutplaneposition -zcutplaneposition 1150 1174 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 } 1182 1205 set _reset 0 1183 1206 } 1184 1207 1208 # nothing to send -- activate the proper ivol 1209 set _first [lindex [get] 0] 1185 1210 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 } 1186 1219 set cname [lindex [$_first components] 0] 1187 1220 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 1191 1231 1192 1232 # Actually write the commands to the server socket. If it fails, we don't … … 1205 1245 # ---------------------------------------------------------------------- 1206 1246 itcl::body Rappture::FlowvisViewer::CurrentDatasets {{what -all}} { 1207 set rlist""1247 return "" 1208 1248 if { $_first == "" } { 1209 1249 return 1210 1250 } 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]} { 1214 1253 array set style { 1215 1254 -cutplanes 1 1216 1255 } 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) 1220 1260 } 1221 1261 } … … 1405 1445 } 1406 1446 switch -- $what { 1407 "-ambient" {1408 if { $_first != "" } {1409 set comp [lindex [$_first components] 0]1410 set tag $_first-$comp1411 set val $_settings($what)1412 set val [expr {0.01*$val}]1413 SendCmd "$tag configure -ambient $val"1414 }1415 }1416 1447 "-axesvisible" { 1417 1448 SendCmd "axis visible $_settings($what)" … … 1442 1473 set tag [lindex $datasets 0] 1443 1474 SendCmd "cutplane visible $bool $tag" 1444 }1445 "-diffuse" {1446 if { $_first != "" } {1447 set comp [lindex [$_first components] 0]1448 set tag $_first-$comp1449 set val $_settings($what)1450 set val [expr {0.01*$val}]1451 SendCmd "$tag configure -diffuse $val"1452 }1453 1475 } 1454 1476 "-gridvisible" { … … 1474 1496 } 1475 1497 } 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 } 1476 1509 "-light2side" { 1477 1510 if { $_first != "" } { … … 1495 1528 set tag $_first-$comp 1496 1529 SendCmd "$tag configure -outline $_settings($what)" 1497 }1498 }1499 "-specularlevel" {1500 if { $_first != "" } {1501 set comp [lindex [$_first components] 0]1502 set tag $_first-$comp1503 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-$comp1512 set val $_settings($what)1513 SendCmd "$tag configure -specularExp $val"1514 1530 } 1515 1531 } … … 1601 1617 } 1602 1618 array set style [lindex [$dataobj components -style $cname] 0] 1619 set tf "$style(-color):$style(-levels)" 1603 1620 # Some tools erroneously set -opacity to 1 in style, so 1604 1621 # override the requested opacity for now 1605 1622 set style(-opacity) 0.5 1606 1623 set _settings(-opacity) [expr $style(-opacity) * 100] 1607 set _dataset2style($dataobj-$cname) $ cname1608 lappend _style2datasets($ cname) $dataobj $cname1609 return $ cname1624 set _dataset2style($dataobj-$cname) $tf 1625 lappend _style2datasets($tf) $dataobj $cname 1626 return $tf 1610 1627 } 1611 1628 … … 1888 1905 } 1889 1906 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) 1907 itcl::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] 1896 1939 } 1897 1940 … … 1997 2040 -command [itcl::code $this AdjustSetting -light2side] 1998 2041 1999 label $inner. ambient_l -text "Ambient" -font $fg2000 ::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)] \ 2002 2045 -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 2022 2048 2023 2049 # Opacity … … 2044 2070 Rappture::Combobox $inner.colormap -width 10 -editable no 2045 2071 } 2072 2046 2073 $inner.colormap choices insert end [GetColormapList -includeNone] 2047 2074 bind $inner.colormap <<Value>> \ … … 2054 2081 1,0 $inner.lighting_l -cspan 4 -anchor w -pady {10 2} \ 2055 2082 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 2069 2091 2070 2092 blt::table configure $inner c0 c1 c3 r* -resize none 2071 blt::table configure $inner r 9-resize expand2093 blt::table configure $inner r6 -resize expand 2072 2094 } 2073 2095 … … 2945 2967 set list "" 2946 2968 foreach tag $_volcomponents($cname) { 2947 if { ![info exists _ datasets($tag)] } {2969 if { ![info exists _serverDatasets($tag)] } { 2948 2970 continue 2949 2971 } -
trunk/gui/scripts/isomarker.tcl
r5639 r6675 125 125 126 126 itcl::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) 128 130 if { $x == "-get" } { 129 131 if { $max == $min } { -
trunk/gui/scripts/nanovisviewer.tcl
r6360 r6675 60 60 public method get {args} 61 61 public method isconnected {} 62 public method limits { tf } 63 public method overMarker { m x } 62 64 public method parameters {title args} { 63 65 # do nothing 64 66 } 67 public method removeDuplicateMarker { m x } 65 68 public method scale {args} 66 69 public method updateTransferFunctions {} 67 70 68 71 # The following methods are only used by this class. 69 private method Add NewMarker { x y }72 private method AddIsoMarker { x y } 70 73 private method AdjustSetting {what {value ""}} 71 74 private method BuildCameraTab {} … … 73 76 private method BuildDownloadPopup { widget command } 74 77 private method BuildViewTab {} 75 private method BuildVolumeComponents {}76 78 private method BuildVolumeTab {} 77 private method ComputeAlphamap { cname } 78 private method ComputeTransferFunction { cname } 79 private method ComputeTransferFunction { tf } 79 80 private method Connect {} 80 81 private method CurrentDatasets {{what -all}} 81 82 private method Disconnect {} 82 83 private method DoResize {} 83 private method DrawLegend { cname}84 private method DrawLegend { tf } 84 85 private method EventuallyRedrawLegend { } 85 86 private method EventuallyResize { w h } 86 87 private method FixLegend {} 87 private method GetColormap { cname color }88 private method GetDatasetsWithComponent { cname }89 88 private method GetImage { args } 90 89 private method GetVtkData { args } 91 private method HideAllMarkers {}92 private method InitComponentSettings { cname }93 90 private method InitSettings { args } 94 91 private method NameTransferFunction { dataobj comp } 95 92 private method Pan {option x y} 96 93 private method PanCamera {} 97 private method ParseLevelsOption { cnamelevels }98 private method ParseMarkersOption { cnamemarkers }94 private method ParseLevelsOption { tf levels } 95 private method ParseMarkersOption { tf markers } 99 96 private method QuaternionToView { q } { 100 97 foreach { _view(-qw) _view(-qx) _view(-qy) _view(-qz) } $q break … … 104 101 private method ReceiveImage { args } 105 102 private method ReceiveLegend { tf vmin vmax size } 106 private method RemoveMarker { x y } 107 private method ResetColormap { cname color } 103 private method ResetColormap { color } 108 104 private method Rotate {option x y} 109 105 private method SendTransferFunctions {} 110 private method SetObjectStyle { dataobj cname }111 106 private method SetOrientation { side } 112 107 private method Slice {option args} 113 108 private method SlicerTip {axis} 114 private method SwitchComponent { cname }115 109 private method ViewToQuaternion {} { 116 110 return [list $_view(-qw) $_view(-qx) $_view(-qy) $_view(-qz)] … … 121 115 private variable _dlist ""; # list of data objects 122 116 private variable _obj2ovride; # maps dataobj => style override 123 private variable _ datasets; # mapsdataobj-component117 private variable _serverDatasets; # contains all the dataobj-component 124 118 # 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. 125 123 126 124 private variable _reset 1; # Connection to server has been reset. … … 128 126 private variable _limits; # Autoscale min/max for all axes 129 127 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 132 133 private variable _settings 133 134 private variable _first ""; # This is the topmost volume. 134 private variable _current ""; # Currently selected component135 private variable _volcomponents; # Maps component name to list of136 # dataobj-component tags137 private variable _componentsList; # List of components found138 private variable _cname2transferFunction139 private variable _cname2defaultcolormap140 135 private variable _width 0 141 136 private variable _height 0 … … 198 193 $_arcball quaternion [ViewToQuaternion] 199 194 195 set _limits(vmin) 0.0 196 set _limits(vmax) 1.0 197 200 198 array set _settings [subst { 201 -ambient 60202 199 -axesvisible 1 203 200 -background black 204 -colormap " default"201 -colormap "BCGYR" 205 202 -cutplanesvisible 0 206 -diffuse 40207 203 -gridvisible 0 208 204 -isosurfaceshading 0 209 205 -legendvisible 1 206 -light 40 210 207 -light2side 1 211 208 -opacity 50 … … 215 212 -qy $_view(-qy) 216 213 -qz $_view(-qz) 217 -specularexponent 90218 -specularlevel 30219 214 -thickness 350 220 215 -volume 1 221 -volumevisible 1222 216 -xcutplaneposition 50 223 -xcutplanevisible 1217 -xcutplanevisible 0 224 218 -xpan $_view(-xpan) 225 219 -ycutplaneposition 50 226 -ycutplanevisible 1220 -ycutplanevisible 0 227 221 -ypan $_view(-ypan) 228 222 -zcutplaneposition 50 229 -zcutplanevisible 1223 -zcutplanevisible 0 230 224 -zoom $_view(-zoom) 231 225 }] … … 299 293 Rappture::Tooltip::for $itk_component(cutplane) \ 300 294 "Show/Hide cutplanes" 301 pack $itk_component(cutplane) -padx 2 -pady 2295 #pack $itk_component(cutplane) -padx 2 -pady 2 302 296 303 297 if { [catch { … … 322 316 bind $itk_component(legend) <Configure> \ 323 317 [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)]328 318 329 319 # Hack around the Tk panewindow. The problem is that the requested … … 344 334 bind $itk_component(view) <ButtonRelease-1> \ 345 335 [itcl::code $this Rotate release %x %y] 346 347 336 bind $itk_component(view) <Configure> \ 348 337 [itcl::code $this EventuallyResize %w %h] … … 404 393 image delete $_image(legend) 405 394 image delete $_image(download) 406 foreach cname [array names _transferFunctionEditors] {407 itcl::delete object $_transferFunctionEditors($cname)408 }409 395 catch { blt::arcball destroy $_arcball } 410 396 array unset _settings … … 536 522 # ---------------------------------------------------------------------- 537 523 itcl::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 } 545 527 foreach dataobj $args { 546 528 if { ![$dataobj isvalid] } { 547 529 continue; # Object doesn't contain valid data. 548 530 } 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} { 563 532 foreach { min max } [$dataobj limits $axis] break 564 533 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 } 568 544 } 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 } 581 548 } 582 549 … … 712 679 713 680 # disconnected -- no more data sitting on server 714 array unset _ datasets681 array unset _serverDatasets 715 682 } 716 683 … … 719 686 # ---------------------------------------------------------------------- 720 687 itcl::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" 723 720 } 724 721 FixLegend … … 758 755 # DrawLegend -- 759 756 # 760 itcl::body Rappture::NanovisViewer::DrawLegend { cname} {757 itcl::body Rappture::NanovisViewer::DrawLegend { tf } { 761 758 set c $itk_component(legend) 762 759 set w [winfo width $c] … … 774 771 -fill $itk_option(-plotforeground) -tags "title text" 775 772 $c lower colorbar 776 $c bind colorbar <ButtonRelease-1> [itcl::code $this Add NewMarker %x %y]773 $c bind colorbar <ButtonRelease-1> [itcl::code $this AddIsoMarker %x %y] 777 774 } 778 775 779 776 # 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)] 788 779 $c coords vmin $lx $ly 789 780 790 $c itemconfigure vmax -text [format %g $ max]781 $c itemconfigure vmax -text [format %g $limits(max)] 791 782 $c coords vmax [expr {$w-$lx}] $ly 792 783 … … 801 792 $c itemconfigure title -text $title 802 793 $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 } 803 824 } 804 825 … … 812 833 # active transfer function is displayed. 813 834 # 814 itcl::body Rappture::NanovisViewer::ReceiveLegend { cnamevmin vmax size } {835 itcl::body Rappture::NanovisViewer::ReceiveLegend { tf vmin vmax size } { 815 836 if { ![isconnected] } { 816 837 return … … 820 841 ReceiveEcho <<line "<read $size bytes for [image width $_image(legend)]x[image height $_image(legend)] legend>" 821 842 822 DrawLegend $ _current843 DrawLegend $tf 823 844 } 824 845 … … 828 849 # The procedure is the response from the render server to each "data 829 850 # 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. 833 866 # 834 867 itcl::body Rappture::NanovisViewer::ReceiveData { args } { … … 841 874 842 875 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 } 844 898 } 845 899 … … 865 919 StartBufferingCommands 866 920 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 867 936 if { $_width != $w || $_height != $h || $_reset } { 868 937 set _width $w … … 874 943 InitSettings -background -axesvisible -gridvisible 875 944 } 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] { 882 946 foreach cname [$dataobj components] { 883 947 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! 885 950 if { [$dataobj type] == "dx" } { 886 951 set data [$dataobj blob $cname] … … 909 974 SendCmd "volume data follows $nbytes $tag" 910 975 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 929 985 if { $_reset } { 930 InitSettings -opacity -light2side -isosurfaceshading \931 -ambient -diffuse -specularlevel -specularexponent \932 -current933 934 986 # 935 987 # Reset the camera and other view parameters 936 988 # 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 $location945 }946 }947 989 set _settings(-qw) $_view(-qw) 948 990 set _settings(-qx) $_view(-qx) … … 959 1001 PanCamera 960 1002 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 } 961 1023 set _reset 0 962 1024 } 963 1025 1026 # nothing to send -- activate the proper ivol 1027 SendCmd "volume state 0" 964 1028 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 } 969 1040 # Actually write the commands to the server socket. If it fails, we don't 970 1041 # care. We're finished here. … … 988 1059 foreach cname [$_first components] { 989 1060 set tag $_first-$cname 990 if { [info exists _ datasets($tag)] && $_datasets($tag) } {1061 if { [info exists _serverDatasets($tag)] && $_serverDatasets($tag) } { 991 1062 array set style { 992 1063 -cutplanes 1 … … 1182 1253 } 1183 1254 switch -- $what { 1184 "-ambient" {1185 # Other parts of the code use the ambient setting to1186 # tell if the component settings have been initialized1187 if { ![info exists _settings($_current${what})] } {1188 InitComponentSettings $_current1189 }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 }1197 1255 "-axesvisible" { 1198 1256 SendCmd "axis visible $_settings($what)" … … 1207 1265 configure -plotbackground $bgcolor \ 1208 1266 -plotforeground $fgcolors($bgcolor) 1209 DrawLegend $_current1267 #DrawLegend $_current 1210 1268 } 1211 1269 "-colormap" { 1212 1270 set color [$itk_component(colormap) value] 1213 1271 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 1220 1274 } 1221 1275 "-cutplanesvisible" { … … 1226 1280 SendCmd "cutplane visible $bool $tag" 1227 1281 } 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 }1236 1282 "-gridvisible" { 1237 1283 SendCmd "grid visible $_settings($what)" … … 1239 1285 "-isosurfaceshading" { 1240 1286 set val $_settings($what) 1241 foreach tag [GetDatasetsWithComponent $_current] { 1242 SendCmd "volume shading isosurface $val $tag" 1243 } 1287 SendCmd "volume shading isosurface $val" 1244 1288 } 1245 1289 "-legendvisible" { … … 1253 1297 } 1254 1298 } 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 } 1255 1310 "-light2side" { 1256 set _settings($_current${what}) $_settings($what)1257 1311 set val $_settings($what) 1258 foreach tag [GetDatasetsWithComponent $_current] { 1259 SendCmd "volume shading light2side $val $tag" 1260 } 1312 SendCmd "volume shading light2side $val" 1261 1313 } 1262 1314 "-opacity" { 1263 set _settings($_current${what}) $_settings($what)1264 1315 set val $_settings($what) 1265 1316 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" 1273 1318 } 1274 1319 "-outlinevisible" { 1275 1320 SendCmd "volume outline state $_settings($what)" 1276 1321 } 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 }1292 1322 "-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 } 1296 1333 } 1297 1334 "-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" 1316 1337 } 1317 1338 "-xcutplaneposition" - "-ycutplaneposition" - "-zcutplaneposition" { … … 1356 1377 set w [expr {$_width-20}] 1357 1378 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" 1361 1383 } 1362 1384 } … … 1372 1394 # server parses the 3D data and sends back the limits via ReceiveData.] 1373 1395 # 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 # 1374 1401 itcl::body Rappture::NanovisViewer::NameTransferFunction { dataobj cname } { 1375 1402 array set style { 1376 1403 -color BCGYR 1377 1404 -levels 6 1378 -markers ""1379 1405 } 1380 1406 set tag $dataobj-$cname 1381 1407 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 1398 1412 } 1399 1413 … … 1407 1421 # the alpha map of the transfer function. 1408 1422 # 1409 itcl::body Rappture::NanovisViewer::ComputeTransferFunction { cname } { 1410 foreach {cmap amap} $_cname2transferFunction($cname) break 1423 itcl::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] 1411 1431 1412 1432 # We have to parse the style attributes for a volume using this … … 1416 1436 # of the volumes (the first in the list) using the transfer-function as a 1417 1437 # 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)] } { 1430 1444 # Have to defer creation of isomarkers until we have data limits 1431 1445 if { [info exists style(-markers)] && 1432 1446 [llength $style(-markers)] > 0 } { 1433 ParseMarkersOption $ cname$style(-markers)1447 ParseMarkersOption $tf $style(-markers) 1434 1448 } 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 }" 1459 1512 } 1460 1513 … … 1508 1561 # marker is a relative value from 0.0 to 1.0. 1509 1562 # 1510 itcl::body Rappture::NanovisViewer::ParseLevelsOption { cnamelevels } {1563 itcl::body Rappture::NanovisViewer::ParseLevelsOption { tf levels } { 1511 1564 set c $itk_component(legend) 1512 set list {}1513 1565 regsub -all "," $levels " " levels 1514 1566 if {[string is int $levels]} { 1515 1567 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 1517 1573 } 1518 1574 } else { 1519 1575 foreach x $levels { 1520 lappend list $x1521 }1522 }1523 set _parsedFunction($cname) 11524 $_transferFunctionEditors($cname) addMarkers $list1525 $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 } 1526 1582 } 1527 1583 … … 1538 1594 # not be seen. 1539 1595 # 1540 itcl::body Rappture::NanovisViewer::ParseMarkersOption { cnamemarkers } {1596 itcl::body Rappture::NanovisViewer::ParseMarkersOption { tf markers } { 1541 1597 set c $itk_component(legend) 1542 set list {}1543 foreach { min max } $_limits($cname) break1544 1598 regsub -all "," $markers " " markers 1545 1599 foreach marker $markers { 1546 1600 set n [scan $marker "%g%s" value suffix] 1547 1601 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 1550 1608 } else { 1551 # $ n : absolute value, compute relative1552 lappend list [expr {(double($value)-$min)/($max-$min)}]1553 }1554 }1555 set _parsedFunction($cname) 11556 $_transferFunctionEditors($cname) addMarkers $list1557 $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 } 1558 1616 } 1559 1617 1560 1618 itcl::body Rappture::NanovisViewer::updateTransferFunctions {} { 1561 1619 $_dispatcher event -idle !send_transfunc 1620 } 1621 1622 itcl::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 1638 itcl::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 1663 itcl::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 1678 itcl::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] 1562 1706 } 1563 1707 … … 1636 1780 #set bfg [option get $itk_component(hull) boldFont Font] 1637 1781 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 1641 1786 1642 1787 checkbutton $inner.isosurface -text "Isosurface shading" -font $fg \ … … 1648 1793 -command [itcl::code $this AdjustSetting -light2side] 1649 1794 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 1679 1801 1680 1802 # Opacity 1681 label $inner. opacity_l -text "Opacity" -font $fg1803 label $inner.clear -text "Clear" -font $fg 1682 1804 ::scale $inner.opacity -from 0 -to 100 -orient horizontal \ 1683 1805 -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 1689 1809 1690 1810 # Tooth thickness … … 1692 1812 ::scale $inner.thickness -from 0 -to 1000 -orient horizontal \ 1693 1813 -variable [itcl::scope _settings(-thickness)] \ 1694 - showvalue off -command [itcl::code $this AdjustSetting -thickness]\1695 - troughcolor grey921814 -width 10 \ 1815 -showvalue off -command [itcl::code $this AdjustSetting -thickness] 1696 1816 label $inner.thick -text "Thick" -font $fg 1697 1817 1698 1818 # Colormap 1699 label $inner.colormap_l -text "Colormap" -font $fg1819 label $inner.colormap_l -text "Colormap" -font "Arial 9" 1700 1820 itk_component add colormap { 1701 1821 Rappture::Combobox $inner.colormap -width 10 -editable no 1702 1822 } 1703 1823 1704 $inner.colormap choices insert end [GetColormapList -includeDefault -includeNone] 1824 $inner.colormap choices insert end [GetColormapList -includeNone] 1825 $itk_component(colormap) value "BCGYR" 1705 1826 bind $inner.colormap <<Value>> \ 1706 1827 [itcl::code $this AdjustSetting -colormap] 1707 $itk_component(colormap) value "default"1708 set _settings(-colormap) "default"1709 1710 # Component1711 label $inner.volcomponents_l -text "Component" -font $fg1712 itk_component add volcomponents {1713 Rappture::Combobox $inner.volcomponents -editable no1714 }1715 bind $inner.volcomponents <<Value>> \1716 [itcl::code $this AdjustSetting -current]1717 1828 1718 1829 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 1745 1845 } 1746 1846 … … 1767 1867 Rappture::Tooltip::for $itk_component(xCutButton) \ 1768 1868 "Toggle the X cut plane on/off" 1769 $itk_component(xCutButton) select1869 #$itk_component(xCutButton) select 1770 1870 1771 1871 itk_component add xCutScale { … … 1795 1895 Rappture::Tooltip::for $itk_component(yCutButton) \ 1796 1896 "Toggle the Y cut plane on/off" 1797 $itk_component(yCutButton) select1897 #$itk_component(yCutButton) select 1798 1898 1799 1899 itk_component add yCutScale { … … 1823 1923 Rappture::Tooltip::for $itk_component(zCutButton) \ 1824 1924 "Toggle the Z cut plane on/off" 1825 $itk_component(zCutButton) select1925 #$itk_component(zCutButton) select 1826 1926 1827 1927 itk_component add zCutScale { … … 1841 1941 1842 1942 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 \ 1850 1951 1851 1952 blt::table configure $inner r0 r1 r2 c* -resize none … … 1998 2099 # VTK file. To download all components/results, we would need 1999 2100 # 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] 2002 2104 return [list .vtk $bytes] 2003 2105 } … … 2083 2185 set _settings(-zoom) $_view(-zoom) 2084 2186 } 2085 2086 #2087 # InitComponentSettings --2088 #2089 # Initializes the volume settings for a specific component. This should2090 # match what's used as global settings above. This is called the first2091 # 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 602096 -colormap "default"2097 -diffuse 402098 -light2side 12099 -opacity 502100 -specularexponent 902101 -specularlevel 302102 -thickness 3502103 -volumevisible 12104 } {2105 set _settings($cname${key}) $value2106 }2107 }2108 2109 #2110 # SwitchComponent --2111 #2112 # This is called when the current component is changed by the dropdown2113 # menu in the volume tab. It synchronizes the global volume settings2114 # 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 $cname2119 }2120 # _settings variables change widgets, except for colormap2121 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 component2132 }2133 2134 #2135 # BuildVolumeComponents --2136 #2137 # This is called from the "scale" method which is called when a new2138 # dataset is added or deleted. It repopulates the dropdown menu of2139 # volume component names. It sets the current component to the first2140 # component in the list (of components found). Finally, if there is2141 # only one component, don't display the label or the combobox in the2142 # volume settings tab.2143 #2144 itcl::body Rappture::NanovisViewer::BuildVolumeComponents {} {2145 $itk_component(volcomponents) choices delete 0 end2146 foreach name $_componentsList {2147 $itk_component(volcomponents) choices insert end $name $name2148 }2149 set _current [lindex $_componentsList 0]2150 $itk_component(volcomponents) value $_current2151 set parent [winfo parent $itk_component(volcomponents)]2152 if { [llength $_componentsList] <= 1 } {2153 # Unpack the components label and dropdown if there's only one2154 # component.2155 blt::table forget $parent.volcomponents_l $parent.volcomponents2156 } else {2157 # Pack the components label and dropdown into the table there's2158 # 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 x2162 }2163 }2164 2165 #2166 # GetDatasetsWithComponents --2167 #2168 # Returns a list of all the datasets (known by the combination of their2169 # data object and component name) that match the given component name.2170 # For example, this is used where we want to change the settings of2171 # 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 continue2181 }2182 lappend list $tag2183 }2184 return $list2185 }2186 2187 #2188 # HideAllMarkers --2189 #2190 # Hide all the markers in all the transfer functions. Can't simply2191 # delete and recreate markers from the <style> since the user may have2192 # created, deleted, or moved markers.2193 #2194 itcl::body Rappture::NanovisViewer::HideAllMarkers {} {2195 foreach cname [array names _transferFunctionEditors] {2196 $_transferFunctionEditors($cname) hideMarkers2197 }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 function2209 if { ![info exists _cname2transferFunction($cname)] } {2210 return2211 }2212 foreach { cmap amap } $_cname2transferFunction($cname) break2213 set cmap [GetColormap $cname $color]2214 set _cname2transferFunction($cname) [list $cmap $amap]2215 SendCmd [list transfunc define $cname $cmap $amap]2216 EventuallyRedrawLegend2217 }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 $cname2225 }2226 2227 set isovalues [$_transferFunctionEditors($cname) values]2228 2229 # Transfer function should be normalized with [0,1] range2230 # The volume shading opacity setting is used to scale opacity2231 # in the volume shader.2232 set max 1.02233 2234 # Use the component-wise thickness setting from the slider2235 # settings widget2236 # Scale values between 0.00001 and 0.010002237 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.02244 }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.02252 } elseif { $x1 > 1.0 } {2253 set x1 1.02254 }2255 if { $x2 < 0.0 } {2256 set x2 0.02257 } elseif { $x2 > 1.0 } {2258 set x2 1.02259 }2260 if { $x3 < 0.0 } {2261 set x3 0.02262 } elseif { $x3 > 1.0 } {2263 set x3 1.02264 }2265 if { $x4 < 0.0 } {2266 set x4 0.02267 } elseif { $x4 > 1.0 } {2268 set x4 1.02269 }2270 # add spikes in the middle2271 lappend amap $x1 0.02272 lappend amap $x2 $max2273 lappend amap $x3 $max2274 lappend amap $x4 0.02275 }2276 if { $last == "" || $last != 1.0 } {2277 lappend amap 1.0 0.02278 }2279 return $amap2280 }2281 2282 itcl::body Rappture::NanovisViewer::SetObjectStyle { dataobj cname } {2283 array set style {2284 -opacity 0.52285 }2286 array set style [lindex [$dataobj components -style $cname] 0]2287 # Some tools erroneously set -opacity to 1 in style, so2288 # override the requested opacity for now2289 set style(-opacity) 0.52290 set _settings($cname-opacity) [expr $style(-opacity) * 100.0]2291 set tag $dataobj-$cname2292 SendCmd "volume shading opacity $style(-opacity) $tag"2293 NameTransferFunction $dataobj $cname2294 } -
trunk/gui/scripts/vtkvolumeviewer.tcl
r6377 r6675 62 62 } 63 63 public method scale {args} 64 public method updateTransferFunctions {}65 64 66 65 # The following methods are only used by this class. 67 private method AddNewMarker { x y }68 66 private method AdjustSetting {what {value ""}} 69 67 private method BuildAxisTab {} 70 68 private method BuildCameraTab {} 69 private method BuildColormap { name colors } 71 70 private method BuildCutplanesTab {} 72 71 private method BuildDownloadPopup { widget command } 73 72 private method BuildViewTab {} 74 private method BuildVolumeComponents {}75 73 private method BuildVolumeTab {} 76 private method ComputeAlphamap { cname } 77 private method ComputeTransferFunction { cname } 74 private method ChangeColormap { dataobj comp color } 78 75 private method Connect {} 79 76 private method CurrentDatasets {args} … … 87 84 private method EventuallyRotate { q } 88 85 private method EventuallySetCutplane { axis args } 89 private method GetColormap { cname color }90 86 private method GetDatasetsWithComponent { cname } 91 87 private method GetImage { args } 92 88 private method GetVtkData { args } 93 private method HideAllMarkers {}94 private method InitComponentSettings { cname }95 89 private method InitSettings { args } 96 90 private method IsValidObject { dataobj } … … 100 94 private method Pan {option x y} 101 95 private method PanCamera {} 102 private method ParseLevelsOption { cname levels }103 private method ParseMarkersOption { cname markers }104 96 private method Pick {x y} 105 97 private method QuaternionToView { q } { … … 110 102 private method ReceiveImage { args } 111 103 private method ReceiveLegend { colormap title min max size } 112 private method RemoveMarker { x y }113 104 private method RequestLegend {} 114 private method ResetColormap { cname color }115 105 private method Rotate {option x y} 116 private method Se ndTransferFunctions {}106 private method SetColormap { dataobj comp } 117 107 private method SetCurrentFieldName { dataobj } 118 private method SetInitialTransferFunction { dataobj cname }119 108 private method SetLegendTip { x y } 120 109 private method SetObjectStyle { dataobj cname } 121 110 private method SetOrientation { side } 122 111 private method Slice {option args} 123 private method SwitchComponent { cname }124 112 private method ViewToQuaternion {} { 125 113 return [list $_view(-qw) $_view(-qx) $_view(-qy) $_view(-qz)] … … 127 115 private method Zoom {option} 128 116 129 private variable _alphamap130 117 private variable _arcball "" 131 118 private variable _dlist ""; # list of data objects … … 141 128 private variable _limits; # Autoscale min/max for all axes 142 129 private variable _view; # View params for 3D view 143 private variable _parsedFunction144 private variable _transferFunctionEditors145 130 private variable _settings 131 private variable _style; # Array of current component styles. 132 private variable _initialStyle; # Array of initial component styles. 146 133 147 134 private variable _start 0 … … 155 142 156 143 private variable _first ""; # This is the topmost dataset. 157 private variable _current ""; # Currently selected component158 144 private variable _volcomponents; # Maps component name to list of 159 145 # dataobj-component tags 160 146 private variable _componentsList; # List of components found 161 private variable _cname2transferFunction162 private variable _cname2defaultcolormap163 147 164 148 private variable _width 0 … … 245 229 -axismode "static" 246 230 -background black 247 -color "default"231 -color BCGYR 248 232 -cutplanelighting 1 249 233 -cutplaneopacity 100 250 234 -cutplanesvisible 0 251 235 -legendvisible 1 252 -volumeambient 40253 -volumeblendmode composite254 -volumediffuse 60255 236 -volumelighting 1 237 -volumematerial 80 256 238 -volumeopacity 50 257 239 -volumeoutline 0 258 240 -volumequality 80 259 -volumespecularexponent 90260 -volumespecularlevel 30261 -volumethickness 350262 241 -volumevisible 1 263 242 -xcutplaneposition 50 … … 374 353 set _image(legend) [image create photo] 375 354 itk_component add legend { 376 canvas $itk_component(plotarea).legend - height50 -highlightthickness 0355 canvas $itk_component(plotarea).legend -width 50 -highlightthickness 0 377 356 } { 378 357 usual … … 380 359 rename -background -plotbackground plotBackground Background 381 360 } 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)]386 361 387 362 # Hack around the Tk panewindow. The problem is that the requested … … 391 366 pack forget $itk_component(view) 392 367 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 396 370 397 371 # Bindings for rotation via mouse … … 729 703 } 730 704 } 731 BuildVolumeComponents732 updateTransferFunctions733 705 } 734 706 … … 872 844 array unset _colormaps 873 845 array unset _dataset2style 874 875 array unset _parsedFunction876 array unset _cname2transferFunction877 846 878 847 set _resizePending 0 … … 1068 1037 InitSettings -color \ 1069 1038 -volumevisible \ 1070 -volumeambient -volumediffuse -volumespecularlevel \ 1071 -volumespecularexponent -volumeblendmode -volumethickness \ 1039 -volumematerial \ 1072 1040 -volumelighting -volumeopacity -volumequality -volumeoutline \ 1073 1041 -cutplanesvisible \ … … 1349 1317 set color [$itk_component(colormap) value] 1350 1318 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 1357 1324 } 1358 1325 "-cutplanelighting" { … … 1416 1383 } 1417 1384 "-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" { 1432 1388 set val $_settings($what) 1433 set _settings($_current${what}) $val1434 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) $mode1443 set _settings($_current${what}) $mode1444 foreach tag [GetDatasetsWithComponent $_current] {1445 SendCmd "volume blendmode $mode $tag"1446 }1447 }1448 "-volumediffuse" {1449 set val $_settings($what)1450 set _settings($_current${what}) $val1451 1389 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] { 1453 1394 SendCmd "volume shading diffuse $diffuse $tag" 1395 SendCmd "volume shading specular $specular $power $tag" 1454 1396 } 1455 1397 } 1456 1398 "-volumelighting" { 1457 1399 set bool $_settings($what) 1458 set _settings($_current${what}) $bool 1459 foreach tag [GetDatasetsWithComponent $_current] { 1400 foreach tag [CurrentDatasets -visible] { 1460 1401 SendCmd "volume lighting $bool $tag" 1461 1402 } … … 1463 1404 "-volumeopacity" { 1464 1405 set val $_settings($what) 1465 set _settings($_current${what}) $val1466 1406 set val [expr {0.01*$val}] 1467 foreach tag [ GetDatasetsWithComponent $_current] {1407 foreach tag [CurrentDatasets -visible] { 1468 1408 SendCmd "volume opacity $val $tag" 1469 1409 } … … 1472 1412 set bool $_settings($what) 1473 1413 SendCmd "outline visible 0" 1474 foreach tag [ GetDatasetsWithComponent $_current] {1414 foreach tag [CurrentDatasets -visible] { 1475 1415 SendCmd "outline visible $bool $tag" 1476 1416 } … … 1478 1418 "-volumequality" { 1479 1419 set val $_settings($what) 1480 set _settings($_current${what}) $val1481 1420 set val [expr {0.01*$val}] 1482 foreach tag [ GetDatasetsWithComponent $_current] {1421 foreach tag [CurrentDatasets -visible] { 1483 1422 SendCmd "volume quality $val $tag" 1484 1423 } 1485 }1486 "-volumespecularlevel" - "-volumespecularexponent" {1487 set val $_settings($what)1488 set _settings($_current${what}) $val1489 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 updateTransferFunctions1498 1424 } 1499 1425 "-volumevisible" { 1500 1426 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" 1515 1429 } 1516 1430 if { $bool } { … … 1564 1478 set _legendPending 0 1565 1479 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 } 1572 1486 # Set the legend on the first dataset. 1573 1487 foreach dataset [CurrentDatasets -visible $_first] { … … 1579 1493 } 1580 1494 } 1495 } 1496 1497 # 1498 # ChangeColormap -- 1499 # 1500 itcl::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 # 1514 itcl::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 # 1552 itcl::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] 1581 1563 } 1582 1564 … … 1675 1657 $inner configure -borderwidth 4 1676 1658 1677 label $inner.volcomponents_l -text "Component" -font $font1678 itk_component add volcomponents {1679 Rappture::Combobox $inner.volcomponents -editable 01680 }1681 bind $inner.volcomponents <<Value>> \1682 [itcl::code $this AdjustSetting -current]1683 1684 1659 checkbutton $inner.visibility \ 1685 1660 -text "Visible" \ … … 1688 1663 -command [itcl::code $this AdjustSetting -volumevisible] 1689 1664 1690 label $inner.lighting_l \1691 -text "Lighting / Material Properties" \1692 -font $bfont1693 1694 1665 checkbutton $inner.lighting \ 1695 1666 -text "Enable Lighting" \ … … 1698 1669 -command [itcl::code $this AdjustSetting -volumelighting] 1699 1670 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)] \ 1705 1674 -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 1729 1677 1730 1678 label $inner.opacity_l -text "Opacity" -font $font … … 1732 1680 -variable [itcl::scope _settings(-volumeopacity)] \ 1733 1681 -showvalue off \ 1734 -command [itcl::code $this AdjustSetting -volumeopacity] \ 1735 -troughcolor grey92 1682 -command [itcl::code $this AdjustSetting -volumeopacity] 1736 1683 1737 1684 label $inner.quality_l -text "Quality" -font $font … … 1739 1686 -variable [itcl::scope _settings(-volumequality)] \ 1740 1687 -showvalue off \ 1741 -command [itcl::code $this AdjustSetting -volumequality] \ 1742 -troughcolor grey92 1688 -command [itcl::code $this AdjustSetting -volumequality] 1743 1689 1744 1690 label $inner.field_l -text "Field" -font $font … … 1749 1695 [itcl::code $this AdjustSetting -field] 1750 1696 1751 label $inner.transferfunction_l \1752 -text "Transfer Function" -font $bfont1753 1754 label $inner.thin -text "Thin" -font $font1755 ::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 grey921760 1761 label $inner.thick -text "Thick" -font $font1762 $inner.thickness set $_settings(-volumethickness)1763 1764 1697 label $inner.colormap_l -text "Colormap" -font $font 1765 1698 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] 1770 1702 bind $inner.colormap <<Value>> \ 1771 1703 [itcl::code $this AdjustSetting -color] 1772 1704 $itk_component(colormap) value $_settings(-color) 1773 1705 1774 label $inner.blendmode_l -text "Blend Mode" -font $font1775 itk_component add blendmode {1776 Rappture::Combobox $inner.blendmode -editable 01777 }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 1788 1706 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 1821 1723 } 1822 1724 … … 2183 2085 } 2184 2086 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) 2189 2091 2190 2092 $itk_component(colormap) value $style(-color) … … 2202 2104 SendCmd "volume opacity $style(-opacity) $tag" 2203 2105 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 2208 2107 } 2209 2108 … … 2240 2139 # 2241 2140 itcl::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) 2247 2143 set w [winfo width $c] 2248 2144 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 2281 2155 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. 2285 2190 $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}] 2287 2203 } 2288 2204 … … 2430 2346 } 2431 2347 2432 #2433 # The -levels option takes a single value that represents the number2434 # of evenly distributed markers based on the current data range. Each2435 # 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 " " levels2441 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 $x2448 }2449 }2450 set _parsedFunction($cname) 12451 $_transferFunctionEditors($cname) addMarkers $list2452 }2453 2454 #2455 # The -markers option takes a list of zero or more values (the values2456 # may be separated either by spaces or commas) that have the following2457 # format:2458 #2459 # N% Percent of current total data range. Converted to2460 # to a relative value between 0.0 and 1.0.2461 # N Absolute value of marker. If the marker is outside of2462 # the current range, it will be displayed on the outer2463 # edge of the legends, but it range it represents will2464 # 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) break2470 regsub -all "," $markers " " markers2471 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 relative2478 lappend list [expr {(double($value)-$min)/($max-$min)}]2479 }2480 }2481 set _parsedFunction($cname) 12482 $_transferFunctionEditors($cname) addMarkers $list2483 }2484 2485 #2486 # SetInitialTransferFunction --2487 #2488 # Creates a transfer function name based on the <style> settings in the2489 # library run.xml file. This placeholder will be used later to create2490 # and send the actual transfer function once the data info has been sent2491 # to us by the render server. [We won't know the volume limits until the2492 # 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-$cname2496 if { ![info exists _cname2transferFunction($cname)] } {2497 ComputeTransferFunction $cname2498 }2499 set _dataset2style($tag) $cname2500 2501 return $cname2502 }2503 2504 #2505 # ComputeTransferFunction --2506 #2507 # Computes and sends the transfer function to the render server. It's2508 # assumed that the volume data limits are known and that the global2509 # transfer-functions slider values have been set up. Both parts are2510 # needed to compute the relative value (location) of the marker, and2511 # 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 this2523 # transfer-function *once*. This sets up the initial isomarkers for the2524 # transfer function. The user may add/delete markers, so we have to2525 # maintain a list of markers for each transfer-function. We use the one2526 # of the volumes (the first in the list) using the transfer-function as a2527 # reference.2528 if { ![info exists _parsedFunction($cname)] ||2529 ![info exists _cname2transferFunction($cname)] } {2530 array set style {2531 -color BCGYR2532 -levels 62533 }2534 # Accumulate the style from all the datasets using it.2535 foreach tag [GetDatasetsWithComponent $cname] {2536 foreach {dataobj cname} [split [lindex $tag 0] -] break2537 set option [lindex [$dataobj components -style $cname] 0]2538 array set style $option2539 }2540 set _settings($cname-color) $style(-color)2541 set cmap [ColorsToColormap $style(-color)]2542 set _cname2defaultcolormap($cname) $cmap2543 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 UI2547 # to allow editing the transfer function2548 array unset style -alphamap2549 if { [info exists style(-alphamap)] &&2550 $style(-alphamap) != "" } {2551 set _alphamap($cname) $style(-alphamap)2552 set _parsedFuntion($cname) 12553 } 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) break2563 }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 map2570 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 function2583 if { ![info exists _cname2transferFunction($cname)] } {2584 return2585 }2586 foreach { cmap amap } $_cname2transferFunction($cname) break2587 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 EventuallyRequestLegend2593 }2594 2595 # ----------------------------------------------------------------------2596 # USAGE: updateTransferFunctions2597 #2598 # This is called by the transfer function editor whenever the2599 # transfer function definition changes.2600 # ----------------------------------------------------------------------2601 itcl::body Rappture::VtkVolumeViewer::updateTransferFunctions {} {2602 foreach cname [array names _volcomponents] {2603 ComputeTransferFunction $cname2604 }2605 EventuallyRequestLegend2606 }2607 2608 itcl::body Rappture::VtkVolumeViewer::AddNewMarker { x y } {2609 if { ![info exists _transferFunctionEditors($_current)] } {2610 continue2611 }2612 # Add a new marker to the current transfer function2613 $_transferFunctionEditors($_current) newMarker $x $y normal2614 }2615 2616 itcl::body Rappture::VtkVolumeViewer::RemoveMarker { x y } {2617 if { ![info exists _transferFunctionEditors($_current)] } {2618 continue2619 }2620 # Add a new marker to the current transfer function2621 $_transferFunctionEditors($_current) deleteMarker $x $y2622 }2623 2624 2348 itcl::body Rappture::VtkVolumeViewer::SetOrientation { side } { 2625 2349 array set positions { … … 2644 2368 2645 2369 # 2646 # InitComponentSettings --2647 #2648 # Initializes the volume settings for a specific component. This2649 # should match what's used as global settings above. This2650 # is called the first time we try to switch to a given component2651 # in SwitchComponent below.2652 #2653 itcl::body Rappture::VtkVolumeViewer::InitComponentSettings { cname } {2654 array set _settings [subst {2655 $cname-color default2656 $cname-volumeambient 402657 $cname-volumeblendmode composite2658 $cname-volumediffuse 602659 $cname-volumelight2side 12660 $cname-volumelighting 12661 $cname-volumeopacity 502662 $cname-volumeoutline 02663 $cname-volumequality 802664 $cname-volumespecularexponent 902665 $cname-volumespecularlevel 302666 $cname-volumethickness 3502667 $cname-volumevisible 12668 }]2669 }2670 2671 #2672 # SwitchComponent --2673 #2674 # This is called when the current component is changed by the2675 # dropdown menu in the volume tab. It synchronizes the global2676 # 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 $cname2681 }2682 # _settings variables change widgets, except for colormap2683 foreach name {2684 -volumeambient2685 -volumeblendmode2686 -volumediffuse2687 -volumelight2side2688 -volumelighting2689 -volumeopacity2690 -volumeoutline2691 -volumequality2692 -volumespecularexponent2693 -volumespecularlevel2694 -volumethickness2695 -volumevisible2696 } {2697 set _settings($name) $_settings(${cname}${name})2698 }2699 $itk_component(colormap) value $_settings($cname-color)2700 set _current $cname; # Reset the current component2701 }2702 2703 #2704 # Alpha map is in the format: normalized_value opacity midpoint sharpness2705 #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 $cname2712 }2713 2714 set isovalues [$_transferFunctionEditors($cname) values]2715 2716 # Currently using volume opacity to scale opacity in2717 # the volume shader. The transfer function always sets full2718 # opacity2719 set max 1.0;2720 2721 # Use the component-wise thickness setting from the slider2722 # settings widget2723 # Scale values between 0.00001 and 0.010002724 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.02730 }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.02738 } elseif { $x1 > 1.0 } {2739 set x1 1.02740 }2741 if { $x2 < 0.0 } {2742 set x2 0.02743 } elseif { $x2 > 1.0 } {2744 set x2 1.02745 }2746 if { $x3 < 0.0 } {2747 set x3 0.02748 } elseif { $x3 > 1.0 } {2749 set x3 1.02750 }2751 if { $x4 < 0.0 } {2752 set x4 0.02753 } elseif { $x4 > 1.0 } {2754 set x4 1.02755 }2756 # add spikes in the middle2757 lappend amap $x1 0.0 0.5 0.02758 lappend amap $x2 $max 0.5 0.02759 lappend amap $x3 $max 0.5 0.02760 lappend amap $x4 0.0 0.5 0.02761 }2762 if { $last == "" || $last != 1.0 } {2763 lappend amap 1.0 0.0 0.5 0.02764 }2765 return $amap2766 }2767 2768 #2769 # HideAllMarkers --2770 #2771 # Hide all the markers in all the transfer functions. Can't simply2772 # delete and recreate markers from the <style> since the user may2773 # have create, deleted, or moved markers.2774 #2775 itcl::body Rappture::VtkVolumeViewer::HideAllMarkers {} {2776 foreach cname [array names _transferFunctionEditors] {2777 $_transferFunctionEditors($cname) hideMarkers2778 }2779 }2780 2781 #2782 2370 # GetDatasetsWithComponent -- 2783 2371 # … … 2792 2380 } 2793 2381 return $_volcomponents($cname) 2794 }2795 2796 #2797 # BuildVolumeComponents --2798 #2799 # This is called from the "scale" method which is called when a2800 # new dataset is added or deleted. It repopulates the dropdown2801 # menu of volume component names. It sets the current component2802 # to the first component in the list (of components found).2803 # Finally, if there is only one component, don't display the2804 # label or the combobox in the volume settings tab.2805 #2806 itcl::body Rappture::VtkVolumeViewer::BuildVolumeComponents {} {2807 $itk_component(volcomponents) choices delete 0 end2808 foreach name $_componentsList {2809 $itk_component(volcomponents) choices insert end $name $name2810 }2811 set _current [lindex $_componentsList 0]2812 $itk_component(volcomponents) value $_current2813 set parent [winfo parent $itk_component(volcomponents)]2814 if { [llength $_componentsList] <= 1 } {2815 # Unpack the components label and dropdown if there's only one2816 # component.2817 catch {blt::table forget $parent.volcomponents_l $parent.volcomponents}2818 } else {2819 # Pack the components label and dropdown into the table there's2820 # 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 x2824 }2825 }2826 2827 itcl::body Rappture::VtkVolumeViewer::GetColormap { cname color } {2828 if { $color == "default" } {2829 return $_cname2defaultcolormap($cname)2830 }2831 return [ColorsToColormap $color]2832 2382 } 2833 2383
Note: See TracChangeset
for help on using the changeset viewer.