source: trunk/gui/scripts/cloud.tcl @ 17

Last change on this file since 17 was 17, checked in by mmc, 18 years ago

Added a capability to MainWin? to syncCutBuffer with the
application. The VNC Java client uses the cutbuffer
instead of the selection for Copy/Paste? to desktop, and
this mechanism keeps the two in sync so Copy/Paste? works
properly. Also, added Cut/Copy/Paste? menus to the right
mouse button of various widgets.

Fixed 3D plotting to work with the vtkCutter so it works
better. Also, added support for 3D meshes in addition
to clouds. Meshes store connectivity, so they are better
at representing holes in data. Fixed the 3D plotter so
that rotate is more intuitive, and added lights so you can
see your data better at any angle.

Fixed the loader so that it can load elements with the ""
value, and so that it doesn't duplicate entries found
more than once by *.xml pattern matching.

File size: 7.4 KB
Line 
1# ----------------------------------------------------------------------
2#  COMPONENT: cloud - represents the mesh for a cloud of points
3#
4#  This object represents the mesh for a cloud of points in an XML
5#  description of a device.  It simplifies the process of extracting
6#  data that represent the mesh.
7# ======================================================================
8#  AUTHOR:  Michael McLennan, Purdue University
9#  Copyright (c) 2004-2005
10#  Purdue Research Foundation, West Lafayette, IN
11# ======================================================================
12package require Itcl
13package require vtk
14
15namespace eval Rappture { # forward declaration }
16
17itcl::class Rappture::Cloud {
18    constructor {xmlobj path} { # defined below }
19    destructor { # defined below }
20
21    public method points {}
22    public method mesh {}
23    public method size {}
24    public method dimensions {}
25    public method limits {which}
26    public method hints {{key ""}}
27
28    public proc fetch {xmlobj path}
29    public proc release {obj}
30
31    private variable _xmlobj ""  ;# ref to XML obj with device data
32    private variable _cloud ""   ;# lib obj representing this cloud
33
34    private variable _units "m"  ;# system of units for this cloud
35    private variable _limits     ;# limits xmin, xmax, ymin, ymax, ...
36
37    private common _xp2obj       ;# used for fetch/release ref counting
38    private common _obj2ref      ;# used for fetch/release ref counting
39}
40
41# ----------------------------------------------------------------------
42# USAGE: Rappture::Cloud::fetch <xmlobj> <path>
43#
44# Clients use this instead of a constructor to fetch the Cloud for
45# a particular <path> in the <xmlobj>.  When the client is done with
46# the cloud, he calls "release" to decrement the reference count.
47# When the cloud is no longer needed, it is cleaned up automatically.
48# ----------------------------------------------------------------------
49itcl::body Rappture::Cloud::fetch {xmlobj path} {
50    set handle "$xmlobj|$path"
51    if {[info exists _xp2obj($handle)]} {
52        set obj $_xp2obj($handle)
53        incr _obj2ref($obj)
54        return $obj
55    }
56
57    set obj [Rappture::Cloud ::#auto $xmlobj $path]
58    set _xp2obj($handle) $obj
59    set _obj2ref($obj) 1
60    return $obj
61}
62
63# ----------------------------------------------------------------------
64# USAGE: Rappture::Cloud::release <obj>
65#
66# Clients call this when they're no longer using a Cloud fetched
67# previously by the "fetch" proc.  This decrements the reference
68# count for the cloud and destroys the object when it is no longer
69# in use.
70# ----------------------------------------------------------------------
71itcl::body Rappture::Cloud::release {obj} {
72    if {[info exists _obj2ref($obj)]} {
73        incr _obj2ref($obj) -1
74        if {$_obj2ref($obj) <= 0} {
75            unset _obj2ref($obj)
76            foreach handle [array names _xp2obj] {
77                if {$_xp2obj($handle) == $obj} {
78                    unset _xp2obj($handle)
79                }
80            }
81            itcl::delete object $obj
82        }
83    } else {
84        error "can't find reference count for $obj"
85    }
86}
87
88# ----------------------------------------------------------------------
89# CONSTRUCTOR
90# ----------------------------------------------------------------------
91itcl::body Rappture::Cloud::constructor {xmlobj path} {
92    if {![Rappture::library isvalid $xmlobj]} {
93        error "bad value \"$xmlobj\": should be Rappture::library"
94    }
95    set _xmlobj $xmlobj
96    set _cloud [$xmlobj element -as object $path]
97
98    set u [$_cloud get units]
99    if {"" != $u} {
100        set _units $u
101    }
102
103    # create the vtk object containing points
104    vtkPoints $this-points
105
106    foreach lim {xmin xmax ymin ymax zmin zmax} {
107        set _limits($lim) ""
108    }
109
110    foreach line [split [$xmlobj get $path.points] \n] {
111        if {"" == [string trim $line]} {
112            continue
113        }
114
115        # make sure we have x,y,z
116        while {[llength $line] < 3} {
117            lappend line "0"
118        }
119
120        # extract each point and add it to the points list
121        foreach {x y z} $line break
122        foreach dim {x y z} {
123            set v [Rappture::Units::convert [set $dim] \
124                -context $_units -to $_units -units off]
125
126            set $dim $v  ;# save back to real x/y/z variable
127
128            if {"" == $_limits(${dim}min)} {
129                set _limits(${dim}min) $v
130                set _limits(${dim}max) $v
131            } else {
132                if {$v < $_limits(${dim}min)} { set _limits(${dim}min) $v }
133                if {$v > $_limits(${dim}max)} { set _limits(${dim}max) $v }
134            }
135        }
136        $this-points InsertNextPoint $x $y $z
137    }
138}
139
140# ----------------------------------------------------------------------
141# DESTRUCTOR
142# ----------------------------------------------------------------------
143itcl::body Rappture::Cloud::destructor {} {
144    # don't destroy the _xmlobj! we don't own it!
145    itcl::delete object $_cloud
146    rename $this-points ""
147}
148
149# ----------------------------------------------------------------------
150# USAGE: points
151#
152# Returns the vtk object containing the points for this mesh.
153# ----------------------------------------------------------------------
154itcl::body Rappture::Cloud::points {} {
155    return $this-points
156}
157
158# ----------------------------------------------------------------------
159# USAGE: mesh
160#
161# Returns the vtk object representing the mesh.
162# ----------------------------------------------------------------------
163itcl::body Rappture::Cloud::mesh {} {
164    return $this-points
165}
166
167# ----------------------------------------------------------------------
168# USAGE: size
169#
170# Returns the number of points in this cloud.
171# ----------------------------------------------------------------------
172itcl::body Rappture::Cloud::size {} {
173    return [$this-points GetNumberOfPoints]
174}
175
176# ----------------------------------------------------------------------
177# USAGE: dimensions
178#
179# Returns the number of dimensions for this object: 1, 2, or 3.
180# ----------------------------------------------------------------------
181itcl::body Rappture::Cloud::dimensions {} {
182    # count the dimensions with real limits
183    set dims 0
184    foreach d {x y z} {
185        if {$_limits(${d}min) != $_limits(${d}max)} {
186            incr dims
187        }
188    }
189    return $dims
190}
191
192# ----------------------------------------------------------------------
193# USAGE: limits x|y|z
194#
195# Returns the {min max} values for the limits of the specified axis.
196# ----------------------------------------------------------------------
197itcl::body Rappture::Cloud::limits {which} {
198    if {![info exists _limits(${which}min)]} {
199        error "bad axis \"$which\": should be x, y, z"
200    }
201    return [list $_limits(${which}min) $_limits(${which}max)]
202}
203
204# ----------------------------------------------------------------------
205# USAGE: hints ?<keyword>?
206#
207# Returns a list of key/value pairs for various hints about plotting
208# this field.  If a particular <keyword> is specified, then it returns
209# the hint for that <keyword>, if it exists.
210# ----------------------------------------------------------------------
211itcl::body Rappture::Cloud::hints {{keyword ""}} {
212    foreach key {label color units} {
213        set str [$_cloud get $key]
214        if {"" != $str} {
215            set hints($key) $str
216        }
217    }
218
219    if {$keyword != ""} {
220        if {[info exists hints($keyword)]} {
221            return $hints($keyword)
222        }
223        return ""
224    }
225    return [array get hints]
226}
Note: See TracBrowser for help on using the repository browser.