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.util.time.*;
27
28
29
30
31 /***
32 * LookupTable is an object that map scalar values into other
33 * scalar or vector values.
34 *
35 * This class is designed as a base class for derivation by other classes.
36 * The build() methods are abstract method
37 * and may require overloading in subclasses.
38 *
39 * @version $Revision: 1.3 $
40 * @author Masahiro Takatsuka (masa@jbeans.net)
41 * @see AttributeArray
42 */
43
44 public abstract class LookupTable extends AttributeArray {
45 private double[] tableRange = new double[2];
46 protected TimeStamp insertTime;
47 protected TimeStamp buildTime;
48 protected int numberOfLookups;
49
50 /***
51 * Construct with range=(0,1); and hsv ranges set up for rainbow color
52 * table (from red to blue).
53 */
54 public LookupTable(int dataType, int dim, int size) {
55 super(dataType);
56 dim = (dim < 1 ? 1 : dim);
57 this.data.setDimension(dim);
58 this.numberOfLookups = size;
59 setNumberOfLookups(size);
60 try {
61 setTableRange(0.0, 1.0);
62 } catch (InvalidDataRangeException e) {
63 }
64 this.insertTime = new TimeStamp();
65 this.buildTime = new TimeStamp();
66 this.buildTime.setTimeStamp(0L);
67 }
68
69 public LookupTable(int dataType, int dim) {
70 this(dataType, dim, 1);
71 }
72
73 /***
74 * Generate lookup table.
75 */
76 abstract protected void build();
77
78 /***
79 * Set the number of colors in the lookup table. Use this method before
80 * building the lookup table. Use SetNumberOfTableValues() to change the
81 * table size after the lookup table has been built.
82 */
83 public void setNumberOfLookups(int number) {
84 number = (number < 2 ? 2 : (number > Integer.MAX_VALUE ? Integer.MAX_VALUE : number));
85 this.numberOfLookups = number;
86 this.data.setNumberOfTuples(number);
87 }
88
89 public int getNumberOfLookups() {
90 return this.numberOfLookups;
91 }
92
93 /***
94 * Set/Get the minimum/maximum scalar values for scalar mapping. Scalar
95 * values less than minimum range value are clamped to minimum range value.
96 * Scalar values greater than maximum range value are clamped to maximum
97 * range value.
98 */
99 public void setTableRange(double[] r) throws InvalidDataRangeException {
100 setTableRange(r[0], r[1]);
101 }
102
103 public void setTableRange(double min, double max) throws InvalidDataRangeException {
104 if (min >= max) {
105 throw new InvalidDataRangeException("Bad table range: " + min + " >= " + max);
106 }
107
108 this.tableRange[0] = min;
109 this.tableRange[1] = max;
110
111 }
112 public double[] getTableRange() {
113 return this.tableRange;
114 }
115
116 /***
117 * Map one value through the lookup table. It returns an array of
118 * double containing corresponding mapped value.
119 */
120 public double[] mapValue(double v) {
121 int indx;
122 int dim = this.data.getDimension();
123
124 indx = (int)((v - this.tableRange[0])/(this.tableRange[1] - this.tableRange[0]) * this.numberOfLookups);
125 indx = (indx < 0 ? 0 : (indx >= this.numberOfLookups ? this.numberOfLookups-1 : indx));
126
127 return this.data.getTuple(indx);
128 }
129
130 /***
131 * map a set of scalars through the lookup table
132 *
133 * @param input an array of primitives (type, char, short, int, long, flost, double).
134 */
135
136
137
138 public void mapValues(Object input, double[] output,
139 int numberOfValues,
140 int inputIncrement) {
141 int indx;
142 int dim = this.data.getDimension();
143 double tmp = 0;
144
145 Class type = DataType.getArrayType(input.getClass());
146 int ptr = 0;
147 double[] tmpArray = new double[dim];
148 for (int i = 0; i < numberOfValues; i++, ptr += inputIncrement) {
149 if (type == Byte.TYPE) {
150 tmp = (double) ((byte[]) input)[ptr];
151 } else if (type == Character.TYPE) {
152 tmp = (double) ((char[]) input)[ptr];
153 } else if (type == Short.TYPE) {
154 tmp = (double) ((short[]) input)[ptr];
155 } else if (type == Integer.TYPE) {
156 tmp = (double) ((int[]) input)[ptr];
157 } else if (type == Long.TYPE) {
158 tmp = (double) ((long[]) input)[ptr];
159 } else if (type == Float.TYPE) {
160 tmp = (double) ((float[]) input)[ptr];
161 } else if (type == Double.TYPE) {
162 tmp = ((double[]) input)[ptr];
163 }
164 indx = (int)((tmp - this.tableRange[0])/(this.tableRange[1] - this.tableRange[0]) * this.numberOfLookups);
165 indx = (indx < 0 ? 0 : (indx >= this.numberOfLookups ? this.numberOfLookups-1 : indx));
166
167 this.data.getTuple(indx * dim, tmpArray);
168 System.arraycopy(tmpArray, 0, output, i * dim, dim);
169 }
170 }
171
172 /***
173 * Specify the number of values (i.e., colors) in the lookup
174 * table. This method simply allocates memory and prepares the table
175 * for use with SetTableValue(). It differs from Build() method in
176 * that the allocated memory is not initialized according to HSVA ramps.
177 */
178 public void setNumberOfTableValues(int number) {
179 setNumberOfLookups(number);
180 }
181
182 /***
183 * Directly load values into lookup table. Use double values for elements.
184 * Make sure that you've either used the build() method or used
185 * setNumberOfTableValues() prior to using this method.
186 */
187 public void setTableValue (int indx, double[] value) {
188 this.data.setTuple(indx, value);
189 this.insertTime.modified();
190 }
191
192 /***
193 * Return a value for the given index into the lookup table.
194 * Values are expressed as double values.
195 */
196 public double[] getTableValue(int id) {
197 return this.data.getTuple(id);
198 }
199
200 /***
201 * Return a rgba color value for the given index into the lookup table.
202 * Color components are expressed as [0,1] float values.
203 */
204 public void getTableValue (int id, double[] value) {
205 this.data.getTuple(id, value);
206 }
207 }
208