001: #include "cbitpart.h"
002: 
003: bool CBitPart::init = false;
004: int CBitPart::B2X[BITS], CBitPart::B2Y[BITS], CBitPart::B2Z[BITS];
005: int CBitPart::XYZ[X][Y][Z];
006: 
007: void CBitPart::InitCoords()
008: {
009:         for (int z = 0; z < Z; ++z)
010:                 for (int y = 0; y < Y; ++y)
011:                         for (int x = 0; x < X; ++x) {
012:                                 int bit = X*Y*z + X*y + x;
013: 
014:                                 XYZ[x][y][z] = bit;
015:                                 B2X[bit] = x;
016:                                 B2Y[bit] = y;
017:                                 B2Z[bit] = z;
018:                         }
019: 
020:         init = true;
021: }
022: 
023: void CBitPart::FromStream(ifstream& ifs)
024: {
025:         int x, y, z, t;
026:         ifs >> x >> y >> z;
027: 
028:         for (int z0 = 0; z0 < z; ++z0)
029:                 for (int y0 = 0; y0 < y; ++y0)
030:                         for (int x0 = 0; x0 < x; ++x0) {
031:                                 ifs >> t;
032:                                 if (t == 1) set(x0, y0, z0);
033:                         }
034: }
035: 
036: int CBitPart::Density()
037: {
038:         int first = NextSetBit(0);
039:         int zeros = 0;
040:         int ret = 0;
041:         for (int i = first+1; i < 60; ++i)
042:                 if (is_set(i)) ret += zeros;
043:                 else ++zeros;
044:         return ret;
045: }
046: 
047: void CBitPart::Swap(int a, int b)
048: {
049:         bool sa = is_set(a);
050:         bool sb = is_set(b);
051:         if (sa == sb) return;
052:         change(a); change(b);
053: }
054: 
055: CBitPart& CBitPart::Move(int mx, int my, int mz)
056: {
057:         INT64 nbits = 0;
058:         for (int i = NextSetBit(0); i != BITS; i = NextSetBit(i+1))
059:                 set(nbits, Coord2Bit(B2X[i]+mx, B2Y[i]+my, B2Z[i]+mz));
060:         bits = nbits;
061: 
062:         return *this;
063: }
064: 
065: bool CBitPart::RotateLocalF90() // local rotate 90 degree clockwise of front
066: {
067:         int max_x = 0, max_y = 0;
068: 
069:         for (int i = NextSetBit(0); i != BITS; i = NextSetBit(i+1)) {
070:                 if (GetX(i) > max_x) max_x = GetX(i);
071:                 if (GetY(i) > max_y) max_y = GetY(i);
072:         }
073: 
074:         if (max_x >= Y) return false;
075:         if (max_y >= X) return false;
076: 
077:         INT64 nbits = 0;
078: 
079:         for (int i = NextSetBit(0); i != BITS; i = NextSetBit(i+1))
080:                 set(nbits, Coord2Bit(max_y-GetY(i), GetX(i), GetZ(i)));
081: 
082:         bits = nbits;
083: 
084:         return true;
085: }
086: 
087: bool CBitPart::RotateLocalT90() // local rotate 90 degree clockwise of top
088: {
089:         int max_x = 0, max_z = 0;
090: 
091:         for (int i = NextSetBit(0); i != BITS; i = NextSetBit(i+1)) {
092:                 if (GetX(i) > max_x) max_x = GetX(i);
093:                 if (GetZ(i) > max_z) max_z = GetZ(i);
094:         }
095: 
096:         if (max_x >= Z) return false;
097:         if (max_z >= X) return false;
098: 
099:         INT64 nbits = 0;
100: 
101:         for (int i = NextSetBit(0); i != BITS; i = NextSetBit(i+1))
102:                 set(nbits, Coord2Bit(GetZ(i), GetY(i), max_x-GetX(i)));
103: 
104:         bits = nbits;
105: 
106:         return true;
107: }
108: 
109: bool CBitPart::RotateLocalS90() // local rotate 90 degree clockwise of side
110: {
111:         int max_y = 0, max_z = 0;
112: 
113:         for (int i = NextSetBit(0); i != BITS; i = NextSetBit(i+1)) {
114:                 if (GetY(i) > max_y) max_y = GetY(i);
115:                 if (GetZ(i) > max_z) max_z = GetZ(i);
116:         }
117: 
118:         if (max_y >= Z) return false;
119:         if (max_z >= Y) return false;
120: 
121:         INT64 nbits = 0;
122: 
123:         for (int i = NextSetBit(0); i != BITS; i = NextSetBit(i+1))
124:                 set(nbits, Coord2Bit(GetX(i), max_z-GetZ(i), GetY(i)));
125: 
126:         bits = nbits;
127: 
128:         return true;
129: }
130: 
131: bool CBitPart::RotateLocalF180() // local rotate 180 degree of front
132: {
133:         int max_x = 0, max_y = 0;
134: 
135:         for (int i = NextSetBit(0); i != BITS; i = NextSetBit(i+1)) {
136:                 if (GetX(i) > max_x) max_x = GetX(i);
137:                 if (GetY(i) > max_y) max_y = GetY(i);
138:         }
139: 
140:         INT64 nbits = 0;
141: 
142:         for (int i = NextSetBit(0); i != BITS; i = NextSetBit(i+1))
143:                 set(nbits, Coord2Bit(max_x-GetX(i), max_y-GetY(i), GetZ(i)));
144: 
145:         bits = nbits;
146: 
147:         return true;
148: }
149: 
150: bool CBitPart::RotateLocalT180() // local rotate 180 degree of top
151: {
152:         int max_x = 0, max_z = 0;
153: 
154:         for (int i = NextSetBit(0); i != BITS; i = NextSetBit(i+1)) {
155:                 if (GetX(i) > max_x) max_x = GetX(i);
156:                 if (GetZ(i) > max_z) max_z = GetZ(i);
157:         }
158: 
159:         INT64 nbits = 0;
160: 
161:         for (int i = NextSetBit(0); i != BITS; i = NextSetBit(i+1))
162:                 set(nbits, Coord2Bit(max_x-GetX(i), GetY(i), max_z-GetZ(i)));
163: 
164:         bits = nbits;
165: 
166:         return true;
167: }
168: 
169: bool CBitPart::RotateLocalS180() // local rotate 180 degree of side
170: {
171:         int max_y = 0, max_z = 0;
172: 
173:         for (int i = NextSetBit(0); i != BITS; i = NextSetBit(i+1)) {
174:                 if (GetY(i) > max_y) max_y = GetY(i);
175:                 if (GetZ(i) > max_z) max_z = GetZ(i);
176:         }
177: 
178:         INT64 nbits = 0;
179: 
180:         for (int i = NextSetBit(0); i != BITS; i = NextSetBit(i+1))
181:                 set(nbits, Coord2Bit(GetX(i), max_y-GetY(i), max_z-GetZ(i)));
182: 
183:         bits = nbits;
184: 
185:         return true;
186: }
187: 
188: void CBitPart::GetMaxima(int& max_x, int& max_y, int& max_z)
189: {
190:         max_x = 0; max_y = 0; max_z = 0;
191:         for (int i = NextSetBit(0); i != BITS; i = NextSetBit(i+1)) {
192:                 if (GetX(i) > max_x) max_x = GetX(i);
193:                 if (GetY(i) > max_y) max_y = GetY(i);
194:                 if (GetZ(i) > max_z) max_z = GetZ(i);
195:         }
196: }
197: 
198: void CBitPart::RotateCubeF180()
199: {
200:         INT64 nbits = 0;
201: 
202:         for (int i = NextSetBit(0); i != BITS; i = NextSetBit(i+1))
203:                 set(nbits, Coord2Bit(X-1-GetX(i), Y-1-GetY(i), GetZ(i)));
204: 
205:         bits = nbits;
206: }
207: 
208: void CBitPart::RotateCubeT180()
209: {
210:         INT64 nbits = 0;
211: 
212:         for (int i = NextSetBit(0); i != BITS; i = NextSetBit(i+1))
213:                 set(nbits, Coord2Bit(X-1-GetX(i), GetY(i), Z-1-GetZ(i)));
214: 
215:         bits = nbits;
216: }
217: 
218: void CBitPart::RotateCubeS180()
219: {
220:         INT64 nbits = 0;
221: 
222:         for (int i = NextSetBit(0); i != BITS; i = NextSetBit(i+1))
223:                 set(nbits, Coord2Bit(GetX(i), Y-1-GetY(i), Z-1-GetZ(i)));
224: 
225:         bits = nbits;
226: }
227: 
228: void CBitPart::ReverseBits()
229: {
230:         INT64 nbits = 0;
231:         for (int i = 0; i < BITS; ++i)
232:                 if (is_set(i)) set(nbits, BITS-1-i);
233:         bits = nbits;
234: }
235: