source: branches/uq/gui/scripts/cloud.tcl @ 5679

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

Full merge 1.3 branch to uq branch to sync. Fixed partial subdirectory merge
by removing mergeinfo from lang/python/Rappture directory.

File size: 8.8 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} {
21        # defined below
22    }
23    destructor {
24        # defined below
25    }
26    public method points {}
27    public method units { axis }
28    public method label { axis }
29    public method vtkdata {}
30    public method dimensions {}
31    public method limits {which}
32    public method hints {{key ""}}
33    public method numpoints {} {
34        return $_numPoints
35    }
36    public method isvalid {} {
37        return $_isValid
38    }
39
40    public proc fetch {xmlobj path}
41    public proc release {obj}
42
43    private variable _xmlobj "";        # ref to XML obj with device data
44    private variable _cloud "";         # lib obj representing this cloud
45    private variable _units "" ;        # system of units for x, y, z
46    private variable _axis2label;       #
47    private variable _axis2units;       #
48    private variable _limits;           # limits x, y, z
49    private variable _numPoints 0
50    private variable _vtkdata ""
51    private variable _points ""
52    private variable _dim 0
53    private variable _isValid 0;        # Indicates if the data is valid.
54
55    private common _xp2obj ;            # Used for fetch/release ref counting
56    private common _obj2ref ;           # Used for fetch/release ref counting
57}
58
59# ----------------------------------------------------------------------
60# USAGE: Rappture::Cloud::fetch <xmlobj> <path>
61#
62# Clients use this instead of a constructor to fetch the Cloud for
63# a particular <path> in the <xmlobj>.  When the client is done with
64# the cloud, he calls "release" to decrement the reference count.
65# When the cloud is no longer needed, it is cleaned up automatically.
66# ----------------------------------------------------------------------
67itcl::body Rappture::Cloud::fetch {xmlobj path} {
68    set handle "$xmlobj|$path"
69    if {[info exists _xp2obj($handle)]} {
70        set obj $_xp2obj($handle)
71        incr _obj2ref($obj)
72        return $obj
73    }
74
75    set obj [Rappture::Cloud ::#auto $xmlobj $path]
76    set _xp2obj($handle) $obj
77    set _obj2ref($obj) 1
78    return $obj
79}
80
81# ----------------------------------------------------------------------
82# USAGE: Rappture::Cloud::release <obj>
83#
84# Clients call this when they're no longer using a Cloud fetched
85# previously by the "fetch" proc.  This decrements the reference
86# count for the cloud and destroys the object when it is no longer
87# in use.
88# ----------------------------------------------------------------------
89itcl::body Rappture::Cloud::release {obj} {
90    if {[info exists _obj2ref($obj)]} {
91        incr _obj2ref($obj) -1
92        if {$_obj2ref($obj) <= 0} {
93            unset _obj2ref($obj)
94            foreach handle [array names _xp2obj] {
95                if {$_xp2obj($handle) == $obj} {
96                    unset _xp2obj($handle)
97                }
98            }
99            itcl::delete object $obj
100        }
101    } else {
102        error "can't find reference count for $obj"
103    }
104}
105
106# ----------------------------------------------------------------------
107# CONSTRUCTOR
108# ----------------------------------------------------------------------
109itcl::body Rappture::Cloud::constructor {xmlobj path} {
110    if {![Rappture::library isvalid $xmlobj]} {
111        error "bad value \"$xmlobj\": should be Rappture::library"
112    }
113    set _xmlobj $xmlobj
114    set _cloud [$xmlobj element -as object $path]
115
116    set _units [$_cloud get units]
117    set first [lindex $_units 0]
118    set list {}
119    foreach u $_units axis { x y z } {
120        if { $u != "" } {
121            set _axis2units($axis) $u
122        } else {
123            set _axis2units($axis) $first
124        }
125        lappend list $_axis2units($axis)
126    }
127    set _units $list
128    foreach label [$_cloud get labels] axis { x y z } {
129        if { $label != "" } {
130            set _axis2label($axis) $label
131        } else {
132            set _axis2label($axis) [string toupper $axis]
133        }
134    }
135
136    set _numPoints 0
137    set _points {}
138    foreach line [split [$xmlobj get $path.points] \n] {
139        if {"" == [string trim $line]} {
140            continue
141        }
142
143        if {[llength $line] > 3} {
144            puts stderr "ERROR: Too many coordinates in cloud points list"
145            return
146        }
147
148        # make sure we have x,y,z
149        while {[llength $line] < 3} {
150            lappend line "0"
151        }
152
153        # Extract each point and add it to the points list
154        foreach {x y z} $line break
155        foreach axis {x y z} {
156            # Units on point coordinates are NOT supported
157            set value [set $axis]
158            # Update limits
159            if { ![info exists _limits($axis)] } {
160                set _limits($axis) [list $value $value]
161            } else {
162                foreach { min max } $_limits($axis) break
163                if {$value < $min} {
164                    set min $value
165                }
166                if {$value > $max} {
167                    set max $value
168                }
169                set _limits($axis) [list $min $max]
170            }
171        }
172        append _points "$x $y $z\n"
173        incr _numPoints
174    }
175    append out "DATASET POLYDATA\n"
176    append out "POINTS $_numPoints double\n"
177    append out $_points
178    set _vtkdata $out
179    if { $_numPoints == 0 } {
180        return
181    }
182    set _dim 0
183    foreach { xmin xmax } $_limits(x) break
184    if { $xmax > $xmin } {
185        incr _dim
186    }
187    foreach { ymin ymax } $_limits(y) break
188    if { $ymax > $ymin } {
189        incr _dim
190    }
191    foreach { zmin zmax } $_limits(z) break
192    if { $zmax > $zmin } {
193        incr _dim
194    }
195    set _isValid 1
196    puts stderr "WARNING: The <cloud> element is deprecated.  Please use an unstructured <mesh> instead."
197}
198
199# ----------------------------------------------------------------------
200# DESTRUCTOR
201# ----------------------------------------------------------------------
202itcl::body Rappture::Cloud::destructor {} {
203    # don't destroy the _xmlobj! we don't own it!
204    itcl::delete object $_cloud
205}
206
207# ----------------------------------------------------------------------
208# USAGE: points
209#
210# Returns a string containing the points for this mesh.
211# ----------------------------------------------------------------------
212itcl::body Rappture::Cloud::points {} {
213    return $_points
214}
215
216# ----------------------------------------------------------------------
217# USAGE: dimensions
218#
219# Returns the number of dimensions for this object: 1, 2, or 3.
220# ----------------------------------------------------------------------
221itcl::body Rappture::Cloud::dimensions {} {
222    return $_dim
223}
224
225# ----------------------------------------------------------------------
226# USAGE: limits x|y|z
227#
228# Returns the {min max} values for the limits of the specified axis.
229# ----------------------------------------------------------------------
230itcl::body Rappture::Cloud::limits { axis } {
231    if { ![info exists _limits($axis)] } {
232        error "bad axis \"$axis\": should be x, y, z"
233    }
234    return $_limits($axis)
235}
236
237#
238# units --
239#
240#       Returns the units of the given axis.
241#
242itcl::body Rappture::Cloud::units { axis } {
243    if { ![info exists _axis2units($axis)] } {
244        return ""
245    }
246    return $_axis2units($axis)
247}
248
249#
250# label --
251#
252#       Returns the label of the given axis.
253#
254itcl::body Rappture::Cloud::label { axis } {
255    if { ![info exists _axis2label($axis)] } {
256        return ""
257    }
258    return $_axis2label($axis)
259}
260
261# ----------------------------------------------------------------------
262# USAGE: hints ?<keyword>?
263#
264# Returns a list of key/value pairs for various hints about plotting
265# this field.  If a particular <keyword> is specified, then it returns
266# the hint for that <keyword>, if it exists.
267# ----------------------------------------------------------------------
268itcl::body Rappture::Cloud::hints {{keyword ""}} {
269    foreach key {label color units} {
270        set str [$_cloud get $key]
271        if {"" != $str} {
272            set hints($key) $str
273        }
274    }
275
276    if {$keyword != ""} {
277        if {[info exists hints($keyword)]} {
278            return $hints($keyword)
279        }
280        return ""
281    }
282    return [array get hints]
283}
284
285itcl::body Rappture::Cloud::vtkdata {} {
286    return $_vtkdata
287}
Note: See TracBrowser for help on using the repository browser.