public static void Calculate(Dictionary <int, byte> bitmap, ref List <SelBox> leastboxes) { // Clear old result leastboxes.Clear(); // Fetch key array int [] keyarr = new int [bitmap.Count]; bitmap.Keys.CopyTo(keyarr, 0); // Unmark all voxels foreach (int key in keyarr) { (bitmap[key]) &= (0xfe); } // Traverse all voxels foreach (int key in keyarr) { // bitmap[key] & 1 is the voxel mark. if ((bitmap[key] & 1) == 0) { // box value byte box_val = bitmap[key]; box_val = (byte)((box_val == 0xfe) ? (0xfe) : (box_val & 0xe0)); // Mark this voxel (bitmap[key]) |= (1); // Begin & end of this box IntVector3 begin = VCIsoData.KeyToIPos(key); IntVector3 end = new IntVector3(begin); // Can extend on xyz direction bool can_extend_x = true; bool can_extend_y = true; bool can_extend_z = true; // Start extending, make box while (can_extend_x || can_extend_y || can_extend_z) { // Try to extend x if (can_extend_x) { bool ext_p = true; bool ext_n = true; List <int> ext_key_p = new List <int> (); List <int> ext_key_n = new List <int> (); for (int y = begin.y; y <= end.y; y++) { for (int z = begin.z; z <= end.z; z++) { int _tst_key_p = VCIsoData.IPosToKey(end.x + 1, y, z); int _tst_key_n = VCIsoData.IPosToKey(begin.x - 1, y, z); byte _tst_val_p = 0xff; byte _tst_val_n = 0xff; if (bitmap.ContainsKey(_tst_key_p)) { _tst_val_p = bitmap[_tst_key_p]; } if (bitmap.ContainsKey(_tst_key_n)) { _tst_val_n = bitmap[_tst_key_n]; } _tst_val_p = (byte)((_tst_val_p == 0xfe) ? (0xfe) : (_tst_val_p & 0xe1)); _tst_val_n = (byte)((_tst_val_n == 0xfe) ? (0xfe) : (_tst_val_n & 0xe1)); if (_tst_val_p != box_val) { ext_p = false; } else { ext_key_p.Add(_tst_key_p); } if (_tst_val_n != box_val) { ext_n = false; } else { ext_key_n.Add(_tst_key_n); } if (!ext_p && !ext_n) { break; } } if (!ext_p && !ext_n) { break; } } if (ext_p) { foreach (int __key in ext_key_p) { // Mark this voxel (bitmap[__key]) |= (1); } end.x++; } if (ext_n) { foreach (int __key in ext_key_n) { // Mark this voxel (bitmap[__key]) |= (1); } begin.x--; } if (!ext_p && !ext_n) { can_extend_x = false; } ext_key_p.Clear(); ext_key_n.Clear(); } // Try to extend z if (can_extend_z) { bool ext_p = true; bool ext_n = true; List <int> ext_key_p = new List <int> (); List <int> ext_key_n = new List <int> (); for (int y = begin.y; y <= end.y; y++) { for (int x = begin.x; x <= end.x; x++) { int _tst_key_p = VCIsoData.IPosToKey(x, y, end.z + 1); int _tst_key_n = VCIsoData.IPosToKey(x, y, begin.z - 1); byte _tst_val_p = 0xff; byte _tst_val_n = 0xff; if (bitmap.ContainsKey(_tst_key_p)) { _tst_val_p = bitmap[_tst_key_p]; } if (bitmap.ContainsKey(_tst_key_n)) { _tst_val_n = bitmap[_tst_key_n]; } _tst_val_p = (byte)((_tst_val_p == 0xfe) ? (0xfe) : (_tst_val_p & 0xe1)); _tst_val_n = (byte)((_tst_val_n == 0xfe) ? (0xfe) : (_tst_val_n & 0xe1)); if (_tst_val_p != box_val) { ext_p = false; } else { ext_key_p.Add(_tst_key_p); } if (_tst_val_n != box_val) { ext_n = false; } else { ext_key_n.Add(_tst_key_n); } if (!ext_p && !ext_n) { break; } } if (!ext_p && !ext_n) { break; } } if (ext_p) { foreach (int __key in ext_key_p) { // Mark this voxel (bitmap[__key]) |= (1); } end.z++; } if (ext_n) { foreach (int __key in ext_key_n) { // Mark this voxel (bitmap[__key]) |= (1); } begin.z--; } if (!ext_p && !ext_n) { can_extend_z = false; } ext_key_p.Clear(); ext_key_n.Clear(); } // Try to extend y if (can_extend_y) { bool ext_p = true; bool ext_n = true; List <int> ext_key_p = new List <int> (); List <int> ext_key_n = new List <int> (); for (int x = begin.x; x <= end.x; x++) { for (int z = begin.z; z <= end.z; z++) { int _tst_key_p = VCIsoData.IPosToKey(x, end.y + 1, z); int _tst_key_n = VCIsoData.IPosToKey(x, begin.y - 1, z); byte _tst_val_p = 0xff; byte _tst_val_n = 0xff; if (bitmap.ContainsKey(_tst_key_p)) { _tst_val_p = bitmap[_tst_key_p]; } if (bitmap.ContainsKey(_tst_key_n)) { _tst_val_n = bitmap[_tst_key_n]; } _tst_val_p = (byte)((_tst_val_p == 0xfe) ? (0xfe) : (_tst_val_p & 0xe1)); _tst_val_n = (byte)((_tst_val_n == 0xfe) ? (0xfe) : (_tst_val_n & 0xe1)); if (_tst_val_p != box_val) { ext_p = false; } else { ext_key_p.Add(_tst_key_p); } if (_tst_val_n != box_val) { ext_n = false; } else { ext_key_n.Add(_tst_key_n); } if (!ext_p && !ext_n) { break; } } if (!ext_p && !ext_n) { break; } } if (ext_p) { foreach (int __key in ext_key_p) { // Mark this voxel (bitmap[__key]) |= (1); } end.y++; } if (ext_n) { foreach (int __key in ext_key_n) { // Mark this voxel (bitmap[__key]) |= (1); } begin.y--; } if (!ext_p && !ext_n) { can_extend_y = false; } ext_key_p.Clear(); ext_key_n.Clear(); } } // Create box SelBox box = new SelBox(); box.m_Box.xMin = (short)(begin.x); box.m_Box.yMin = (short)(begin.y); box.m_Box.zMin = (short)(begin.z); box.m_Box.xMax = (short)(end.x); box.m_Box.yMax = (short)(end.y); box.m_Box.zMax = (short)(end.z); box.m_Val = (byte)(box_val | 0x07); leastboxes.Add(box); } } // Sort leastboxes.Sort(SortSelBox); // Increase all voxels foreach (int key in keyarr) { (bitmap[key]) |= (0x01); } }
public static int SortSelBox(SelBox a, SelBox b) { return((int)(a.m_Val) - (int)(b.m_Val)); }