source: branches/uq/gui/scripts/transferfunctioneditor.tcl @ 5679

Last change on this file since 5679 was 5679, checked in by ldelgass, 9 years ago

Full merge 1.3 branch to uq branch to sync. Fixed partial subdirectory merge
by removing mergeinfo from lang/python/Rappture directory.

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