Docjar: A Java Source and Docuemnt Enginecom.*    java.*    javax.*    org.*    all    new    plug-in

Quick Search    Search Deep

Source code: com/trapezium/chisel/reorganizers/ShapeConnectivitySplitter.java


1   /*
2    * @(#)ShapeConnectivitySplitter.java
3    *
4    * Copyright (c) 1998 by Trapezium Development LLC.  All Rights Reserved.
5    *
6    * The information in this file is the property of Trapezium Development LLC
7    * and may be used only in accordance with the terms of the license granted
8    * by Trapezium.
9    *
10   */
11  package com.trapezium.chisel.reorganizers;
12  
13  import com.trapezium.chisel.*;
14  import com.trapezium.chisel.reducers.IFS_SpaceStructureLoader;
15  import com.trapezium.parse.TokenTypes;
16  import com.trapezium.vrml.VrmlElement;
17  import com.trapezium.vrml.Value;
18  import com.trapezium.vrml.node.Node;
19  import com.trapezium.vrml.node.DEFUSENode;
20  import com.trapezium.vrml.node.space.SpaceStructure;
21  import com.trapezium.vrml.node.space.SpacePrimitive;
22  import com.trapezium.vrml.node.space.SpaceEntitySet;
23  import com.trapezium.vrml.fields.Field;
24  import com.trapezium.vrml.fields.FieldValue;
25  import com.trapezium.vrml.fields.MFFieldValue;
26  import java.util.BitSet;
27  
28  /**
29   *  Splits IndexedFaceSets into connectivity sections, each in its
30   *  own IndexedFaceSet.
31   */
32  public class ShapeConnectivitySplitter extends IFS_SpaceStructureLoader {
33      SpaceStructure ss;
34      String[] skipFields;
35  
36    public ShapeConnectivitySplitter() {
37      super( "Splitting IndexedFaceSet by connectivity..." );
38      skipFields = new String[ 5 ];
39      skipFields[0] = "coordIndex";
40      skipFields[1] = "color";
41      skipFields[2] = "colorIndex";
42      skipFields[3] = "normal";
43      skipFields[4] = "normalIndex";
44    }
45  
46    class ConnectivityInfo {
47        Node shape;
48        Node ifs;
49        SpaceStructure ss;
50  
51        public ConnectivityInfo( Node shape, SpaceStructure ss, Node ifs ) {
52            this.shape = shape;
53            this.ss = ss;
54            this.ifs = ifs;
55        }
56  
57        public Node getShape() {
58            return( shape );
59        }
60  
61        public Node getIFS() {
62            return( ifs );
63        }
64  
65        public SpaceStructure getSpaceStructure() {
66            return( ss );
67        }
68    }
69  
70      public void setSpaceStructure( SpaceStructure ss ) {
71          this.ss = ss;
72      }
73  
74      /** This chisel taks the approach of just replacing entire Shape node.
75       *  This approach is a mistake, makes PROTO/IS handling nearly impossible.
76       *  Have to rewrite this to use field-by-field replacement technique.
77       */
78      public void attemptOptimization( Node n ) {
79          System.out.println( "ShapeConnectivitySplitter attemptOptimization" );
80          ss = null;
81          super.attemptOptimization( n );
82          if ( ss != null ) {
83              Node shape = n.getParent( "Shape" );
84              if ( shape != null ) {
85                  replaceRange( shape.getFirstTokenOffset(), shape.getLastTokenOffset(), new ConnectivityInfo( shape, ss, n ));
86              }
87          }
88      }
89  
90      
91    public void optimize( TokenPrinter tp, Object param, int startTokenOffset, int endTokenOffset ) {
92        System.out.println( "ShapeConnectivitySplitter optimizing" );
93          if ( param instanceof ConnectivityInfo ) {
94              ConnectivityInfo info = (ConnectivityInfo)param;
95              SpaceStructure ss = info.getSpaceStructure();
96              Node ifs = info.getIFS();
97              System.out.println( "marking connectivity" );
98              ss.markConnectivity();
99              int numberConnected = ss.numberConnectivity();
100             System.out.println( numberConnected + " connected" );
101             if ( numberConnected <= 1 ) {
102                 tp.printRange( startTokenOffset, endTokenOffset, false );
103             } else {
104                 initOffsets( ifs );
105                 for ( int i = 0; i < numberConnected; i++ ) {
106                     System.out.println( "Generating shape " + (i+1) + " of " + numberConnected );
107                     printHeader( tp, startTokenOffset, endTokenOffset );
108                     printSkippingFields( tp, ifs, skipFields );
109                     printCoordIndex( tp, ss, i );
110           printColorInfo( tp, ss, i, ifs );
111           printNormalInfo( tp, ss, i, ifs );
112                     printTrailer( tp, endTokenOffset );
113                 }
114             }
115         }
116     }
117     
118     /** Print up to first field in IFS */
119     int firstIFSfieldOffset;
120     int lastIFSfieldOffset;
121     String[] fieldNames;
122     void setFieldOffset( Field f ) {
123         if ( f != null ) {
124             int firstOffset = f.getFirstTokenOffset();
125             int lastOffset = f.getLastTokenOffset();
126             if ( firstOffset != -1 ) {
127                 if ( firstIFSfieldOffset == -1 ) {
128                     firstIFSfieldOffset = firstOffset;
129                 } else if ( firstOffset < firstIFSfieldOffset ) {
130                     firstIFSfieldOffset = firstOffset;
131                 }
132             }
133             if ( lastOffset != -1 ) {
134                 if ( lastIFSfieldOffset == -1 ) {
135                     lastIFSfieldOffset = lastOffset;
136                 } else if ( lastOffset > lastIFSfieldOffset ) {
137                     lastIFSfieldOffset = lastOffset;
138                 }
139             }
140         }
141     }
142  
143     void initOffsets( Node ifs ) {
144         firstIFSfieldOffset = -1;
145         lastIFSfieldOffset = -1;
146         if ( fieldNames == null ) {
147             fieldNames = ifs.getFieldNames();
148         }
149         for ( int i = 0; i < fieldNames.length; i++ ) {
150             setFieldOffset( ifs.getField( fieldNames[i] ));
151         }
152     }
153      
154     void printHeader( TokenPrinter tp, int startTokenOffset, int endTokenOffset ) {
155         printRange( tp, startTokenOffset, firstIFSfieldOffset, endTokenOffset );
156     }
157     
158     void printTrailer( TokenPrinter tp, int endTokenOffset ) {
159         printRange( tp, lastIFSfieldOffset + 1, endTokenOffset + 1, endTokenOffset );
160     }
161     
162     void printRange( TokenPrinter tp, int firstInRange, int lastInRange, int tokenBoundary ) {
163         int scanner = firstInRange;
164         dataSource.setState( scanner );
165         while ( scanner != -1 ) {
166             if ( scanner > tokenBoundary ) {
167                 break;
168             }
169             tp.print( dataSource, scanner );
170             scanner = dataSource.getNextToken();
171             if ( scanner >= lastInRange ) {
172                 break;
173             }
174         }
175     }
176             
177   /** Print color info for a specific connectivity section */
178   void printColorInfo( TokenPrinter tp, SpaceStructure ss, int offset, Node ifs ) {
179     Field color = ifs.getField( "color" );
180     Field colorIndex = ifs.getField( "colorIndex" );
181     boolean colorPerVertex = ifs.getBoolValue( "colorPerVertex" );
182     if ( colorPerVertex ) {
183         if ( color != null ) {
184             tp.printRange( color.getFirstTokenOffset(), color.getLastTokenOffset(), false );
185         }
186         if ( colorIndex != null ) {
187             tp.printRange( colorIndex.getFirstTokenOffset(), colorIndex.getLastTokenOffset(), false );
188         }
189     } else {
190       if ( colorIndex == null ) {
191         if ( color != null ) {
192           printValues( tp, ss, offset, color.getFirstTokenOffset(),
193             color.getLastTokenOffset(), 3 );
194         }
195       } else {
196         printValues( tp, ss, offset, colorIndex.getFirstTokenOffset(),
197           colorIndex.getLastTokenOffset(), 1 );
198       }
199     }
200   }
201 
202   /** Print normal info for a specific connectivity section */
203   void printNormalInfo( TokenPrinter tp, SpaceStructure ss, int offset, Node ifs ) {
204     Field normal = ifs.getField( "normal" );
205     Field normalIndex = ifs.getField( "normalIndex" );
206     boolean normalPerVertex = ifs.getBoolValue( "normalPerVertex" );
207     if ( !normalPerVertex ) {
208       if ( normalIndex == null ) {
209         if ( normal != null ) {
210           printValues( tp, ss, offset, normal.getFirstTokenOffset(),
211             normal.getLastTokenOffset(), 3 );
212         }
213       } else {
214         printValues( tp, ss, offset, normalIndex.getFirstTokenOffset(),            normalIndex.getLastTokenOffset(), 1 );
215       }
216     }
217   }
218 
219   void printValues( TokenPrinter tp, SpaceStructure ss, int offset, 
220     int scanner, int endTokenOffset, int factor ) {
221     dataSource.setState( scanner );
222     while ( true ) {
223         int type = dataSource.getType( scanner );
224       tp.print( dataSource, scanner, type );
225       if ( type == TokenTypes.LeftBracket ) {
226         scanner = dataSource.getNextToken();
227         break;
228       }
229       scanner = dataSource.getNextToken();
230     }
231         SpaceEntitySet faces = ss.getEntitySet( SpacePrimitive.Face );
232         int numberFaces = faces.getNumberEntities();
233         for ( int i = 0; i < numberFaces; i++ ) {
234             if ( ss.getConnectivity( i ) == offset ) {
235         for ( int j = 0; j < factor; j++ ) {
236           scanner = dataSource.skipNonNumbers();
237           tp.print( dataSource, scanner, TokenTypes.NumberToken );
238           scanner = dataSource.getNextToken();
239         }
240       } else {
241         for ( int j = 0; j < factor; j++ ) {
242           scanner = dataSource.skipNonNumbers();
243           scanner = dataSource.getNextToken();
244         }
245       }
246     }
247     while ( true ) {
248       tp.print( dataSource, scanner );
249       if ( scanner == endTokenOffset ) {
250         break;
251       }
252       scanner = dataSource.getNextToken();
253     }
254   }
255 
256     void printCoordIndex( TokenPrinter tp, SpaceStructure ss, int offset ) {
257         tp.print( "coordIndex [" );
258         SpaceEntitySet faces = ss.getEntitySet( SpacePrimitive.Face );
259         int numberFaces = faces.getNumberEntities();
260         for ( int i = 0; i < numberFaces; i++ ) {
261             if ( ss.getConnectivity( i ) == offset ) {
262                 printFace( tp, ss, faces, faces.getEntity( i ));
263             }
264         }
265         tp.print( "]" );
266     }
267     
268     void printFace( TokenPrinter tp, SpaceStructure ss, SpaceEntitySet faces, SpacePrimitive face ) {
269         int numberVertices = faces.getCount( face, SpacePrimitive.Vertex );
270         for ( int i = 0; i < numberVertices; i++ ) {
271             tp.print( faces.getValue( face, SpacePrimitive.Vertex, i ));
272         }
273         tp.print( -1 );
274     }
275     
276     void printSkippingFields( TokenPrinter tp, Node ifs, String[] fieldList ) {
277         int[] startFieldOffset = new int[fieldList.length];
278         int[] endFieldOffset = new int[fieldList.length];
279         int scanner = firstIFSfieldOffset;
280         int end = lastIFSfieldOffset+1;
281         dataSource.setState( scanner );
282         if ( end > scanner ) {
283             int range = end - scanner;
284             BitSet unprintable = new BitSet( range );
285             for ( int i = 0; i < fieldList.length; i++ ) {
286                 Field f = ifs.getField( fieldList[i] );
287                 if ( f != null ) {
288                     int firstInRange = f.getFirstTokenOffset() - scanner;
289                     int lastInRange = f.getLastTokenOffset() - scanner;
290                     if (( firstInRange >= 0 ) && ( firstInRange < range ) &&
291                         ( lastInRange >= 0 ) && ( lastInRange < range ) &&
292                         ( lastInRange >= firstInRange )) {
293                         for ( int j = firstInRange; j <= lastInRange; j++ ) {
294                             unprintable.set( j );
295                         }
296                     }
297                 }
298             }
299             while ( scanner < end ) {
300                 if ( unprintable.get( scanner - firstIFSfieldOffset )) {
301                     scanner = dataSource.getNextToken();
302                     continue;
303                 }
304                 tp.print( dataSource, scanner );
305                 scanner = dataSource.getNextToken();
306             }
307         }
308     }
309             
310         
311 
312     public void replaceCoord( TokenPrinter tp, SpaceStructure ss, int startTokenOffset, int endTokenOffset ) {
313     }
314 
315     public void replaceCoordIndex( TokenPrinter tp, SpaceStructure ss, int startTokenOffset, int endTokenOffset ) {
316     }
317 
318     public void replaceTexCoordIndex( TokenPrinter tp, SpaceStructure ss, int startTokenOffset, int endTokenOffset ) {
319     }
320 }
321 
322