View Javadoc

1   /* -------------------------------------------------------------------
2    * Java source file for the class GeometryModeler
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: GeometryModeler.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.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                 Implementation of class GeometryModeler                
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  	/* ------------------------ not serialized ------------------------ */
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         // Process the listeners last to first, notifying
117         // those that are interested in this event
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 		/* the lister "l" might have a reference of this object.
208 		   so, remove it!
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         // Process the listeners last to first, notifying
236         // those that are interested in this event
237         for (int i = listeners.length - 2; i >= 0; i -= 2) {
238             if (listeners[i] == SceneGraphObjectListener.class) {
239                 // Lazily create the event:
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         // Process the listeners last to first, notifying
252         // those that are interested in this event
253         for (int i = listeners.length - 2; i >= 0; i -= 2) {
254             if (listeners[i] == SceneGraphObjectListener.class) {
255                 // Lazily create the event:
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 }