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

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

merging some fixes from the trunk

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    if { [winfo exists $_canvas] } {
149        $_canvas delete $_name
150    }
151}
152
153itcl::body Rappture::TransferFunctionEditor::name {} {
154    return $_name
155}
156
157itcl::body Rappture::TransferFunctionEditor::Activate { name } {
158    if  { $_activePress || $_activeMotion } {
159        $_canvas itemconfigure $_labels($name) -state normal
160        $_canvas itemconfigure $_ticks($name) -image $_activeIcon
161        $_canvas itemconfigure title -state hidden
162    }
163}
164
165itcl::body Rappture::TransferFunctionEditor::Deactivate { name } {
166    if  { $_activePress || $_activeMotion } {
167        #puts stderr "do nothing for Deactivate"
168    } else {
169        $_canvas itemconfigure $_labels($name) -state hidden
170        $_canvas itemconfigure $_ticks($name) -image $_normalIcon
171        $_canvas itemconfigure title -state normal
172    }
173}
174
175itcl::body Rappture::TransferFunctionEditor::SetVisibility { name bool } {
176    if { $bool } {
177        $_canvas itemconfigure $_ticks($name) -state normal
178        $_canvas raise $_ticks($name)
179    } else {
180        $_canvas itemconfigure $_ticks($name) -state hidden
181    }
182}
183
184itcl::body Rappture::TransferFunctionEditor::GetScreenPosition { name } {
185    set x [GetRelativeValue $name]
186    if { $x < 0.0 } {
187        set x 0.0
188    } elseif { $x > 1.0 } {
189        set x 1.0
190    }
191    set low 10
192    set w [winfo width $_canvas]
193    set high [expr {$w  - 10}]
194    set x [expr {round($x*($high - $low) + $low)}]
195    return $x
196}
197
198itcl::body Rappture::TransferFunctionEditor::SetScreenPosition { name } {
199    set value $_values($name)
200    set x [GetScreenPosition $name]
201    set absval [GetAbsoluteValue $name]
202    set y 31
203    $_canvas itemconfigure $_labels($name) -text [format %g $absval]
204    $_canvas coords $_ticks($name) $x [expr {$y+3}]
205    $_canvas coords $_labels($name) $x [expr {$y+5}]
206}
207
208itcl::body Rappture::TransferFunctionEditor::GetAbsoluteValue { name } {
209    foreach {min max} $_limits break
210    return [expr {($_values($name) * ($max - $min)) + $min}]
211}
212
213itcl::body Rappture::TransferFunctionEditor::SetAbsoluteValue { name value } {
214    foreach {min max} $_limits break
215    set absval $value
216    set relval [expr {($absval - $min) / ($max - $min)}]
217    set _values($name) $relval
218    set y 31
219    $_canvas itemconfigure $_label -text [format %g $absval]
220    set x [GetScreenPosition $name]
221    $_canvas coords $_ticks($name) $x [expr {$y+3}]
222    $_canvas coords $_labels($name) $x [expr {$y+5}]
223    return $absval
224}
225
226itcl::body Rappture::TransferFunctionEditor::GetRelativeValue  { name } {
227    return $_values($name)
228}
229
230itcl::body Rappture::TransferFunctionEditor::SetRelativeValue  { name value } {
231    set _values($name) $value
232    set x [GetScreenPosition $name]
233    set y 31
234    set absval [GetAbsoluteValue $name]
235    $_canvas itemconfigure $_labels($name) -text [format %g $absval]
236    $_canvas coords $_ticks($name) $x [expr {$y+3}]
237    $_canvas coords $_labels($name) $x [expr {$y+5}]
238}
239
240itcl::body Rappture::TransferFunctionEditor::EnterTick { name } {
241    set _activeMotion 1
242    Activate $name
243    $_canvas raise $_ticks($name)
244}
245
246itcl::body Rappture::TransferFunctionEditor::LeaveTick { name } {
247    set _activeMotion 0
248    Deactivate $name
249}
250
251itcl::body Rappture::TransferFunctionEditor::StartDrag { name x y } {
252    $_canvas raise $_ticks($name)
253    set _activePress 1
254    Activate $name
255    $_canvas itemconfigure limits -state hidden
256    $_canvas itemconfigure title -state hidden
257}
258
259itcl::body Rappture::TransferFunctionEditor::StopDrag { name x y } {
260    ContinueDrag $name $x $y
261    RemoveDuplicateMarkers $name $x $y
262    set _activePress 0
263    Deactivate $name
264    $_canvas itemconfigure limits -state normal
265    $_canvas itemconfigure title -state normal
266}
267
268itcl::body Rappture::TransferFunctionEditor::ContinueDrag { name x y } {
269    set w [winfo width $_canvas]
270    SetRelativeValue $name [expr {double($x-10)/($w-20)}]
271    UpdateViewer
272    $_canvas raise $_ticks($name)
273    set _activePress 1
274    Activate $name
275    $_canvas itemconfigure limits -state hidden
276    $_canvas itemconfigure title -state hidden
277}
278
279itcl::body Rappture::TransferFunctionEditor::GetOverlappingMarkers { x y } {
280    set list {}
281    foreach id [$_canvas find overlapping $x $y $x $y] {
282        if { [info exists _id2name($id)] } {
283            lappend list $_id2name($id)
284        }
285    }
286    return $list
287}
288
289itcl::body Rappture::TransferFunctionEditor::hideMarkers { {list {}} } {
290    if { $list == "" } {
291        set list [array names _values]
292    }
293    foreach name $list {
294        SetVisibility $name 0
295    }
296}
297
298itcl::body Rappture::TransferFunctionEditor::showMarkers { {limits {}} } {
299    if { $limits != "" } {
300        set _limits $limits
301        foreach name [array names _values] {
302            SetScreenPosition $name
303        }
304    }
305    foreach name [array names _values] {
306        SetVisibility $name 1
307    }
308}
309
310itcl::body Rappture::TransferFunctionEditor::RemoveDuplicateMarkers {name x y} {
311    foreach marker [GetOverlappingMarkers $x $y] {
312        if { $marker != $name } {
313            Activate $marker
314            set markerx [GetScreenPosition $marker]
315            if { ($x < ($markerx-3)) || ($x > ($markerx+3)) } {
316                continue
317            }
318            $_canvas delete $_ticks($marker)
319            $_canvas delete $_labels($marker)
320            array unset _ticks $marker
321            array unset _labels $marker
322            array unset _values $marker
323            bell
324        }
325    }
326}
327
328itcl::body Rappture::TransferFunctionEditor::addMarkers { values } {
329    foreach value $values {
330        set name [newMarker 0 0 hidden]
331        SetRelativeValue $name $value
332    }
333}
334
335itcl::body Rappture::TransferFunctionEditor::removeMarkers { names } {
336    if { $names == "" } {
337        set names [array names _values]
338    }
339    foreach name $names {
340        $_canvas delete $_ticks($name)
341        $_canvas delete $_labels($name)
342        array unset _ticks $name
343        array unset _labels $name
344        array unset _values $name
345    }
346    UpdateViewer
347}
348
349itcl::body Rappture::TransferFunctionEditor::UpdateViewer {} {
350    # Tell the nanovis/flowvis client to update its transfer functions
351    # now that a marker position has changed.
352    if { $command != "" } {
353        eval uplevel \#0 $command
354    }
355}
Note: See TracBrowser for help on using the repository browser.