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

Last change on this file since 3515 was 3489, checked in by gah, 11 years ago

fix deprecated cloud to be backward compatible

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