1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23 package net.jbeans.j3d.data;
24
25 /* ------------------ Import classes (packages) ------------------- *//package-summary/html">class="comment"> ------------------ Import classes (packages) ------------------- *//package-summary.html">class="comment">/* ------------------ Import classes (packages) ------------------- *//package-summary.html">class="comment"> ------------------ Import classes (packages) ------------------- */
26 import net.jbeans.lang.*;
27
28
29
30
31 /***
32 * DataArray is an superclass for all net.jbeans.j3d.data array objects.
33 * Subclasses of this class handle specific primitive data (boolean, bit,
34 * char, short, int, long, float, double, String.)
35 *
36 * The data structure of DataArray is an array of tuples.
37 * Each tuple is a n-dimensional array. DataArray also can be seen as
38 * a <code>m x n</code> matrix, where m is the number of tuples, and n is the
39 * number of dimension in a tuple. the DataArray can be used to
40 * represent various data such as scalars, vectors, texture coordinates,
41 * tensors...
42 *
43 * The Visualization Toolkit (VTK)'s data model was used to create this class
44 * and associated subclasses.
45 *
46 * @version $Revision: 1.3 $
47 * @author Masahiro Takatsuka (masa@jbeans.net)
48 */
49
50 public abstract class DataArray {
51 protected Object array;
52 protected int size;
53 protected int maxId;
54 protected int dimension;
55 protected double[] tupleT;
56
57 /***
58 * Construct a DataArray object with the specified tuple dimension.
59 * <PRE>
60 * </PRE>
61 *
62 * @param dim the dimension of the tuple.
63 * @return A new DataArray object.
64 */
65 public DataArray(int dim) {
66 this.array = null;
67 this.size = 0;
68 this.maxId = -1;
69 this.dimension = (dim < 1 ? 1 : dim);
70 this.tupleT = new double[this.dimension];
71 }
72
73 public DataArray(DataArray da) {
74 this(da.dimension);
75 copy(da);
76 }
77
78 public void copy(DataArray da) {
79 allocate(da.size);
80 this.maxId = da.maxId;
81 this.dimension = da.dimension;
82 this.tupleT = new double[this.dimension];
83 }
84
85 public abstract boolean allocate(int size);
86
87 /***
88 * Release storage and reset array to initial state.
89 */
90 public void initialize() {
91 this.array = null;
92 this.size = 0;
93 this.maxId = -1;
94 }
95
96 /***
97 * Virtual constructor creates an object of the same type as this one.
98 * The created object also has the same number of components. You are
99 * responsible for freeing the object.
100 */
101 public abstract DataArray makeObject();
102
103 /***
104 * Return a array pointer. For image pipeline interface and other
105 * special pointer manipulation.
106 */
107 public Object getData() {
108 return this.array;
109 }
110
111 /***
112 * resize the array.
113 */
114 protected abstract Object resize(int size);
115
116 /***
117 * Return the underlying data type. An integer indicating data type is
118 * returned as specified in DataType class.
119 * <PRE>
120 * </PRE>
121 *
122 * @return the underlying data type.
123 */
124 public int getDataType() {
125 return DataType.VOID;
126 }
127
128 /***
129 * Resize object to just fit data requirement. Reclaims extra memory.
130 */
131 public void squeeze() {
132 resize(this.maxId + 1);
133 }
134
135
136
137 /***
138 * Reset to an empty state, without freeing any memory.
139 */
140 public void reset() {
141 this.maxId = -1;
142 }
143
144 /***
145 * Return the size of the data.
146 */
147 public int getSize() {
148 return this.size;
149 }
150
151 /***
152 * What is the maximum id currently in the array.
153 */
154 public int getMaxId() {
155 return this.maxId;
156 }
157
158 /***
159 * ensures data is allocated from the location <code>id</code>
160 * for the number of items requested. Set maxId according to the
161 * number of data values requested.
162 */
163 public Object ensureSpace(int id, int number) {
164 int newSize = id + number;
165 if (newSize > this.size ) {
166 resize(newSize);
167 }
168 if ((--newSize) > this.maxId ) {
169 this.maxId = newSize;
170 }
171 return this.array;
172 }
173
174 /***
175 * Return the data element at the <code>i</code>th tuple and
176 * <code>j</code>th element location.
177 * Note that <code>i</code> is less than number of tuples and
178 * <code>j</code> is less than the dimension. This method can be
179 * overridden for more efficiency.
180 * <PRE>
181 * </PRE>
182 *
183 * @param i the index to the <code>i</code>th tuple.
184 * @param j the index to the <code>j</code>th element of the tuple.
185 * @return element.
186 */
187 public double getElement(int i, int j) throws ArrayIndexOutOfBoundsException {
188 if ((i < 0 || i >= getNumberOfTuples()) ||
189 (j < 0 || j >= this.dimension)) {
190 throw new ArrayIndexOutOfBoundsException();
191 }
192 double[] d = new double[this.dimension];
193
194 getTuple(i, d);
195 return d[j];
196 }
197
198 /***
199 * Set the data element at the <code>i</code>th tuple and
200 * <code>j</code>th element location.
201 * Note that <code>i</code> is less than number of tuples and
202 * <code>j</code> is less than the dimension.
203 * <PRE>
204 * </PRE>
205 *
206 * @param i the index to the <code>i</code>th tuple.
207 * @param j the index to the <code>j</code>th element of the tuple.
208 * @param e the element to be set.
209 * @return void
210 */
211 public void setElement(int i, int j, double e) throws ArrayIndexOutOfBoundsException {
212 if ((i < 0) || (j < 0 || j >= this.dimension)) {
213 throw new ArrayIndexOutOfBoundsException();
214 }
215 double[] tuple = new double[this.dimension];
216
217 if ( i < getNumberOfTuples()) {
218 getTuple(i, tuple);
219 }
220
221 tuple[j] = e;
222 setTuple(i, tuple);
223 }
224
225 /***
226 * Insert the data element at <code>i</code>th tuple and
227 * <code>j</code>th element location.
228 * <PRE>
229 * </PRE>
230 *
231 * @param (parameter-name) (description)
232 * @return void
233 */
234 public void insertElement(int i, int j, double e) throws ArrayIndexOutOfBoundsException {
235 if ((i < 0) || (j < 0 || j >= this.dimension)) {
236 throw new ArrayIndexOutOfBoundsException();
237 }
238 double[] tuple = new double[this.dimension];
239
240 if ( i < getNumberOfTuples() ) {
241 getTuple(i, tuple);
242 }
243
244 tuple[j] = e;
245 insertTuple(i, tuple);
246 }
247
248 /***
249 * Set the dimension (n). Must be >= 1.
250 */
251 public void setDimension(int dim) {
252 this.dimension = dim < 1 ? 1 : (dim > Integer.MAX_VALUE ? Integer.MAX_VALUE : dim);
253 }
254
255 /***
256 * Get the dimension (n) of the elements.
257 */
258 public int getDimension() {
259 return this.dimension;
260 }
261
262 /***
263 * Get the data as a double array in the range (tupleMin,tupleMax) and
264 * (compMin, compMax). The resulting float array consists of all data in
265 * the tuple range specified and only the element range specified. This
266 * process typically requires casting the data from native form into
267 * floating point values. This method is provided as a convenience for data
268 * exchange, and is not very fast.
269 * <PRE>
270 * </PRE>
271 *
272 * @param tupleMin
273 * @param tupleMax
274 * @param eleMin
275 * @param eleMax
276 * @return void
277 */
278 public void getData(int tupleMin, int tupleMax, int eleMin, int eleMax, DataArray data) {
279 double[] tuple = new double[getDimension()];
280 int start = 0;
281 int length = (tupleMax - tupleMin+1) * (eleMax - eleMin + 1);
282
283 for (int j = tupleMin; j <= tupleMax; j++) {
284 getTuple(j, tuple);
285 for (int i = eleMin; i <= eleMax; i++) {
286 data.setElement(j, i, tuple[i]);
287 }
288 }
289 }
290
291 /***
292 * Get the data tuple at <code>i</code>th location by filling in a
293 * user-provided array. Make sure that your array is large enough to hold
294 * number of elements being returned.
295 * <PRE>
296 * </PRE>
297 *
298 * @param i
299 * @param tuple
300 * @return void
301 */
302 public abstract void getTuple(int i, double[] tuple);
303
304 /***
305 * Set the data tuple at <code>i</code>th location.
306 * Note that range checking is not performed; use this method in
307 * conjunction with setNumberOfTuples() to allocate space.
308 * <PRE>
309 * </PRE>
310 *
311 * @param i
312 * @param tuple
313 * @return void
314 */
315 public abstract void setTuple(int i, double[] tuple);
316
317 /***
318 * Insert the data tuple at <code>i</code>th location.
319 * Note that memory allocation is performed as necessary to hold the data.
320 * <PRE>
321 * </PRE>
322 *
323 * @param i
324 * @param tuple
325 * @return void
326 */
327 public abstract void insertTuple(int i, double[] tuple);
328
329 /***
330 * Insert the data tuple at the end of the array and return the location at
331 * which the data was inserted. Memory is allocated as necessary to hold
332 * the data.
333 * <PRE>
334 * </PRE>
335 *
336 * @param tuple
337 * @return the location at which the data was inserted.
338 */
339 public abstract int insertNextTuple(double[] tuple);
340
341 /***
342 * Set the number of tuples (a element group) in the array. Note that
343 * this may allocate space depending on the number of elements.
344 * <PRE>
345 * </PRE>
346 *
347 * @param number the number of tuples.
348 * @return void
349 */
350 public abstract void setNumberOfTuples(int number);
351
352 /***
353 * Get the number of tuples (a element group) in the array.
354 * <PRE>
355 * </PRE>
356 *
357 * @return the number of tuples.
358 */
359 public int getNumberOfTuples() {
360 return (this.maxId + 1) / this.dimension;
361 }
362
363 /***
364 * Get the data tuple at <code>i</code>th location. Return it as an array.
365 * <PRE>
366 * </PRE>
367 *
368 * @param i the index of the <code>i</code>th tuple.
369 * @return an array containing tuple.
370 */
371 public abstract double[] getTuple(int i);
372 }
373