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

Last change on this file since 14 was 14, checked in by mmc, 19 years ago

Added a new <mesh> type and a viewer for mesh geometries.
Needed this for Prophet, and it's a little hard-coded to
their test case. Hack job, but it works. Also fixed the
tooltips so they don't hang around in strange cases.

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