source: branches/1.3/gui/scripts/transferfunctioneditor.tcl @ 4706

Last change on this file since 4706 was 4504, checked in by gah, 10 years ago

merge transferfunctioneditor into nanovis, fix cloud with units

File size: 11.2 KB
Line 
1# -*- mode: tcl; indent-tabs-mode: nil -*-
2
3# ----------------------------------------------------------------------
4#  COMPONENT: transferfunctioneditor - Rudimentary editor for 3D volume
5#                                      transfer functions
6#
7#  This class is used to modify transfer functions used in volume rendering
8#  on 3D scalar/vector datasets.
9#
10# ======================================================================
11#  AUTHOR:  Michael McLennan, Purdue University
12#  Copyright (c) 2004-2012  HUBzero Foundation, LLC
13#
14#  See the file "license.terms" for information on usage and
15#  redistribution of this file, and for a DISCLAIMER OF ALL WARRANTIES.
16# ======================================================================
17package require Itk
18package require BLT
19package require Img
20
21itcl::class Rappture::TransferFunctionEditor {
22    private variable _nextId 0;         # Used to create unique marker names
23    private variable _values;           # Relative values for each marker.
24    private variable _limits;           # Over limits of transfer function.
25    private variable _labels;           # Label id for each marker.
26    private variable _ticks;            # Tick id for each marker.
27    private variable _canvas    ""
28    private variable _name "";          # Name of transfer function.
29    private variable _activeMotion   0
30    private variable _activePress    0
31    private variable _id2name
32    private common   _normalIcon [Rappture::icon nvlegendmark]
33    private common   _activeIcon [Rappture::icon nvlegendmark2]
34    public variable command ""
35
36    private method SetAbsoluteValue { name x }
37    private method GetAbsoluteValue { name }
38    private method ContinueDrag { name x y }
39    private method EnterTick { name }
40    private method GetOverlappingMarkers { x y }
41    private method GetScreenPosition { name }
42    private method LeaveTick { name }
43    private method SetRelativeValue  { name x }
44    private method GetRelativeValue  { name }
45    private method RemoveDuplicateMarkers {name x y}
46    private method SetScreenPosition { name }
47    private method SetVisibility { name bool }
48    private method StartDrag { name x y }
49    private method StopDrag { name x y }
50    private method Activate { name }
51    private method Deactivate { name }
52    private method UpdateViewer {}
53
54    constructor {c name args} {}
55    destructor {}
56    public method limits { min max }
57    public method names {}
58    public method name {}
59    public method values {}
60    public method absoluteValues {}
61    public method removeMarkers { list }
62    public method addMarkers { values }
63    public method newMarker { x y state }
64    public method deleteMarker { x y }
65    public method hideMarkers { {list {}} }
66    public method showMarkers { {limits {}} }
67}
68
69itcl::body Rappture::TransferFunctionEditor::constructor {c name args} {
70    set _canvas $c
71    set _name $name
72    set _limits [list 0.0 1.0]
73    eval configure $args
74}
75
76itcl::body Rappture::TransferFunctionEditor::limits { min max } {
77    set _limits [list $min $max]
78}
79
80itcl::body Rappture::TransferFunctionEditor::names {} {
81    return [lsort [array names _values]]
82}
83
84itcl::body Rappture::TransferFunctionEditor::values {} {
85    set list {}
86    foreach name [array names _ticks] {
87        lappend list [GetRelativeValue $name]
88    }
89    return [lsort -real $list]
90}
91
92itcl::body Rappture::TransferFunctionEditor::absoluteValues {} {
93    set list {}
94    foreach name [array names _values] {
95        lappend list [GetAbsoluteValue $name]
96    }
97    return $list
98}
99
100itcl::body Rappture::TransferFunctionEditor::deleteMarker { x y } {
101    foreach marker [GetOverlappingMarkers $x $y] {
102        $_canvas delete $_ticks($marker)
103        $_canvas delete $_labels($marker)
104        array unset _ticks $marker
105        array unset _labels $marker
106        array unset _values $marker
107        bell
108        UpdateViewer
109    }
110}
111
112itcl::body Rappture::TransferFunctionEditor::newMarker { x y state } {
113    foreach id [$_canvas find overlapping \
114                    [expr $x-5] [expr $y-5] [expr $x+5] [expr $y+5]] {
115        if { [info exists _id2name($id)] } {
116            puts stderr "Too close to existing marker"
117            return;                     # Too close to existing marker
118        }
119    }
120    set name "tick[incr _nextId]"
121    set w [winfo width $_canvas]
122    set h [winfo height $_canvas]
123
124    set _ticks($name) [$_canvas create image 0 $h \
125                           -image $_normalIcon -anchor s \
126                           -tags "tick $_name $this" -state $state]
127    set _labels($name) [$_canvas create text 0 $h \
128                            -anchor n -fill white -font "Helvetica 8" \
129                            -tags "labels $this $_name" -state $state]
130    set _id2name($_ticks($name)) $name
131    $_canvas bind $_ticks($name) <Enter> [itcl::code $this EnterTick $name]
132    $_canvas bind $_ticks($name) <Leave> [itcl::code $this LeaveTick $name]
133    $_canvas bind $_ticks($name) <ButtonPress-1> \
134        [itcl::code $this StartDrag $name %x %y]
135    $_canvas bind $_ticks($name) <B1-Motion> \
136        [itcl::code $this ContinueDrag $name %x %y]
137    $_canvas bind $_ticks($name) <ButtonRelease-1> \
138        [itcl::code $this StopDrag $name %x %y]
139
140    SetRelativeValue $name [expr {double($x-10)/($w-20)}]
141    if { $state == "normal" } {
142        UpdateViewer
143    }
144    return $name
145}
146
147itcl::body Rappture::TransferFunctionEditor::destructor {} {
148    $_canvas delete $_name
149}
150
151itcl::body Rappture::TransferFunctionEditor::name {} {
152    return $_name
153}
154
155itcl::body Rappture::TransferFunctionEditor::Activate { name } {
156    if  { $_activePress || $_activeMotion } {
157        $_canvas itemconfigure $_labels($name) -state normal
158        $_canvas itemconfigure $_ticks($name) -image $_activeIcon
159        $_canvas itemconfigure title -state hidden
160    }
161}
162
163itcl::body Rappture::TransferFunctionEditor::Deactivate { name } {
164    if  { $_activePress || $_activeMotion } {
165        #puts stderr "do nothing for Deactivate"
166    } else {
167        $_canvas itemconfigure $_labels($name) -state hidden
168        $_canvas itemconfigure $_ticks($name) -image $_normalIcon
169        $_canvas itemconfigure title -state normal
170    }
171}
172
173itcl::body Rappture::TransferFunctionEditor::SetVisibility { name bool } {
174    if { $bool } {
175        $_canvas itemconfigure $_ticks($name) -state normal
176        $_canvas raise $_ticks($name)
177    } else {
178        $_canvas itemconfigure $_ticks($name) -state hidden
179    }
180}
181
182itcl::body Rappture::TransferFunctionEditor::GetScreenPosition { name } {
183    set x [GetRelativeValue $name]
184    if { $x < 0.0 } {
185        set x 0.0
186    } elseif { $x > 1.0 } {
187        set x 1.0
188    }
189    set low 10
190    set w [winfo width $_canvas]
191    set high [expr {$w  - 10}]
192    set x [expr {round($x*($high - $low) + $low)}]
193    return $x
194}
195
196itcl::body Rappture::TransferFunctionEditor::SetScreenPosition { name } {
197    set value $_values($name)
198    set x [GetScreenPosition $name]
199    set absval [GetAbsoluteValue $name]
200    set y 31
201    $_canvas itemconfigure $_labels($name) -text [format %g $absval]
202    $_canvas coords $_ticks($name) $x [expr {$y+3}]
203    $_canvas coords $_labels($name) $x [expr {$y+5}]
204}
205
206itcl::body Rappture::TransferFunctionEditor::GetAbsoluteValue { name } {
207    foreach {min max} $_limits break
208    return [expr {($_values($name) * ($max - $min)) + $min}]
209}
210
211itcl::body Rappture::TransferFunctionEditor::SetAbsoluteValue { name value } {
212    foreach {min max} $_limits break
213    set absval $value
214    set relval [expr {($absval - $min) / ($max - $min)}]
215    set _values($name) $relval
216    set y 31
217    $_canvas itemconfigure $_label -text [format %g $absval]
218    set x [GetScreenPosition $name]
219    $_canvas coords $_ticks($name) $x [expr {$y+3}]
220    $_canvas coords $_labels($name) $x [expr {$y+5}]
221    return $absval
222}
223
224itcl::body Rappture::TransferFunctionEditor::GetRelativeValue  { name } {
225    return $_values($name)
226}
227
228itcl::body Rappture::TransferFunctionEditor::SetRelativeValue  { name value } {
229    set _values($name) $value
230    set x [GetScreenPosition $name]
231    set y 31
232    set absval [GetAbsoluteValue $name]
233    $_canvas itemconfigure $_labels($name) -text [format %g $absval]
234    $_canvas coords $_ticks($name) $x [expr {$y+3}]
235    $_canvas coords $_labels($name) $x [expr {$y+5}]
236}
237
238itcl::body Rappture::TransferFunctionEditor::EnterTick { name } {
239    set _activeMotion 1
240    Activate $name
241    $_canvas raise $_ticks($name)
242}
243
244itcl::body Rappture::TransferFunctionEditor::LeaveTick { name } {
245    set _activeMotion 0
246    Deactivate $name
247}
248
249itcl::body Rappture::TransferFunctionEditor::StartDrag { name x y } {
250    $_canvas raise $_ticks($name)
251    set _activePress 1
252    Activate $name
253    $_canvas itemconfigure limits -state hidden
254    $_canvas itemconfigure title -state hidden
255}
256
257itcl::body Rappture::TransferFunctionEditor::StopDrag { name x y } {
258    ContinueDrag $name $x $y
259    RemoveDuplicateMarkers $name $x $y
260    set _activePress 0
261    Deactivate $name
262    $_canvas itemconfigure limits -state normal
263    $_canvas itemconfigure title -state normal
264}
265
266itcl::body Rappture::TransferFunctionEditor::ContinueDrag { name x y } {
267    set w [winfo width $_canvas]
268    SetRelativeValue $name [expr {double($x-10)/($w-20)}]
269    UpdateViewer
270    $_canvas raise $_ticks($name)
271    set _activePress 1
272    Activate $name
273    $_canvas itemconfigure limits -state hidden
274    $_canvas itemconfigure title -state hidden
275}
276
277itcl::body Rappture::TransferFunctionEditor::GetOverlappingMarkers { x y } {
278    set list {}
279    foreach id [$_canvas find overlapping $x $y $x $y] {
280        if { [info exists _id2name($id)] } {
281            lappend list $_id2name($id)
282        }
283    }
284    return $list
285}
286
287itcl::body Rappture::TransferFunctionEditor::hideMarkers { {list {}} } {
288    if { $list == "" } {
289        set list [array names _values]
290    }
291    foreach name $list {
292        SetVisibility $name 0
293    }
294}
295
296itcl::body Rappture::TransferFunctionEditor::showMarkers { {limits {}} } {
297    if { $limits != "" } {
298        set _limits $limits
299        foreach name [array names _values] {
300            SetScreenPosition $name
301        }
302    }
303    foreach name [array names _values] {
304        SetVisibility $name 1
305    }
306}
307
308itcl::body Rappture::TransferFunctionEditor::RemoveDuplicateMarkers {name x y} {
309    foreach marker [GetOverlappingMarkers $x $y] {
310        if { $marker != $name } {
311            Activate $marker
312            set markerx [GetScreenPosition $marker]
313            if { ($x < ($markerx-3)) || ($x > ($markerx+3)) } {
314                continue
315            }
316            $_canvas delete $_ticks($marker)
317            $_canvas delete $_labels($marker)
318            array unset _ticks $marker
319            array unset _labels $marker
320            array unset _values $marker
321            bell
322        }
323    }
324}
325
326itcl::body Rappture::TransferFunctionEditor::addMarkers { values } {
327    foreach value $values {
328        set name [newMarker 0 0 hidden]
329        SetRelativeValue $name $value
330    }
331}
332
333itcl::body Rappture::TransferFunctionEditor::removeMarkers { names } {
334    if { $names == "" } {
335        set names [array names _values]
336    }
337    foreach name $names {
338        $_canvas delete $_ticks($name)
339        $_canvas delete $_labels($name)
340        array unset _ticks $name
341        array unset _labels $name
342        array unset _values $name
343    }
344    UpdateViewer
345}
346
347itcl::body Rappture::TransferFunctionEditor::UpdateViewer {} {
348    # Tell the nanovis/flowvis client to update its transfer functions
349    # now that a marker position has changed.
350    if { $command != "" } {
351        eval uplevel \#0 $command
352    }
353}
Note: See TracBrowser for help on using the repository browser.