001:
002:
003:
004:
005:
006:
007:
008:
009:
010:
011:
012:
013:
014:
015:
016:
017:
018:
019:
020:
021:
022:
023:
024: #include <string.h>
025: #include <fstream.h>
026: #include "Piece.h"
027: #include "InventorWriter.h"
028:
029:
030: long long Piece::mask = (1ll << PC_X_DIM) - 1ll;
031:
032: Piece::Piece(int inId, int (*dimensions)[3], bool (*description)[PC_Z_DIM][PC_Y_DIM][PC_X_DIM],
033: bool skipSymmetry, bool specialSymmetry) : numPositions(0), numRotations(1)
034: {
035: _bbox = dimensions;
036: _cubes = description;
037:
038: id = inId;
039:
040: piece = 0;
041:
042: for (int i=0; i<GC_X_DIM; i++)
043: for (int j=0; j<GC_Y_DIM; j++)
044: for (int k=0; k<GC_Z_DIM; k++) {
045: if(i>=(*_bbox)[2] || j>=(*_bbox)[1] || k>=(*_bbox)[0]) continue;
046: if((*_cubes)[i][j][k])
047: piece |= ((1ll << ((k * GC_Y_DIM + j) * GC_X_DIM)) << i);
048: }
049:
050: int tmp = (*_bbox)[0];
051: (*_bbox)[0] = (*_bbox)[2];
052: (*_bbox)[2] = tmp;
053:
054: rotations[0] = piece;
055: rotatedBBoxes = new int*[MAX_NUM_ROT];
056: rotatedBBoxes[0] = *dimensions;
057:
058: buildRotations();
059: buildPositions(skipSymmetry, specialSymmetry);
060:
061: for (int i=0; i<GC_X_DIM*GC_Y_DIM*GC_Z_DIM; i++)
062: occupiedCoordsIndex[i] = 0;
063: buildOuccupanceInfo();
064:
065: }
066:
067:
068: long long Piece::addRotation(long long rotatedPiece, int* rotatedBBox)
069: {
070: int i;
071: for (i=0; i< numRotations; i++)
072: if (rotations[i] == rotatedPiece) break;
073:
074: if(i==numRotations) {
075: rotations[i] = rotatedPiece;
076: rotatedBBoxes[i] = rotatedBBox;
077: numRotations++;
078: }
079:
080: return rotatedPiece;
081: }
082:
083:
084: void Piece::buildRotations()
085: {
086: long long current = piece;
087:
088: for(int i=1; i<4; i++) {
089: int *tmpXBBox = new int[3];
090:
091: tmpXBBox[0] = (*_bbox)[0];
092: tmpXBBox[1] = (*_bbox)[2];
093: tmpXBBox[2] = (*_bbox)[1];
094:
095: if((i%2 && tmpXBBox[1]>GC_Y_DIM) || (i%2 && tmpXBBox[2]>GC_Z_DIM)) continue;
096: addRotation(Puzzle::rotate(current, i, 0, 0, *_bbox, mask), (i % 2 ? tmpXBBox : *_bbox));
097: }
098:
099: int nr = numRotations;
100: for(int i=0; i<nr; i++) {
101: int *tmpYBBox = new int[3];
102: tmpYBBox[0] = rotatedBBoxes[i][2];
103: tmpYBBox[1] = rotatedBBoxes[i][1];
104: tmpYBBox[2] = rotatedBBoxes[i][0];
105:
106: for(int j=1; j<4; j++) {
107: if((j%2 && tmpYBBox[0]>GC_X_DIM) || (j%2 && tmpYBBox[2]>GC_Z_DIM)) continue;
108: addRotation(Puzzle::rotate(rotations[i], 0, j, 0, rotatedBBoxes[i], mask),
109: (j % 2 ? tmpYBBox : rotatedBBoxes[i]));
110: }
111: }
112:
113: nr = numRotations;
114: for(int i=0; i<nr; i++) {
115: int *tmpZBBox = new int[3];
116: tmpZBBox[0] = rotatedBBoxes[i][1];
117: tmpZBBox[1] = rotatedBBoxes[i][0];
118: tmpZBBox[2] = rotatedBBoxes[i][2];
119:
120: for(int j=1; j<4; j++) {
121: if((j%2 && tmpZBBox[0]>GC_X_DIM) || (j%2 && tmpZBBox[1]>GC_Y_DIM)) continue;
122: addRotation(Puzzle::rotate(rotations[i], 0, 0, j, rotatedBBoxes[i], mask),
123: (j % 2 ? tmpZBBox : rotatedBBoxes[i]));
124: }
125: }
126:
127: }
128:
129: long long Piece::mirror(long long piece, bool xAxis, bool yAxis, bool zAxis)
130: {
131: long long result = 0;
132: long long mask = 0;
133:
134: for(int i=0; i<GC_Z_DIM; i++)
135: for(int j=0; j<GC_Y_DIM; j++) {
136: mask = ((long long) 1) << ((i*GC_Y_DIM + j) * GC_X_DIM);
137: for(int k=0; k<GC_X_DIM; k++, mask <<= 1)
138: if(piece & mask) {
139: result |= ((((long long) 1) <<
140: (xAxis ? GC_X_DIM-1-k : k)) <<
141: (((zAxis ? GC_Z_DIM-1-i : i)*GC_Y_DIM +
142: (yAxis ? GC_Y_DIM-1-j : j)) * GC_X_DIM));
143: }
144: }
145:
146: return result;
147: }
148:
149:
150: void Piece::buildPositions(bool skipSymmetry, bool specialSymmetry)
151: {
152:
153: if(!specialSymmetry)
154: for(int l=0; l < GC_Z_DIM; l++)
155: for(int k=0; k < GC_Y_DIM; k++) {
156: int trY = (l*GC_Y_DIM + k) * GC_X_DIM;
157: for(int j=0; j < GC_X_DIM; j++)
158: for(int i=0; i< numRotations; i++) {
159: if (j > GC_X_DIM - rotatedBBoxes[i][0] ||
160: k > GC_Y_DIM - rotatedBBoxes[i][1] ||
161: l > GC_Z_DIM - rotatedBBoxes[i][2]) continue;
162: long long nextPiece = ((rotations[i] <<j) << trY);
163: if(skipSymmetry) {
164: bool found = false;
165: for(int pos=0; pos < numPositions; pos++)
166: if(positions[pos] == mirror(nextPiece, true, true, false) ||
167: positions[pos] == mirror(nextPiece, true, false, true) ||
168: positions[pos] == mirror(nextPiece, false, true, true) ||
169: positions[pos] == nextPiece)
170: found = true;
171: if(found) continue;
172: }
173: positions[numPositions] = nextPiece;
174: positionRotation[numPositions] = i;
175: numPositions++;
176: }
177: }
178:
179: else
180: for(int l=GC_Z_DIM-1; l>=0; l--)
181: for(int k=GC_Y_DIM-1; k>=0; k--) {
182: int trY = (l*GC_Y_DIM + k) * GC_X_DIM;
183: for(int j=GC_X_DIM-1; j>=0; j--)
184: for(int i=0; i< numRotations; i++) {
185: if (j > GC_X_DIM - rotatedBBoxes[i][0] ||
186: k > GC_Y_DIM - rotatedBBoxes[i][1] ||
187: l > GC_Z_DIM - rotatedBBoxes[i][2]) continue;
188: long long nextPiece = ((rotations[i] <<j) << trY);
189: {
190: bool found = false;
191: for(int pos=0; pos < numPositions; pos++)
192: if(positions[pos] == mirror(nextPiece, true, false, true))
193: found = true;
194: if(found) continue;
195: }
196: positions[numPositions] = nextPiece;
197: positionRotation[numPositions] = i;
198: numPositions++;
199: }
200: }
201: }
202:
203:
204:
205:
206: void Piece::buildOuccupanceInfo()
207: {
208:
209: long long mask = 1;
210: int maxPos = 0;
211:
212: for(int j=0; j < GC_Z_DIM; j++)
213: for(int k=0; k < GC_Y_DIM; k++)
214: for(int l=0; l < GC_X_DIM; l++, mask <<= 1)
215: for(int i=0; i<numPositions; i++)
216: if(positions[i] & mask && !(positions[i] & (mask-1))) {
217:
218: int off = (j*GC_Y_DIM + k)*GC_X_DIM + l + 4;
219: occupiedCoords[off][occupiedCoordsIndex[off]] = positions[i] << 4;
220: occupiedCoordsPositionIndex[off][occupiedCoordsIndex[off]] = i;
221: occupiedCoordsIndex[off]++;
222: }
223:
224: }
225:
226: void Piece::dumpPositionInfo()
227: {
228: cout << "int piece" << id << "NumPositions = " << numPositions << ";" << endl;
229:
230: cout << "long long piece" << id << "Positions[" << numPositions << "] = {" << endl << " ";
231: for (int i=0; i < numPositions; i++) {
232: cout << "0x" << hex << positions[i] << ", ";
233: if(!((i+1)%4)) cout << endl << " ";
234: }
235: cout << dec << endl << "};" << endl;
236: }
237:
238:
239:
240:
241: void Piece::dumpOuccupanceInfo(bool hi)
242: {
243:
244: int start = hi ? 32 : 0;
245: int stop = hi ? GC_X_DIM*GC_Y_DIM*GC_Z_DIM : 32;
246:
247: cout << " {" << endl;
248: for (int i=start; i < stop; i++) {
249: cout << "\t{ ";
250: for (int j=0; j < occupiedCoordsIndex[i]; j++) {
251: if(hi)
252: cout << "0x" << hex << (int)(occupiedCoords[i][j]>>32) << ", ";
253: else
254: cout << "0x" << hex << occupiedCoords[i][j] << ", ";
255: if(!((j+1)%4)) cout << endl << "\t ";
256: }
257: cout << endl << "\t}," << endl;
258: }
259:
260: cout << dec << " }," << endl << endl << endl;
261:
262: }
263:
264:
265:
266:
267: void Piece::dumpOuccupanceIndexInfo(bool hi)
268: {
269: int start = hi ? 32 : 0;
270: int stop = hi ? GC_X_DIM*GC_Y_DIM*GC_Z_DIM : 32;
271:
272: cout << " {" << endl;
273:
274: for (int i=start; i < stop; i++) {
275: if(!((i-start)%10)) cout << " ";
276: cout << occupiedCoordsIndex[i] << ", ";
277: if(!((i-start+1)%10)) cout << endl;
278: }
279: cout << dec << endl << " }," << endl << endl;
280: }
281:
282:
283:
284:
285:
286:
287: #ifdef DEBUG_BIN
288:
289: void Piece::writeRotatedPiecesAsIV(ofstream & out, const int indentLevel, const int pieceNo)
290: {
291:
292: for(int l=0; l<numRotations; l++) {
293: out << InventorWriter::indent;
294: out << InventorWriter::beginGroup;
295:
296: InventorWriter::writeTranslation(out,
297: l%5 * 7 * InventorWriter::baseUnit,
298: l/5 * -5 * InventorWriter::baseUnit, 0.0);
299:
300: InventorWriter::writeBBox(out, indentLevel+1, rotatedBBoxes[l]);
301:
302: int m = 0, hiLo = 0;
303: for (int i=0; i<GC_Z_DIM; i++) {
304: for (int j=0; j<GC_Y_DIM; j++)
305: for (int k=0; k<GC_X_DIM; k++, m++)
306: if(!(rotations[l] & (1ll << m))) continue;
307: else writeAsIV(out, indentLevel+1, pieceNo, k, j, i);
308: }
309:
310: out << InventorWriter::indent;
311: out << InventorWriter::endGroup;
312: }
313:
314: }
315:
316:
317:
318: void Piece::writePiecePositionsAsIV(ofstream & out, const int indentLevel, const int pieceNo)
319: {
320:
321: int bbox[] = { 3, 4, 5 };
322:
323: for(int l=0; l<numPositions; l++) {
324: out << InventorWriter::indent;
325: out << InventorWriter::beginGroup;
326:
327: InventorWriter::writeTranslation(out,
328: l%5 * 7 * InventorWriter::baseUnit,
329: l/5 * -5 * InventorWriter::baseUnit, 0.0);
330:
331: InventorWriter::writeBBox(out, indentLevel+1, bbox);
332:
333: int m = 0, hiLo = 0;
334: for (int i=0; i<GC_Z_DIM; i++) {
335: for (int j=0; j<GC_Y_DIM; j++)
336: for (int k=0; k<GC_X_DIM; k++, m++) {
337: if((positions[l] & (1ll << m)))
338: writeAsIV(out, indentLevel+1, pieceNo, k, j, i);
339: }
340: }
341:
342: out << InventorWriter::indent;
343: out << InventorWriter::endGroup;
344: }
345:
346: }
347:
348:
349:
350: void Piece::writeDescriptionAsIV(ofstream & out, const int indentLevel, const int pieceNo)
351: {
352: for (int i=0; i<(*_bbox)[2]; i++)
353: for (int j=0; j<(*_bbox)[1]; j++)
354: for (int k=0; k<(*_bbox)[0]; k++)
355: if(!(*_cubes)[i][j][k]) continue;
356: else writeAsIV(out, indentLevel, pieceNo, i, j, k);
357: }
358:
359:
360: void Piece::writePieceAsIV(ofstream & out, const int indentLevel, const int pieceNo)
361: {
362: int m = 0, hiLo = 0;
363: for (int i=0; i<GC_Z_DIM; i++) {
364: for (int j=0; j<GC_Y_DIM; j++)
365: for (int k=0; k<GC_X_DIM; k++, m++)
366: if(!(piece & (1ll << m))) continue;
367: else writeAsIV(out, indentLevel, pieceNo, i, j, k);
368: }
369: }
370:
371:
372: void Piece::writeAsIV(ofstream & out, const int indentLevel, const int pieceNo,
373: const int x, const int y, const int z)
374: {
375:
376: for (int l=0; l<indentLevel; l++)
377: out << InventorWriter::indent;
378: out << InventorWriter::beginGroup;
379:
380: for (int l=0; l<=indentLevel; l++)
381: out << InventorWriter::indent;
382: InventorWriter::writeColor(out, pieceNo);
383:
384: for (int l=0; l<=indentLevel; l++)
385: out << InventorWriter::indent;
386: InventorWriter::writeTranslation(out,
387: x * InventorWriter::baseUnit,
388: y * InventorWriter::baseUnit,
389: z * InventorWriter::baseUnit);
390:
391: for (int l=0; l<=indentLevel; l++)
392: out << InventorWriter::indent;
393: InventorWriter::writeCube(out);
394:
395: for (int l=0; l<indentLevel; l++)
396: out << InventorWriter::indent;
397: out << InventorWriter::endGroup;
398:
399: }
400:
401: #endif