1 |
|
2 |
######################################################## |
3 |
# |
4 |
# Copyright (c) 2003-2010 by University of Queensland |
5 |
# Earth Systems Science Computational Center (ESSCC) |
6 |
# http://www.uq.edu.au/esscc |
7 |
# |
8 |
# Primary Business: Queensland, Australia |
9 |
# Licensed under the Open Software License version 3.0 |
10 |
# http://www.opensource.org/licenses/osl-3.0.php |
11 |
# |
12 |
######################################################## |
13 |
|
14 |
__copyright__="""Copyright (c) 2003-2010 by University of Queensland |
15 |
Earth Systems Science Computational Center (ESSCC) |
16 |
http://www.uq.edu.au/esscc |
17 |
Primary Business: Queensland, Australia""" |
18 |
__license__="""Licensed under the Open Software License version 3.0 |
19 |
http://www.opensource.org/licenses/osl-3.0.php""" |
20 |
__url__="https://launchpad.net/escript-finley" |
21 |
|
22 |
""" |
23 |
:var __author__: name of author |
24 |
:var __copyright__: copyrights |
25 |
:var __license__: licence agreement |
26 |
:var __url__: url entry point on documentation |
27 |
:var __version__: version |
28 |
:var __date__: date of the version |
29 |
""" |
30 |
|
31 |
__author__="John Ngui, john.ngui@uq.edu.au" |
32 |
|
33 |
from mapper import DataSetMapper |
34 |
from lookuptable import LookupTable |
35 |
from actor import Actor3D |
36 |
from constant import Viewport, Color, Lut, WarpMode, ColorMode |
37 |
from warp import Warp |
38 |
from outline import Outline |
39 |
from transform import Transform |
40 |
from plane import Plane |
41 |
from cutter import Cutter |
42 |
from average import CellDataToPointData |
43 |
|
44 |
# NOTE: DataSetMapper, Actor3D, Warp, Transform, Plane and Cutter were |
45 |
# inherited to allow access to their public methods from the driver. |
46 |
class Carpet(DataSetMapper, Actor3D, Warp, Transform, Plane, Cutter): |
47 |
""" |
48 |
Class that shows a scalar field on a plane deformated along the normal. |
49 |
""" |
50 |
|
51 |
# The SOUTH_WEST default viewport is used when there is only one viewport. |
52 |
# This saves the user from specifying the viewport when there is only one. |
53 |
# If no warp_mode is specified, the data will be deformated using scalar |
54 |
# data. If no lut is specified, the color scheme will be used. |
55 |
def __init__(self, scene, data_collector, viewport = Viewport.SOUTH_WEST, |
56 |
warp_mode = WarpMode.SCALAR, lut = Lut.COLOR, |
57 |
cell_to_point = False, outline = True): |
58 |
""" |
59 |
Initialise the Carpet. |
60 |
|
61 |
:attention: The source can either be point or cell data. If the source is cell data, a conversion to point data may or may not be required, in order for the object to be rendered correctly. If a conversion is needed, the 'cell_to_point' flag must be set to 'True', otherwise 'False' (which is the default). On occasions, an inaccurate object may be rendered from cell data even after conversion. When 3D data is used, a cut will be performed on the scalar field using a plane before deformation occurs on the plane. However, if 2D data is used a cut will NOT be performed and deformation will instead occur immediately on the scalar field. Pyvisi distinguishes 2D from 3D data by retrieving the length of the z-axis. A 2D data is assumed to have a z-axis length of zero while a 3D data is assumed to have a z-axis length of non-zero. There are exceptions to these rules where some 2D data may have a non-zero z-axis length. However, such exceptions are not taken into account at this stage. |
62 |
|
63 |
:type scene: `Scene` object |
64 |
:param scene: Scene in which objects are to be rendered on |
65 |
:type data_collector: `DataCollector` object |
66 |
:param data_collector: Deal with source of data for visualisation |
67 |
:type viewport: `Viewport` constant |
68 |
:param viewport: Viewport in which objects are to be rendered on |
69 |
:param warp_mode: `WarpMode` constant |
70 |
:type warp_mode: Mode in which to deform the scalar field |
71 |
:type lut: `Lut` constant |
72 |
:param lut: Lookup table color scheme |
73 |
:type cell_to_point: Boolean |
74 |
:param cell_to_point: Converts cell data to point data (by averaging) |
75 |
:type outline: Boolean |
76 |
:param outline: Places an outline around the domain surface |
77 |
""" |
78 |
|
79 |
self.__data_collector = data_collector |
80 |
self.__viewport = viewport |
81 |
self.__warp_mode = warp_mode |
82 |
self.__lut = lut |
83 |
self.__cell_to_point = cell_to_point |
84 |
self.__outline = outline |
85 |
|
86 |
# Keeps track whether Carpet has been modified. |
87 |
self.__modified = True |
88 |
Transform.__init__(self) |
89 |
Plane.__init__(self) |
90 |
Cutter.__init__(self) |
91 |
Warp.__init__(self, self.__warp_mode) |
92 |
DataSetMapper.__init__(self) |
93 |
Actor3D.__init__(self) |
94 |
scene._addVisualizationModules(self) |
95 |
|
96 |
# ----- Outline ----- |
97 |
|
98 |
# NOTE: Changes cannot be made to the Outline's properties from the |
99 |
# driver. |
100 |
if(self.__outline == True): |
101 |
outline = Outline(self.__data_collector._getDataCollectorOutput()) |
102 |
mapper = DataSetMapper() |
103 |
mapper._setupDataSetMapper(outline._getOutlineOutput()) |
104 |
|
105 |
actor3D = Actor3D() |
106 |
actor3D._setupActor3D(mapper._getDataSetMapper()) |
107 |
# Default outline color is black. |
108 |
actor3D.setColor(Color.BLACK) |
109 |
|
110 |
# Default line width is 1. |
111 |
actor3D._setLineWidth(1) |
112 |
scene._addActor3D(self.__viewport, actor3D._getActor3D()) |
113 |
|
114 |
# ----- Carpet ----- |
115 |
|
116 |
# NOTE: Lookup table color mapping (color or grey scale) MUST be set |
117 |
# before DataSetMapper. If it is done after DataSetMapper, no effect |
118 |
# will take place. |
119 |
if(self.__lut == Lut.COLOR): # Colored lookup table. |
120 |
self.__lookup_table = LookupTable() |
121 |
self.__lookup_table._setTableValue() |
122 |
elif(self.__lut == Lut.GREY_SCALE): # Grey scaled lookup table. |
123 |
self.__lookup_table = LookupTable() |
124 |
self.__lookup_table._setLookupTableToGreyScale() |
125 |
|
126 |
self._setupPlane(self._getTransform()) |
127 |
|
128 |
def _isModified(self): |
129 |
""" |
130 |
Return whether the Carpet or DataCollector has been modified. |
131 |
|
132 |
:rtype: Boolean |
133 |
:return: True or False |
134 |
""" |
135 |
|
136 |
return self.__modified or self.__data_collector._isModified() |
137 |
|
138 |
def _render(self, scene): |
139 |
""" |
140 |
Render the carpet. |
141 |
|
142 |
:type scene: `Scene` object |
143 |
:param scene: Scene in which objects are to be rendered on |
144 |
""" |
145 |
|
146 |
# This entire 'if' section had to be moved from the __init__ method |
147 |
# due to the use of 'GetBounds()'. A source (i.e. xml file) must be |
148 |
# supplied before 'GetBounds()' is able to return the correct value |
149 |
# when executed. This is to accommodate for lazy evaluation. |
150 |
if(self.__modified): |
151 |
# Get the bounds of the object in the form of |
152 |
# (xmin, xmax, ymin, ymax, zmin, zmax). |
153 |
bounds = \ |
154 |
self.__data_collector._getDataCollectorOutput().GetBounds() |
155 |
# Length of the z-axis (max - min). Assumption is made that if the |
156 |
# length of the z-axis is equal to zero, the the data set is 2D. |
157 |
# Otherwise, the data set is 3D. However, there are exceptions |
158 |
# to this rule as some 2D data sets may have a z-axis length |
159 |
# of non-zero, but such exceptions are not taken into account here. |
160 |
z_axis_length = bounds[5] - bounds[4] |
161 |
|
162 |
if(self.__cell_to_point == True): #Convert cell data to point data. |
163 |
c2p = CellDataToPointData(\ |
164 |
self.__data_collector._getDataCollectorOutput()) |
165 |
if(z_axis_length != 0): # A cutter is used for 3D data. |
166 |
self._setupCutter(c2p._getCellToPointOutput(), \ |
167 |
self._getPlane()) |
168 |
self._setupWarp(self._getCutterOutput()) |
169 |
elif(z_axis_length == 0): # A cutter is not used for 2D data. |
170 |
self._setupWarp(c2p._getCellToPointOutput()) |
171 |
|
172 |
elif(self.__cell_to_point == False): # No conversion happens. |
173 |
if(z_axis_length != 0): # A cutter is used for 3D data. |
174 |
self._setupCutter(\ |
175 |
self.__data_collector._getDataCollectorOutput(), \ |
176 |
self._getPlane()) |
177 |
self._setupWarp(self._getCutterOutput()) |
178 |
elif(z_axis_length == 0): # A cutter is not used for 2D data. |
179 |
self._setupWarp( |
180 |
self.__data_collector._getDataCollectorOutput()) |
181 |
|
182 |
self._setupDataSetMapper(self._getWarpOutput(), |
183 |
self.__lookup_table._getLookupTable()) |
184 |
|
185 |
self._setupActor3D(self._getDataSetMapper()) |
186 |
scene._addActor3D(self.__viewport, self._getActor3D()) |
187 |
|
188 |
|
189 |
if (self._isModified() == True): |
190 |
if(self.__data_collector._isScalarSet() == True): |
191 |
self.__data_collector._setActiveScalar() |
192 |
|
193 |
# self._isScalarRangeSet checks whether the scalar range has been |
194 |
# specified by the user. If it has, then the scalar range |
195 |
# read from the source will be ignored. |
196 |
if(not(self._isScalarRangeSet())): |
197 |
self._setScalarRange(self.__data_collector._getScalarRange()) |
198 |
self.__modified = False |
199 |
|
200 |
|
201 |
|