001: /*
002: * $RCSfile: TreeScan.java,v $
003: *
004: * Copyright (c) 2007 Sun Microsystems, Inc. All rights reserved.
005: *
006: * Redistribution and use in source and binary forms, with or without
007: * modification, are permitted provided that the following conditions
008: * are met:
009: *
010: * - Redistribution of source code must retain the above copyright
011: * notice, this list of conditions and the following disclaimer.
012: *
013: * - Redistribution in binary form must reproduce the above copyright
014: * notice, this list of conditions and the following disclaimer in
015: * the documentation and/or other materials provided with the
016: * distribution.
017: *
018: * Neither the name of Sun Microsystems, Inc. or the names of
019: * contributors may be used to endorse or promote products derived
020: * from this software without specific prior written permission.
021: *
022: * This software is provided "AS IS," without a warranty of any
023: * kind. ALL EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND
024: * WARRANTIES, INCLUDING ANY IMPLIED WARRANTY OF MERCHANTABILITY,
025: * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT, ARE HEREBY
026: * EXCLUDED. SUN MICROSYSTEMS, INC. ("SUN") AND ITS LICENSORS SHALL
027: * NOT BE LIABLE FOR ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF
028: * USING, MODIFYING OR DISTRIBUTING THIS SOFTWARE OR ITS
029: * DERIVATIVES. IN NO EVENT WILL SUN OR ITS LICENSORS BE LIABLE FOR
030: * ANY LOST REVENUE, PROFIT OR DATA, OR FOR DIRECT, INDIRECT, SPECIAL,
031: * CONSEQUENTIAL, INCIDENTAL OR PUNITIVE DAMAGES, HOWEVER CAUSED AND
032: * REGARDLESS OF THE THEORY OF LIABILITY, ARISING OUT OF THE USE OF OR
033: * INABILITY TO USE THIS SOFTWARE, EVEN IF SUN HAS BEEN ADVISED OF THE
034: * POSSIBILITY OF SUCH DAMAGES.
035: *
036: * You acknowledge that this software is not designed, licensed or
037: * intended for use in the design, construction, operation or
038: * maintenance of any nuclear facility.
039: *
040: * $Revision: 1.3 $
041: * $Date: 2007/02/09 17:17:03 $
042: * $State: Exp $
043: */
044:
045: package org.jdesktop.j3d.utils.scenegraph.traverser;
046:
047: import java.util.Enumeration;
048: import java.util.HashSet;
049: import java.util.BitSet;
050:
051: import javax.media.j3d.Group;
052: import javax.media.j3d.SharedGroup;
053: import javax.media.j3d.Node;
054: import javax.media.j3d.Link;
055: import javax.media.j3d.Switch;
056:
057: public class TreeScan extends Object {
058:
059: private static HashSet visitedSharedGroups = null;
060:
061: /** Traverse the SceneGraph starting at node treeRoot. Every time a node of
062: * class nodeClass is found call processNode method in processor.
063: * @param treeRoot The root of the SceneGraph to search
064: * @param nodeClass The class of the node(s) to search for
065: * @param processor The class containing the processNode method which will be
066: * called every time the correct nodeClass is found in the Scene Graph.
067: * @param onlyEnabledSwitchChildren when true only recurse into Switch
068: * children which are enabled
069: * @param sharedGroupsOnce when true only process SharedGroups once,
070: * regardless how many Links refer to them
071: * @throws CapabilityNotSetException If the node is live or compiled and the scene graph
072: * contains groups without ALLOW_CHILDREN_READ capability
073: */
074: public static void findNode(javax.media.j3d.Node treeRoot,
075: Class nodeClass, ProcessNodeInterface processor,
076: boolean onlyEnabledSwitchChildren, boolean sharedGroupsOnce)
077: throws javax.media.j3d.CapabilityNotSetException {
078:
079: Class[] nodeClasses = new Class[] { nodeClass };
080:
081: findNode(treeRoot, nodeClasses, processor,
082: onlyEnabledSwitchChildren, sharedGroupsOnce);
083:
084: }
085:
086: /** Traverse the SceneGraph starting at node treeRoot. Every time a node of
087: * class nodeClass is found call processNode method in processor.
088: * @param treeRoot The root of the SceneGraph to search
089: * @param nodeClasses The list of classes of the node(s) to search for
090: * @param processor The class containing the processNode method which will be
091: * called every time the correct nodeClass is found in the Scene Graph.
092: * @param onlyEnabledSwitchChildren when true only recurse into Switch
093: * children which are enabled
094: * @param sharedGroupsOnce when true only process SharedGroups once,
095: * regardless how many Links refer to them
096: * @throws CapabilityNotSetException If the node is live or compiled and the scene graph
097: * contains groups without ALLOW_CHILDREN_READ capability
098: */
099: public static void findNode(javax.media.j3d.Node treeRoot,
100: Class[] nodeClasses, ProcessNodeInterface processor,
101: boolean onlyEnabledSwitchChildren, boolean sharedGroupsOnce)
102: throws javax.media.j3d.CapabilityNotSetException {
103: if (sharedGroupsOnce)
104: if (visitedSharedGroups == null)
105: visitedSharedGroups = new HashSet();
106:
107: actualFindNode(treeRoot, nodeClasses, processor,
108: onlyEnabledSwitchChildren, sharedGroupsOnce);
109:
110: if (sharedGroupsOnce)
111: visitedSharedGroups.clear();
112: }
113:
114: /**
115: * Conveniance method to return a Class given the full Class name
116: * without throwing ClassNotFoundException
117: *
118: * If the class is not available an error message is displayed and a
119: * runtime exception thrown
120: */
121: public static Class getClass(String str) {
122: try {
123: return Class.forName(str);
124: } catch (ClassNotFoundException e) {
125: e.printStackTrace();
126: throw new RuntimeException("BAD CLASS " + str);
127: }
128: }
129:
130: private static void actualFindNode(Node treeRoot,
131: Class[] nodeClasses, ProcessNodeInterface processor,
132: boolean onlyEnabledSwitchChildren, boolean sharedGroupsOnce)
133: throws javax.media.j3d.CapabilityNotSetException {
134: boolean doChildren = true;
135:
136: if (treeRoot == null)
137: return;
138:
139: //System.out.print( treeRoot.getClass().getName()+" ");
140: //System.out.print( nodeClasses[0].getName()+" ");
141: //System.out.println( nodeClasses[0].isAssignableFrom( treeRoot.getClass() ));
142: for (int i = 0; i < nodeClasses.length; i++)
143: if (nodeClasses[i].isAssignableFrom(treeRoot.getClass())) {
144: doChildren = processor.processNode(treeRoot);
145: i = nodeClasses.length;
146: }
147:
148: if (!doChildren)
149: return;
150:
151: if (onlyEnabledSwitchChildren && treeRoot instanceof Switch) {
152: int whichChild = ((Switch) treeRoot).getWhichChild();
153:
154: if (whichChild == Switch.CHILD_ALL) {
155: Enumeration e = ((Group) treeRoot).getAllChildren();
156: while (e.hasMoreElements())
157: actualFindNode((Node) e.nextElement(), nodeClasses,
158: processor, onlyEnabledSwitchChildren,
159: sharedGroupsOnce);
160: } else if (whichChild == Switch.CHILD_MASK) {
161: BitSet set = ((Switch) treeRoot).getChildMask();
162: for (int s = 0; s < set.length(); s++) {
163: if (set.get(s))
164: actualFindNode(((Switch) treeRoot).getChild(s),
165: nodeClasses, processor,
166: onlyEnabledSwitchChildren,
167: sharedGroupsOnce);
168: }
169: } else if (whichChild == Switch.CHILD_NONE) {
170: // DO nothing
171: } else
172: actualFindNode(((Switch) treeRoot).currentChild(),
173: nodeClasses, processor,
174: onlyEnabledSwitchChildren, sharedGroupsOnce);
175: } else if (treeRoot instanceof Group) {
176: Enumeration e = ((Group) treeRoot).getAllChildren();
177: while (e != null && e.hasMoreElements())
178: actualFindNode((Node) e.nextElement(), nodeClasses,
179: processor, onlyEnabledSwitchChildren,
180: sharedGroupsOnce);
181: }
182: }
183: // private static void actualFindNode( javax.media.j3d.Node treeRoot,
184: // Class[] nodeClasses,
185: // ProcessNodeInterface processor,
186: // boolean onlyEnabledSwitchChildren,
187: // boolean sharedGroupsOnce ) throws
188: // javax.media.j3d.CapabilityNotSetException {
189: //
190: // //if (onlyEnabledSwitchChildren)
191: // // throw new RuntimeException( "OnlyEnabledSwitchChildren not implemented");
192: //
193: //// System.out.print(treeRoot+" ");
194: //// if (treeRoot.getUserData()!=null && treeRoot.getUserData() instanceof org.jdesktop.lg.sg.internal.wrapper.SceneGraphObjectWrapper)
195: //// System.out.println(treeRoot.getUserData());
196: //// else
197: //// System.out.println();
198: //
199: // if (treeRoot == null)
200: // return;
201: //
202: // if (treeRoot instanceof SharedGroup && sharedGroupsOnce) {
203: // if (visitedSharedGroups.contains( treeRoot ))
204: // return;
205: // else
206: // visitedSharedGroups.add( treeRoot );
207: // }
208: //
209: // //System.out.print( treeRoot.getClass().getName()+" ");
210: // //System.out.print( nodeClasses[0].getName()+" ");
211: // //System.out.println( nodeClasses[0].isAssignableFrom( treeRoot.getClass() ));
212: // for(int i=0; i<nodeClasses.length; i++)
213: // if (nodeClasses[i].isAssignableFrom( treeRoot.getClass() ))
214: // processor.processNode( treeRoot );
215: //
216: // if (onlyEnabledSwitchChildren && treeRoot instanceof Switch ) {
217: // int whichChild = ((Switch)treeRoot).getWhichChild();
218: //
219: // if (whichChild==Switch.CHILD_ALL) {
220: // Enumeration e = ((Group)treeRoot).getAllChildren();
221: // while( e.hasMoreElements() )
222: // actualFindNode( (Node)e.nextElement(), nodeClasses, processor,
223: // onlyEnabledSwitchChildren, sharedGroupsOnce );
224: // } else if (whichChild==Switch.CHILD_MASK) {
225: // BitSet set = ((Switch)treeRoot).getChildMask();
226: // for(int s=0; s<set.length(); s++) {
227: // if (set.get(s))
228: // actualFindNode( ((Switch)treeRoot).getChild(s), nodeClasses,
229: // processor, onlyEnabledSwitchChildren, sharedGroupsOnce );
230: // }
231: // } else if (whichChild==Switch.CHILD_NONE) {
232: // // DO nothing
233: // } else
234: // actualFindNode( ((Switch)treeRoot).currentChild(), nodeClasses,
235: // processor, onlyEnabledSwitchChildren, sharedGroupsOnce );
236: // } else if (treeRoot instanceof Group) {
237: // Enumeration e = ((Group)treeRoot).getAllChildren();
238: // while( e!=null && e.hasMoreElements() )
239: // actualFindNode( (Node)e.nextElement(), nodeClasses, processor,
240: // onlyEnabledSwitchChildren, sharedGroupsOnce );
241: // } else if (treeRoot instanceof Link) {
242: // actualFindNode( ((Link)treeRoot).getSharedGroup(), nodeClasses, processor,
243: // onlyEnabledSwitchChildren, sharedGroupsOnce );
244: // }
245: // }
246: }
|