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

Quick Search    Search Deep

Source code: com/trapezium/chisel/mutators/IFS_Converter.java


1   /*
2    * @(#)IFS_Converter.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.mutators;
12  
13  import com.trapezium.chisel.*;
14  
15  import com.trapezium.vrml.node.Node;
16  import com.trapezium.vrml.VrmlElement;
17  import com.trapezium.vrml.fields.Field;
18  import com.trapezium.vrml.fields.FieldValue;
19  import com.trapezium.vrml.fields.MFFieldValue;
20  import com.trapezium.vrml.node.DEFUSENode;
21  
22  
23  /**
24   *  This base class chisel turns IndexedFaceSets into IndexedLineSets or PointSet
25   */
26  abstract public class IFS_Converter extends Optimizer {
27      /** single option, sets emissiveColor because otherwise ILS might
28       *  be invisible.
29       */
30      boolean setEmissiveColor;
31      
32      /** Preserve original as first in a LOD */
33      boolean preserveOriginalInLOD;
34      
35      /** range for level 0 */
36      int level0range;
37  
38      /** The Node type we are converting to -- either IndexedLineSet or PointSEt */
39      String convertTo;
40      
41      /** Constructor, only notify on IndexedFaceSets */
42    public IFS_Converter( String convertTo ) {
43      super( "IndexedFaceSet", "Converting IndexedFaceSet to " + convertTo );
44      setEmissiveColor = true;
45      this.convertTo = convertTo;
46      preserveOriginalInLOD = false;
47      level0range = 10;
48    }
49  
50      /** Always replace the entire containing Shape node */
51    public void attemptOptimization( Node n ) {
52        Node ifs = n;
53        n = n.getNodeParent();
54          if ( n instanceof DEFUSENode ) {
55              n = n.getNodeParent();
56          }
57        if ( n != null ) {
58            replaceRange( n.getFirstTokenOffset(), n.getLastTokenOffset(), n );
59        }
60    }
61  
62  
63      void preserveField( TokenPrinter tp, Node n, String fieldName ) {
64         Field f = n.getField( fieldName );
65         if ( f != null ) {
66            tp.printRange( f.getFirstTokenOffset(), f.getLastTokenOffset(), false );
67         }
68    }
69  
70    // RangeReplacer calls this when it has a range of tokens to replace
71    public void optimize( TokenPrinter tp, Object param, int startTokenOffset, int endTokenOffset ) {
72      if ( param instanceof Node ) {
73          Node shape = (Node)param;
74          
75          // if preserving original Shape in LOD 0, we rewrite it here
76          if ( preserveOriginalInLOD ) {
77              tp.print( "LOD { range [" );
78              tp.print( level0range );
79              tp.print( "]" );
80              tp.print( "level [" );
81              tp.flush();
82              tp.printRange( shape.getFirstTokenOffset(), shape.getLastTokenOffset(), false );
83          }
84          
85          Field f = shape.getField( "geometry" );
86          Node ifs = f.getNodeValue();
87          Field fa = shape.getField( "appearance" );
88          Node appearanceNode = null;
89          String appearanceDEFName = null;
90          Node materialNode = null;
91          String materialDEFName = null;
92          boolean preserveMaterial = false;
93  
94          // if we are preserving original in LOD, DEFs are preserved there
95          if (( fa != null ) && !preserveOriginalInLOD ) {
96              appearanceNode = fa.getNodeValue();
97              if ( appearanceNode != null ) {
98                  if ( appearanceNode.getParent() instanceof DEFUSENode ) {
99                      DEFUSENode appearanceDEF = (DEFUSENode)(appearanceNode.getParent());
100                     if ( appearanceDEF.isUsed() ) {
101                         appearanceDEFName = appearanceDEF.getDEFName();
102                         preserveMaterial = true;
103                     }
104                 }
105                 Field fm = appearanceNode.getField( "material" );
106                 if ( fm != null ) {
107                     materialNode = fm.getNodeValue();
108                     if ( materialNode != null ) {
109                         if ( materialNode.getParent() instanceof DEFUSENode ) {
110                             DEFUSENode materialDEF = (DEFUSENode)(materialNode.getParent());
111                             if ( materialDEF.isUsed() ) {
112                                 materialDEFName = materialDEF.getDEFName();
113                                 preserveMaterial = true;
114                             }
115                         }
116                     }
117                 }
118             }
119           }
120                 
121         tp.print( "Shape {" );
122         // if there is an appearance node DEFfed, preserve the DEF
123         tp.print( "appearance" );
124         if ( appearanceDEFName != null ) {
125             tp.print( "DEF" );
126             tp.print( appearanceDEFName );
127         }
128            tp.print( "Appearance {" );
129            if ( appearanceDEFName != null ) {
130                // if its DEFfed, preserve its texture & textureTransform fields
131                // since they may be used
132                preserveField( tp, appearanceNode, "texture" );
133                preserveField( tp, appearanceNode, "textureTransform" );
134              }
135              // now print the matierial field
136              tp.print( "material" );
137              if ( materialDEFName != null ) {
138                  tp.print( "DEF" );
139                  tp.print( materialDEFName );
140              }
141              tp.print( "Material {" );
142              if ( preserveMaterial ) {
143                  // if its DEFfed, preserve its fields
144                  preserveField( tp, materialNode, "ambientIntensity" );
145                  preserveField( tp, materialNode, "diffuseColor" );
146                  preserveField( tp, materialNode, "shininess" );
147                  preserveField( tp, materialNode, "specularColor" );
148                  preserveField( tp, materialNode, "transparency" );
149             }
150             tp.print( "emissiveColor" );
151 
152             boolean printedColor = false;
153         if ( setEmissiveColor ) {
154                 Field appearance = shape.getField( "appearance" );
155                 if ( appearance != null ) {
156                     appearanceNode = appearance.getNodeValue();
157                     if ( appearanceNode != null ) {
158                       Field material = appearanceNode.getField( "material" );
159                       if ( material != null ) {
160                           materialNode = material.getNodeValue();
161                           if ( materialNode != null ) {
162                               Field diffuseColor = materialNode.getField( "diffuseColor" );
163                               if ( diffuseColor != null ) {
164                                   tp.printRange( diffuseColor.getFirstTokenOffset() + 1, diffuseColor.getLastTokenOffset(), false );
165                                   printedColor = true;
166                               }
167                           }
168                       }
169                   }
170               }
171           }
172           if ( !printedColor ) {
173               tp.print( "1 1 1" );
174           }
175           tp.print( "} }" );
176           tp.flush();
177           tp.print( "geometry" );
178 
179         Field coord = ifs.getField( "coord" );
180         startTokenOffset = ifs.getFirstTokenOffset();
181         int coordStart = -1;
182         if ( coord != null ) {
183             coordStart = coord.getFirstTokenOffset();
184         }
185         Node coordNode = coord.getNodeValue();
186         boolean coordNodeIsUSE = false;
187         String coordDEFname = null;
188         if ( coordNode != null ) {
189             VrmlElement vn = coordNode.getParent();
190             if ( vn instanceof DEFUSENode ) {
191                 DEFUSENode dun = (DEFUSENode)vn;
192                 if ( !dun.isDEF() ) {
193                     coordDEFname = dun.getDEFName();
194                     coordNodeIsUSE = true;
195                 }
196             }
197           }
198         Field coordIndex = ifs.getField( "coordIndex" );
199         int coordIndexStart = -1;
200         if ( coordIndex != null ) {
201             coordIndexStart = coordIndex.getFirstTokenOffset();
202         }
203         Field color = ifs.getField( "color" );
204         int colorStart = -1;
205         if ( color != null ) {
206             colorStart = color.getFirstTokenOffset();
207         }
208         Field colorIndex = ifs.getField( "colorIndex" );
209         int colorIndexStart = -1;
210         if ( colorIndex != null ) {
211             colorIndexStart = colorIndex.getFirstTokenOffset();
212         }
213         Field colorPerVertex = ifs.getField( "colorPerVertex" );
214         int colorPerVertexStart = -1;
215         if ( colorPerVertex != null ) {
216             colorPerVertexStart = colorPerVertex.getFirstTokenOffset();
217         }
218         Field normal = ifs.getField( "normal" );
219         int normalStart = -1;
220         if ( normal != null ) {
221             normalStart = normal.getFirstTokenOffset();
222         }
223         Field normalIndex = ifs.getField( "normalIndex" );
224         int normalIndexStart = -1;
225         if ( normalIndex != null ) {
226             normalIndexStart = normalIndex.getFirstTokenOffset();
227         }
228         Field normalPerVertex = ifs.getField( "normalPerVertex" );
229         int normalPerVertexStart = -1;
230         if ( normalPerVertex != null ) {
231             normalPerVertexStart = normalPerVertex.getFirstTokenOffset();
232         }
233         int breakOffset = getBreakOffset( coordStart, coordIndexStart );
234         breakOffset = getBreakOffset( breakOffset, colorStart );
235         breakOffset = getBreakOffset( breakOffset, colorIndexStart );
236         breakOffset = getBreakOffset( breakOffset, normalStart );
237         breakOffset = getBreakOffset( breakOffset, normalIndexStart );
238         breakOffset = getBreakOffset( breakOffset, colorPerVertexStart );
239         breakOffset = getBreakOffset( breakOffset, normalPerVertexStart );
240         breakOffset--;
241         tp.print( convertTo );
242         printIFSrange( tp, startTokenOffset + 1, breakOffset, ifs );
243         if ( coordStart != -1 ) {
244             if ( coordNodeIsUSE ) {
245                 tp.print( "coord USE" );
246                 tp.print( coordDEFname );
247             } else {
248                     printIFSrange( tp, coordStart, coord.getLastTokenOffset(), ifs );
249                 }
250         }
251         if ( coordIndexStart != -1 ) {
252             printCoordIndex( tp, coordIndex );
253         }
254         convertColorInfo( ifs, tp, colorStart, color, colorPerVertexStart, colorPerVertex, colorIndexStart, colorIndex );
255         // end braces for PointSet/ILS and Shape
256         tp.print( "} }" );
257         if ( preserveOriginalInLOD ) {
258             tp.print( "] }" );
259         }
260     }
261   }
262   
263   /** Print a range of tokens from an IFS, but skip ccw, convex, creaseAngle and solid
264    *  fields.
265    */
266   int[] skipStart;
267   int[] skipEnd;
268   void printIFSrange( TokenPrinter tp, int start, int end, Node ifs ) {
269       Field ccw = ifs.getField( "ccw" );
270       Field convex = ifs.getField( "convex" );
271       Field creaseAngle = ifs.getField( "creaseAngle" );
272       Field solid = ifs.getField( "solid" );
273       if ( skipStart == null ) {
274           skipStart = new int[4];
275           skipEnd = new int[4];
276       }
277       for ( int i = 0; i < 4; i++ ) {
278           skipStart[i] = skipEnd[i] = -1;
279       }
280       if ( ccw != null ) {
281           skipStart[0] = ccw.getFirstTokenOffset();
282           skipEnd[0] = ccw.getLastTokenOffset();
283       }
284       if ( convex != null ) {
285           skipStart[1] = convex.getFirstTokenOffset();
286           skipEnd[1] = convex.getLastTokenOffset();
287       }
288       if ( creaseAngle != null ) {
289           skipStart[2] = creaseAngle.getFirstTokenOffset();
290           skipEnd[2] = creaseAngle.getLastTokenOffset();
291       }
292       if ( solid != null ) {
293           skipStart[3] = solid.getFirstTokenOffset();
294           skipEnd[3] = solid.getLastTokenOffset();
295       }
296       for ( int scanner = start; scanner <= end; scanner++ ) {
297           if ( okToPrint( scanner )) {
298               tp.print( dataSource, scanner );
299           }
300       }
301   }
302   
303   /** Check if the token is within the skipping range */
304   boolean okToPrint( int offset ) {
305       for ( int i = 0; i < 4; i++ ) {
306           if (( offset >= skipStart[i] ) && ( offset <= skipEnd[i] )) {
307               return( false );
308           }
309       }
310       return( true );
311   }
312 
313 
314     int getBreakOffset( int a, int b ) {
315         if ( a == -1 ) {
316             return( b );
317         } else if ( b == -1 ) {
318             return( a );
319         } else if ( a < b ) {
320             return( a );
321         } else {
322             return( b );
323         }
324     }
325 
326     abstract void printCoordIndex( TokenPrinter tp, Field coordIndex );
327     abstract void convertColorInfo( Node n, TokenPrinter tp, 
328         int colorStart, VrmlElement color,
329         int colorPerVertexStart, VrmlElement colorPerVertex,
330         int colorIndexStart, VrmlElement colorIndex );
331 
332     /** Option interface, allow set emissiveColor to diffuseColor option */
333     public int getNumberOptions() {
334         return( 3 );
335     }
336 
337     /** Get the class for an option */
338     public Class getOptionClass( int offset ) {
339         if ( offset < 2 ) {
340             return( Boolean.TYPE );
341         } else {
342             return( Integer.TYPE );
343         }
344     }
345 
346     public String getOptionLabel( int offset ) {
347         if ( offset == 0 ) {
348             return( "set emissiveColor to diffuseColor" );
349         } else if ( offset == 1 ) {
350             return( "preserve original IFS in LOD level 0" );
351         } else if ( offset == 2 ) {
352             return( "level 0 range" );
353         } else {
354             return( null );
355         }
356     }
357 
358     public Object getOptionValue( int offset ) {
359         if ( offset == 0 ) {
360             return( booleanToOptionValue( setEmissiveColor ));
361         } else if ( offset == 1 ) {
362             return( booleanToOptionValue( preserveOriginalInLOD ));
363         } else {
364             return( intToOptionValue( level0range ));
365         }
366     }
367 
368     public void setOptionValue( int offset, Object value ) {
369         if ( offset == 0 ) {
370             setEmissiveColor = optionValueToBoolean(value);
371         } else if ( offset == 1 ) {
372             preserveOriginalInLOD = optionValueToBoolean(value);
373         } else {
374             level0range = optionValueToInt(value);
375         }
376     }
377 }
378 
379