View Javadoc
1   /* -------------------------------------------------------------------
2    * Java source file for the class DataArray
3    * 
4    * Copyright (c), 2003, Masahiro Takatsuka.
5    * All Rights Researved.
6    * 
7    * Original Author: Masahiro Takatsuka (masa@jbeans.net)
8    * $Author: takatsukam $
9    * 
10   * $Date: 2004/03/03 11:53:05 $
11   * 
12   * $Id: DataArray.java,v 1.3 2004/03/03 11:53:05 takatsukam Exp $
13   * 
14   * Reference:		Document no:
15   * ___				___
16   * 
17   * To Do:
18   * ___
19   * 
20  ------------------------------------------------------------------- */
21  
22  /* --------------------------- Package ---------------------------- */
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                    Implementation of class DataArray                   
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;			// allocated size of data
53  	protected int maxId;		// maximum index inserted thus far
54  	protected int dimension;	// the number of elements per tuple
55  	protected double[] tupleT;	// temp buffer for returning tuple.
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 	// public abstract void squeeze();
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