1 /*****************************************************************************
2 * Virtual Mockup for Machine Vision
3 * Copyright (C) 2001-2003 Fabio R. de Miranda, João E. Kogler Jr.,
4 * Carlos S. Santos.
5 * Virtual Mockup for Machine Vision Project funded by SENAC-SP
6 *
7 * Permission is granted to redistribute and/or modify this
8 * software under the terms of the GNU Lesser General Public
9 * License as published by the Free Software Foundation; either
10 * version 2.1 of the License, or (at your option) any later version.
11 *
12 * This software is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * Lesser General Public License (http://www.gnu.org/copyleft/lesser.html)
16 * for more details.
17 *
18 *****************************************************************************/
19
20 package camera3d;
21
22
23 import javax.swing.Icon;
24 import javax.swing.ImageIcon;
25 import javax.media.j3d.*;
26 import javax.vecmath.Color3f;
27 import camera3d.event.*;
28 import java.util.*;
29
30 /***
31 * Holds Geometry content that can be added to scene graph.
32 *
33 * @author Fábio Roberto de Miranda
34 */
35 public class VcContent extends VcObject {
36 // overrides VcObject.instanceCounter
37 // allows instance counting of different subclasses of VcObject
38 private static int instanceCounter = 0;
39
40 /* List of degradation modes; each mode corresponds to the index of its representation
41 (i.e. geometry) in a switch group.
42 To create a new degradation mode, add it to the end of list of modes and
43 increment the numDegradeModes variable so it reflects the new number of
44 degradation modes
45 */
46 /*** No degradation mode, shows default geometry. */
47 public static final int DEGRADE_NONE = 0;
48 /*** Degradation mode that shows a box instead of the geometry. */
49 public static final int DEGRADE_BOX = 1;
50 /*** Degradation mode that shows simplified geometry. */
51 public static final int DEGRADE_SIMPLIFIED = 2;
52 /*** Number of degradation modes. */
53 private int numDegradeModes = 3;
54 /*** Holds value of current degradation mode.*/
55 private int degradeMode = DEGRADE_NONE;
56
57 //TransparencyAttributes transparencyAttributes;
58
59 /* we switch between the two transparecy attributes declared below as this object
60 is selected/unselected; simply changing changing the transparency value of
61 a single TransparencyAttributes object didn't work, as some geometries disappeared
62 from the scene when we did that (this is probably due to a bug in Java3D 1.3) */
63 /*** Normal transparency attributes */
64 private TransparencyAttributes opaque = new TransparencyAttributes();
65 /*** Transparency attributes to be used when object is selected. Specify
66 * transparency value of 0.5*/
67 private TransparencyAttributes transparent = new TransparencyAttributes(TransparencyAttributes.FASTEST,0.5f);
68
69 /*** List of Apperances from content nodes that have been added to this object.
70 * It is kept so we can change switch the TransparencyAttributes during selection.*/
71 private List appearances = new ArrayList();
72
73 private PolygonAttributes polygonAttributes;
74
75 private Icon contentIcon = new ImageIcon(this.getClass().getResource("icons/content_item.gif"));
76
77 /*** Controls exhibition of different geometries, according to degradation mode settings.*/
78 private Switch sGroup = new Switch(0);
79
80
81 /*** Indicate whether this object is undergoing a transformation. */
82 private boolean transforming = false;
83
84 /***
85 * Creates content object. No geometry is created at this time, for including
86 * geometry use the addNode method.
87 */
88 public VcContent() {
89 this.setLabel("content"+VcContent.instanceCounter++);
90
91 polygonAttributes = new PolygonAttributes(PolygonAttributes.POLYGON_FILL, PolygonAttributes.CULL_BACK, 0.0f, false, 0.0f);
92 polygonAttributes.setCapability(PolygonAttributes.ALLOW_MODE_READ);
93 polygonAttributes.setCapability(PolygonAttributes.ALLOW_MODE_WRITE);
94
95 // for implementing degradation modes
96
97 sGroup.setCapability(Node.ALLOW_LOCAL_TO_VWORLD_READ);
98 sGroup.setCapability(Group.ALLOW_CHILDREN_EXTEND);
99 sGroup.setCapability(Group.ALLOW_CHILDREN_READ);
100 sGroup.setCapability(Group.ALLOW_CHILDREN_WRITE);
101 sGroup.setCapability(Switch.ALLOW_SWITCH_READ);
102 sGroup.setCapability(Switch.ALLOW_SWITCH_WRITE);
103 sGroup.setPickable(true);
104
105 // creates groups which will hold different representations
106 // corresponding to the various degradation modes
107 for(int i=0;i<numDegradeModes;i++){
108 // these BranchGroup must not appear in Picking Reports, as that would
109 // interfire with functioning of the picking behavior
110 // TODO: try to figure out a way so BGs are no longer necessary (currently
111 // they are needed so alternative geometries can be dettached inside computeBoundingBox
112 // method); Only the default geometry (index 0) should be pickable.
113 BranchGroup bGroup = new BranchGroup();
114 bGroup.setCapability(Node.ALLOW_LOCAL_TO_VWORLD_READ);
115 bGroup.setCapability(Group.ALLOW_CHILDREN_EXTEND);
116 bGroup.setCapability(Group.ALLOW_CHILDREN_READ);
117 bGroup.setCapability(Group.ALLOW_CHILDREN_WRITE);
118 bGroup.setCapability(BranchGroup.ALLOW_DETACH);
119 bGroup.setPickable(true);
120 sGroup.addChild(bGroup);
121 }
122 super.addNode(sGroup);
123 }
124
125 /***
126 * Returns the number of objects instatiated so far.
127 */
128 public static int getInstanceCounter(){
129 return instanceCounter;
130 }
131
132 /***
133 * Adds a Node to this object branch graph.
134 */
135 public void addNode(Node n){
136 setSingleAttributes(n);
137 ((Group)sGroup.getChild(VcContent.DEGRADE_NONE)).addChild(n);
138 if(addNodeEvent==null){
139 addNodeEvent = new VcNodeAddedEvent(this,n);
140 }else addNodeEvent.setNode(n);
141 currentEvent = addNodeEvent;
142 notifyChangeListeners();
143 }
144
145 /***
146 * Overrides VcObject.computeBoundingBox, so BoundingBox gets calculated only
147 * in relation to default geometry and not to degraded ones.
148 */
149 void computeBoundingBox(){
150 GeometryUtility.computeBoundingBox((Group)sGroup.getChild(VcContent.DEGRADE_NONE),
151 this.boundingBox);
152 Shape3D simplified = makeAlternateGeometry(sGroup.getChild(VcContent.DEGRADE_NONE));
153 BranchGroup brGroup = (BranchGroup)sGroup.getChild(VcContent.DEGRADE_SIMPLIFIED);
154 brGroup.detach();
155 brGroup.addChild(simplified);
156 if(sGroup.numChildren()>VcContent.DEGRADE_SIMPLIFIED){
157 sGroup.setChild(brGroup,VcContent.DEGRADE_SIMPLIFIED);
158 }else sGroup.addChild(brGroup);
159 }
160
161 /***
162 * Configures Appearance of content nodes so TransparencyAttributes can be changed
163 * during selection.
164 */
165 private void setSingleAttributes(Node node){
166 if (node instanceof Group ) {
167 Enumeration enum = null;
168 try {
169 enum = ((Group)node).getAllChildren();
170 }catch (CapabilityNotSetException cns){
171 System.out.println("Capability error at Node:"+((Group)node)+" :"+this.label);
172 cns.printStackTrace();
173 }
174 while (enum.hasMoreElements()){
175 setSingleAttributes((Node)enum.nextElement());
176 }
177 }else if(node instanceof Shape3D){
178 // Extract Geometry information from Shape3D
179 Appearance app = ((Shape3D)node).getAppearance();
180 if(app!=null){
181 app.setTransparencyAttributes(opaque);
182 app.setCapability(Appearance.ALLOW_TRANSPARENCY_ATTRIBUTES_READ);
183 app.setCapability(Appearance.ALLOW_TRANSPARENCY_ATTRIBUTES_WRITE);
184 appearances.add(app);
185 }
186 }else if (node instanceof Link){
187 setSingleAttributes(((Link)node).getSharedGroup());
188 }
189 }
190
191 Shape3D makeAlternateGeometry(Node node){
192 Shape3D retVal = new Shape3D();
193 List boxes = new ArrayList();
194 recursivelyCreateBBoxArray(node,boxes);
195
196 Shape3D dummy = new Shape3D();
197 Iterator iter = boxes.iterator();
198 Color3f color = new Color3f(1.0f, 1.0f, 1.0f);
199 while(iter.hasNext()){
200 GeometryUtility.createBoxGeometry((BoundingBox)iter.next(),dummy,color);
201 retVal.addGeometry(dummy.getGeometry());
202 }
203
204 return retVal;
205 }
206
207 private void recursivelyCreateBBoxArray(Node node, List boxList){
208 if(node instanceof Group){
209 Enumeration enum = null;
210 try {
211 enum = ((Group)node).getAllChildren();
212 }catch (CapabilityNotSetException cns){
213 System.out.println("Capability error at Node:"+((Group)node)+" :"+this.label);
214 cns.printStackTrace();
215 }
216 while (enum.hasMoreElements()){
217 recursivelyCreateBBoxArray((Node)enum.nextElement(),
218 boxList);
219 }
220 }
221 else if(node instanceof Shape3D){
222 BoundingBox bbox = new BoundingBox();
223 GeometryUtility.computeBoundingBox((Shape3D)node,bbox);
224 if(boxList==null) boxList = new ArrayList();
225 boxList.add(bbox);
226 }
227 }
228
229 /***
230 * Sets degradation mode, a resource to show a alternative geometry during transformations.
231 */
232 public void setDegradeMode(int mode){
233 // checks if mode is legal before setting
234 if(mode<this.numDegradeModes)
235 this.degradeMode = mode;
236 else this.degradeMode = VcContent.DEGRADE_NONE;
237 }
238
239 public int getDegradeMode(){
240 return this.degradeMode;
241 }
242
243
244 public void select(){
245 super.select();
246 /* commented out 19/03/2003 */
247 //transparencyAttributes.setTransparencyMode(TransparencyAttributes.FASTEST);
248 //transparencyAttributes.setTransparency(0.5f);
249 Iterator iter = appearances.iterator();
250 while(iter.hasNext()){
251 ((Appearance)iter.next()).setTransparencyAttributes(transparent);
252 }
253 //polygonAttributes.setPolygonMode(PolygonAttributes.POLYGON_LINE);
254 }
255
256 public void unselect(){
257 super.unselect();
258 /* commented out 19/03/2003 */
259 //transparencyAttributes.setTransparencyMode(TransparencyAttributes.NONE);
260 //transparencyAttributes.setTransparency(0.0f);
261 Iterator iter = appearances.iterator();
262 while(iter.hasNext()){
263 ((Appearance)iter.next()).setTransparencyAttributes(opaque);
264 }
265 //polygonAttributes.setPolygonMode(PolygonAttributes.POLYGON_FILL);
266 }
267
268
269 /***
270 * Used to indicate whether this object is undergoing a transformation or not,
271 * to display some visual cues (axis, boundingBoxes, etc)
272 */
273 public void setOngoingTransformation(boolean transforming){
274 if(transforming){
275 if(degradeMode!=VcContent.DEGRADE_NONE){
276 sGroup.setWhichChild(this.degradeMode);
277 }
278 }else{
279 // no degradation if object is not tranforming
280 sGroup.setWhichChild(VcContent.DEGRADE_NONE);
281 }
282 // sets new value of flag
283 this.transforming = transforming;
284 }
285
286 public boolean underOngoingTransformation(){
287 return false;
288 }
289
290 /***
291 * Returns the Icon associated with content objects.
292 */
293 public Icon getIcon(){
294 return this.contentIcon;
295 }
296
297 /***
298 * Sets the Icon associated with content objects.
299 */
300 public void setIcon(Icon contentIcon){
301 this.contentIcon= contentIcon;
302 }
303
304 /***
305 * Returns an array with all nodes contained.
306 */
307 public Node[] getContent(){
308 ArrayList list = new ArrayList();
309 //Enumeration enum = pivotTG.getAllChildren();
310 // We will only return the default representation and not
311 // the degraded ones
312 Enumeration enum = ((Group)sGroup.getChild(VcContent.DEGRADE_NONE)).getAllChildren();
313 while(enum.hasMoreElements()){
314 Object next = enum.nextElement();
315 if (next instanceof Node){
316 Node n = (Node)next;
317 list.add(n);
318 }
319 }
320 Node[] nodes = new Node[list.size()];
321 list.toArray(nodes);
322 return nodes;
323 }
324 }
This page was automatically generated by Maven