Changeset 1349
- Timestamp:
- Mar 20, 2009, 6:54:23 PM (16 years ago)
- Location:
- trunk/gui/scripts
- Files:
-
- 10 added
- 3 deleted
- 4 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/gui/scripts/flowvisviewer.tcl
r1343 r1349 1 1 2 2 # ---------------------------------------------------------------------- 3 # COMPONENT: flowvisviewer - 3D vector field rendering 4 # 5 # This widget performs vector field rendering on 3D scalar/vector datasets. 6 # It connects to the Nanovis server running on a rendering farm, 7 # transmits data, and displays the results. 3 # COMPONENT: flowvisviewer - 3D flow rendering 4 # 5 # 6 # This widget performs volume and flow rendering on 3D scalar/vector datasets. 7 # It connects to the Flowvis server running on a rendering farm, transmits 8 # data, and displays the results. 9 # 8 10 # ====================================================================== 9 # AUTHOR: Derrick Kearney, Purdue University10 # Copyright (c) 200 5-2009Purdue Research Foundation11 # 12 # See the file "license.terms" for information on usage and13 # redistribution ofthis file, and for a DISCLAIMER OF ALL WARRANTIES.11 # AUTHOR: Michael McLennan, Purdue University 12 # Copyright (c) 2004-2005 Purdue Research Foundation 13 # 14 # See the file "license.terms" for information on usage and redistribution of 15 # this file, and for a DISCLAIMER OF ALL WARRANTIES. 14 16 # ====================================================================== 15 16 17 package require Itk 17 18 package require BLT … … 19 20 20 21 option add *FlowvisViewer.width 4i widgetDefault 22 option add *FlowvisViewer*cursor crosshair widgetDefault 21 23 option add *FlowvisViewer.height 4i widgetDefault 22 24 option add *FlowvisViewer.foreground black widgetDefault … … 25 27 option add *FlowvisViewer.plotBackground black widgetDefault 26 28 option add *FlowvisViewer.plotForeground white widgetDefault 27 option add *FlowvisViewer.plotOutline white widgetDefault 29 #FIXME: why is plot outline gray? not white? 30 option add *FlowvisViewer.plotOutline gray widgetDefault 28 31 option add *FlowvisViewer.font \ 29 32 -*-helvetica-medium-r-normal-*-12-* widgetDefault 30 option add *FlowvisViewer.boldFont \31 -*-helvetica-bold-r-normal-*-12-* widgetDefault32 33 33 34 # must use this name -- plugs into Rappture::resources::load 34 35 proc FlowvisViewer_init_resources {} { 35 36 Rappture::resources::register \ 36 37 nanovis_server Rappture::FlowvisViewer::SetServerList 37 38 } 38 39 … … 45 46 46 47 constructor { hostlist args } { 47 48 Rappture::VisViewer::constructor $hostlist 48 49 } { 49 50 # defined below 50 51 } 51 52 destructor { 52 # defined below 53 } 54 53 # defined below 54 } 55 55 public proc SetServerList { namelist } { 56 56 Rappture::VisViewer::SetServerList "nanovis" $namelist 57 57 } 58 58 public method add {dataobj {settings ""}} … … 62 62 public method download {option args} 63 63 public method parameters {title args} { 64 64 # do nothing 65 65 } 66 66 public method isconnected {} 67 68 public method GetLimits { tf } 69 public method UpdateTransferFunctions {} 70 public method RemoveDuplicateIsoMarker { m x } 71 public method OverIsoMarker { m x } 72 73 public method drawer {what who} 74 public method camera {option args} 67 75 68 76 protected method Connect {} 69 77 protected method Disconnect {} 70 78 79 protected method SendCmd {string} 71 80 protected method _send {string} 72 protected method _send_dataobjs {} 73 protected method ReceiveImage {option size} 74 protected method ReceiveFile {option size} 75 private method ReceiveLegend {tf vmin vmax size} 76 protected method _receive_echo {channel {data ""}} 77 78 protected method _rebuild {} 79 protected method _currentVolumeIds {{what -all}} 80 protected method _zoom {option} 81 protected method _pan {option x y} 82 protected method _rotate {option x y} 83 protected method _slice {option args} 84 protected method _slicertip {axis} 85 86 protected method _flow {option args} 87 protected method _play {} 88 protected method _pause {} 89 90 protected method _state {comp} 91 protected method _fixSettings {what {value ""}} 92 protected method _getTransfuncData {dataobj comp} 93 81 protected method SendDataObjs {} 82 protected method SendTransferFunctions {} 83 84 protected method ReceiveImage { args } 85 protected method ReceiveLegend { ivol vmin vmax size } 86 protected method ReceiveData { args } 87 88 protected method Rebuild {} 89 protected method CurrentVolumeIds {{what -all}} 90 protected method Zoom {option} 91 protected method Pan {option x y} 92 protected method Rotate {option x y} 93 protected method Slice {option args} 94 protected method SlicerTip {axis} 95 96 protected method Flow {option args} 97 protected method Play {} 98 protected method Pause {} 99 public method flow {option} 100 public method record {option} 101 102 protected method State {comp} 103 protected method FixSettings {what {value ""}} 104 protected method FixLegend {} 105 106 # The following methods are only used by this class. 107 private method NameTransferFunction { ivol } 108 private method ComputeTransferFunction { tf } 109 private method AddIsoMarker { x y } 110 private method ParseMarkersOption { tf ivol markers } 111 private method ParseLevelsOption { tf ivol levels } 112 private method BuildCutplanesDrawer {} 113 private method BuildSettingsDrawer {} 114 private method BuildCameraDrawer {} 115 private method PanCamera {} 94 116 95 117 private variable outbuf_ ;# buffer for outgoing commands 96 118 97 119 private variable dlist_ "" ;# list of data objects 98 private variable obj2style_ ;# maps dataobj => style settings 120 private variable all_data_objs_ 121 private variable id2style_ ;# maps id => style settings 99 122 private variable obj2ovride_ ;# maps dataobj => style override 100 private variable obj2id_ ;# maps dataobj => heightmapID in server101 private variable id2obj_ ;# maps heightmap ID => dataobjin server123 private variable obj2id_ ;# maps dataobj => volume ID in server 124 private variable id2obj_ ;# maps dataobj => volume ID in server 102 125 private variable sendobjs_ "" ;# list of data objs to send to server 103 private variable receiveIds_ ;# list of data responses from the server 104 private variable click_ ;# info used for _rotate operations 126 private variable receiveIds_ ;# list of data objs to send to server 127 private variable obj2styles_ ;# maps id => style settings 128 private variable style2ids_ ;# maps id => style settings 129 130 private variable click_ ;# info used for Rotate operations 105 131 private variable limits_ ;# autoscale min/max for all axes 106 132 private variable view_ ;# view params for 3D view 107 108 private common settings_ ;# Array used for checkbuttons and radiobuttons133 private variable isomarkers_ ;# array of isosurface level values 0..1 134 private common settings_ 109 135 private variable activeTf_ "" ;# The currently active transfer function. 110 111 common _downloadPopup ;# download options from popup 112 113 private variable _afterId "" ;# current "after" event for play op 114 private common _play ;# options for "play" operation 115 set _play(speed) 10 136 private variable flow_ 137 # This 138 # indicates which isomarkers and transfer 139 # function to use when changing markers, 140 # opacity, or thickness. 141 common downloadPopup_ ;# download options from popup 142 143 private variable drawer_ 144 private common hardcopy_ 116 145 } 117 146 … … 124 153 # CONSTRUCTOR 125 154 # ---------------------------------------------------------------------- 126 itcl::body Rappture::FlowvisViewer::constructor {hostlist args} { 155 itcl::body Rappture::FlowvisViewer::constructor { hostlist args } { 156 157 # Draw legend event 158 $_dispatcher register !legend 159 $_dispatcher dispatch $this !legend "[itcl::code $this FixLegend]; list" 127 160 # Send dataobjs event 128 161 $_dispatcher register !send_dataobjs 129 162 $_dispatcher dispatch $this !send_dataobjs \ 130 "[itcl::code $this _send_dataobjs]; list" 163 "[itcl::code $this SendDataObjs]; list" 164 # Send transfer functions event 165 $_dispatcher register !send_transfunc 166 $_dispatcher dispatch $this !send_transfunc \ 167 "[itcl::code $this SendTransferFunctions]; list" 131 168 # Rebuild event 132 169 $_dispatcher register !rebuild 133 $_dispatcher dispatch $this !rebuild "[itcl::code $this _rebuild]; list" 134 135 array set _downloadPopup { 136 format jpg 137 } 138 170 $_dispatcher dispatch $this !rebuild "[itcl::code $this Rebuild]; list" 171 172 $_dispatcher register !play 173 $_dispatcher dispatch $this !play "[itcl::code $this flow next]; list" 174 139 175 set outbuf_ "" 140 176 set flow_(state) "stopped" 177 array set downloadPopup_ { 178 format jpg 179 } 180 array set play_ { 181 } 141 182 # 142 183 # Populate parser with commands handle incoming requests 143 184 # 144 185 $_parser alias image [itcl::code $this ReceiveImage] 145 $_parser alias file [itcl::code $this ReceiveFile] 186 $_parser alias legend [itcl::code $this ReceiveLegend] 187 $_parser alias data [itcl::code $this ReceiveData] 146 188 147 189 # Initialize the view to some default parameters. … … 151 193 psi 0 152 194 zoom 1.0 153 dx0154 dy0195 pan-x 0 196 pan-y 0 155 197 } 156 198 set obj2id_(count) 0 157 158 itk_component add zoom { 159 frame $itk_component(controls).zoom 199 set id2obj_(count) 0 200 set limits_(vmin) 0.0 201 set limits_(vmax) 1.0 202 set settings_($this-theta) $view_(theta) 203 set settings_($this-phi) $view_(phi) 204 set settings_($this-psi) $view_(psi) 205 set settings_($this-pan-x) $view_(pan-x) 206 set settings_($this-pan-y) $view_(pan-y) 207 set settings_($this-zoom) $view_(zoom) 208 set settings_($this-speed) 10 209 210 itk_component add reset { 211 button $itk_component(controls).reset \ 212 -borderwidth 1 -padx 1 -pady 1 \ 213 -image [Rappture::icon reset-view] \ 214 -command [itcl::code $this Zoom reset] 160 215 } { 161 usual 162 rename -background -controlbackground controlBackground Background 163 } 164 pack $itk_component(zoom) -side top 165 166 itk_component add reset { 167 button $itk_component(zoom).reset \ 216 usual 217 ignore -borderwidth 218 rename -highlightbackground -controlbackground controlBackground Background 219 } 220 pack $itk_component(reset) -side top -padx 2 -pady 1 221 Rappture::Tooltip::for $itk_component(reset) "Reset the view to the default zoom level" 222 223 itk_component add zoomin { 224 button $itk_component(controls).zin \ 225 -borderwidth 1 -padx 1 -pady 1 \ 226 -image [Rappture::icon zoom-in] \ 227 -command [itcl::code $this Zoom in] 228 } { 229 usual 230 ignore -borderwidth 231 rename -highlightbackground -controlbackground controlBackground Background 232 } 233 pack $itk_component(zoomin) -side top -padx 1 -pady 1 234 Rappture::Tooltip::for $itk_component(zoomin) "Zoom in" 235 236 itk_component add zoomout { 237 button $itk_component(controls).zout \ 238 -borderwidth 1 -padx 1 -pady 1 \ 239 -image [Rappture::icon zoom-out] \ 240 -command [itcl::code $this Zoom out] 241 } { 242 usual 243 ignore -borderwidth 244 rename -highlightbackground -controlbackground controlBackground Background 245 } 246 pack $itk_component(zoomout) -side top -padx 2 -pady 1 247 Rappture::Tooltip::for $itk_component(zoomout) "Zoom out" 248 249 itk_component add settingsButton { 250 label $itk_component(controls).settingsbutton \ 168 251 -borderwidth 1 -padx 1 -pady 1 \ 169 -image [Rappture::icon reset-view] \ 170 -command [itcl::code $this _zoom reset] 252 -relief "raised" -image [Rappture::icon wrench] 171 253 } { 172 254 usual 173 255 ignore -borderwidth 174 rename -highlightbackground -controlbackground controlBackground Background 175 } 176 pack $itk_component(reset) -side left -padx {4 1} -pady 2 177 Rappture::Tooltip::for $itk_component(reset) "Reset the view to the default zoom level" 178 179 itk_component add zoomin { 180 button $itk_component(zoom).zin \ 256 rename -highlightbackground -controlbackground controlBackground \ 257 Background 258 } 259 pack $itk_component(settingsButton) -padx 2 -pady 1 \ 260 -ipadx 1 -ipady 1 261 Rappture::Tooltip::for $itk_component(settingsButton) \ 262 "Configure settings" 263 bind $itk_component(settingsButton) <ButtonPress> \ 264 [itcl::code $this drawer toggle settings] 265 pack $itk_component(settingsButton) -side bottom \ 266 -padx 2 -pady 2 -anchor e 267 268 BuildSettingsDrawer 269 270 itk_component add cutplanesButton { 271 label $itk_component(controls).cutplanesbutton \ 181 272 -borderwidth 1 -padx 1 -pady 1 \ 182 -image [Rappture::icon zoom-in] \ 183 -command [itcl::code $this _zoom in] 273 -relief "raised" -image [Rappture::icon cutbutton] 184 274 } { 185 275 usual 186 276 ignore -borderwidth 187 rename -highlightbackground -controlbackground controlBackground Background 188 } 189 pack $itk_component(zoomin) -side left -padx 1 -pady 2 190 Rappture::Tooltip::for $itk_component(zoomin) "Zoom in" 191 192 itk_component add zoomout { 193 button $itk_component(zoom).zout \ 277 rename -highlightbackground -controlbackground controlBackground \ 278 Background 279 } 280 Rappture::Tooltip::for $itk_component(cutplanesButton) \ 281 "Set cutplanes" 282 bind $itk_component(cutplanesButton) <ButtonPress> \ 283 [itcl::code $this drawer toggle cutplanes] 284 pack $itk_component(cutplanesButton) -side bottom \ 285 -padx 2 -pady { 0 2 } -ipadx 1 -ipady 1 286 287 BuildCutplanesDrawer 288 289 itk_component add cameraButton { 290 label $itk_component(controls).camerabutton \ 194 291 -borderwidth 1 -padx 1 -pady 1 \ 195 -image [Rappture::icon zoom-out] \ 196 -command [itcl::code $this _zoom out] 292 -relief "raised" -image [Rappture::icon camera] 197 293 } { 198 294 usual 199 295 ignore -borderwidth 200 rename -highlightbackground -controlbackground controlBackground Background 201 } 202 pack $itk_component(zoomout) -side left -padx {1 4} -pady 2 203 Rappture::Tooltip::for $itk_component(zoomout) "Zoom out" 204 205 # 206 # Create slicer controls... 207 # 208 itk_component add slicers { 209 frame $itk_component(controls).slicers 210 } { 211 usual 212 rename -background -controlbackground controlBackground Background 213 } 214 pack $itk_component(slicers) -side bottom -padx 4 -pady 2 215 grid rowconfigure $itk_component(slicers) 1 -weight 1 216 # 217 # X-value slicer... 218 # 219 itk_component add xslice { 220 label $itk_component(slicers).xslice \ 221 -borderwidth 1 -relief raised -padx 1 -pady 1 \ 222 -image [Rappture::icon x-cutplane] 223 } { 224 usual 225 ignore -borderwidth 226 rename -highlightbackground -controlbackground controlBackground Background 227 } 228 bind $itk_component(xslice) <ButtonPress> \ 229 [itcl::code $this _slice axis x toggle] 230 Rappture::Tooltip::for $itk_component(xslice) \ 231 "Toggle the X cut plane on/off" 232 grid $itk_component(xslice) -row 1 -column 0 -sticky ew -padx 1 233 234 itk_component add xslicer { 235 ::scale $itk_component(slicers).xval -from 100 -to 0 \ 236 -width 10 -orient vertical -showvalue off \ 237 -borderwidth 1 -highlightthickness 0 \ 238 -command [itcl::code $this _slice move x] 239 } { 240 usual 241 ignore -borderwidth 242 ignore -highlightthickness 243 rename -highlightbackground -controlbackground controlBackground Background 244 rename -troughcolor -controldarkbackground controlDarkBackground Background 245 } 246 $itk_component(xslicer) set 50 247 $itk_component(xslicer) configure -state disabled 248 grid $itk_component(xslicer) -row 2 -column 0 -padx 1 249 Rappture::Tooltip::for $itk_component(xslicer) \ 250 "@[itcl::code $this _slicertip x]" 251 252 # 253 # Y-value slicer... 254 # 255 itk_component add yslice { 256 label $itk_component(slicers).yslice \ 257 -borderwidth 1 -relief raised -padx 1 -pady 1 \ 258 -image [Rappture::icon y-cutplane] 259 } { 260 usual 261 ignore -borderwidth 262 rename -highlightbackground -controlbackground controlBackground Background 263 } 264 bind $itk_component(yslice) <ButtonPress> \ 265 [itcl::code $this _slice axis y toggle] 266 Rappture::Tooltip::for $itk_component(yslice) \ 267 "Toggle the Y cut plane on/off" 268 grid $itk_component(yslice) -row 1 -column 1 -sticky ew -padx 1 269 270 itk_component add yslicer { 271 ::scale $itk_component(slicers).yval -from 100 -to 0 \ 272 -width 10 -orient vertical -showvalue off \ 273 -borderwidth 1 -highlightthickness 0 \ 274 -command [itcl::code $this _slice move y] 275 } { 276 usual 277 ignore -borderwidth 278 ignore -highlightthickness 279 rename -highlightbackground -controlbackground controlBackground Background 280 rename -troughcolor -controldarkbackground controlDarkBackground Background 281 } 282 $itk_component(yslicer) set 50 283 $itk_component(yslicer) configure -state disabled 284 grid $itk_component(yslicer) -row 2 -column 1 -padx 1 285 Rappture::Tooltip::for $itk_component(yslicer) \ 286 "@[itcl::code $this _slicertip y]" 287 288 # 289 # Z-value slicer... 290 # 291 itk_component add zslice { 292 label $itk_component(slicers).zslice \ 293 -borderwidth 1 -relief raised -padx 1 -pady 1 \ 294 -image [Rappture::icon z-cutplane] 295 } { 296 usual 297 ignore -borderwidth 298 rename -highlightbackground -controlbackground controlBackground Background 299 } 300 grid $itk_component(zslice) -row 1 -column 2 -sticky ew -padx 1 301 bind $itk_component(zslice) <ButtonPress> \ 302 [itcl::code $this _slice axis z toggle] 303 Rappture::Tooltip::for $itk_component(zslice) \ 304 "Toggle the Z cut plane on/off" 305 306 itk_component add zslicer { 307 ::scale $itk_component(slicers).zval -from 100 -to 0 \ 308 -width 10 -orient vertical -showvalue off \ 309 -borderwidth 1 -highlightthickness 0 \ 310 -command [itcl::code $this _slice move z] 311 } { 312 usual 313 ignore -borderwidth 314 ignore -highlightthickness 315 rename -highlightbackground -controlbackground controlBackground Background 316 rename -troughcolor -controldarkbackground controlDarkBackground Background 317 } 318 $itk_component(zslicer) set 50 319 $itk_component(zslicer) configure -state disabled 320 grid $itk_component(zslicer) -row 2 -column 2 -padx 1 321 Rappture::Tooltip::for $itk_component(zslicer) \ 322 "@[itcl::code $this _slicertip z]" 296 rename -highlightbackground -controlbackground controlBackground \ 297 Background 298 } 299 Rappture::Tooltip::for $itk_component(cameraButton) \ 300 "Camera settings" 301 bind $itk_component(cameraButton) <ButtonPress> \ 302 [itcl::code $this drawer toggle camera] 303 pack $itk_component(cameraButton) -side bottom \ 304 -padx 2 -pady 1 -ipadx 1 -ipady 1 305 306 BuildCameraDrawer 323 307 324 308 # … … 326 310 # 327 311 itk_component add volume { 328 label $itk_component(slicers).volume \ 329 -borderwidth 1 -relief sunken -padx 1 -pady 1 \ 330 -text "Volume" 312 label $itk_component(controls).volume \ 313 -borderwidth 1 -relief sunken -padx 1 -pady 1 \ 314 -text "Volume" \ 315 -image [Rappture::icon playback-record] 316 } { 317 usual 318 ignore -borderwidth 319 rename -highlightbackground -controlbackground controlBackground Background 320 } 321 bind $itk_component(volume) <ButtonPress> \ 322 [itcl::code $this Slice volume toggle] 323 Rappture::Tooltip::for $itk_component(volume) \ 324 "Toggle the volume cloud on/off" 325 pack $itk_component(volume) -padx 1 -pady 1 326 327 # Legend 328 329 set _image(legend) [image create photo] 330 itk_component add legend { 331 canvas $itk_component(area).legend -height 50 -highlightthickness 0 332 } { 333 usual 334 ignore -highlightthickness 335 rename -background -plotbackground plotBackground Background 336 } 337 pack $itk_component(legend) -side bottom -fill x 338 bind $itk_component(legend) <Configure> \ 339 [list $_dispatcher event -idle !legend] 340 341 342 # Create flow controls... 343 344 itk_component add flowctrl { 345 frame $itk_interior.flowctrl 331 346 } { 332 347 usual 333 ignore -borderwidth 334 rename -highlightbackground -controlbackground controlBackground Background 335 } 336 bind $itk_component(volume) <ButtonPress> \ 337 [itcl::code $this _slice volume toggle] 338 Rappture::Tooltip::for $itk_component(volume) \ 339 "Toggle the volume cloud on/off" 340 grid $itk_component(volume) -row 0 -column 0 -columnspan 3 \ 341 -sticky ew -padx 1 -pady 2 342 343 # 344 # Settings panel... 345 # 346 itk_component add settings { 347 button $itk_component(controls).settings -text "Settings..." \ 348 -borderwidth 1 -relief flat -overrelief raised \ 349 -padx 2 -pady 1 \ 350 -command [list $itk_component(controls).panel activate $itk_component(controls).settings left] 348 rename -background -controlbackground controlBackground Background 349 } 350 pack $itk_component(flowctrl) -side top -padx 4 -pady 0 -fill x 351 352 # flow record button... 353 itk_component add rewind { 354 button $itk_component(flowctrl).reset \ 355 -borderwidth 1 -padx 1 -pady 1 \ 356 -image [Rappture::icon flow-rewind] \ 357 -command [itcl::code $this flow rewind] 351 358 } { 352 usual 353 ignore -borderwidth 354 rename -background -controlbackground controlBackground Background 355 rename -highlightbackground -controlbackground controlBackground Background 356 } 357 pack $itk_component(settings) -side top 358 359 Rappture::Balloon $itk_component(controls).panel -title "Settings" 360 set inner [$itk_component(controls).panel component inner] 361 frame $inner.scales 362 pack $inner.scales -side top -fill x 363 grid columnconfigure $inner.scales 1 -weight 1 364 set fg [option get $itk_component(hull) font Font] 365 set bfg [option get $itk_component(hull) boldFont Font] 366 367 label $inner.scales.diml -text "Dim" -font $fg 368 grid $inner.scales.diml -row 0 -column 0 -sticky e 369 ::scale $inner.scales.light -from 0 -to 100 -orient horizontal \ 370 -showvalue off -command [itcl::code $this _fixSettings light] 371 grid $inner.scales.light -row 0 -column 1 -sticky ew 372 label $inner.scales.brightl -text "Bright" -font $fg 373 grid $inner.scales.brightl -row 0 -column 2 -sticky w 374 $inner.scales.light set 20 375 376 label $inner.scales.fogl -text "Fog" -font $fg 377 grid $inner.scales.fogl -row 1 -column 0 -sticky e 378 ::scale $inner.scales.transp -from 0 -to 100 -orient horizontal \ 379 -showvalue off -command [itcl::code $this _fixSettings transp] 380 grid $inner.scales.transp -row 1 -column 1 -sticky ew 381 label $inner.scales.plasticl -text "Plastic" -font $fg 382 grid $inner.scales.plasticl -row 1 -column 2 -sticky w 383 $inner.scales.transp set 20 384 385 label $inner.scales.zerol -text "Clear" -font $fg 386 grid $inner.scales.zerol -row 2 -column 0 -sticky e 387 ::scale $inner.scales.opacity -from 0 -to 100 -orient horizontal \ 388 -showvalue off -command [itcl::code $this _fixSettings opacity] 389 grid $inner.scales.opacity -row 2 -column 1 -sticky ew 390 label $inner.scales.onel -text "Opaque" -font $fg 391 grid $inner.scales.onel -row 2 -column 2 -sticky w 392 $inner.scales.opacity set 100 393 394 label $inner.scales.thinl -text "Thin" -font $fg 395 grid $inner.scales.thinl -row 3 -column 0 -sticky e 396 ::scale $inner.scales.thickness -from 0 -to 1000 -orient horizontal \ 397 -showvalue off -command [itcl::code $this _fixSettings thickness] 398 grid $inner.scales.thickness -row 3 -column 1 -sticky ew 399 label $inner.scales.thickl -text "Thick" -font $fg 400 grid $inner.scales.thickl -row 3 -column 2 -sticky w 401 $inner.scales.thickness set 350 402 403 set ::Rappture::FlowvisViewer::settings_($this-isosurface) 0 404 ::checkbutton $inner.scales.isosurface \ 405 -text "Isosurface shading" \ 406 -variable ::Rappture::FlowvisViewer::settings_($this-isosurface) \ 407 -command [itcl::code $this _fixSettings isosurface] 408 grid $inner.scales.isosurface -row 4 -column 0 -columnspan 2 -sticky w 409 410 set ::Rappture::FlowvisViewer::settings_($this-axes) 1 411 ::checkbutton $inner.scales.axes \ 412 -text "Axes" \ 413 -variable ::Rappture::FlowvisViewer::settings_($this-axes) \ 414 -command [itcl::code $this _fixSettings axes] 415 grid $inner.scales.axes -row 5 -column 0 -columnspan 2 -sticky w 416 417 set ::Rappture::FlowvisViewer::settings_($this-grid) 0 418 ::checkbutton $inner.scales.grid \ 419 -text "Grid" \ 420 -variable ::Rappture::FlowvisViewer::settings_($this-grid) \ 421 -command [itcl::code $this _fixSettings grid] 422 grid $inner.scales.grid -row 6 -column 0 -columnspan 2 -sticky w 423 424 set ::Rappture::FlowvisViewer::settings_($this-outline) 1 425 ::checkbutton $inner.scales.outline \ 426 -text "Outline" \ 427 -variable ::Rappture::FlowvisViewer::settings_($this-outline) \ 428 -command [itcl::code $this _fixSettings outline] 429 grid $inner.scales.outline -row 7 -column 0 -columnspan 2 -sticky w 430 431 set ::Rappture::FlowvisViewer::settings_($this-particlevis) 1 432 ::checkbutton $inner.scales.particlevis \ 433 -text "Particle Visible" \ 434 -variable ::Rappture::FlowvisViewer::settings_($this-particlevis) \ 435 -command [itcl::code $this _fixSettings particlevis] 436 grid $inner.scales.particlevis -row 8 -column 0 -columnspan 2 -sticky w 437 438 set ::Rappture::FlowvisViewer::settings_($this-lic) 1 439 ::checkbutton $inner.scales.lic \ 440 -text "Lic" \ 441 -variable ::Rappture::FlowvisViewer::settings_($this-lic) \ 442 -command [itcl::code $this _fixSettings lic] 443 grid $inner.scales.lic -row 9 -column 0 -columnspan 2 -sticky w 444 445 # how do we know when to make something an itk component? 446 447 label $inner.scales.framecntlabel -text "# Frames" -font $fg 448 grid $inner.scales.framecntlabel -row 10 -column 0 -sticky e 449 Rappture::Spinint $inner.scales.framecnt 450 $inner.scales.framecnt value 100 451 grid $inner.scales.framecnt -row 10 -column 1 -sticky w 452 453 label $inner.scales.speedl -text "Flow Speed:" -font $bfg 454 grid $inner.scales.speedl -row 11 -column 0 -sticky e 455 frame $inner.scales.speed 456 grid $inner.scales.speed -row 11 -column 1 -sticky ew 457 label $inner.scales.speed.slowl -text "Slower" -font $fg 458 pack $inner.scales.speed.slowl -side left 459 ::scale $inner.scales.speed.value -from 100 -to 1 \ 460 -showvalue 0 -orient horizontal \ 461 -variable ::Rappture::FlowvisViewer::_play(speed) 462 pack $inner.scales.speed.value -side left 463 label $inner.scales.speed.fastl -text "Faster" -font $fg 464 pack $inner.scales.speed.fastl -side left 465 466 # 467 # Create flow controls... 468 # 469 itk_component add flowctrl { 470 frame $itk_component(controls).flowctrl 359 usual 360 ignore -borderwidth 361 rename -highlightbackground -controlbackground controlBackground Background 362 } 363 Rappture::Tooltip::for $itk_component(rewind) \ 364 "Rewind the flow sequence to the beginning" 365 pack $itk_component(rewind) -padx 1 -side left 366 367 # flow stop button... 368 itk_component add stop { 369 button $itk_component(flowctrl).stop \ 370 -borderwidth 1 -padx 1 -pady 1 \ 371 -image [Rappture::icon flow-stop] \ 372 -command [itcl::code $this flow stop] 471 373 } { 472 usual 473 rename -background -controlbackground controlBackground Background 474 } 475 pack $itk_component(flowctrl) -side top -padx 4 -pady 0 476 grid rowconfigure $itk_component(flowctrl) 1 -weight 1 477 478 # 479 # flow record button... 480 # 481 itk_component add record { 482 label $itk_component(flowctrl).record \ 483 -borderwidth 1 -relief raised -padx 1 -pady 1 \ 484 -image [Rappture::icon playback-record] 485 } { 486 usual 487 ignore -borderwidth 488 rename -highlightbackground -controlbackground controlBackground Background 489 } 490 bind $itk_component(record) <ButtonPress> \ 491 [itcl::code $this _flow movie record toggle] 492 Rappture::Tooltip::for $itk_component(record) \ 493 "Record flow visualization" 494 grid $itk_component(record) -row 1 -column 0 -padx 1 495 496 # 497 # flow stop button... 498 # 499 itk_component add stop { 500 label $itk_component(flowctrl).stop \ 501 -borderwidth 1 -relief sunken -padx 1 -pady 1 \ 502 -image [Rappture::icon playback-stop] 503 } { 504 usual 505 ignore -borderwidth 506 rename -highlightbackground -controlbackground controlBackground Background 507 } 508 bind $itk_component(stop) <ButtonPress> \ 509 [itcl::code $this _flow movie stop toggle] 374 usual 375 ignore -borderwidth 376 rename -highlightbackground -controlbackground controlBackground Background 377 } 510 378 Rappture::Tooltip::for $itk_component(stop) \ 511 512 grid $itk_component(stop) -row 1 -column 1 -padx 1379 "Stop flow visualization" 380 pack $itk_component(stop) -padx 1 -side left 513 381 514 382 # … … 516 384 # 517 385 itk_component add play { 518 label $itk_component(flowctrl).play \ 519 -borderwidth 1 -relief raised -padx 1 -pady 1 \ 520 -image [Rappture::icon playback-start] 386 button $itk_component(flowctrl).play \ 387 -borderwidth 1 -padx 1 -pady 1 \ 388 -image [Rappture::icon flow-play] \ 389 -command [itcl::code $this flow toggle] 521 390 } { 522 523 524 525 } 526 bind $itk_component(play) <ButtonPress> \527 [itcl::code $this _flow movie play toggle] 391 usual 392 ignore -borderwidth 393 rename -highlightbackground -controlbackground controlBackground Background 394 } 395 set fg [option get $itk_component(hull) font Font] 396 528 397 Rappture::Tooltip::for $itk_component(play) \ 529 "Play/Pause flow visualization" 530 grid $itk_component(play) -row 1 -column 2 -padx 1 398 "Play/Pause flow visualization" 399 pack $itk_component(play) -padx 1 -side left 400 401 # how do we know when to make something an itk component? 402 403 ::scale $itk_component(flowctrl).value -from 100 -to 1 \ 404 -showvalue 0 -orient horizontal -width 12 -length 150 \ 405 -variable [itcl::scope settings_(speed)] 406 pack $itk_component(flowctrl).value -side right 407 408 itk_component add speedlabel { 409 label $itk_component(flowctrl).speedl -text "Flow Rate:" -font $fg 410 } { 411 usual 412 rename -background -controlbackground controlBackground Background 413 } 414 pack $itk_component(speedlabel) -side right 415 416 Rappture::Spinint $itk_component(flowctrl).framecnt 417 $itk_component(flowctrl).framecnt value 100 418 pack $itk_component(flowctrl).framecnt -side right 419 label $itk_component(flowctrl).framecntlabel -text "# Frames" -font $fg 420 pack $itk_component(flowctrl).framecntlabel -side right 421 531 422 532 423 # Bindings for rotation via mouse 533 424 bind $itk_component(3dview) <ButtonPress-1> \ 534 [itcl::code $this _rotate click %x %y]425 [itcl::code $this Rotate click %x %y] 535 426 bind $itk_component(3dview) <B1-Motion> \ 536 [itcl::code $this _rotate drag %x %y]427 [itcl::code $this Rotate drag %x %y] 537 428 bind $itk_component(3dview) <ButtonRelease-1> \ 538 [itcl::code $this _rotate release %x %y]429 [itcl::code $this Rotate release %x %y] 539 430 bind $itk_component(3dview) <Configure> \ 540 [itcl::code $this _send "screen %w %h"]431 [itcl::code $this SendCmd "screen %w %h"] 541 432 542 433 # Bindings for panning via mouse 543 434 bind $itk_component(3dview) <ButtonPress-2> \ 544 [itcl::code $this _pan click %x %y]435 [itcl::code $this Pan click %x %y] 545 436 bind $itk_component(3dview) <B2-Motion> \ 546 [itcl::code $this _pan drag %x %y]437 [itcl::code $this Pan drag %x %y] 547 438 bind $itk_component(3dview) <ButtonRelease-2> \ 548 [itcl::code $this _pan release %x %y]439 [itcl::code $this Pan release %x %y] 549 440 550 441 # Bindings for panning via keyboard 551 442 bind $itk_component(3dview) <KeyPress-Left> \ 552 [itcl::code $this _pan set -10 0]443 [itcl::code $this Pan set -10 0] 553 444 bind $itk_component(3dview) <KeyPress-Right> \ 554 [itcl::code $this _pan set 10 0]445 [itcl::code $this Pan set 10 0] 555 446 bind $itk_component(3dview) <KeyPress-Up> \ 556 [itcl::code $this _pan set 0 -10]447 [itcl::code $this Pan set 0 -10] 557 448 bind $itk_component(3dview) <KeyPress-Down> \ 558 [itcl::code $this _pan set 0 10]449 [itcl::code $this Pan set 0 10] 559 450 bind $itk_component(3dview) <Shift-KeyPress-Left> \ 560 [itcl::code $this _pan set -2 0]451 [itcl::code $this Pan set -2 0] 561 452 bind $itk_component(3dview) <Shift-KeyPress-Right> \ 562 [itcl::code $this _pan set 2 0]453 [itcl::code $this Pan set 2 0] 563 454 bind $itk_component(3dview) <Shift-KeyPress-Up> \ 564 [itcl::code $this _pan set 0 -2]455 [itcl::code $this Pan set 0 -2] 565 456 bind $itk_component(3dview) <Shift-KeyPress-Down> \ 566 [itcl::code $this _pan set 0 2]457 [itcl::code $this Pan set 0 2] 567 458 568 459 # Bindings for zoom via keyboard 569 460 bind $itk_component(3dview) <KeyPress-Prior> \ 570 [itcl::code $this _zoom out]461 [itcl::code $this Zoom out] 571 462 bind $itk_component(3dview) <KeyPress-Next> \ 572 [itcl::code $this _zoom in]463 [itcl::code $this Zoom in] 573 464 574 465 bind $itk_component(3dview) <Enter> "focus $itk_component(3dview)" 575 466 576 467 if {[string equal "x11" [tk windowingsystem]]} { 577 578 bind $itk_component(3dview) <4> [itcl::code $this _zoom out]579 bind $itk_component(3dview) <5> [itcl::code $this _zoom in]468 # Bindings for zoom via mouse 469 bind $itk_component(3dview) <4> [itcl::code $this Zoom out] 470 bind $itk_component(3dview) <5> [itcl::code $this Zoom in] 580 471 } 581 472 … … 594 485 $_dispatcher cancel !rebuild 595 486 $_dispatcher cancel !send_dataobjs 487 $_dispatcher cancel !send_transfunc 596 488 image delete $_image(plot) 489 image delete $_image(legend) 597 490 image delete $_image(download) 491 array unset settings_ $this-* 598 492 } 599 493 … … 607 501 itcl::body Rappture::FlowvisViewer::add {dataobj {settings ""}} { 608 502 array set params { 609 610 611 612 613 614 615 503 -color auto 504 -width 1 505 -linestyle solid 506 -brightness 0 507 -raise 0 508 -description "" 509 -param "" 616 510 } 617 511 foreach {opt val} $settings { 618 619 620 621 512 if {![info exists params($opt)]} { 513 error "bad setting \"$opt\": should be [join [lsort [array names params]] {, }]" 514 } 515 set params($opt) $val 622 516 } 623 517 if {$params(-color) == "auto" || $params(-color) == "autoreset"} { 624 625 518 # can't handle -autocolors yet 519 set params(-color) black 626 520 } 627 521 628 522 set pos [lsearch -exact $dataobj $dlist_] 629 523 if {$pos < 0} { 630 lappend dlist_ $dataobj 631 set obj2ovride_($dataobj-color) $params(-color) 632 set obj2ovride_($dataobj-width) $params(-width) 633 set obj2ovride_($dataobj-raise) $params(-raise) 634 $_dispatcher event -idle !rebuild 524 lappend dlist_ $dataobj 525 set all_data_objs_($dataobj) 1 526 set obj2ovride_($dataobj-color) $params(-color) 527 set obj2ovride_($dataobj-width) $params(-width) 528 set obj2ovride_($dataobj-raise) $params(-raise) 529 $_dispatcher event -idle !rebuild 635 530 } 636 531 } … … 646 541 itcl::body Rappture::FlowvisViewer::get {args} { 647 542 if {[llength $args] == 0} { 648 543 set args "-objects" 649 544 } 650 545 … … 652 547 switch -- $op { 653 548 -objects { 654 # put the dataobj list in order according to -raise options 655 set dlist $dlist_ 656 foreach obj $dlist { 657 if { [info exists obj2ovride_($obj-raise)] && 658 $obj2ovride_($obj-raise)} { 659 set i [lsearch -exact $dlist $obj] 660 if {$i >= 0} { 661 set dlist [lreplace $dlist $i $i] 662 lappend dlist $obj 663 } 664 } 665 } 666 return $dlist 549 # put the dataobj list in order according to -raise options 550 set dlist $dlist_ 551 foreach obj $dlist { 552 if {[info exists obj2ovride_($obj-raise)] && $obj2ovride_($obj-raise)} { 553 set i [lsearch -exact $dlist $obj] 554 if {$i >= 0} { 555 set dlist [lreplace $dlist $i $i] 556 lappend dlist $obj 557 } 558 } 559 } 560 return $dlist 667 561 } 668 562 -image { 669 if {[llength $args] != 2} { 670 error "wrong # args: should be \"get -image 3dview|legend\"" 671 } 672 switch -- [lindex $args end] { 673 3dview { 674 return $_image(plot) 675 } 676 default { 677 error "bad image name \"[lindex $args end]\": should be 3dview or legend" 678 } 679 } 563 if {[llength $args] != 2} { 564 error "wrong # args: should be \"get -image 3dview|legend\"" 565 } 566 switch -- [lindex $args end] { 567 3dview { 568 return $_image(plot) 569 } 570 legend { 571 return $_image(legend) 572 } 573 default { 574 error "bad image name \"[lindex $args end]\": should be 3dview or legend" 575 } 576 } 680 577 } 681 578 default { 682 579 error "bad option \"$op\": should be -objects or -image" 683 580 } 684 581 } … … 688 585 # USAGE: delete ?<dataobj1> <dataobj2> ...? 689 586 # 690 # Clients use this to delete a dataobj from the plot. If no dataobjs 691 # are specified, then all dataobjs are deleted. 587 # Clients use this to delete a dataobj from the plot. If no dataobjs 588 # are specified, then all dataobjs are deleted. No data objects are 589 # deleted. They are only removed from the display list. 590 # 692 591 # ---------------------------------------------------------------------- 693 592 itcl::body Rappture::FlowvisViewer::delete {args} { 694 593 if {[llength $args] == 0} { 695 set args $dlist_ 696 } 697 698 # delete all specified dataobjs 594 set args $dlist_ 595 } 596 # Delete all specified dataobjs 699 597 set changed 0 700 598 foreach dataobj $args { 701 set pos [lsearch -exact $dlist_ $dataobj] 702 if {$pos >= 0} { 703 set dlist_ [lreplace $dlist_ $pos $pos] 704 foreach key [array names obj2ovride_ $dataobj-*] { 705 unset obj2ovride_($key) 706 } 707 set changed 1 708 } 709 } 710 711 # if anything changed, then rebuild the plot 599 set pos [lsearch -exact $dlist_ $dataobj] 600 if { $pos >= 0 } { 601 set dlist_ [lreplace $dlist_ $pos $pos] 602 foreach key [array names obj2ovride_ $dataobj-*] { 603 unset obj2ovride_($key) 604 } 605 set changed 1 606 } 607 } 608 # If anything changed, then rebuild the plot 712 609 if {$changed} { 713 610 $_dispatcher event -idle !rebuild 714 611 } 715 612 } … … 726 623 itcl::body Rappture::FlowvisViewer::scale {args} { 727 624 foreach val {xmin xmax ymin ymax zmin zmax vmin vmax} { 728 625 set limits_($val) "" 729 626 } 730 627 foreach obj $args { 731 foreach axis {x y z v} { 732 foreach {min max} [$obj limits $axis] break 733 if {"" != $min && "" != $max} { 734 if {"" == $limits_(${axis}min)} { 735 set limits_(${axis}min) $min 736 set limits_(${axis}max) $max 737 } else { 738 if {$min < $limits_(${axis}min)} { 739 set limits_(${axis}min) $min 740 } 741 if {$max > $limits_(${axis}max)} { 742 set limits_(${axis}max) $max 743 } 744 } 745 } 746 } 628 foreach axis {x y z v} { 629 630 foreach { min max } [$obj limits $axis] break 631 632 if {"" != $min && "" != $max} { 633 if {"" == $limits_(${axis}min)} { 634 set limits_(${axis}min) $min 635 set limits_(${axis}max) $max 636 } else { 637 if {$min < $limits_(${axis}min)} { 638 set limits_(${axis}min) $min 639 } 640 if {$max > $limits_(${axis}max)} { 641 set limits_(${axis}max) $max 642 } 643 } 644 } 645 } 747 646 } 748 647 } … … 760 659 itcl::body Rappture::FlowvisViewer::download {option args} { 761 660 switch $option { 762 coming { 763 if {[catch { 764 blt::winop snap $itk_component(area) $_image(download) 765 }]} { 766 $_image(download) configure -width 1 -height 1 767 $_image(download) put #000000 768 } 769 } 770 controls { 771 # no controls for this download yet 772 return "" 773 } 774 now { 775 switch -- $_downloadPopup(format) { 776 jpg { 777 # Get the image data (as base64) and decode it back to 778 # binary. This is better than writing to temporary files. 779 # When we switch to the BLT picture image it won't be 780 # necessary to decode the image data. 781 set bytes [$_image(download) data \ 782 -format "jpeg -quality 100"] 783 set bytes [Rappture::encoding::decode -as b64 $bytes] 784 return [list .jpg $bytes] 785 } 786 } 787 } 788 default { 789 error "bad option \"$option\": should be coming, controls, now" 790 } 661 coming { 662 if {[catch {blt::winop snap $itk_component(area) $_image(download)}]} { 663 $_image(download) configure -width 1 -height 1 664 $_image(download) put #000000 665 } 666 } 667 controls { 668 # no controls for this download yet 669 return "" 670 } 671 now { 672 # Doing an image base64 encode/decode has to be better than 673 # writing the image to a file and reading it back in. 674 set data [$_image(plot) data -format jpeg] 675 set data [Rappture::encoding::decode -as b64 $data] 676 return [list .jpg $data] 677 } 678 default { 679 error "bad option \"$option\": should be coming, controls, now" 680 } 791 681 } 792 682 } … … 800 690 # ---------------------------------------------------------------------- 801 691 itcl::body Rappture::FlowvisViewer::Connect {} { 802 Disconnect803 692 set _hosts [GetServerList "nanovis"] 804 693 if { "" == $_hosts } { 805 694 return 0 806 695 } 807 696 set result [VisViewer::Connect $_hosts] 697 if { $result } { 698 set w [winfo width $itk_component(3dview)] 699 set h [winfo height $itk_component(3dview)] 700 SendCmd "screen $w $h" 701 } 808 702 return $result 809 703 } … … 818 712 } 819 713 820 # ----------------------------------------------------------------------821 # USAGE: Disconnect822 # 823 # Clients use this method to disconnect from the current rendering824 # server.825 # ----------------------------------------------------------------------714 # 715 # Disconnect -- 716 # 717 # Clients use this method to disconnect from the current rendering 718 # server. 719 # 826 720 itcl::body Rappture::FlowvisViewer::Disconnect {} { 827 721 VisViewer::Disconnect 828 722 723 # disconnected -- no more data sitting on server 829 724 set outbuf_ "" 830 # disconnected -- no more data sitting on server831 725 catch {unset obj2id_} 832 726 array unset id2obj_ 833 727 set obj2id_(count) 0 834 set id2obj_(coun d) 0728 set id2obj_(count) 0 835 729 set sendobjs_ "" 836 730 } 837 731 838 # 839 # _send 732 itcl::body Rappture::FlowvisViewer::_send {string} { 733 SendCmd $string 734 } 735 # 736 # SendCmd 840 737 # 841 738 # Send commands off to the rendering server. If we're currently … … 843 740 # sent later. 844 741 # 845 itcl::body Rappture::FlowvisViewer:: _send {string} {742 itcl::body Rappture::FlowvisViewer::SendCmd {string} { 846 743 if {[llength $sendobjs_] > 0} { 847 744 append outbuf_ $string "\n" 848 745 } else { 849 if {[SendBytes $string]} { 850 foreach line [split $string \n] { 851 SendEcho >>line $line 852 } 853 } 854 } 855 } 856 857 # ---------------------------------------------------------------------- 858 # USAGE: _send_dataobjs 746 foreach line [split $string \n] { 747 SendEcho >>line $line 748 } 749 SendBytes $string 750 } 751 } 752 753 # ---------------------------------------------------------------------- 754 # USAGE: SendDataObjs 859 755 # 860 756 # Used internally to send a series of volume objects off to the … … 862 758 # between so the interface doesn't lock up. 863 759 # ---------------------------------------------------------------------- 864 itcl::body Rappture::FlowvisViewer:: _send_dataobjs {} {760 itcl::body Rappture::FlowvisViewer::SendDataObjs {} { 865 761 blt::busy hold $itk_component(hull); update idletasks 866 867 # Reset the overall limits868 if { $sendobjs_ != "" } {869 set limits_(vmin) ""870 set limits_(vmax) ""871 }872 762 foreach dataobj $sendobjs_ { 873 foreach comp [$dataobj components] { 874 set data [$dataobj values $comp] 875 876 # tell the engine to expect some data 877 set nbytes [string length $data] 878 if { ![SendBytes "flow data follows $nbytes"] } { 879 return 880 } 881 if { ![SendBytes $data] } { 882 return 883 } 884 set id $obj2id_(count) 885 incr obj2id_(count) 886 set id2obj_($id) [list $dataobj $comp] 887 set obj2id_($dataobj-$comp) $id 888 set receiveIds_($id) 1 889 } 763 foreach comp [$dataobj components] { 764 # Send the data as one huge base64-encoded mess -- yuck! 765 set data [$dataobj values $comp] 766 set nbytes [string length $data] 767 if { ![SendBytes "flow data follows $nbytes"] } { 768 return 769 } 770 if { ![SendBytes $data] } { 771 return 772 } 773 set ivol $obj2id_(count) 774 incr obj2id_(count) 775 776 set id2obj_($ivol) [list $dataobj $comp] 777 set obj2id_($dataobj-$comp) $ivol 778 NameTransferFunction $ivol 779 set receiveIds_($ivol) 1 780 } 890 781 } 891 782 set sendobjs_ "" … … 894 785 # activate the proper volume 895 786 set first [lindex [get] 0] 896 if {"" != $first} { 897 set axis [$first hints updir] 898 if {"" != $axis} { 899 _send "up $axis" 900 } 901 } 902 903 # FIXME: does vectorid command turn off other vectors? 787 if { "" != $first } { 788 set axis [$first hints updir] 789 if {"" != $axis} { 790 SendCmd "up $axis" 791 } 792 # The active transfer function is by default the first component of 793 # the first data object. This assumes that the data is always 794 # successfully transferred. 795 set comp [lindex [$first components] 0] 796 set activeTf_ $id2style_($obj2id_($first-$comp)) 797 } 904 798 foreach key [array names obj2id_ *-*] { 905 _send "flow vectorid $obj2id_($key)" 799 set state [string match $first-* $key] 800 set ivol $obj2id_($key) 801 SendCmd "volume state $state $ivol" 906 802 } 907 803 908 804 # sync the state of slicers 909 set vols [ _currentVolumeIds -cutplanes]805 set vols [CurrentVolumeIds -cutplanes] 910 806 foreach axis {x y z} { 911 _send "cutplane state [_state ${axis}slice] $axis $vols" 912 set pos [expr {0.01*[$itk_component(${axis}slicer) get]}] 913 _send "cutplane position $pos $axis $vols" 914 } 915 807 SendCmd "cutplane state [State ${axis}CutButton] $axis $vols" 808 set pos [expr {0.01*[$itk_component(${axis}CutScale) get]}] 809 SendCmd "cutplane position $pos $axis $vols" 810 } 811 SendCmd "volume data state [State volume] $vols" 812 813 if 0 { 814 # Add this when we fix grid for volumes 815 SendCmd "volume axis label x \"\"" 816 SendCmd "volume axis label y \"\"" 817 SendCmd "volume axis label z \"\"" 818 SendCmd "grid axisname x X eV" 819 SendCmd "grid axisname y Y eV" 820 SendCmd "grid axisname z Z eV" 821 } 916 822 # if there are any commands in the buffer, send them now that we're done 917 823 SendBytes $outbuf_ … … 920 826 921 827 # ---------------------------------------------------------------------- 828 # USAGE: SendTransferFunctions 829 # ---------------------------------------------------------------------- 830 itcl::body Rappture::FlowvisViewer::SendTransferFunctions {} { 831 if { $activeTf_ == "" } { 832 return 833 } 834 set tf $activeTf_ 835 set first [lindex [get] 0] 836 837 # Insure that the global opacity and thickness settings (in the slider 838 # settings widgets) are used for the active transfer-function. Update the 839 # values in the settings_ varible. 840 set inner $itk_component(settingsFrame) 841 set value [$inner.opacity get] 842 set opacity [expr { double($value) * 0.01 }] 843 set settings_($this-$tf-opacity) $opacity 844 set value [$inner.thickness get] 845 # Scale values between 0.00001 and 0.01000 846 set thickness [expr {double($value) * 0.0001}] 847 set settings_($this-$tf-thickness) $thickness 848 849 if { ![info exists $obj2styles_($first)] } { 850 foreach tf $obj2styles_($first) { 851 ComputeTransferFunction $tf 852 } 853 FixLegend 854 } 855 } 856 857 # ---------------------------------------------------------------------- 922 858 # USAGE: ReceiveImage -bytes <size> 923 859 # … … 926 862 # specified <size> will follow. 927 863 # ---------------------------------------------------------------------- 928 itcl::body Rappture::FlowvisViewer::ReceiveImage {option size} { 929 if {[IsConnected]} { 930 set bytes [ReceiveBytes $size] 864 set counter 0 865 itcl::body Rappture::FlowvisViewer::ReceiveImage { args } { 866 if {![isconnected]} { 867 return 868 } 869 array set info { 870 -type image 871 } 872 array set info $args 873 set bytes [ReceiveBytes $info(-bytes)] 874 ReceiveEcho <<line "<read $info(-bytes) bytes" 875 if { $info(-type) == "image" } { 876 ReceiveEcho "for [image width $_image(plot)]x[image height $_image(plot)] image>" 931 877 $_image(plot) configure -data $bytes 932 ReceiveEcho <<line "<read $size bytes for [image width $_image(plot)]x[image height $_image(plot)] image>" 933 } 934 } 935 936 # ---------------------------------------------------------------------- 937 # USAGE: ReceiveFile -bytes <size> 938 # 939 # Invoked automatically whenever the "file" command comes in from 940 # the rendering server. Indicates that binary file data with the 941 # specified <size> will follow. 942 # ---------------------------------------------------------------------- 943 itcl::body Rappture::FlowvisViewer::ReceiveFile {option size} { 944 if {[IsConnected]} { 945 set bytes [ReceiveBytes $size] 946 ReceiveEcho <<line "<read $size bytes for file>" 947 948 # raise the record button back up. 949 $itk_component(record) configure -relief raised 950 951 # FIXME: manually download file??? 952 set mesg [Rappture::filexfer::download $bytes "flowmovie.mpeg"] 953 } 954 } 955 956 # ---------------------------------------------------------------------- 957 # USAGE: _rebuild 958 # 959 # Called automatically whenever something changes that affects the 960 # data in the widget. Clears any existing data and rebuilds the 961 # widget to display new data. 962 # ---------------------------------------------------------------------- 963 itcl::body Rappture::FlowvisViewer::_rebuild {} { 878 } elseif { $info(type) == "movie" } { 879 set tag $this-movie-$info(-token) 880 set hardcopy_($tag) $bytes 881 } 882 } 883 884 # 885 # ReceiveLegend -- 886 # 887 # The procedure is the response from the render server to each "legend" 888 # command. The server sends back a "legend" command invoked our 889 # the slave interpreter. The purpose is to collect data of the image 890 # representing the legend in the canvas. In addition, the isomarkers 891 # of the active transfer function are displayed. 892 # 893 # I don't know is this is the right place to display the isomarkers. 894 # I don't know all the different paths used to draw the plot. There's 895 # "Rebuild", "add", etc. 896 # 897 itcl::body Rappture::FlowvisViewer::ReceiveLegend { tf vmin vmax size } { 898 if { ![isconnected] } { 899 return 900 } 901 set bytes [ReceiveBytes $size] 902 $_image(legend) configure -data $bytes 903 ReceiveEcho <<line "<read $size bytes for [image width $_image(legend)]x[image height $_image(legend)] legend>" 904 905 set c $itk_component(legend) 906 set w [winfo width $c] 907 set h [winfo height $c] 908 #foreach { dataobj comp } $id2obj_($ivol) break 909 set lx 10 910 set ly [expr {$h - 1}] 911 if {"" == [$c find withtag transfunc]} { 912 $c create image 10 10 -anchor nw \ 913 -image $_image(legend) -tags transfunc 914 $c create text $lx $ly -anchor sw \ 915 -fill $itk_option(-plotforeground) -tags "limits vmin" 916 $c create text [expr {$w-$lx}] $ly -anchor se \ 917 -fill $itk_option(-plotforeground) -tags "limits vmax" 918 $c lower transfunc 919 $c bind transfunc <ButtonRelease-1> \ 920 [itcl::code $this AddIsoMarker %x %y] 921 } 922 # Display the markers used by the active transfer function. 923 #set tf $activeTf_ 924 925 array set limits [GetLimits $tf] 926 $c itemconfigure vmin -text [format %.2g $limits(min)] 927 $c coords vmin $lx $ly 928 929 $c itemconfigure vmax -text [format %.2g $limits(max)] 930 $c coords vmax [expr {$w-$lx}] $ly 931 932 if { [info exists isomarkers_($tf)] } { 933 foreach m $isomarkers_($tf) { 934 $m Show 935 } 936 } 937 } 938 939 # 940 # ReceiveData -- 941 # 942 # The procedure is the response from the render server to each "data 943 # follows" command. The server sends back a "data" command invoked our 944 # the # slave interpreter. The purpose is to collect the min/max of the 945 # volume sent # to the render server. Since the client (flowvisviewer) 946 # doesn't parse 3D # data formats, we rely on the server (flowvis) to 947 # tell us what the limits # are. Once we've received the limits to all 948 # the data we've sent (tracked by # receiveIds_) we can then determine 949 # what the transfer functions are for these # volumes. 950 # 951 # Note: There is a considerable tradeoff in having the server report 952 # back what the data limits are. It means that much of the code 953 # having to do with transfer-functions has to wait for the data 954 # to come back, since the isomarkers are calculated based upon 955 # the data limits. The client code is much messier because of 956 # this. The alternative is to parse any of the 3D formats on the 957 # client side. 958 # 959 itcl::body Rappture::FlowvisViewer::ReceiveData { args } { 960 if { ![isconnected] } { 961 return 962 } 963 # Arguments from server are name value pairs. Stuff them in an array. 964 array set info $args 965 966 set ivol $info(id); # Id of volume created by server. 967 968 set limits_($ivol-min) $info(min); # Minimum value of the volume. 969 set limits_($ivol-max) $info(max); # Maximum value of the volume. 970 set limits_(vmin) $info(vmin); # Overall minimum value. 971 set limits_(vmax) $info(vmax); # Overall maximum value. 972 973 unset receiveIds_($ivol) 974 if { [array size receiveIds_] == 0 } { 975 UpdateTransferFunctions 976 } 977 } 978 979 # 980 # Rebuild -- 981 # 982 # Called automatically whenever something changes that affects the data 983 # in the widget. Clears any existing data and rebuilds the widget to 984 # display new data. 985 # 986 itcl::body Rappture::FlowvisViewer::Rebuild {} { 987 988 # Hide all the isomarkers. Can't remove them. Have to remember the 989 # settings since the user may have created/deleted/moved markers. 990 991 foreach tf [array names isomarkers_] { 992 foreach m $isomarkers_($tf) { 993 $m Hide 994 } 995 } 996 964 997 # in the midst of sending data? then bail out 965 998 if {[llength $sendobjs_] > 0} { 966 return 967 } 999 return 1000 } 1001 968 1002 # Find any new data that needs to be sent to the server. Queue this up on 969 1003 # the sendobjs_ list, and send it out a little at a time. Do this first, 970 1004 # before we rebuild the rest. 971 1005 foreach dataobj [get] { 972 set comp [lindex [$dataobj components] 0] 973 if {![info exists obj2id_($dataobj-$comp)]} { 974 set i [lsearch -exact $sendobjs_ $dataobj] 975 if {$i < 0} { 976 lappend sendobjs_ $dataobj 977 } 978 } 979 } 980 if {[llength $sendobjs_] > 0} { 981 # Send off new data objects 982 $_dispatcher event -idle !send_dataobjs 983 } else { 984 # Nothing to send -- activate the proper volume 985 set first [lindex [get] 0] 986 if {"" != $first} { 987 set axis [$first hints updir] 988 if {"" != $axis} { 989 _send "up $axis" 990 } 991 } 992 foreach key [array names obj2id_ *-*] { 993 set state [string match $first-* $key] 994 _send "flow vectorid $obj2id_($key)" 995 } 996 } 997 998 # Reset the screen size. 1006 set comp [lindex [$dataobj components] 0] 1007 if {![info exists obj2id_($dataobj-$comp)]} { 1008 set i [lsearch -exact $sendobjs_ $dataobj] 1009 if {$i < 0} { 1010 lappend sendobjs_ $dataobj 1011 } 1012 } 1013 } 999 1014 set w [winfo width $itk_component(3dview)] 1000 1015 set h [winfo height $itk_component(3dview)] 1001 _send "screen $w $h" 1002 1016 SendCmd "screen $w $h" 1017 1018 # 1003 1019 # Reset the camera and other view parameters 1020 # 1004 1021 set xyz [Euler2XYZ $view_(theta) $view_(phi) $view_(psi)] 1005 _send "camera angle $xyz" 1006 _send "camera zoom $view_(zoom)" 1007 1008 # _fixSettings wireframe 1009 _fixSettings light 1010 _fixSettings transp 1011 _fixSettings isosurface 1012 _fixSettings grid 1013 _fixSettings axes 1014 _fixSettings outline 1015 # _fixSettings contourlines 1016 } 1017 1018 # ---------------------------------------------------------------------- 1019 # USAGE: _currentVolumeIds ?-cutplanes? 1022 SendCmd "camera angle $xyz" 1023 PanCamera 1024 SendCmd "camera zoom $view_(zoom)" 1025 1026 set settings_($this-theta) $view_(theta) 1027 set settings_($this-phi) $view_(phi) 1028 set settings_($this-psi) $view_(psi) 1029 set settings_($this-pan-x) $view_(pan-x) 1030 set settings_($this-pan-y) $view_(pan-y) 1031 set settings_($this-zoom) $view_(zoom) 1032 1033 FixSettings light 1034 FixSettings transp 1035 FixSettings isosurface 1036 FixSettings grid 1037 FixSettings axes 1038 FixSettings outline 1039 1040 if {[llength $sendobjs_] > 0} { 1041 # send off new data objects 1042 $_dispatcher event -idle !send_dataobjs 1043 return 1044 } 1045 1046 # nothing to send -- activate the proper ivol 1047 set first [lindex [get] 0] 1048 if {"" != $first} { 1049 set axis [$first hints updir] 1050 if {"" != $axis} { 1051 SendCmd "up $axis" 1052 } 1053 foreach key [array names obj2id_ *-*] { 1054 set state [string match $first-* $key] 1055 SendCmd "volume state $state $obj2id_($key)" 1056 } 1057 # 1058 # The obj2id_ and id2style_ arrays may or may not have the right 1059 # information. It's possible for the server to know about volumes 1060 # that the client has assumed it's deleted. We could add checks. 1061 # But this problem needs to be fixed not bandaided. 1062 set comp [lindex [$first components] 0] 1063 set ivol $obj2id_($first-$comp) 1064 1065 foreach comp [$first components] { 1066 foreach ivol $obj2id_($first-$comp) { 1067 NameTransferFunction $ivol 1068 } 1069 } 1070 } 1071 1072 # sync the state of slicers 1073 set vols [CurrentVolumeIds -cutplanes] 1074 foreach axis {x y z} { 1075 SendCmd "cutplane state [State ${axis}CutButton] $axis $vols" 1076 set pos [expr {0.01*[$itk_component(${axis}CutScale) get]}] 1077 SendCmd "cutplane position $pos $axis $vols" 1078 } 1079 SendCmd "volume data state [State volume] $vols" 1080 $_dispatcher event -idle !legend 1081 } 1082 1083 # ---------------------------------------------------------------------- 1084 # USAGE: CurrentVolumeIds ?-cutplanes? 1020 1085 # 1021 1086 # Returns a list of volume server IDs for the current volume being … … 1023 1088 # of IDs if the current data object has multiple components. 1024 1089 # ---------------------------------------------------------------------- 1025 itcl::body Rappture::FlowvisViewer:: _currentVolumeIds {{what -all}} {1090 itcl::body Rappture::FlowvisViewer::CurrentVolumeIds {{what -all}} { 1026 1091 set rlist "" 1027 1092 1028 1093 set first [lindex [get] 0] 1029 foreach key [array names _obj2id*-*] {1030 1031 1032 1033 1034 1035 1036 1037 1038 lappend rlist $_obj2id($key)1039 1040 1094 foreach key [array names obj2id_ *-*] { 1095 if {[string match $first-* $key]} { 1096 array set style { 1097 -cutplanes 1 1098 } 1099 foreach {dataobj comp} [split $key -] break 1100 array set style [lindex [$dataobj components -style $comp] 0] 1101 1102 if {$what != "-cutplanes" || $style(-cutplanes)} { 1103 lappend rlist $obj2id_($key) 1104 } 1105 } 1041 1106 } 1042 1107 return $rlist … … 1044 1109 1045 1110 # ---------------------------------------------------------------------- 1046 # USAGE: _zoom in1047 # USAGE: _zoom out1048 # USAGE: _zoom reset1111 # USAGE: Zoom in 1112 # USAGE: Zoom out 1113 # USAGE: Zoom reset 1049 1114 # 1050 1115 # Called automatically when the user clicks on one of the zoom 1051 1116 # controls for this widget. Changes the zoom for the current view. 1052 1117 # ---------------------------------------------------------------------- 1053 itcl::body Rappture::FlowvisViewer:: _zoom {option} {1118 itcl::body Rappture::FlowvisViewer::Zoom {option} { 1054 1119 switch -- $option { 1055 1120 "in" { 1056 1121 set view_(zoom) [expr {$view_(zoom)*1.25}] 1122 set settings_($this-zoom) $view_(zoom) 1057 1123 } 1058 1124 "out" { 1059 1125 set view_(zoom) [expr {$view_(zoom)*0.8}] 1126 set settings_($this-zoom) $view_(zoom) 1060 1127 } 1061 1128 "reset" { 1062 1129 array set view_ { 1063 1130 theta 45 1064 1131 phi 45 1065 1132 psi 0 1066 zoom 1067 dx01068 dy01133 zoom 1.0 1134 pan-x 0 1135 pan-y 0 1069 1136 } 1070 set xyz [Euler2XYZ $view_(theta) $view_(phi) $view_(psi)] 1071 _send "camera angle $xyz" 1072 _send "camera pan $view_(dx) $view_(dy)" 1073 } 1074 } 1075 _send "camera zoom $view_(zoom)" 1076 } 1077 1078 # ---------------------------------------------------------------------- 1079 # USAGE: $this _pan click x y 1080 # $this _pan drag x y 1081 # $this _pan release x y 1137 set first [lindex [get] 0] 1138 if { $first != "" } { 1139 set location [$first hints camera] 1140 if { $location != "" } { 1141 array set view_ $location 1142 } 1143 } 1144 set xyz [Euler2XYZ $view_(theta) $view_(phi) $view_(psi)] 1145 SendCmd "camera angle $xyz" 1146 PanCamera 1147 set settings_($this-theta) $view_(theta) 1148 set settings_($this-phi) $view_(phi) 1149 set settings_($this-psi) $view_(psi) 1150 set settings_($this-pan-x) $view_(pan-x) 1151 set settings_($this-pan-y) $view_(pan-y) 1152 set settings_($this-zoom) $view_(zoom) 1153 } 1154 } 1155 SendCmd "camera zoom $view_(zoom)" 1156 } 1157 1158 itcl::body Rappture::FlowvisViewer::PanCamera {} { 1159 #set x [expr ($view_(pan-x)) / $limits_(xrange)] 1160 #set y [expr ($view_(pan-y)) / $limits_(yrange)] 1161 set x $view_(pan-x) 1162 set y $view_(pan-y) 1163 SendCmd "camera pan $x $y" 1164 } 1165 1166 # ---------------------------------------------------------------------- 1167 # USAGE: Rotate click <x> <y> 1168 # USAGE: Rotate drag <x> <y> 1169 # USAGE: Rotate release <x> <y> 1170 # 1171 # Called automatically when the user clicks/drags/releases in the 1172 # plot area. Moves the plot according to the user's actions. 1173 # ---------------------------------------------------------------------- 1174 itcl::body Rappture::FlowvisViewer::Rotate {option x y} { 1175 switch -- $option { 1176 click { 1177 $itk_component(3dview) configure -cursor fleur 1178 set click_(x) $x 1179 set click_(y) $y 1180 set click_(theta) $view_(theta) 1181 set click_(phi) $view_(phi) 1182 } 1183 drag { 1184 if {[array size click_] == 0} { 1185 Rotate click $x $y 1186 } else { 1187 set w [winfo width $itk_component(3dview)] 1188 set h [winfo height $itk_component(3dview)] 1189 if {$w <= 0 || $h <= 0} { 1190 return 1191 } 1192 1193 if {[catch { 1194 # this fails sometimes for no apparent reason 1195 set dx [expr {double($x-$click_(x))/$w}] 1196 set dy [expr {double($y-$click_(y))/$h}] 1197 }]} { 1198 return 1199 } 1200 1201 # 1202 # Rotate the camera in 3D 1203 # 1204 if {$view_(psi) > 90 || $view_(psi) < -90} { 1205 # when psi is flipped around, theta moves backwards 1206 set dy [expr {-$dy}] 1207 } 1208 set theta [expr {$view_(theta) - $dy*180}] 1209 while {$theta < 0} { set theta [expr {$theta+180}] } 1210 while {$theta > 180} { set theta [expr {$theta-180}] } 1211 1212 if {abs($theta) >= 30 && abs($theta) <= 160} { 1213 set phi [expr {$view_(phi) - $dx*360}] 1214 while {$phi < 0} { set phi [expr {$phi+360}] } 1215 while {$phi > 360} { set phi [expr {$phi-360}] } 1216 set psi $view_(psi) 1217 } else { 1218 set phi $view_(phi) 1219 set psi [expr {$view_(psi) - $dx*360}] 1220 while {$psi < -180} { set psi [expr {$psi+360}] } 1221 while {$psi > 180} { set psi [expr {$psi-360}] } 1222 } 1223 1224 set view_(theta) $theta 1225 set view_(phi) $phi 1226 set view_(psi) $psi 1227 set xyz [Euler2XYZ $theta $phi $psi] 1228 set settings_($this-theta) $view_(theta) 1229 set settings_($this-phi) $view_(phi) 1230 set settings_($this-psi) $view_(psi) 1231 SendCmd "camera angle $xyz" 1232 set click_(x) $x 1233 set click_(y) $y 1234 } 1235 } 1236 release { 1237 Rotate drag $x $y 1238 $itk_component(3dview) configure -cursor "" 1239 catch {unset click_} 1240 } 1241 default { 1242 error "bad option \"$option\": should be click, drag, release" 1243 } 1244 } 1245 } 1246 1247 # ---------------------------------------------------------------------- 1248 # USAGE: $this Pan click x y 1249 # $this Pan drag x y 1250 # $this Pan release x y 1082 1251 # 1083 1252 # Called automatically when the user clicks on one of the zoom 1084 1253 # controls for this widget. Changes the zoom for the current view. 1085 1254 # ---------------------------------------------------------------------- 1086 itcl::body Rappture::FlowvisViewer:: _pan {option x y} {1255 itcl::body Rappture::FlowvisViewer::Pan {option x y} { 1087 1256 # Experimental stuff 1088 1257 set w [winfo width $itk_component(3dview)] 1089 1258 set h [winfo height $itk_component(3dview)] 1090 1259 if { $option == "set" } { 1091 set x [expr $x / double($w)] 1092 set y [expr $y / double($h)] 1093 set view_(dx) [expr $view_(dx) + $x] 1094 set view_(dy) [expr $view_(dy) + $y] 1095 _send "camera pan $view_(dx) $view_(dy)" 1096 return 1260 set x [expr $x / double($w)] 1261 set y [expr $y / double($h)] 1262 set view_(pan-x) [expr $view_(pan-x) + $x] 1263 set view_(pan-y) [expr $view_(pan-y) + $y] 1264 PanCamera 1265 set settings_($this-pan-x) $view_(pan-x) 1266 set settings_($this-pan-y) $view_(pan-y) 1267 return 1097 1268 } 1098 1269 if { $option == "click" } { 1099 1100 1101 1270 set click_(x) $x 1271 set click_(y) $y 1272 $itk_component(3dview) configure -cursor hand1 1102 1273 } 1103 1274 if { $option == "drag" || $option == "release" } { 1104 set dx [expr ($click_(x) - $x)/double($w)] 1105 set dy [expr ($click_(y) - $y)/double($h)] 1106 set click_(x) $x 1107 set click_(y) $y 1108 set view_(dx) [expr $view_(dx) - $dx] 1109 set view_(dy) [expr $view_(dy) - $dy] 1110 _send "camera pan $view_(dx) $view_(dy)" 1275 set dx [expr ($click_(x) - $x)/double($w)] 1276 set dy [expr ($click_(y) - $y)/double($h)] 1277 set click_(x) $x 1278 set click_(y) $y 1279 set view_(pan-x) [expr $view_(pan-x) - $dx] 1280 set view_(pan-y) [expr $view_(pan-y) - $dy] 1281 PanCamera 1282 set settings_($this-pan-x) $view_(pan-x) 1283 set settings_($this-pan-y) $view_(pan-y) 1111 1284 } 1112 1285 if { $option == "release" } { 1113 $itk_component(3dview) configure -cursor "" 1114 } 1115 } 1116 1117 # ---------------------------------------------------------------------- 1118 # USAGE: _rotate click <x> <y> 1119 # USAGE: _rotate drag <x> <y> 1120 # USAGE: _rotate release <x> <y> 1121 # 1122 # Called automatically when the user clicks/drags/releases in the 1123 # plot area. Moves the plot according to the user's actions. 1124 # ---------------------------------------------------------------------- 1125 itcl::body Rappture::FlowvisViewer::_rotate {option x y} { 1126 switch -- $option { 1127 click { 1128 $itk_component(3dview) configure -cursor fleur 1129 array set click_ [subst { 1130 x $x 1131 y $y 1132 theta $view_(theta) 1133 phi $view_(phi) 1134 }] 1135 } 1136 drag { 1137 if {[array size click_] == 0} { 1138 _rotate click $x $y 1139 } else { 1140 set w [winfo width $itk_component(3dview)] 1141 set h [winfo height $itk_component(3dview)] 1142 if {$w <= 0 || $h <= 0} { 1143 return 1144 } 1145 1146 if {[catch { 1147 # this fails sometimes for no apparent reason 1148 set dx [expr {double($x-$click_(x))/$w}] 1149 set dy [expr {double($y-$click_(y))/$h}] 1150 }] != 0 } { 1151 return 1152 } 1153 1154 # 1155 # Rotate the camera in 3D 1156 # 1157 if {$view_(psi) > 90 || $view_(psi) < -90} { 1158 # when psi is flipped around, theta moves backwards 1159 set dy [expr {-$dy}] 1160 } 1161 set theta [expr {$view_(theta) - $dy*180}] 1162 while {$theta < 0} { set theta [expr {$theta+180}] } 1163 while {$theta > 180} { set theta [expr {$theta-180}] } 1164 1165 if {abs($theta) >= 30 && abs($theta) <= 160} { 1166 set phi [expr {$view_(phi) - $dx*360}] 1167 while {$phi < 0} { set phi [expr {$phi+360}] } 1168 while {$phi > 360} { set phi [expr {$phi-360}] } 1169 set psi $view_(psi) 1170 } else { 1171 set phi $view_(phi) 1172 set psi [expr {$view_(psi) - $dx*360}] 1173 while {$psi < -180} { set psi [expr {$psi+360}] } 1174 while {$psi > 180} { set psi [expr {$psi-360}] } 1175 } 1176 1177 set view_(theta) $theta 1178 set view_(phi) $phi 1179 set view_(psi) $psi 1180 set xyz [Euler2XYZ $view_(theta) $view_(phi) $view_(psi)] 1181 _send "camera angle $xyz" 1182 set click_(x) $x 1183 set click_(y) $y 1184 } 1185 } 1186 release { 1187 _rotate drag $x $y 1188 $itk_component(3dview) configure -cursor "" 1189 catch {unset click_} 1190 } 1191 default { 1192 error "bad option \"$option\": should be click, drag, release" 1193 } 1194 } 1195 } 1196 1197 # ---------------------------------------------------------------------- 1198 # USAGE: _slice axis x|y|z ?on|off|toggle? 1199 # USAGE: _slice move x|y|z <newval> 1200 # USAGE: _slice volume ?on|off|toggle? 1286 $itk_component(3dview) configure -cursor "" 1287 } 1288 } 1289 1290 # ---------------------------------------------------------------------- 1291 # USAGE: Slice axis x|y|z ?on|off|toggle? 1292 # USAGE: Slice move x|y|z <newval> 1293 # USAGE: Slice volume ?on|off|toggle? 1201 1294 # 1202 1295 # Called automatically when the user drags the slider to move the … … 1205 1298 # data set. 1206 1299 # ---------------------------------------------------------------------- 1207 itcl::body Rappture::FlowvisViewer:: _slice {option args} {1300 itcl::body Rappture::FlowvisViewer::Slice {option args} { 1208 1301 switch -- $option { 1209 axis { 1210 if {[llength $args] < 1 || [llength $args] > 2} { 1211 error "wrong # args: should be \"_slice axis x|y|z ?on|off|toggle?\"" 1302 axis { 1303 if {[llength $args] < 1 || [llength $args] > 2} { 1304 error "wrong # args: should be \"Slice axis x|y|z ?on|off|toggle?\"" 1305 } 1306 set axis [lindex $args 0] 1307 set op [lindex $args 1] 1308 if {$op == ""} { 1309 set op "on" 1212 1310 } 1213 set axis [lindex $args 0] 1214 set op [lindex $args 1] 1215 if {$op == ""} { set op "on" } 1216 1217 set current [_state ${axis}slice] 1218 if {$op == "toggle"} { 1219 if {$current == "on"} { set op "off" } else { set op "on" } 1220 } 1221 if {$op} { 1222 $itk_component(${axis}slicer) configure -state normal 1223 _send "cutplane state 1 $axis [_currentVolumeIds -cutplanes]" 1224 $itk_component(${axis}slice) configure -relief sunken 1225 } else { 1226 $itk_component(${axis}slicer) configure -state disabled 1227 _send "cutplane state 0 $axis [_currentVolumeIds -cutplanes]" 1228 $itk_component(${axis}slice) configure -relief raised 1229 } 1230 } 1231 move { 1232 if {[llength $args] != 2} { 1233 error "wrong # args: should be \"_slice move x|y|z newval\"" 1234 } 1235 set axis [lindex $args 0] 1236 set newval [lindex $args 1] 1237 1238 set newpos [expr {0.01*$newval}] 1311 set current [State ${axis}CutButton] 1312 if {$op == "toggle"} { 1313 if {$current == "on"} { 1314 set op "off" 1315 } else { 1316 set op "on" 1317 } 1318 } 1319 if {$op} { 1320 $itk_component(${axis}CutButton) configure \ 1321 -image [Rappture::icon ${axis}-cutplane-on] \ 1322 -relief sunken 1323 SendCmd "cutplane state 1 $axis [CurrentVolumeIds -cutplanes]" 1324 $itk_component(${axis}CutScale) configure -state normal 1325 } else { 1326 $itk_component(${axis}CutButton) configure \ 1327 -image [Rappture::icon ${axis}-cutplane-off] \ 1328 -relief raised 1329 SendCmd "cutplane state 0 $axis [CurrentVolumeIds -cutplanes]" 1330 $itk_component(${axis}CutScale) configure -state disabled 1331 } 1332 } 1333 move { 1334 if {[llength $args] != 2} { 1335 error "wrong # args: should be \"Slice move x|y|z newval\"" 1336 } 1337 set axis [lindex $args 0] 1338 set newval [lindex $args 1] 1339 1340 set newpos [expr {0.01*$newval}] 1239 1341 # set newval [expr {0.01*($newval-50) 1240 1342 # *($limits_(${axis}max)-$limits_(${axis}min)) 1241 1343 # + 0.5*($limits_(${axis}max)+$limits_(${axis}min))}] 1242 1344 1243 # show the current value in the readout 1244 #puts "readout: $axis = $newval" 1245 1246 set ids [_currentVolumeIds -cutplanes] 1247 _send "cutplane position $newpos $axis $ids" 1248 } 1249 volume { 1250 if {[llength $args] > 1} { 1251 error "wrong # args: should be \"_slice volume ?on|off|toggle?\"" 1252 } 1253 set op [lindex $args 0] 1254 if {$op == ""} { set op "on" } 1255 1256 set current [_state volume] 1257 if {$op == "toggle"} { 1258 if {$current == "on"} { set op "off" } else { set op "on" } 1259 } 1260 1261 if {$op} { 1262 _send "volume data state on [_currentVolumeIds]" 1263 $itk_component(volume) configure -relief sunken 1264 } else { 1265 _send "volume data state off [_currentVolumeIds]" 1266 $itk_component(volume) configure -relief raised 1267 } 1268 } 1269 default { 1270 error "bad option \"$option\": should be axis, move, or volume" 1271 } 1272 } 1273 } 1274 1275 # ---------------------------------------------------------------------- 1276 # USAGE: _slicertip <axis> 1345 # show the current value in the readout 1346 #puts "readout: $axis = $newval" 1347 1348 set ids [CurrentVolumeIds -cutplanes] 1349 SendCmd "cutplane position $newpos $axis $ids" 1350 } 1351 volume { 1352 if {[llength $args] > 1} { 1353 error "wrong # args: should be \"Slice volume ?on|off|toggle?\"" 1354 } 1355 set op [lindex $args 0] 1356 if {$op == ""} { set op "on" } 1357 1358 set current $settings_($this-volume) 1359 if {$op == "toggle"} { 1360 if {$current} { 1361 set op "off" 1362 } else { 1363 set op "on" 1364 } 1365 } 1366 1367 if {$op} { 1368 SendCmd "volume data state on [CurrentVolumeIds]" 1369 $itk_component(volume) configure -relief sunken 1370 set settings_($this-volume) 1 1371 } else { 1372 SendCmd "volume data state off [CurrentVolumeIds]" 1373 $itk_component(volume) configure -relief raised 1374 set settings_($this-volume) 0 1375 } 1376 } 1377 default { 1378 error "bad option \"$option\": should be axis, move, or volume" 1379 } 1380 } 1381 } 1382 1383 # ---------------------------------------------------------------------- 1384 # USAGE: SlicerTip <axis> 1277 1385 # 1278 1386 # Used internally to generate a tooltip for the x/y/z slicer controls. 1279 1387 # Returns a message that includes the current slicer value. 1280 1388 # ---------------------------------------------------------------------- 1281 itcl::body Rappture::FlowvisViewer:: _slicertip {axis} {1282 set val [$itk_component(${axis} slicer) get]1389 itcl::body Rappture::FlowvisViewer::SlicerTip {axis} { 1390 set val [$itk_component(${axis}CutScale) get] 1283 1391 # set val [expr {0.01*($val-50) 1284 1392 # *($limits_(${axis}max)-$limits_(${axis}min)) … … 1288 1396 1289 1397 # ---------------------------------------------------------------------- 1290 # USAGE: _flow movie record|stop|play ?on|off|toggle?1398 # USAGE: Flow movie record|stop|play ?on|off|toggle? 1291 1399 # 1292 1400 # Called when the user clicks on the record, stop or play buttons 1293 1401 # for flow visualization. 1294 1402 # ---------------------------------------------------------------------- 1295 itcl::body Rappture::FlowvisViewer:: _flow {option args} {1403 itcl::body Rappture::FlowvisViewer::Flow {option args} { 1296 1404 switch -- $option { 1297 1298 1299 error "wrong # args: should be \"_flow movie record|stop|play ?on|off|toggle?\""1300 1301 1302 1303 1304 1305 set current [_state $action]1306 1307 1308 1309 1310 1311 1312 1313 1314 1315 1316 if { [$itk_component(re cord) cget -relief] != "sunken" } {1317 $itk_component(re cord) configure -relief sunken1405 movie { 1406 if {[llength $args] < 1 || [llength $args] > 2} { 1407 error "wrong # args: should be \"Flow movie record|stop|play ?on|off|toggle?\"" 1408 } 1409 set action [lindex $args 0] 1410 set op [lindex $args 1] 1411 if {$op == ""} { set op "on" } 1412 1413 set current [State $action] 1414 if {$op == "toggle"} { 1415 if {$current == "on"} { 1416 set op "off" 1417 } else { 1418 set op "on" 1419 } 1420 } 1421 set cmds "" 1422 switch -- $action { 1423 record { 1424 if { [$itk_component(rewind) cget -relief] != "sunken" } { 1425 $itk_component(rewind) configure -relief sunken 1318 1426 $itk_component(stop) configure -relief raised 1319 1427 $itk_component(play) configure -relief raised 1320 set inner \1321 [$itk_component(controls).panel component inner]1322 set frames [$inner.scales.framecnt value]1428 set inner $itk_component(settingsFrame) 1429 set frames [$inner.framecnt value] 1430 set settings_(numframes) $frames 1323 1431 set cmds "flow capture $frames" 1324 1432 _send $cmds 1325 1433 } 1326 1327 1434 } 1435 stop { 1328 1436 if { [$itk_component(stop) cget -relief] != "sunken" } { 1329 $itk_component(re cord) configure -relief raised1437 $itk_component(rewind) configure -relief raised 1330 1438 $itk_component(stop) configure -relief sunken 1331 1439 $itk_component(play) configure -relief raised … … 1334 1442 _send $cmds 1335 1443 } 1336 1337 1444 } 1445 play { 1338 1446 if { [$itk_component(play) cget -relief] != "sunken" } { 1339 $itk_component(record) configure -relief raised 1447 $itk_component(rewind) configure -relief raised 1448 $itk_component(stop) configure -relief raised 1449 $itk_component(play) configure \ 1450 -image [Rappture::icon flow-pause] \ 1451 -relief sunken 1452 bind $itk_component(play) <ButtonPress> \ 1453 [itcl::code $this _pause] 1454 flow next 1455 } 1456 } 1457 default { 1458 error "bad option \"$option\": should be one of record|stop|play" 1459 } 1460 1461 } 1462 } 1463 default { 1464 error "bad option \"$option\": should be movie" 1465 } 1466 } 1467 } 1468 1469 # ---------------------------------------------------------------------- 1470 # USAGE: Play 1471 # 1472 # ---------------------------------------------------------------------- 1473 itcl::body Rappture::FlowvisViewer::Play {} { 1474 SendCmd "flow play" 1475 set delay [expr {int(ceil(pow($settings_(speed)/10.0+2,2.0)*15))}] 1476 $_dispatcher event -after $delay !play 1477 } 1478 1479 # ---------------------------------------------------------------------- 1480 # USAGE: Pause 1481 # 1482 # Invoked when the user hits the "pause" button to stop playing the 1483 # current sequence of frames as a movie. 1484 # ---------------------------------------------------------------------- 1485 itcl::body Rappture::FlowvisViewer::Pause {} { 1486 $_dispatcher cancel !play 1487 1488 # Toggle the button to "play" mode 1489 $itk_component(play) configure \ 1490 -image [Rappture::icon flow-start] \ 1491 -relief raised 1492 bind $itk_component(play) <ButtonPress> \ 1493 [itcl::code $this Flow movie play toggle] 1494 } 1495 1496 # ---------------------------------------------------------------------- 1497 # USAGE: State <component> 1498 # 1499 # Used internally to determine the state of a toggle button. 1500 # The <component> is the itk component name of the button. 1501 # Returns on/off for the state of the button. 1502 # ---------------------------------------------------------------------- 1503 itcl::body Rappture::FlowvisViewer::State {comp} { 1504 if {[$itk_component(${comp}) cget -relief] == "sunken"} { 1505 return "on" 1506 } 1507 return "off" 1508 } 1509 1510 # ---------------------------------------------------------------------- 1511 # USAGE: FixSettings <what> ?<value>? 1512 # 1513 # Used internally to update rendering settings whenever parameters 1514 # change in the popup settings panel. Sends the new settings off 1515 # to the back end. 1516 # ---------------------------------------------------------------------- 1517 itcl::body Rappture::FlowvisViewer::FixSettings {what {value ""}} { 1518 switch -- $what { 1519 light { 1520 if {[isconnected]} { 1521 set val $settings_($this-light) 1522 set sval [expr {0.1*$val}] 1523 SendCmd "volume shading diffuse $sval" 1524 set sval [expr {sqrt($val+1.0)}] 1525 SendCmd "volume shading specular $sval" 1526 } 1527 } 1528 transp { 1529 if {[isconnected]} { 1530 set val $settings_($this-transp) 1531 set sval [expr {0.2*$val+1}] 1532 SendCmd "volume shading opacity $sval" 1533 } 1534 } 1535 opacity { 1536 if {[isconnected] && $activeTf_ != "" } { 1537 set val $settings_($this-opacity) 1538 set sval [expr { 0.01 * double($val) }] 1539 set tf $activeTf_ 1540 set settings_($this-$tf-opacity) $sval 1541 UpdateTransferFunctions 1542 } 1543 } 1544 1545 thickness { 1546 if {[isconnected] && $activeTf_ != "" } { 1547 set val $settings_($this-thickness) 1548 # Scale values between 0.00001 and 0.01000 1549 set sval [expr {0.0001*double($val)}] 1550 set tf $activeTf_ 1551 set settings_($this-$tf-thickness) $sval 1552 UpdateTransferFunctions 1553 } 1554 } 1555 "outline" { 1556 if {[isconnected]} { 1557 SendCmd "volume outline state $settings_($this-outline)" 1558 } 1559 } 1560 "isosurface" { 1561 if {[isconnected]} { 1562 SendCmd "volume shading isosurface $settings_($this-isosurface)" 1563 } 1564 } 1565 "grid" { 1566 if { [isconnected] } { 1567 SendCmd "grid visible $settings_($this-grid)" 1568 } 1569 } 1570 "axes" { 1571 if { [isconnected] } { 1572 SendCmd "axis visible $settings_($this-axes)" 1573 } 1574 } 1575 "legend" { 1576 if { $settings_($this-legend) } { 1577 pack $itk_component(legend) -side bottom -fill x 1578 } else { 1579 pack forget $itk_component(legend) 1580 } 1581 FixLegend 1582 } 1583 "volume" { 1584 Slice volume $settings_($this-volume) 1585 } 1586 "particles" { 1587 } 1588 default { 1589 error "don't know how to fix $what" 1590 } 1591 } 1592 } 1593 1594 # ---------------------------------------------------------------------- 1595 # USAGE: FixLegend 1596 # 1597 # Used internally to update the legend area whenever it changes size 1598 # or when the field changes. Asks the server to send a new legend 1599 # for the current field. 1600 # ---------------------------------------------------------------------- 1601 itcl::body Rappture::FlowvisViewer::FixLegend {} { 1602 set lineht [font metrics $itk_option(-font) -linespace] 1603 set w [expr {[winfo width $itk_component(legend)]-20}] 1604 set h [expr {[winfo height $itk_component(legend)]-20-$lineht}] 1605 if {$w > 0 && $h > 0 && "" != $activeTf_} { 1606 SendCmd "legend $activeTf_ $w $h" 1607 } else { 1608 # Can't do this as this will remove the items associated with the 1609 # isomarkers. 1610 1611 #$itk_component(legend) delete all 1612 } 1613 } 1614 1615 # 1616 # NameTransferFunction -- 1617 # 1618 # Creates a transfer function name based on the <style> settings in the 1619 # library run.xml file. This placeholder will be used later to create 1620 # and send the actual transfer function once the data info has been sent 1621 # to us by the render server. [We won't know the volume limits until the 1622 # server parses the 3D data and sends back the limits via ReceiveData.] 1623 # 1624 # FIXME: The current way we generate transfer-function names completely 1625 # ignores the -markers option. The problem is that we are forced 1626 # to compute the name from an increasing complex set of values: 1627 # color, levels, marker, opacity. I think we're stuck doing it 1628 # now. 1629 # 1630 itcl::body Rappture::FlowvisViewer::NameTransferFunction { ivol } { 1631 array set style { 1632 -color rainbow 1633 -levels 6 1634 -opacity 1.0 1635 } 1636 foreach {dataobj comp} $id2obj_($ivol) break 1637 array set style [lindex [$dataobj components -style $comp] 0] 1638 set tf "$style(-color):$style(-levels):$style(-opacity)" 1639 1640 set id2style_($ivol) $tf 1641 lappend obj2styles_($dataobj) $tf 1642 lappend style2ids_($tf) $ivol 1643 } 1644 1645 # 1646 # ComputeTransferFunction -- 1647 # 1648 # Computes and sends the transfer function to the render server. It's 1649 # assumed that the volume data limits are known and that the global 1650 # transfer-functions slider values have be setup. Both parts are 1651 # needed to compute the relative value (location) of the marker, and 1652 # the alpha map of the transfer function. 1653 # 1654 itcl::body Rappture::FlowvisViewer::ComputeTransferFunction { tf } { 1655 array set style { 1656 -color rainbow 1657 -levels 6 1658 -opacity 1.0 1659 } 1660 set dataobj ""; set comp "" 1661 foreach ivol $style2ids_($tf) { 1662 if { [info exists id2obj_($ivol)] } { 1663 foreach {dataobj comp} $id2obj_($ivol) break 1664 break 1665 } 1666 } 1667 if { $dataobj == "" } { 1668 return 0 1669 } 1670 array set style [lindex [$dataobj components -style $comp] 0] 1671 1672 1673 # We have to parse the style attributes for a volume using this 1674 # transfer-function *once*. This sets up the initial isomarkers for the 1675 # transfer function. The user may add/delete markers, so we have to 1676 # maintain a list of markers for each transfer-function. We use the one 1677 # of the volumes (the first in the list) using the transfer-function as a 1678 # reference. 1679 # 1680 # FIXME: The current way we generate transfer-function names completely 1681 # ignores the -markers option. The problem is that we are forced 1682 # to compute the name from an increasing complex set of values: 1683 # color, levels, marker, opacity. I think the cow's out of the 1684 # barn on this one. 1685 1686 if { ![info exists isomarkers_($tf)] } { 1687 # Have to defer creation of isomarkers until we have data limits 1688 if { [info exists style(-markers)] } { 1689 ParseMarkersOption $tf $ivol $style(-markers) 1690 } else { 1691 ParseLevelsOption $tf $ivol $style(-levels) 1692 } 1693 } 1694 if {$style(-color) == "rainbow"} { 1695 set style(-color) "white:yellow:green:cyan:blue:magenta" 1696 } 1697 set clist [split $style(-color) :] 1698 set cmap "0.0 [Color2RGB white] " 1699 for {set i 0} {$i < [llength $clist]} {incr i} { 1700 set x [expr {double($i+1)/([llength $clist]+1)}] 1701 set color [lindex $clist $i] 1702 append cmap "$x [Color2RGB $color] " 1703 } 1704 append cmap "1.0 [Color2RGB $color]" 1705 1706 set tag $this-$tf 1707 if { ![info exists settings_($tag-opacity)] } { 1708 set settings_($tag-opacity) $style(-opacity) 1709 } 1710 set max $settings_($tag-opacity) 1711 1712 set isovalues {} 1713 foreach m $isomarkers_($tf) { 1714 lappend isovalues [$m GetRelativeValue] 1715 } 1716 # Sort the isovalues 1717 set isovalues [lsort -real $isovalues] 1718 1719 if { ![info exists settings_($tag-thickness)]} { 1720 set settings_($tag-thickness) 0.05 1721 } 1722 set delta $settings_($tag-thickness) 1723 1724 set first [lindex $isovalues 0] 1725 set last [lindex $isovalues end] 1726 set wmap "" 1727 if { $first == "" || $first != 0.0 } { 1728 lappend wmap 0.0 0.0 1729 } 1730 foreach x $isovalues { 1731 set x1 [expr {$x-$delta-0.00001}] 1732 set x2 [expr {$x-$delta}] 1733 set x3 [expr {$x+$delta}] 1734 set x4 [expr {$x+$delta+0.00001}] 1735 if { $x1 < 0.0 } { 1736 set x1 0.0 1737 } elseif { $x1 > 1.0 } { 1738 set x1 1.0 1739 } 1740 if { $x2 < 0.0 } { 1741 set x2 0.0 1742 } elseif { $x2 > 1.0 } { 1743 set x2 1.0 1744 } 1745 if { $x3 < 0.0 } { 1746 set x3 0.0 1747 } elseif { $x3 > 1.0 } { 1748 set x3 1.0 1749 } 1750 if { $x4 < 0.0 } { 1751 set x4 0.0 1752 } elseif { $x4 > 1.0 } { 1753 set x4 1.0 1754 } 1755 # add spikes in the middle 1756 lappend wmap $x1 0.0 1757 lappend wmap $x2 $max 1758 lappend wmap $x3 $max 1759 lappend wmap $x4 0.0 1760 } 1761 if { $last == "" || $last != 1.0 } { 1762 lappend wmap 1.0 0.0 1763 } 1764 SendBytes "transfunc define $tf { $cmap } { $wmap }\n" 1765 return [SendBytes "volume shading transfunc $tf $style2ids_($tf)\n"] 1766 } 1767 1768 # ---------------------------------------------------------------------- 1769 # CONFIGURATION OPTION: -plotbackground 1770 # ---------------------------------------------------------------------- 1771 itcl::configbody Rappture::FlowvisViewer::plotbackground { 1772 if { [isconnected] } { 1773 foreach {r g b} [Color2RGB $itk_option(-plotbackground)] break 1774 #fix this! 1775 #SendCmd "color background $r $g $b" 1776 } 1777 } 1778 1779 # ---------------------------------------------------------------------- 1780 # CONFIGURATION OPTION: -plotforeground 1781 # ---------------------------------------------------------------------- 1782 itcl::configbody Rappture::FlowvisViewer::plotforeground { 1783 if { [isconnected] } { 1784 foreach {r g b} [Color2RGB $itk_option(-plotforeground)] break 1785 #fix this! 1786 #SendCmd "color background $r $g $b" 1787 } 1788 } 1789 1790 # ---------------------------------------------------------------------- 1791 # CONFIGURATION OPTION: -plotoutline 1792 # ---------------------------------------------------------------------- 1793 itcl::configbody Rappture::FlowvisViewer::plotoutline { 1794 # Must check if we are connected because this routine is called from the 1795 # class body when the -plotoutline itk_option is defined. At that point 1796 # the FlowvisViewer class constructor hasn't been called, so we can't 1797 # start sending commands to visualization server. 1798 if { [isconnected] } { 1799 if {"" == $itk_option(-plotoutline)} { 1800 SendCmd "volume outline state off" 1801 } else { 1802 SendCmd "volume outline state on" 1803 SendCmd "volume outline color [Color2RGB $itk_option(-plotoutline)]" 1804 } 1805 } 1806 } 1807 1808 # 1809 # The -levels option takes a single value that represents the number 1810 # of evenly distributed markers based on the current data range. Each 1811 # marker is a relative value from 0.0 to 1.0. 1812 # 1813 itcl::body Rappture::FlowvisViewer::ParseLevelsOption { tf ivol levels } { 1814 set c $itk_component(legend) 1815 regsub -all "," $levels " " levels 1816 if {[string is int $levels]} { 1817 for {set i 1} { $i <= $levels } {incr i} { 1818 set x [expr {double($i)/($levels+1)}] 1819 set m [IsoMarker \#auto $c $this $tf] 1820 $m SetRelativeValue $x 1821 lappend isomarkers_($tf) $m 1822 } 1823 } else { 1824 foreach x $levels { 1825 set m [IsoMarker \#auto $c $this $tf] 1826 $m SetRelativeValue $x 1827 lappend isomarkers_($tf) $m 1828 } 1829 } 1830 } 1831 1832 # 1833 # The -markers option takes a list of zero or more values (the values 1834 # may be separated either by spaces or commas) that have the following 1835 # format: 1836 # 1837 # N% Percent of current total data range. Converted to 1838 # to a relative value between 0.0 and 1.0. 1839 # N Absolute value of marker. If the marker is outside of 1840 # the current range, it will be displayed on the outer 1841 # edge of the legends, but it range it represents will 1842 # not be seen. 1843 # 1844 itcl::body Rappture::FlowvisViewer::ParseMarkersOption { tf ivol markers } { 1845 set c $itk_component(legend) 1846 regsub -all "," $markers " " markers 1847 foreach marker $markers { 1848 set n [scan $marker "%g%s" value suffix] 1849 if { $n == 2 && $suffix == "%" } { 1850 # ${n}% : Set relative value. 1851 set value [expr {$value * 0.01}] 1852 set m [IsoMarker \#auto $c $this $tf] 1853 $m SetRelativeValue $value 1854 lappend isomarkers_($tf) $m 1855 } else { 1856 # ${n} : Set absolute value. 1857 set m [IsoMarker \#auto $c $this $tf] 1858 $m SetAbsoluteValue $value 1859 lappend isomarkers_($tf) $m 1860 } 1861 } 1862 } 1863 1864 # ---------------------------------------------------------------------- 1865 # USAGE: UndateTransferFunctions 1866 # ---------------------------------------------------------------------- 1867 itcl::body Rappture::FlowvisViewer::UpdateTransferFunctions {} { 1868 $_dispatcher event -idle !send_transfunc 1869 } 1870 1871 itcl::body Rappture::FlowvisViewer::AddIsoMarker { x y } { 1872 if { $activeTf_ == "" } { 1873 error "active transfer function isn't set" 1874 } 1875 set tf $activeTf_ 1876 set c $itk_component(legend) 1877 set m [IsoMarker \#auto $c $this $tf] 1878 set w [winfo width $c] 1879 $m SetRelativeValue [expr {double($x-10)/($w-20)}] 1880 lappend isomarkers_($tf) $m 1881 UpdateTransferFunctions 1882 return 1 1883 } 1884 1885 itcl::body Rappture::FlowvisViewer::RemoveDuplicateIsoMarker { marker x } { 1886 set tf [$marker GetTransferFunction] 1887 set bool 0 1888 if { [info exists isomarkers_($tf)] } { 1889 set list {} 1890 set marker [namespace tail $marker] 1891 foreach m $isomarkers_($tf) { 1892 set sx [$m GetScreenPosition] 1893 if { $m != $marker } { 1894 if { $x >= ($sx-3) && $x <= ($sx+3) } { 1895 $marker SetRelativeValue [$m GetRelativeValue] 1896 itcl::delete object $m 1897 bell 1898 set bool 1 1899 continue 1900 } 1901 } 1902 lappend list $m 1903 } 1904 set isomarkers_($tf) $list 1905 UpdateTransferFunctions 1906 } 1907 return $bool 1908 } 1909 1910 itcl::body Rappture::FlowvisViewer::OverIsoMarker { marker x } { 1911 set tf [$marker GetTransferFunction] 1912 if { [info exists isomarkers_($tf)] } { 1913 set marker [namespace tail $marker] 1914 foreach m $isomarkers_($tf) { 1915 set sx [$m GetScreenPosition] 1916 if { $m != $marker } { 1917 set bool [expr { $x >= ($sx-3) && $x <= ($sx+3) }] 1918 $m Activate $bool 1919 } 1920 } 1921 } 1922 return "" 1923 } 1924 1925 itcl::body Rappture::FlowvisViewer::GetLimits { tf } { 1926 set limits_(min) "" 1927 set limits_(max) "" 1928 foreach ivol $style2ids_($tf) { 1929 if { ![info exists limits_($ivol-min)] } { 1930 error "can't find $ivol limits" 1931 } 1932 if { $limits_(min) == "" || $limits_(min) > $limits_($ivol-min) } { 1933 set limits_(min) $limits_($ivol-min) 1934 } 1935 if { $limits_(max) == "" || $limits_(max) < $limits_($ivol-max) } { 1936 set limits_(max) $limits_($ivol-max) 1937 } 1938 } 1939 return [array get limits_] 1940 } 1941 1942 1943 # 1944 # flow -- 1945 # 1946 # Called when the user clicks on the stop or play buttons 1947 # for flow visualization. 1948 # 1949 # $this flow start 1950 # $this flow stop 1951 # $this flow toggle 1952 # $this flow rewind 1953 # $this flow pause 1954 # $this flow next 1955 # 1956 itcl::body Rappture::FlowvisViewer::flow {option} { 1957 switch -- $option { 1958 "stop" { 1959 if { $flow_(state) != "stopped" } { 1960 # Reset the play button to off 1961 $itk_component(play) configure -image [Rappture::icon flow-play] 1962 $_dispatcher cancel !play 1963 SendCmd "flow reset" 1964 set flow_(state) "stopped" 1965 } 1966 } 1967 "pause" { 1968 if { $flow_(state) == "playing" } { 1969 # Reset the play button to pause 1970 # Convert to the play button. 1971 $itk_component(play) configure -image [Rappture::icon flow-play] 1972 $_dispatcher cancel !play 1973 set flow_(state) "paused" 1974 } 1975 } 1976 "start" { 1977 if { $flow_(state) != "playing" } { 1978 # Starts the "flow next" requests to the server. 1979 # Convert to the pause button. 1980 $itk_component(play) configure \ 1981 -image [Rappture::icon flow-pause] 1982 flow next 1983 set flow_(state) "playing" 1984 } 1985 } 1986 "toggle" { 1987 if { $flow_(state) == "playing" } { 1988 flow pause 1989 } else { 1990 flow start 1991 } 1992 } 1993 "rewind" { 1994 if { $flow_(state) != "stopped" } { 1995 SendCmd "flow reset" 1996 } 1997 } 1998 "next" { 1999 # This operation should not be called by public routines. 2000 SendCmd "flow play" 2001 set delay [expr {int(ceil(pow($settings_(speed)/10.0+2,2.0)*15))}] 2002 $_dispatcher event -after $delay !play 2003 } 2004 default { 2005 error "bad option \"$option\": should be start, stop, toggle, or reset." 2006 } 2007 } 2008 } 2009 2010 # 2011 # record -- 2012 # 2013 # Called when the user clicks on the record, stop or play buttons 2014 # for flow visualization. 2015 # 2016 # $this record on 2017 # $this record off 2018 # $this record toggle 2019 # 2020 # 2021 itcl::body Rappture::FlowvisViewer::record {option} { 2022 switch -- $option { 2023 movie { 2024 if {[llength $args] < 1 || [llength $args] > 2} { 2025 error "wrong # args: should be \"Flow movie record|stop|play ?on|off|toggle?\"" 2026 } 2027 set action [lindex $args 0] 2028 set op [lindex $args 1] 2029 if {$op == ""} { set op "on" } 2030 2031 set current [State $action] 2032 if {$op == "toggle"} { 2033 if {$current == "on"} { 2034 set op "off" 2035 } else { 2036 set op "on" 2037 } 2038 } 2039 set cmds "" 2040 switch -- $action { 2041 record { 2042 if { [$itk_component(rewind) cget -relief] != "sunken" } { 2043 $itk_component(rewind) configure -relief sunken 2044 $itk_component(stop) configure -relief raised 2045 $itk_component(play) configure -relief raised 2046 set inner $itk_component(settingsFrame) 2047 set frames [$inner.framecnt value] 2048 set cmds "flow capture $frames" 2049 _send $cmds 2050 } 2051 } 2052 stop { 2053 if { [$itk_component(stop) cget -relief] != "sunken" } { 2054 $itk_component(rewind) configure -relief raised 2055 $itk_component(stop) configure -relief sunken 2056 $itk_component(play) configure -relief raised 2057 _pause 2058 set cmds "flow reset" 2059 _send $cmds 2060 } 2061 } 2062 play { 2063 if { [$itk_component(play) cget -relief] != "sunken" } { 2064 $itk_component(rewind) configure -relief raised 1340 2065 $itk_component(stop) configure -relief raised 1341 2066 $itk_component(play) configure \ … … 1344 2069 bind $itk_component(play) <ButtonPress> \ 1345 2070 [itcl::code $this _pause] 1346 _play2071 Play 1347 2072 } 1348 } 1349 default { 1350 error "bad option \"$option\": should be one of record|stop|play" 1351 } 1352 2073 } 2074 default { 2075 error "bad option \"$option\": should be one of record|stop|play" 2076 } 2077 2078 } 2079 } 2080 default { 2081 error "bad option \"$option\": should be movie" 2082 } 2083 } 2084 } 2085 2086 2087 itcl::body Rappture::FlowvisViewer::drawer { what who } { 2088 if { [info exists drawer_(current)] && $who != $drawer_(current) } { 2089 drawer deactivate $drawer_(current) 2090 } 2091 switch -- ${what} { 2092 "activate" { 2093 $itk_component(drawer) add $itk_component($who) -sticky nsew 2094 after idle [list focus $itk_component($who)] 2095 if { ![info exists drawer_($who)] } { 2096 set rw [winfo reqwidth $itk_component($who)] 2097 set w [winfo width $itk_component(drawer)] 2098 set x [expr $w - $rw] 2099 $itk_component(drawer) sash place 0 $x 0 2100 set drawer_($who) 1 2101 } else { 2102 set w [winfo width $itk_component(drawer)] 2103 puts stderr "w of drawer is $w" 2104 puts stderr "w of last($who) is $drawer_($who-lastx)" 2105 set x [expr $w - $drawer_($who-lastx) - 10] 2106 puts stderr "setting sash to $x for $who" 2107 $itk_component(drawer) sash place 0 $x 0 2108 $itk_component(drawer) paneconfigure $itk_component($who) \ 2109 -width $drawer_($who-lastx) 2110 $itk_component(3dview) configure -width $x 2111 } 2112 set drawer_(current) $who 2113 $itk_component(${who}Button) configure -relief sunken -bd 1 2114 } 2115 "deactivate" { 2116 # Save the current width of the drawer. 2117 puts stderr "component=$who" 2118 set width [winfo width $itk_component($who)] 2119 set reqwidth [winfo reqwidth $itk_component($who)] 2120 if { $reqwidth < $width } { 2121 set width $reqwidth 2122 } 2123 set x [lindex [$itk_component(drawer) sash coord 0] 0] 2124 puts stderr "sashx=$x" 2125 set drawer_($who-lastx) $width 2126 $itk_component(drawer) forget $itk_component($who) 2127 $itk_component(${who}Button) configure -relief raised -bd 1 2128 unset drawer_(current) 2129 } 2130 "toggle" { 2131 set slaves [$itk_component(drawer) panes] 2132 if { [lsearch $slaves $itk_component($who)] >= 0 } { 2133 drawer deactivate $who 2134 } else { 2135 drawer activate $who 1353 2136 } 1354 2137 } 1355 default { 1356 error "bad option \"$option\": should be movie" 2138 "resize" { 2139 set bbox [$itk_component(${who}Canvas) bbox all] 2140 set wid [winfo width $itk_component(${who}Frame)] 2141 $itk_component(${who}Canvas) configure -width $wid \ 2142 -scrollregion $bbox -yscrollincrement 0.1i 1357 2143 } 1358 2144 } 1359 2145 } 1360 2146 1361 # ---------------------------------------------------------------------- 1362 # USAGE: _play 1363 # 1364 # ---------------------------------------------------------------------- 1365 itcl::body Rappture::FlowvisViewer::_play {} { 1366 set cmds {flow play} 1367 _send $cmds 1368 set delay [expr {int(ceil(pow($_play(speed)/10.0+2,2.0)*15))}] 1369 set _afterId [after $delay [itcl::code $this _play]] 1370 } 1371 1372 # ---------------------------------------------------------------------- 1373 # USAGE: _pause 1374 # 1375 # Invoked when the user hits the "pause" button to stop playing the 1376 # current sequence of frames as a movie. 1377 # ---------------------------------------------------------------------- 1378 itcl::body Rappture::FlowvisViewer::_pause {} { 1379 if {"" != $_afterId} { 1380 catch {after cancel $_afterId} 1381 set _afterId "" 1382 } 1383 1384 # toggle the button to "play" mode 1385 $itk_component(play) configure \ 1386 -image [Rappture::icon playback-start] \ 1387 -relief raised 1388 bind $itk_component(play) <ButtonPress> \ 1389 [itcl::code $this _flow movie play toggle] 1390 1391 } 1392 1393 # ---------------------------------------------------------------------- 1394 # USAGE: _state <component> 1395 # 1396 # Used internally to determine the state of a toggle button. 1397 # The <component> is the itk component name of the button. 1398 # Returns on/off for the state of the button. 1399 # ---------------------------------------------------------------------- 1400 itcl::body Rappture::FlowvisViewer::_state {comp} { 1401 if {[$itk_component($comp) cget -relief] == "sunken"} { 1402 return "on" 1403 } 1404 return "off" 1405 } 1406 1407 # ---------------------------------------------------------------------- 1408 # USAGE: _fixSettings <what> ?<value>? 1409 # 1410 # Used internally to update rendering settings whenever parameters 1411 # change in the popup settings panel. Sends the new settings off 1412 # to the back end. 1413 # ---------------------------------------------------------------------- 1414 itcl::body Rappture::FlowvisViewer::_fixSettings { what {value ""} } { 1415 set inner [$itk_component(controls).panel component inner] 1416 switch -- $what { 1417 light { 1418 if {[isconnected]} { 1419 set val [$inner.scales.light get] 1420 set sval [expr {0.1*$val}] 1421 _send "volume shading diffuse $sval" 1422 1423 set sval [expr {sqrt($val+1.0)}] 1424 _send "volume shading specular $sval" 2147 itcl::body Rappture::FlowvisViewer::BuildSettingsDrawer {} { 2148 foreach { key value } { 2149 grid 0 2150 axes 1 2151 outline 1 2152 volume 1 2153 legend 1 2154 particles 1 2155 lic 1 2156 light 40 2157 transp 50 2158 opacity 100 2159 thickness 350 2160 } { 2161 set settings_($this-$key) $value 2162 } 2163 itk_component add settings { 2164 Rappture::Scroller $itk_component(drawer).settings \ 2165 -xscrollmode auto -yscrollmode auto \ 2166 -highlightthickness 0 2167 } 2168 2169 itk_component add settingsCanvas { 2170 canvas $itk_component(settings).canvas -highlightthickness 0 2171 } { 2172 ignore -highlightthickness 2173 } 2174 $itk_component(settings) contents $itk_component(settingsCanvas) 2175 2176 itk_component add settingsFrame { 2177 frame $itk_component(settingsCanvas).frame \ 2178 -highlightthickness 0 2179 } { 2180 ignore -highlightthickness 2181 } 2182 $itk_component(settingsCanvas) create window 0 0 \ 2183 -anchor nw -window $itk_component(settingsFrame) 2184 bind $itk_component(settingsFrame) <Configure> \ 2185 [itcl::code $this drawer resize settings] 2186 2187 set inner $itk_component(settingsFrame) 2188 2189 label $inner.title -text "View Settings" -font "Arial 10 bold" 2190 label $inner.volset -text "Volume Settings" -font "Arial 10 bold" 2191 2192 set fg [option get $itk_component(hull) font Font] 2193 #set bfg [option get $itk_component(hull) boldFont Font] 2194 2195 label $inner.dim -text "Dim" -font $fg 2196 ::scale $inner.light -from 0 -to 100 -orient horizontal \ 2197 -variable [itcl::scope settings_($this-light)] \ 2198 -width 10 \ 2199 -showvalue off -command [itcl::code $this FixSettings light] 2200 label $inner.bright -text "Bright" -font $fg 2201 2202 label $inner.fog -text "Fog" -font $fg 2203 ::scale $inner.transp -from 0 -to 100 -orient horizontal \ 2204 -variable [itcl::scope settings_($this-transp)] \ 2205 -width 10 \ 2206 -showvalue off -command [itcl::code $this FixSettings transp] 2207 label $inner.plastic -text "Plastic" -font $fg 2208 2209 label $inner.clear -text "Clear" -font $fg 2210 ::scale $inner.opacity -from 0 -to 100 -orient horizontal \ 2211 -variable [itcl::scope settings_($this-opacity)] \ 2212 -width 10 \ 2213 -showvalue off -command [itcl::code $this FixSettings opacity] 2214 label $inner.opaque -text "Opaque" -font $fg 2215 2216 label $inner.thin -text "Thin" -font $fg 2217 ::scale $inner.thickness -from 0 -to 1000 -orient horizontal \ 2218 -variable [itcl::scope settings_($this-thickness)] \ 2219 -width 10 \ 2220 -showvalue off -command [itcl::code $this FixSettings thickness] 2221 label $inner.thick -text "Thick" -font $fg 2222 2223 set ::Rappture::FlowvisViewer::settings_($this-isosurface) 0 2224 checkbutton $inner.isosurface \ 2225 -text "Isosurface shading" \ 2226 -variable [itcl::scope settings_($this-isosurface)] \ 2227 -command [itcl::code $this FixSettings isosurface] \ 2228 -font "Arial 9" 2229 2230 checkbutton $inner.axes \ 2231 -text "Axes" \ 2232 -variable [itcl::scope settings_($this-axes)] \ 2233 -command [itcl::code $this FixSettings axes] \ 2234 -font "Arial 9" 2235 2236 checkbutton $inner.grid \ 2237 -text "Grid" \ 2238 -variable [itcl::scope settings_($this-grid)] \ 2239 -command [itcl::code $this FixSettings grid] \ 2240 -font "Arial 9" 2241 2242 checkbutton $inner.outline \ 2243 -text "Outline" \ 2244 -variable [itcl::scope settings_($this-outline)] \ 2245 -command [itcl::code $this FixSettings outline] \ 2246 -font "Arial 9" 2247 2248 checkbutton $inner.legend \ 2249 -text "Legend" \ 2250 -variable [itcl::scope settings_($this-legend)] \ 2251 -command [itcl::code $this FixSettings legend] \ 2252 -font "Arial 9" 2253 2254 checkbutton $inner.volume \ 2255 -text "Volume" \ 2256 -variable [itcl::scope settings_($this-volume)] \ 2257 -command [itcl::code $this FixSettings volume] \ 2258 -font "Arial 9" 2259 2260 checkbutton $inner.particles \ 2261 -text "Particles" \ 2262 -variable [itcl::scope settings_($this-particles)] \ 2263 -command [itcl::code $this FixSettings particles] \ 2264 -font "Arial 9" 2265 2266 checkbutton $inner.lic \ 2267 -text "Lic" \ 2268 -variable [itcl::scope settings_($this-lic)] \ 2269 -command [itcl::code $this FixSettings lic] \ 2270 -font "Arial 9" 2271 2272 blt::table $inner \ 2273 0,0 $inner.title -anchor w -columnspan 4 \ 2274 1,1 $inner.axes -columnspan 2 -anchor w \ 2275 2,1 $inner.grid -columnspan 2 -anchor w \ 2276 3,1 $inner.outline -columnspan 2 -anchor w \ 2277 4,1 $inner.volume -columnspan 2 -anchor w \ 2278 1,3 $inner.legend -columnspan 2 -anchor w \ 2279 2,3 $inner.particles -columnspan 2 -anchor w \ 2280 3,3 $inner.lic -columnspan 1 -anchor w \ 2281 9,0 $inner.volset -anchor w -columnspan 4 \ 2282 11,1 $inner.dim -anchor e \ 2283 11,2 $inner.light -columnspan 2 \ 2284 11,4 $inner.bright -anchor w \ 2285 12,1 $inner.fog -anchor e \ 2286 12,2 $inner.transp -columnspan 2 \ 2287 12,4 $inner.plastic -anchor w \ 2288 13,1 $inner.clear -anchor e \ 2289 13,2 $inner.opacity -columnspan 2 \ 2290 13,4 $inner.opaque -anchor w \ 2291 14,1 $inner.thin -anchor e \ 2292 14,2 $inner.thickness -columnspan 2 \ 2293 14,4 $inner.thick -anchor w \ 2294 2295 blt::table configure $inner c0 -resize expand -width 4 2296 } 2297 2298 itcl::body Rappture::FlowvisViewer::BuildCutplanesDrawer {} { 2299 itk_component add cutplanes { 2300 Rappture::Scroller $itk_component(drawer).cutplanes \ 2301 -xscrollmode auto -yscrollmode auto \ 2302 -highlightthickness 0 2303 } 2304 2305 # 2306 # Create slicer controls... 2307 # 2308 itk_component add cutplanesCanvas { 2309 canvas $itk_component(cutplanes).canvas -highlightthickness 0 2310 } { 2311 ignore -highlightthickness 2312 } 2313 $itk_component(cutplanes) contents $itk_component(cutplanesCanvas) 2314 2315 itk_component add cutplanesFrame { 2316 frame $itk_component(cutplanesCanvas).frame \ 2317 -highlightthickness 0 2318 } { 2319 ignore -highlightthickness 2320 } 2321 $itk_component(cutplanesCanvas) create window 0 0 \ 2322 -anchor nw -window $itk_component(cutplanesFrame) 2323 bind $itk_component(cutplanesFrame) <Configure> \ 2324 [itcl::code $this drawer resize cutplanes] 2325 2326 set inner $itk_component(cutplanesFrame) 2327 2328 label $inner.title -text "Cutplanes" -font "Arial 10 bold" 2329 2330 # X-value slicer... 2331 itk_component add xCutButton { 2332 label $itk_component(cutplanes).xbutton \ 2333 -borderwidth 1 -relief raised -padx 1 -pady 1 \ 2334 -image [Rappture::icon x-cutplane-off] \ 2335 -highlightthickness 0 2336 } { 2337 usual 2338 ignore -borderwidth -highlightthickness 2339 rename -highlightbackground -controlbackground \ 2340 controlBackground Background 2341 } 2342 bind $itk_component(xCutButton) <ButtonPress> \ 2343 [itcl::code $this Slice axis x toggle] 2344 Rappture::Tooltip::for $itk_component(xCutButton) \ 2345 "Toggle the X cut plane on/off" 2346 2347 itk_component add xCutScale { 2348 ::scale $itk_component(cutplanes).xval -from 100 -to 0 \ 2349 -width 10 -orient vertical -showvalue off \ 2350 -borderwidth 1 -highlightthickness 0 \ 2351 -command [itcl::code $this Slice move x] 2352 } { 2353 usual 2354 ignore -borderwidth 2355 ignore -highlightthickness 2356 rename -highlightbackground -controlbackground \ 2357 controlBackground Background 2358 rename -troughcolor -controldarkbackground \ 2359 controlDarkBackground Background 2360 } 2361 $itk_component(xCutScale) set 50 2362 #$itk_component(xCutScale) configure -state disabled 2363 Rappture::Tooltip::for $itk_component(xCutScale) \ 2364 "@[itcl::code $this SlicerTip x]" 2365 2366 # Y-value slicer... 2367 itk_component add yCutButton { 2368 label $itk_component(cutplanes).ybutton \ 2369 -borderwidth 1 -relief raised -padx 1 -pady 1 \ 2370 -image [Rappture::icon y-cutplane-off] \ 2371 -highlightthickness 0 2372 } { 2373 usual 2374 ignore -borderwidth -highlightthickness 2375 rename -highlightbackground -controlbackground \ 2376 controlBackground Background 2377 } 2378 bind $itk_component(yCutButton) <ButtonPress> \ 2379 [itcl::code $this Slice axis y toggle] 2380 Rappture::Tooltip::for $itk_component(yCutButton) \ 2381 "Toggle the Y cut plane on/off" 2382 2383 itk_component add yCutScale { 2384 ::scale $itk_component(cutplanes).yval -from 100 -to 0 \ 2385 -width 10 -orient vertical -showvalue off \ 2386 -borderwidth 1 -highlightthickness 0 \ 2387 -command [itcl::code $this Slice move y] 2388 } { 2389 usual 2390 ignore -borderwidth 2391 ignore -highlightthickness 2392 rename -highlightbackground -controlbackground controlBackground Background 2393 rename -troughcolor -controldarkbackground controlDarkBackground Background 2394 } 2395 $itk_component(yCutScale) set 50 2396 #$itk_component(yCutScale) configure -state disabled 2397 Rappture::Tooltip::for $itk_component(yCutScale) \ 2398 "@[itcl::code $this SlicerTip y]" 2399 2400 # Z-value slicer... 2401 itk_component add zCutButton { 2402 label $itk_component(cutplanes).zbutton \ 2403 -borderwidth 1 -relief raised -padx 1 -pady 1 \ 2404 -image [Rappture::icon z-cutplane-off] \ 2405 -highlightthickness 0 2406 } { 2407 usual 2408 ignore -borderwidth -highlightthickness 2409 rename -highlightbackground -controlbackground controlBackground Background 2410 } 2411 bind $itk_component(zCutButton) <ButtonPress> \ 2412 [itcl::code $this Slice axis z toggle] 2413 Rappture::Tooltip::for $itk_component(zCutButton) \ 2414 "Toggle the Z cut plane on/off" 2415 2416 itk_component add zCutScale { 2417 ::scale $itk_component(cutplanes).zval -from 100 -to 0 \ 2418 -width 10 -orient vertical -showvalue off \ 2419 -borderwidth 1 -highlightthickness 0 \ 2420 -command [itcl::code $this Slice move z] 2421 } { 2422 usual 2423 ignore -borderwidth 2424 ignore -highlightthickness 2425 rename -highlightbackground -controlbackground controlBackground Background 2426 rename -troughcolor -controldarkbackground controlDarkBackground Background 2427 } 2428 $itk_component(zCutScale) set 50 2429 #$itk_component(zCutScale) configure -state disabled 2430 Rappture::Tooltip::for $itk_component(zCutScale) \ 2431 "@[itcl::code $this SlicerTip z]" 2432 2433 blt::table $inner \ 2434 0,0 $inner.title -anchor w -columnspan 4 \ 2435 3,1 $itk_component(xCutButton) \ 2436 3,2 $itk_component(yCutButton) \ 2437 3,3 $itk_component(zCutButton) \ 2438 2,1 $itk_component(xCutScale) \ 2439 2,2 $itk_component(yCutScale) \ 2440 2,3 $itk_component(zCutScale) \ 2441 2442 blt::table configure $inner c0 -resize expand -width 4 2443 } 2444 2445 itcl::body Rappture::FlowvisViewer::BuildCameraDrawer {} { 2446 2447 itk_component add camera { 2448 Rappture::Scroller $itk_component(drawer).camerascrl \ 2449 -xscrollmode auto -yscrollmode auto \ 2450 -highlightthickness 0 2451 } 2452 2453 itk_component add cameraCanvas { 2454 canvas $itk_component(camera).canvas -highlightthickness 0 2455 } { 2456 ignore -highlightthickness 2457 } 2458 $itk_component(camera) contents $itk_component(cameraCanvas) 2459 2460 itk_component add cameraFrame { 2461 frame $itk_component(cameraCanvas).frame \ 2462 -highlightthickness 0 2463 } 2464 $itk_component(cameraCanvas) create window 0 0 \ 2465 -anchor nw -window $itk_component(cameraFrame) 2466 bind $itk_component(cameraFrame) <Configure> \ 2467 [itcl::code $this drawer resize camera] 2468 2469 set inner $itk_component(cameraFrame) 2470 2471 label $inner.title -text "Camera Settings" -font "Arial 10 bold" 2472 2473 set labels { phi theta psi pan-x pan-y zoom } 2474 blt::table $inner \ 2475 0,0 $inner.title -anchor w -columnspan 4 2476 set row 1 2477 foreach tag $labels { 2478 label $inner.${tag}label -text $tag -font "Arial 9" 2479 entry $inner.${tag} -font "Arial 9" -bg white \ 2480 -textvariable [itcl::scope settings_($this-$tag)] 2481 bind $inner.${tag} <KeyPress-Return> \ 2482 [itcl::code $this camera set ${tag}] 2483 blt::table $inner \ 2484 $row,1 $inner.${tag}label -anchor e \ 2485 $row,2 $inner.${tag} -anchor w 2486 incr row 2487 } 2488 bind $inner.title <Shift-ButtonPress> \ 2489 [itcl::code $this camera show] 2490 blt::table configure $inner c0 -resize expand -width 4 2491 blt::table configure $inner c1 c2 -resize none 2492 blt::table configure $inner c3 -resize expand 2493 2494 } 2495 2496 2497 2498 # camera -- 2499 itcl::body Rappture::FlowvisViewer::camera {option args} { 2500 switch -- $option { 2501 "show" { 2502 puts [array get view_] 2503 } 2504 "set" { 2505 set who [lindex $args 0] 2506 set x $settings_($this-$who) 2507 set code [catch { string is double $x } result] 2508 if { $code != 0 || !$result } { 2509 set settings_($this-$who) $view_($who) 2510 return 2511 } 2512 switch -- $who { 2513 "pan-x" - "pan-y" { 2514 set view_($who) $settings_($this-$who) 2515 PanCamera 2516 } 2517 "phi" - "theta" - "psi" { 2518 set view_($who) $settings_($this-$who) 2519 set xyz [Euler2XYZ $view_(theta) $view_(phi) $view_(psi)] 2520 _send "camera angle $xyz" 2521 } 2522 "zoom" { 2523 set view_($who) $settings_($this-$who) 2524 _send "camera zoom $view_(zoom)" 2525 } 1425 2526 } 1426 2527 } 1427 transp { 1428 if {[isconnected]} { 1429 set val [$inner.scales.transp get] 1430 set sval [expr {0.2*$val+1}] 1431 _send "volume shading opacity $sval" 1432 } 1433 } 1434 opacity { 1435 if {[isconnected] && $activeTf_ != "" } { 1436 set val [$inner.scales.opacity get] 1437 set sval [expr { 0.01 * double($val) }] 1438 set tf $activeTf_ 1439 set settings_($this-$tf-opacity) $sval 1440 UpdateTransferFunctions 1441 } 1442 } 1443 1444 thickness { 1445 if {[isconnected] && $activeTf_ != "" } { 1446 set val [$inner.scales.thickness get] 1447 # Scale values between 0.00001 and 0.01000 1448 set sval [expr {0.0001*double($val)}] 1449 set tf $activeTf_ 1450 set settings_($this-$tf-thickness) $sval 1451 UpdateTransferFunctions 1452 } 1453 } 1454 "outline" { 1455 if {[isconnected]} { 1456 _send "volume outline state $settings_($this-outline)" 1457 } 1458 } 1459 "isosurface" { 1460 if {[isconnected]} { 1461 _send "volume shading isosurface $settings_($this-isosurface)" 1462 } 1463 } 1464 "grid" { 1465 if { [IsConnected] } { 1466 _send "grid visible $settings_($this-grid)" 1467 } 1468 } 1469 "particlevis" { 1470 if { [IsConnected] } { 1471 _send "flow particle visible $settings_($this-particlevis)" 1472 } 1473 } 1474 "lic" { 1475 if { [IsConnected] } { 1476 _send "flow lic $settings_($this-lic)" 1477 } 1478 } 1479 "axes" { 1480 if { [IsConnected] } { 1481 _send "axis visible $settings_($this-axes)" 1482 } 1483 } 1484 default { 1485 error "don't know how to fix $what: should be grid, axes, contourlines, or legend" 1486 } 1487 } 1488 } 1489 1490 # ---------------------------------------------------------------------- 1491 # USAGE: _getTransfuncData <dataobj> <comp> 1492 # 1493 # Used internally to compute the colormap and alpha map used to define 1494 # a transfer function for the specified component in a data object. 1495 # Returns: name {v r g b ...} {v w ...} 1496 # ---------------------------------------------------------------------- 1497 itcl::body Rappture::FlowvisViewer::_getTransfuncData {dataobj comp} { 1498 array set style { 1499 -color rainbow 1500 -levels 6 1501 -opacity 0.5 1502 } 1503 array set style [lindex [$dataobj components -style $comp] 0] 1504 set sname "$style(-color):$style(-levels):$style(-opacity)" 1505 1506 if {$style(-color) == "rainbow"} { 1507 set style(-color) "white:yellow:green:cyan:blue:magenta" 1508 } 1509 set clist [split $style(-color) :] 1510 set color white 1511 set cmap "0.0 [Color2RGB $color] " 1512 set range [expr $limits_(vmax) - $limits_(vmin)] 1513 for {set i 0} {$i < [llength $clist]} {incr i} { 1514 set xval [expr {double($i+1)/([llength $clist]+1)}] 1515 set color [lindex $clist $i] 1516 append cmap "$xval [Color2RGB $color] " 1517 } 1518 append cmap "1.0 [Color2RGB $color] " 1519 1520 set opacity $style(-opacity) 1521 set levels $style(-levels) 1522 set wmap {} 1523 if {[string is int $levels]} { 1524 lappend wmap 0.0 0.0 1525 set delta [expr {0.125/($levels+1)}] 1526 for {set i 1} {$i <= $levels} {incr i} { 1527 # add spikes in the middle 1528 set xval [expr {double($i)/($levels+1)}] 1529 lappend wmap [expr {$xval-$delta-0.01}] 0.0 1530 lappend wmap [expr {$xval-$delta}] $opacity 1531 lappend wmap [expr {$xval+$delta}] $opacity 1532 lappend wmap [expr {$xval+$delta+0.01}] 0.0 1533 } 1534 lappend wmap 1.0 0.0 1535 } else { 1536 lappend wmap 0.0 0.0 1537 set delta 0.05 1538 foreach xval [split $levels ,] { 1539 lappend wmap [expr {$xval-$delta}] 0.0 1540 lappend $xval $opacity 1541 lappend [expr {$xval+$delta}] 0.0 1542 } 1543 lappend wmap 1.0 0.0 1544 } 1545 return [list $sname $cmap $wmap] 1546 } 1547 1548 # ---------------------------------------------------------------------- 1549 # CONFIGURATION OPTION: -plotbackground 1550 # ---------------------------------------------------------------------- 1551 itcl::configbody Rappture::FlowvisViewer::plotbackground { 1552 foreach {r g b} [Color2RGB $itk_option(-plotbackground)] break 1553 #fix this! 1554 #_send "color background $r $g $b" 1555 } 1556 1557 # ---------------------------------------------------------------------- 1558 # CONFIGURATION OPTION: -plotforeground 1559 # ---------------------------------------------------------------------- 1560 itcl::configbody Rappture::FlowvisViewer::plotforeground { 1561 foreach {r g b} [Color2RGB $itk_option(-plotforeground)] break 1562 #fix this! 1563 #_send "color background $r $g $b" 1564 } 1565 1566 # ---------------------------------------------------------------------- 1567 # CONFIGURATION OPTION: -plotoutline 1568 # ---------------------------------------------------------------------- 1569 itcl::configbody Rappture::FlowvisViewer::plotoutline { 1570 if {[IsConnected]} { 1571 _send "grid linecolor [Color2RGB $itk_option(-plotoutline)]" 1572 } 1573 } 2528 } 2529 } -
trunk/gui/scripts/heightmapviewer.tcl
r1343 r1349 69 69 protected method _send {string} 70 70 protected method _send_dataobjs {} 71 protected method ReceiveImage { option size}71 protected method ReceiveImage { args } 72 72 private method _ReceiveLegend {tf vmin vmax size} 73 73 private method _BuildSettingsDrawer {} … … 100 100 private common settings_ ;# Array used for checkbuttons and radiobuttons 101 101 private variable initialized_ 102 private common hardcopy_ 102 103 } 103 104 … … 360 361 # flag can also request the internal images being shown. 361 362 # ---------------------------------------------------------------------- 362 itcl::body Rappture::HeightmapViewer::get { args} {363 itcl::body Rappture::HeightmapViewer::get { args } { 363 364 if {[llength $args] == 0} { 364 365 set args "-objects" … … 410 411 # are specified, then all dataobjs are deleted. 411 412 # ---------------------------------------------------------------------- 412 itcl::body Rappture::HeightmapViewer::delete { args} {413 itcl::body Rappture::HeightmapViewer::delete { args } { 413 414 if {[llength $args] == 0} { 414 415 set args $dlist_ … … 443 444 # the user scans through data in the ResultSet viewer. 444 445 # ---------------------------------------------------------------------- 445 itcl::body Rappture::HeightmapViewer::scale { args} {446 itcl::body Rappture::HeightmapViewer::scale { args } { 446 447 foreach val {xmin xmax ymin ymax zmin zmax vmin vmax} { 447 448 set limits_($val) "" … … 649 650 # specified <size> will follow. 650 651 # ---------------------------------------------------------------------- 651 itcl::body Rappture::HeightmapViewer::ReceiveImage {option size} { 652 if {[IsConnected]} { 653 set bytes [ReceiveBytes $size] 652 itcl::body Rappture::HeightmapViewer::ReceiveImage { args } { 653 if {![IsConnected]} { 654 return 655 } 656 array set info { 657 -type image 658 } 659 array set info $args 660 set bytes [ReceiveBytes $info(-bytes)] 661 ReceiveEcho <<line "<read $info(-bytes) bytes" 662 if { $info(-type) == "image" } { 654 663 $_image(plot) configure -data $bytes 655 ReceiveEcho <<line "<read $size bytes for [image width $_image(plot)]x[image height $_image(plot)] image>" 664 ReceiveEcho <<line "<read for [image width $_image(plot)]x[image height $_image(plot)] image>" 665 } elseif { $info(type) == "print" } { 666 set tag $this-print-$info(-token) 667 set hardcopy_($tag) $bytes 656 668 } 657 669 } -
trunk/gui/scripts/molvisviewer.tcl
r1346 r1349 1647 1647 # 3) user cancels the operation. 1648 1648 tkwait variable $var 1649 1650 # Clean up. 1649 1651 $_dispatcher cancel !pngtimeout 1650 1652 WaitIcon stop $inner.icon … … 1653 1655 destroy $popup 1654 1656 update 1657 1655 1658 if { $hardcopy_($this-$token) != "" } { 1656 1659 return [list .png $hardcopy_($this-$token)] -
trunk/gui/scripts/nanovisviewer.tcl
r1343 r1349 73 73 protected method _SendTransferFunctions {} 74 74 75 protected method _ReceiveImage { option size}75 protected method _ReceiveImage { args } 76 76 protected method _ReceiveLegend { ivol vmin vmax size } 77 77 protected method _ReceiveData { args } 78 protected method _ReceivePrint { option size }79 78 80 79 protected method _rebuild {} … … 124 123 # opacity, or thickness. 125 124 #common _downloadPopup ;# download options from popup 125 private common _hardcopy 126 126 } 127 127 … … 239 239 label $itk_component(slicers).xslice \ 240 240 -borderwidth 1 -relief raised -padx 1 -pady 1 \ 241 -image [Rappture::icon x-cutplane ]241 -image [Rappture::icon x-cutplane-off] 242 242 } { 243 243 usual … … 275 275 label $itk_component(slicers).yslice \ 276 276 -borderwidth 1 -relief raised -padx 1 -pady 1 \ 277 -image [Rappture::icon y-cutplane ]277 -image [Rappture::icon y-cutplane-off] 278 278 } { 279 279 usual … … 311 311 label $itk_component(slicers).zslice \ 312 312 -borderwidth 1 -relief raised -padx 1 -pady 1 \ 313 -image [Rappture::icon z-cutplane ]313 -image [Rappture::icon z-cutplane-off] 314 314 } { 315 315 usual … … 895 895 896 896 # ---------------------------------------------------------------------- 897 # USAGE: _ReceiveImage -bytes <size> 897 # USAGE: _ReceiveImage -bytes <size> -type <type> -token <token> 898 898 # 899 899 # Invoked automatically whenever the "image" command comes in from … … 902 902 # ---------------------------------------------------------------------- 903 903 set counter 0 904 itcl::body Rappture::NanovisViewer::_ReceiveImage {option size} { 905 if { [isconnected] } { 906 global counter 907 incr counter 908 set bytes [ReceiveBytes $size] 904 itcl::body Rappture::NanovisViewer::_ReceiveImage { args } { 905 if { ![isconnected] } { 906 return 907 } 908 global counter 909 incr counter 910 array set info { 911 -token "???" 912 -bytes 0 913 -type image 914 } 915 array set info $args 916 set bytes [ReceiveBytes $info(-bytes)] 917 ReceiveEcho <<line "<read $info(-bytes) bytes for [image width $_image(plot)]x[image height $_image(plot)] image>" 918 if { $info(-type) == "image" } { 909 919 $_image(plot) configure -data $bytes 910 ReceiveEcho <<line "<read $size bytes for [image width $_image(plot)]x[image height $_image(plot)] image>" 920 } elseif { $info(type) == "print" } { 921 set tag $this-print-$info(-token) 922 set _hardcopy($tag) $bytes 911 923 } 912 924 } … … 1009 1021 1010 1022 # ---------------------------------------------------------------------- 1011 # USAGE: _ReceivePrint -bytes <size>1012 #1013 # Invoked automatically whenever the "image" command comes in from1014 # the rendering server. Indicates that binary image data with the1015 # specified <size> will follow.1016 # ----------------------------------------------------------------------1017 itcl::body Rappture::NanovisViewer::_ReceivePrint {option size} {1018 if { [isconnected] } {1019 set bytes [ReceiveBytes $size]1020 set f [open /tmp/junk "w"]1021 puts $f $bytes1022 close $f1023 $_image(download) configure -data $bytes1024 update1025 puts stderr "<read $size bytes for [image width $_image(download)]x[image height $_image(download)] image>"1026 }1027 }1028 1029 # ----------------------------------------------------------------------1030 1023 # USAGE: _rebuild 1031 1024 # … … 1326 1319 } 1327 1320 if {$op} { 1321 $itk_component(${axis}slice) configure \ 1322 -image [Rappture::icon ${axis}-cutplane-on] \ 1323 -relief sunken 1328 1324 $itk_component(${axis}slicer) configure -state normal 1329 1325 _send "cutplane state 1 $axis [_currentVolumeIds -cutplanes]" 1330 $itk_component(${axis}slice) configure -relief sunken1331 1326 } else { 1327 $itk_component(${axis}slice) configure \ 1328 -image [Rappture::icon ${axis}-cutplane-off] \ 1329 -relief raised 1332 1330 $itk_component(${axis}slicer) configure -state disabled 1333 1331 _send "cutplane state 0 $axis [_currentVolumeIds -cutplanes]" 1334 $itk_component(${axis}slice) configure -relief raised1335 1332 } 1336 1333 }
Note: See TracChangeset
for help on using the changeset viewer.