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

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

Added support for contour plots of 3D data sets.

File size: 7.2 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 {} {
172puts "dimensions for cloud [$_cloud element -as id]"
173puts [string range [$_cloud xml] 0 300]
174    # count the dimensions with real limits
175    set dims 0
176    foreach d {x y z} {
177puts "checking dims: $d => $_limits(${d}min) $_limits(${d}max)"
178        if {$_limits(${d}min) != $_limits(${d}max)} {
179            incr dims
180        }
181    }
182    return $dims
183}
184
185# ----------------------------------------------------------------------
186# USAGE: limits x|y|z
187#
188# Returns the {min max} values for the limits of the specified axis.
189# ----------------------------------------------------------------------
190itcl::body Rappture::Cloud::limits {which} {
191    if {![info exists _limits(${which}min)]} {
192        error "bad axis \"$which\": should be x, y, z"
193    }
194    return [list $_limits(${which}min) $_limits(${which}max)]
195}
196
197# ----------------------------------------------------------------------
198# USAGE: hints ?<keyword>?
199#
200# Returns a list of key/value pairs for various hints about plotting
201# this field.  If a particular <keyword> is specified, then it returns
202# the hint for that <keyword>, if it exists.
203# ----------------------------------------------------------------------
204itcl::body Rappture::Cloud::hints {{keyword ""}} {
205    foreach key {label color units} {
206        set str [$_cloud get $key]
207        if {"" != $str} {
208            set hints($key) $str
209        }
210    }
211
212    if {$keyword != ""} {
213        if {[info exists hints($keyword)]} {
214            return $hints($keyword)
215        }
216        return ""
217    }
218    return [array get hints]
219}
Note: See TracBrowser for help on using the repository browser.