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.modeler.geometry;
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 java.io.*;
27 import java.lang.reflect.*;
28 import java.util.*;
29 import javax.media.j3d.*;
30 import javax.swing.event.*;
31
32 import net.jbeans.j3d.event.*;
33
34 import net.jbeans.lang.*;
35 import net.jbeans.bean.adapter.*;
36 import net.jbeans.util.debug.*;
37
38
39
40
41 /***
42 * GeometryModeler is an abstract and super class of all modelers to create
43 * javax.media.j3d.Geometry object from data.
44 *
45 * A modeler is an object which creates javax.media.j3d.Geometry object(s)
46 * from a given dataset.
47 *
48 * @version $Revision: 1.3 $
49 * @author Masahiro Takatsuka (masa@jbeans.net)
50 * @see Serializable, GeometryUpdater
51 */
52
53 public abstract class GeometryModeler implements Serializable, GeometryUpdater {
54 private static final boolean DEBUG = Debug.getDebugFlag(GeometryModeler.class);
55
56 public static final int SCALAR_MODE_DEFAULT = 0;
57 public static final int SCALAR_MODE_USE_POINT_DATA = 1;
58 public static final int SCALAR_MODE_USE_CELL_DATA = 2;
59
60
61 transient protected EventListenerList geometryListeners = new EventListenerList();
62 transient protected double[] bounds;
63 transient protected double[] center;
64 transient protected int scalarMode;
65
66 /***
67 *
68 */
69 transient protected Vector geoms;
70
71 /***
72 */
73 public GeometryModeler() {
74 super();
75 this.bounds = new double[6];
76 this.bounds[0] = this.bounds[2] = this.bounds[4] = -1.0;
77 this.bounds[1] = this.bounds[3] = this.bounds[5] = 1.0;
78 this.center = new double[3];
79 this.center[0] = this.center[1] = this.center[2] = 0.0;
80 this.scalarMode = SCALAR_MODE_DEFAULT;
81 initialize();
82 }
83
84 private void initialize() {
85 this.geometryListeners = new EventListenerList();
86 this.geoms = new Vector();
87 }
88
89 /***
90 * Construct a javax.media.j3d.GeometryArray object.
91 * This method should call setData(Geometry) method to set
92 * a newly created Geometry. The setData() method then call
93 * fireGoemtryCreated() method notify all listeners.
94 */
95 protected void model() {
96 modelGeometry();
97 fireGeometryCreated();
98 }
99
100 protected abstract void modelGeometry();
101
102 /***
103 * Update a javax.media.j3d.GeometryArray object.
104 * This method should call setGeometry(Geometry) method to set
105 * a newly created Geometry. The setGeometry() method then call
106 * fireGoemtryCreated() method notify all listeners.
107 */
108 protected void update() {
109 ((GeometryArray) this.geoms.get(0)).updateData(this);
110 fireGeometryChanged();
111 }
112
113 protected void clearGeometry() {
114 int size = this.geoms.size();
115 Object[] listeners = geometryListeners.getListenerList();
116
117
118 for (int i = listeners.length - 2; i >= 0; i -= 2) {
119 if (listeners[i] == SceneGraphObjectListener.class) {
120 SceneGraphObjectListener l = (SceneGraphObjectListener) listeners[i+1];
121 Object target = l;
122 if (l instanceof Proxy) {
123 InvocationHandler handler = Proxy.getInvocationHandler(l);
124 target = AdapterHandler.getTarget(handler);
125 }
126 if (target != null) {
127 try {
128 Class[] argTypes = {Geometry.class};
129 for (int j = 0; j < this.geoms.size(); j++) {
130 if (DEBUG) {
131 System.out.println("removing : " + this.geoms.get(j));
132 }
133 Object[] args = {this.geoms.get(j)};
134 ClassUtil.makeObjectPerform(target, "removeGeometry", args, argTypes);
135 }
136 } catch (Exception e) {
137 if (DEBUG) {
138 e.printStackTrace();
139 }
140 }
141 }
142 }
143 }
144 this.geoms = new Vector();
145 }
146
147 protected void setGeometry(Geometry geom) {
148 addGeometry(0, geom);
149 }
150
151 protected void addGeometry(Geometry geom) {
152 this.geoms.add(this.geoms.size(), geom);
153 }
154
155 protected void addGeometry(int index, Geometry geom) {
156 if (DEBUG) {
157 System.out.println("adding geom (" + index + "):" + geom);
158 }
159 geom.setCapability(GeometryArray.ALLOW_FORMAT_READ);
160 geom.setCapability(GeometryArray.ALLOW_COORDINATE_READ);
161 geom.setCapability(GeometryArray.ALLOW_COUNT_READ);
162 geom.setCapability(GeometryArray.ALLOW_REF_DATA_READ);
163 geom.setCapability(GeometryArray.ALLOW_REF_DATA_WRITE);
164 geom.setCapability(IndexedGeometryArray.ALLOW_COORDINATE_INDEX_READ);
165 this.geoms.add(index, geom);
166 }
167
168 /***
169 * Returns the current shape object.
170 */
171 public Geometry getGeometry() {
172 return (Geometry) this.geoms.get(0);
173 }
174
175 /***
176 * Returns the current shape object.
177 */
178 public Geometry[] getGeometries() {
179 return (Geometry[]) this.geoms.toArray(new Geometry[]{});
180 }
181
182 /***
183 *
184 */
185 public abstract void updateData(Geometry geom);
186
187 /***
188 * Serialization methods
189 */
190 private void readObject(ObjectInputStream s) throws ClassNotFoundException, IOException {
191 s.defaultReadObject();
192 initialize();
193 }
194
195 /***
196 * adds an SceneGraphObjectListener to the shape
197 */
198 public void addGeometryListener(SceneGraphObjectListener l) {
199 this.geometryListeners.add(SceneGraphObjectListener.class, l);
200 }
201
202 /***
203 * removes an GeometryListener from the shape.
204 */
205 public void removeGeometryListener(SceneGraphObjectListener l) {
206 this.geometryListeners.remove(SceneGraphObjectListener.class, l);
207
208
209
210 if (l instanceof Proxy) {
211 InvocationHandler handler = Proxy.getInvocationHandler(l);
212 Object target = AdapterHandler.getTarget(handler);
213 if (target != null) {
214 try {
215 Class[] argTypes = {Geometry.class};
216 for (int i = 0; i < this.geoms.size(); i++) {
217 Object[] args = {this.geoms.get(i)};
218 ClassUtil.makeObjectPerform(target, "removeGeometry", args, argTypes);
219 }
220 } catch (Exception e) {
221 if (DEBUG) {
222 e.printStackTrace();
223 }
224 }
225 }
226 }
227 }
228
229 /***
230 * Notify all listeners that have registered interest for
231 * notification on this event type.
232 */
233 private void fireGeometryCreated() {
234 Object[] listeners = geometryListeners.getListenerList();
235
236
237 for (int i = listeners.length - 2; i >= 0; i -= 2) {
238 if (listeners[i] == SceneGraphObjectListener.class) {
239
240 ((SceneGraphObjectListener)listeners[i+1]).objectCreated(new EventObject(this));
241 }
242 }
243 }
244
245 /***
246 * Notify all listeners that have registered interest for
247 * notification on this event type.
248 */
249 private void fireGeometryChanged() {
250 Object[] listeners = geometryListeners.getListenerList();
251
252
253 for (int i = listeners.length - 2; i >= 0; i -= 2) {
254 if (listeners[i] == SceneGraphObjectListener.class) {
255
256 ((SceneGraphObjectListener)listeners[i+1]).objectChanged(new EventObject(this));
257 }
258 }
259 }
260
261 public double[] getBounds() {
262 double[] bounds = {-1.0,1.0, -1.0,1.0, -1.0,1.0};
263 return bounds;
264 }
265
266 /***
267 * Get the bounds for this Prop as (Xmin,Xmax,Ymin,Ymax,Zmin,Zmax).
268 */
269 public void getBounds(double[] bounds) {
270 getBounds();
271 for (int i = 0; i < 6; i++) {
272 bounds[i] = this.bounds[i];
273 }
274 }
275
276 public double[] getCenter() {
277 getBounds();
278 for (int i = 0; i < 3; i++) {
279 this.center[i] = (this.bounds[2*i+1] + this.bounds[2*i]) / 2.0;
280 }
281 return this.center;
282 }
283
284 public double getLength() {
285 double diff, l = 0.0;
286
287 getBounds();
288 for (int i = 0; i < 3; i++) {
289 diff = this.bounds[2*i+1] - this.bounds[2*i];
290 l += diff * diff;
291 }
292
293 return Math.sqrt(l);
294 }
295 }