Source code: com/trapezium/chisel/mutators/IFS_Smasher.java
1 package com.trapezium.chisel.mutators;
2
3 import com.trapezium.chisel.*;
4
5 import com.trapezium.vrml.node.space.SpaceStructure;
6 import com.trapezium.vrml.node.space.SpaceEntitySet;
7 import com.trapezium.vrml.node.space.SpacePrimitive;
8 import com.trapezium.parse.TokenTypes;
9
10 public class IFS_Smasher extends Origami {
11 boolean smashOnX;
12 boolean smashOnY;
13 boolean smashOnZ;
14 public IFS_Smasher() {
15 super();
16 dx = 1;
17 dy = 1;
18 dz = 1;
19 smashOnX = false;
20 smashOnY = false;
21 smashOnZ = true;
22 }
23
24 boolean smashedOnX;
25 boolean smashedOnY;
26 boolean smashedOnZ;
27 int callCount;
28
29 /** Replace the entire set of coordinates once for each smash plane.
30 * NOTE: this increases the number of coordinates, so if there are
31 * any other fields that are supposed to correspond one-for-one with
32 * the coordinates, these must get repeated as well (not implemented)
33 *
34 * @param tp TokenPrinter to print to
35 * @param ss the SpaceStructure containing the locatinos
36 * @param startTokenOffset first token in range to replace
37 * @param lastTokenOffset last token in range to replace
38 */
39 public void replaceCoord( TokenPrinter tp, SpaceStructure ss, int startTokenOffset, int endTokenOffset ) {
40 callCount = 0;
41 if ( smashOnX ) callCount++;
42 if ( smashOnY ) callCount++;
43 if ( smashOnZ ) callCount++;
44 smashedOnX = smashOnX;
45 smashedOnY = smashOnY;
46 smashedOnZ = smashOnZ;
47
48 for ( int i = 0; i < callCount; i++ ) {
49 super.replaceCoord( tp, ss, startTokenOffset, endTokenOffset, (i == 0 ), (i==(callCount-1)) );
50 if ( smashedOnX ) {
51 smashedOnX = false;
52 } else if ( smashedOnY ) {
53 smashedOnY = false;
54 } else if ( smashedOnZ ) {
55 smashedOnZ = false;
56 }
57 }
58 }
59
60 public void printCoords( TokenPrinter tp, SpaceEntitySet mc, SpacePrimitive sp ) {
61 if ( smashedOnX ) {
62 tp.print( (float)mc.getX() );
63 tp.print( (float)sp.getY() );
64 tp.print( (float)sp.getZ() );
65 } else {
66 tp.print( (float)sp.getX() );
67 if ( smashedOnY ) {
68 tp.print( (float)mc.getY() );
69 tp.print( (float)sp.getZ() );
70 } else {
71 tp.print( (float)sp.getY() );
72 if ( smashedOnZ ) {
73 tp.print( (float)mc.getZ() );
74 } else {
75 tp.print( (float)sp.getZ() );
76 }
77 }
78 }
79 }
80
81 /** Replace the coordIndex values.
82 * NOTE: this may create multiple sets of faces, any other fields which
83 * correspond one-per-face must also be generated multiple times.
84 */
85 public void replaceCoordIndex( TokenPrinter tp, SpaceStructure ss, int startTokenOffset, int endTokenOffset ) {
86 for ( int i = 0; i < callCount; i++ ) {
87 replaceCoordIndex( i*numberVertices, tp, startTokenOffset, endTokenOffset, (i==0), (i==(callCount-1)) );
88 }
89 }
90
91 /** Replace the colorIndex values.
92 * NOTE: the colorIndex may be one per face, so is generated multiple
93 * times.
94 */
95 public void replaceColorIndex( TokenPrinter tp, SpaceStructure ss, int startTokenOffset, int endTokenOffset ) {
96 for ( int i = 0; i < callCount; i++ ) {
97 replaceColors( tp, startTokenOffset, endTokenOffset, (i == 0 ), (i == (callCount-1)));
98 }
99 }
100
101 public void replaceColor( TokenPrinter tp, SpaceStructure ss, int startTokenOffset, int endTokenOffset ) {
102 for ( int i = 0; i < callCount; i++ ) {
103 replaceColors( tp, startTokenOffset, endTokenOffset, (i == 0 ), (i == (callCount-1)));
104 }
105 }
106
107 public void replaceColors( TokenPrinter tp, int startTokenOffset, int endTokenOffset, boolean printStart, boolean printEnd ) {
108 int scanner = startTokenOffset;
109 dataSource.setState( scanner );
110 while ( true ) {
111 int type = dataSource.getType( scanner );
112 if ( printStart ) {
113 tp.print( dataSource, scanner, type );
114 }
115 if ( type == TokenTypes.LeftBracket ) {
116 scanner = dataSource.getNextToken();
117 break;
118 }
119 scanner = dataSource.getNextToken();
120 }
121 while ( true ) {
122 int type = dataSource.getType( scanner );
123 if ( type == TokenTypes.RightBracket ) {
124 break;
125 }
126 tp.print( dataSource, scanner, type );
127 scanner = dataSource.getNextToken();
128 }
129 while ( true ) {
130 if ( printEnd ) {
131 tp.print( dataSource, scanner );
132 }
133 if ( scanner == endTokenOffset ) {
134 break;
135 }
136 scanner = dataSource.getNextToken();
137 }
138 }
139
140 int firstNumberOffset;
141 void replaceCoordIndex( int offset, TokenPrinter tp, int startTokenOffset, int endTokenOffset, boolean printStart, boolean printEnd ) {
142 int scanner;
143 if ( printStart ) {
144 scanner = startTokenOffset;
145 dataSource.setState( scanner );
146 while ( true ) {
147 int type = dataSource.getType( scanner );
148 tp.print( dataSource, scanner, type );
149 if ( type == TokenTypes.LeftBracket ) {
150 break;
151 }
152 scanner = dataSource.getNextToken();
153 }
154 scanner = firstNumberOffset = dataSource.getNextToken();
155 } else {
156 scanner = firstNumberOffset;
157 dataSource.setState( scanner );
158 }
159 // print the numbers, with possible offset
160 while ( true ) {
161 int type = dataSource.getType( scanner );
162 if ( type == TokenTypes.RightBracket ) {
163 break;
164 } else if ( type == TokenTypes.NumberToken ) {
165 int value = dataSource.getIntValue( scanner );
166 if ( value != -1 ) {
167 value += offset;
168 }
169 tp.print( value );
170 } else {
171 tp.print( dataSource, scanner, type );
172 }
173 scanner = dataSource.getNextToken();
174 }
175 if ( printEnd ) {
176 tp.print( dataSource, scanner );
177 }
178 }
179
180 /** Get the class for an option */
181 public Class getOptionClass( int offset ) {
182 return( Boolean.TYPE );
183 }
184
185 public String getOptionLabel( int offset ) {
186 switch (offset) {
187 case DX:
188 return( "smash on X plane" );
189 case DY:
190 return( "smash on Y plane" );
191 case DZ:
192 return( "smash on Z plane" );
193 }
194 return null;
195 }
196
197 public Object getOptionValue( int offset ) {
198 switch (offset) {
199 case DX:
200 return( booleanToOptionValue(smashOnX) );
201 case DY:
202 return( booleanToOptionValue(smashOnY) );
203 case DZ:
204 return( booleanToOptionValue(smashOnZ) );
205 }
206 return "";
207 }
208
209 public void setOptionValue( int offset, Object value ) {
210 switch (offset) {
211 case DX:
212 smashOnX = optionValueToBoolean(value);
213 break;
214 case DY:
215 smashOnY = optionValueToBoolean(value);
216 break;
217 case DZ:
218 smashOnZ = optionValueToBoolean(value);
219 break;
220 }
221 }
222 }