/opencascade-6.5.1/ros/src/Voxel/Voxel_ROctBoolDS.cxx

https://github.com/jehc/MondocosmOS · C++ · 717 lines · 554 code · 77 blank · 86 comment · 84 complexity · 33af78a4298adb5fa999bc947c5e1509 MD5 · raw file

  1. // File: Voxel_ROctBoolDS.cxx
  2. // Created: Mon Sep 01 11:00:08 2008
  3. // Author: Vladislav ROMASHKO
  4. // <vladislav.romashko@opencascade.com>
  5. #include <Voxel_ROctBoolDS.ixx>
  6. #include <Voxel_SplitData.hxx>
  7. #include <stdlib.h>
  8. static Standard_Byte gbits[8] = {1, 2, 4, 8, 16, 32, 64, 128};
  9. static Standard_Byte gnbits[8] = {255-1, 255-2, 255-4, 255-8, 255-16, 255-32, 255-64, 255-128};
  10. /* Data structure of the ROctBoolDS
  11. SplitData: 1 byte (8 values)
  12. (a) SplitData: 8 bytes (64 values)
  13. (b) SplitData: 64 bytes (512 values)
  14. (c) SplitData: ...
  15. (d) SplitData: ...
  16. */
  17. // Empty constructor
  18. Voxel_ROctBoolDS::Voxel_ROctBoolDS():Voxel_DS()
  19. {
  20. }
  21. // Constructor with intialization.
  22. Voxel_ROctBoolDS::Voxel_ROctBoolDS(const Standard_Real x, const Standard_Real y, const Standard_Real z,
  23. const Standard_Real xlen, const Standard_Real ylen, const Standard_Real zlen,
  24. const Standard_Integer nbx, const Standard_Integer nby, const Standard_Integer nbz)
  25. :Voxel_DS()
  26. {
  27. Init(x, y, z, xlen, ylen, zlen, nbx, nby, nbz);
  28. }
  29. // Initialization.
  30. void Voxel_ROctBoolDS::Init(const Standard_Real x, const Standard_Real y, const Standard_Real z,
  31. const Standard_Real xlen, const Standard_Real ylen, const Standard_Real zlen,
  32. const Standard_Integer nbx, const Standard_Integer nby, const Standard_Integer nbz)
  33. {
  34. Destroy();
  35. Voxel_DS::Init(x, y, z, xlen, ylen, zlen, nbx, nby, nbz);
  36. if (!myNbX || !myNbY || !myNbZ)
  37. return;
  38. Standard_Integer nb_slices = RealToInt(ceil(myNbXY * myNbZ / 8.0));
  39. myData = (Standard_Address) calloc(nb_slices, sizeof(Voxel_SplitData*));
  40. }
  41. // Destructor
  42. void Voxel_ROctBoolDS::Destroy()
  43. {
  44. if (myData)
  45. {
  46. SetZero();
  47. free((Voxel_SplitData**)myData);
  48. myData = 0;
  49. }
  50. }
  51. // A recursive method of deletion of data.
  52. static void SetZeroSplitData(Voxel_SplitData* data)
  53. {
  54. // Values:
  55. free((Standard_Byte*) data->GetValues());
  56. data->GetValues() = 0;
  57. if (data->GetSplitData())
  58. {
  59. SetZeroSplitData((Voxel_SplitData*) data->GetSplitData());
  60. }
  61. delete (data);
  62. data = 0;
  63. }
  64. void Voxel_ROctBoolDS::SetZero()
  65. {
  66. if (myData)
  67. {
  68. Standard_Integer ix = 0, nb_slices = RealToInt(ceil(myNbXY * myNbZ / 8.0));
  69. for (; ix < nb_slices; ix++)
  70. {
  71. if (((Voxel_SplitData**)myData)[ix])
  72. {
  73. SetZeroSplitData((Voxel_SplitData*)((Voxel_SplitData**)myData)[ix]);
  74. }
  75. }
  76. }
  77. }
  78. // Access to the boolean information attached to a particular voxel:
  79. // Info: (ix >= 0 && ix < theNb_x), etc.
  80. void Voxel_ROctBoolDS::Set(const Standard_Integer ix, const Standard_Integer iy, const Standard_Integer iz,
  81. const Standard_Boolean data)
  82. {
  83. Standard_Integer ibit = ix + myNbX * iy + myNbXY * iz;
  84. Standard_Integer islice = ibit >> 3;
  85. if (!data && !((Voxel_SplitData**)myData)[islice])
  86. return; // don't allocate a slice of data for setting a 0 value
  87. // Allocate the slice if it is not done yet.
  88. if (!((Voxel_SplitData**)myData)[islice])
  89. {
  90. ((Voxel_SplitData**)myData)[islice] = (Voxel_SplitData*) new Voxel_SplitData;
  91. // Values:
  92. ((Voxel_SplitData**)myData)[islice]->GetValues() =
  93. (Standard_Byte*) calloc(1/*one byte: 8 1-bit values*/, sizeof(Standard_Byte));
  94. // Sub-voxels:
  95. ((Voxel_SplitData*)((Voxel_SplitData**)myData)[islice])->GetSplitData() = 0;
  96. }
  97. // Value
  98. Standard_Byte value = *((Standard_Byte*)((Voxel_SplitData*)((Voxel_SplitData**)myData)[islice])->GetValues());
  99. // Position of data in the 8 bit-"value".
  100. Standard_Integer shift = ibit - (islice << 3);
  101. // Set data
  102. if (data != ((value & gbits[shift]) ? Standard_True : Standard_False))
  103. {
  104. if (data)
  105. value |= gbits[shift];
  106. else
  107. value &= gnbits[shift];
  108. *((Standard_Byte*)((Voxel_SplitData*)((Voxel_SplitData**)myData)[islice])->GetValues()) = value;
  109. }
  110. // Set the same value to sub-voxels.
  111. if (((Voxel_SplitData*)((Voxel_SplitData**)myData)[islice])->GetSplitData())
  112. {
  113. // Get sub-value
  114. Standard_Byte subvalue = ((Standard_Byte*)((Voxel_SplitData*)((Voxel_SplitData*)((Voxel_SplitData**)myData)[islice])->GetSplitData())->GetValues())[shift];
  115. // Set sub-value
  116. if (subvalue != (data ? 255 : 0))
  117. {
  118. subvalue = data ? 255 : 0;
  119. ((Standard_Byte*)((Voxel_SplitData*)((Voxel_SplitData*)((Voxel_SplitData**)myData)[islice])->GetSplitData())->GetValues())[shift] = subvalue;
  120. }
  121. // Set the same value to sub-sub-voxels.
  122. if (((Voxel_SplitData*)((Voxel_SplitData*)((Voxel_SplitData**)myData)[islice])->GetSplitData())->GetSplitData())
  123. {
  124. // Start index of 64-bit value (index of byte of sub-sub-voxel).
  125. Standard_Integer ibyte2 = (shift << 3);
  126. for (Standard_Integer ioct2 = 0; ioct2 < 8; ioct2++)
  127. {
  128. // Get sub-sub-value
  129. Standard_Byte subsubvalue = ((Standard_Byte*)((Voxel_SplitData*)((Voxel_SplitData*)((Voxel_SplitData*)((Voxel_SplitData**)myData)[islice])->GetSplitData())->GetSplitData())->GetValues())[ibyte2 + ioct2];
  130. // Set sub-sub-value
  131. if (subsubvalue != (data ? 255 : 0))
  132. {
  133. subsubvalue = data ? 255 : 0;
  134. ((Standard_Byte*)((Voxel_SplitData*)((Voxel_SplitData*)((Voxel_SplitData*)((Voxel_SplitData**)myData)[islice])->GetSplitData())->GetSplitData())->GetValues())[ibyte2 + ioct2] = subsubvalue;
  135. }
  136. }
  137. }
  138. }
  139. }
  140. void Voxel_ROctBoolDS::Set(const Standard_Integer ix, const Standard_Integer iy, const Standard_Integer iz,
  141. const Standard_Integer ioct1, const Standard_Boolean data)
  142. {
  143. Standard_Integer ibit = ix + myNbX * iy + myNbXY * iz;
  144. Standard_Integer islice = ibit >> 3;
  145. if (!data && !((Voxel_SplitData**)myData)[islice])
  146. return; // don't allocate a slice of data for setting a 0 value
  147. // Allocate the slice if it is not done yet.
  148. if (!((Voxel_SplitData**)myData)[islice])
  149. {
  150. ((Voxel_SplitData**)myData)[islice] = (Voxel_SplitData*) new Voxel_SplitData;
  151. // Values:
  152. ((Voxel_SplitData*)((Voxel_SplitData**)myData)[islice])->GetValues() =
  153. (Standard_Byte*) calloc(1/*one byte: 8 1-bit values*/, sizeof(Standard_Byte));
  154. // Sub-voxels:
  155. ((Voxel_SplitData*)((Voxel_SplitData**)myData)[islice])->GetSplitData() = 0;
  156. }
  157. // Check sub-voxels of the first level
  158. if (!((Voxel_SplitData*)((Voxel_SplitData**)myData)[islice])->GetSplitData())
  159. {
  160. // Sub-voxels:
  161. ((Voxel_SplitData*)((Voxel_SplitData**)myData)[islice])->GetSplitData() = (Voxel_SplitData*) new Voxel_SplitData;
  162. // Value of sub-voxels:
  163. ((Voxel_SplitData*)((Voxel_SplitData*)((Voxel_SplitData**)myData)[islice])->GetSplitData())->GetValues() =
  164. (Standard_Byte*) calloc(8/*eight bytes: 8 sub-voxels for each voxel*/, sizeof(Standard_Byte));
  165. // Set parent value
  166. Standard_Byte parent_value = *((Standard_Byte*)((Voxel_SplitData*)((Voxel_SplitData**)myData)[islice])->GetValues());
  167. if (parent_value)
  168. {
  169. for (Standard_Integer shift = 0; shift < 8; shift++)
  170. {
  171. if ((parent_value & gbits[shift]) ? Standard_True : Standard_False)
  172. {
  173. ((Standard_Byte*)((Voxel_SplitData*)((Voxel_SplitData*)((Voxel_SplitData**)myData)[islice])->GetSplitData())->GetValues())[shift] = 255;
  174. }
  175. else
  176. {
  177. ((Standard_Byte*)((Voxel_SplitData*)((Voxel_SplitData*)((Voxel_SplitData**)myData)[islice])->GetSplitData())->GetValues())[shift] = 0;
  178. }
  179. }
  180. }
  181. // Sub-sub-voxels
  182. ((Voxel_SplitData*)((Voxel_SplitData*)((Voxel_SplitData**)myData)[islice])->GetSplitData())->GetSplitData() = 0;
  183. }
  184. // Index of sub-voxel corresponding to ioct1: 8 voxels correspond to 64 sub-voxels.
  185. Standard_Integer ibyte = ibit - (islice << 3);
  186. // Value
  187. Standard_Byte value = ((Standard_Byte*)((Voxel_SplitData*)((Voxel_SplitData*)((Voxel_SplitData**)myData)[islice])->GetSplitData())->GetValues())[ibyte];
  188. // Set data
  189. if (data != ((value & gbits[ioct1]) ? Standard_True : Standard_False))
  190. {
  191. if (data)
  192. value |= gbits[ioct1];
  193. else
  194. value &= gnbits[ioct1];
  195. ((Standard_Byte*)((Voxel_SplitData*)((Voxel_SplitData*)((Voxel_SplitData**)myData)[islice])->GetSplitData())->GetValues())[ibyte] = value;
  196. }
  197. // Set the same value to sub-voxels.
  198. if (((Voxel_SplitData*)((Voxel_SplitData*)((Voxel_SplitData**)myData)[islice])->GetSplitData())->GetSplitData())
  199. {
  200. // Start index of 64-bit value (index of byte of sub-sub-voxel).
  201. Standard_Integer ibyte2 = (ibyte << 3) + ioct1;
  202. // Get sub-sub-value
  203. Standard_Byte subsubvalue = ((Standard_Byte*)((Voxel_SplitData*)((Voxel_SplitData*)((Voxel_SplitData*)((Voxel_SplitData**)myData)[islice])->GetSplitData())->GetSplitData())->GetValues())[ibyte2];
  204. // Set sub-sub-value
  205. if (subsubvalue != (data ? 255 : 0))
  206. {
  207. subsubvalue = data ? 255 : 0;
  208. ((Standard_Byte*)((Voxel_SplitData*)((Voxel_SplitData*)((Voxel_SplitData*)((Voxel_SplitData**)myData)[islice])->GetSplitData())->GetSplitData())->GetValues())[ibyte2] = subsubvalue;
  209. }
  210. }
  211. }
  212. void Voxel_ROctBoolDS::Set(const Standard_Integer ix, const Standard_Integer iy, const Standard_Integer iz,
  213. const Standard_Integer ioct1, const Standard_Integer ioct2, const Standard_Boolean data)
  214. {
  215. Standard_Integer ibit = ix + myNbX * iy + myNbXY * iz;
  216. Standard_Integer islice = ibit >> 3;
  217. if (!data && !((Voxel_SplitData**)myData)[islice])
  218. return; // don't allocate a slice of data for setting a 0 value
  219. // Allocate the slice if it is not done yet.
  220. if (!((Voxel_SplitData**)myData)[islice])
  221. {
  222. ((Voxel_SplitData**)myData)[islice] = (Voxel_SplitData*) new Voxel_SplitData;
  223. // Values:
  224. ((Voxel_SplitData*)((Voxel_SplitData**)myData)[islice])->GetValues() =
  225. (Standard_Byte*) calloc(1/*one byte: 8 1-bit values*/, sizeof(Standard_Byte));
  226. // Sub-voxels:
  227. ((Voxel_SplitData*)((Voxel_SplitData**)myData)[islice])->GetSplitData() = 0;
  228. }
  229. // Check sub-voxels of the first level
  230. if (!((Voxel_SplitData*)((Voxel_SplitData**)myData)[islice])->GetSplitData())
  231. {
  232. // Sub-voxels:
  233. ((Voxel_SplitData*)((Voxel_SplitData**)myData)[islice])->GetSplitData() = (Voxel_SplitData*) new Voxel_SplitData;
  234. // Value of sub-voxels:
  235. ((Voxel_SplitData*)((Voxel_SplitData*)((Voxel_SplitData**)myData)[islice])->GetSplitData())->GetValues() =
  236. (Standard_Byte*) calloc(8/*eight bytes: 8 sub-voxels for each voxel*/, sizeof(Standard_Byte));
  237. // Set parent value
  238. Standard_Byte parent_value = *((Standard_Byte*)((Voxel_SplitData*)((Voxel_SplitData**)myData)[islice])->GetValues());
  239. if (parent_value)
  240. {
  241. for (Standard_Integer shift = 0; shift < 8; shift++)
  242. {
  243. if ((parent_value & gbits[shift]) ? Standard_True : Standard_False)
  244. {
  245. ((Standard_Byte*)((Voxel_SplitData*)((Voxel_SplitData*)((Voxel_SplitData**)myData)[islice])->GetSplitData())->GetValues())[shift] = 255;
  246. }
  247. else
  248. {
  249. ((Standard_Byte*)((Voxel_SplitData*)((Voxel_SplitData*)((Voxel_SplitData**)myData)[islice])->GetSplitData())->GetValues())[shift] = 0;
  250. }
  251. }
  252. }
  253. // Sub-sub-voxels
  254. ((Voxel_SplitData*)((Voxel_SplitData*)((Voxel_SplitData**)myData)[islice])->GetSplitData())->GetSplitData() = 0;
  255. }
  256. // Check sub-voxels of the second level
  257. if (!((Voxel_SplitData*)((Voxel_SplitData*)((Voxel_SplitData**)myData)[islice])->GetSplitData())->GetSplitData())
  258. {
  259. // Sub-voxels 2:
  260. ((Voxel_SplitData*)((Voxel_SplitData*)((Voxel_SplitData**)myData)[islice])->GetSplitData())->GetSplitData() =
  261. (Voxel_SplitData*) new Voxel_SplitData;
  262. // Value of sub-voxels 2:
  263. ((Voxel_SplitData*)((Voxel_SplitData*)((Voxel_SplitData*)((Voxel_SplitData**)myData)[islice])->GetSplitData())->GetSplitData())->GetValues() =
  264. (Standard_Byte*) calloc(64/*sixty four bytes: 8 sub-voxels for each sub-voxel for each voxel*/,
  265. sizeof(Standard_Byte));
  266. // Set parent value
  267. for (Standard_Integer ibyte1 = 0; ibyte1 < 8; ibyte1++)
  268. {
  269. Standard_Byte parent_value = ((Standard_Byte*)((Voxel_SplitData*)((Voxel_SplitData*)((Voxel_SplitData**)myData)[islice])->GetSplitData())->GetValues())[ibyte1];
  270. if (parent_value)
  271. {
  272. Standard_Integer ibyte2 = (ibyte1 << 3);
  273. for (Standard_Integer shift = 0; shift < 8; shift++)
  274. {
  275. if ((parent_value & gbits[shift]) ? Standard_True : Standard_False)
  276. {
  277. ((Standard_Byte*)((Voxel_SplitData*)((Voxel_SplitData*)((Voxel_SplitData*)((Voxel_SplitData**)myData)[islice])->GetSplitData())->GetSplitData())->GetValues())[ibyte2 + shift] = 255;
  278. }
  279. else
  280. {
  281. ((Standard_Byte*)((Voxel_SplitData*)((Voxel_SplitData*)((Voxel_SplitData*)((Voxel_SplitData**)myData)[islice])->GetSplitData())->GetSplitData())->GetValues())[ibyte2 + shift] = 0;
  282. }
  283. }
  284. }
  285. }
  286. // Sub-sub-sub-voxels
  287. ((Voxel_SplitData*)((Voxel_SplitData*)((Voxel_SplitData*)((Voxel_SplitData**)myData)[islice])->GetSplitData())->GetSplitData())->GetSplitData() = 0;
  288. }
  289. // Index of sub-voxel corresponding to ioct1: 8 voxels correspond to 64 sub-voxels.
  290. Standard_Integer ibyte1 = ibit - (islice << 3); // imdex of byte of 8-byte value (sub-voxel 1).
  291. Standard_Integer ibyte2 = (ibyte1 << 3) + ioct1; // index of byte of 64-byte value (sub-voxel 2)
  292. // Value
  293. Standard_Byte value = ((Standard_Byte*)((Voxel_SplitData*)((Voxel_SplitData*)((Voxel_SplitData*)((Voxel_SplitData**)myData)[islice])->GetSplitData())->GetSplitData())->GetValues())[ibyte2];
  294. // Set data
  295. if (data != ((value & gbits[ioct2]) ? Standard_True : Standard_False))
  296. {
  297. if (data)
  298. value |= gbits[ioct2];
  299. else
  300. value &= gnbits[ioct2];
  301. ((Standard_Byte*)((Voxel_SplitData*)((Voxel_SplitData*)((Voxel_SplitData*)((Voxel_SplitData**)myData)[islice])->GetSplitData())->GetSplitData())->GetValues())[ibyte2] = value;
  302. }
  303. }
  304. Standard_Boolean Voxel_ROctBoolDS::Get(const Standard_Integer ix, const Standard_Integer iy, const Standard_Integer iz) const
  305. {
  306. Standard_Integer ibit = ix + myNbX * iy + myNbXY * iz;
  307. Standard_Integer islice = ibit >> 3;
  308. // If the slice of data is not allocated, it means that its values are 0.
  309. if (!((Voxel_SplitData**)myData)[islice])
  310. return Standard_False;
  311. // Value (byte)
  312. Standard_Byte value = *((Standard_Byte*)((Voxel_SplitData*)((Voxel_SplitData**)myData)[islice])->GetValues());
  313. // Position of data in the 8 bit-"value".
  314. Standard_Integer shift = ibit - (islice << 3);
  315. return ((value & gbits[shift]) ? Standard_True : Standard_False);
  316. }
  317. Standard_Boolean Voxel_ROctBoolDS::Get(const Standard_Integer ix, const Standard_Integer iy, const Standard_Integer iz,
  318. const Standard_Integer ioct1) const
  319. {
  320. Standard_Integer ibit = ix + myNbX * iy + myNbXY * iz;
  321. Standard_Integer islice = ibit >> 3;
  322. // If the slice of data is not allocated, it means that its values are 0.
  323. if (!((Voxel_SplitData**)myData)[islice])
  324. return Standard_False;
  325. // If the voxel is not split, return the value of the voxel.
  326. if (!((Voxel_SplitData*)((Voxel_SplitData**)myData)[islice])->GetSplitData())
  327. return Get(ix, iy, iz);
  328. // Index of sub-voxel corresponding to ioct1: 8 voxels correspond to 64 sub-voxels.
  329. Standard_Integer ibyte = ibit - (islice << 3);
  330. // Value
  331. Standard_Byte value = ((Standard_Byte*)((Voxel_SplitData*)((Voxel_SplitData*)((Voxel_SplitData**)myData)[islice])->GetSplitData())->GetValues())[ibyte];
  332. return ((value & gbits[ioct1]) ? Standard_True : Standard_False);
  333. }
  334. Standard_Boolean Voxel_ROctBoolDS::Get(const Standard_Integer ix, const Standard_Integer iy, const Standard_Integer iz,
  335. const Standard_Integer ioct1, const Standard_Integer ioct2) const
  336. {
  337. Standard_Integer ibit = ix + myNbX * iy + myNbXY * iz;
  338. Standard_Integer islice = ibit >> 3;
  339. // If the slice of data is not allocated, it means that its values are 0.
  340. if (!((Voxel_SplitData**)myData)[islice])
  341. return Standard_False;
  342. // If the voxel is not split, return the value of the voxel.
  343. if (!((Voxel_SplitData*)((Voxel_SplitData**)myData)[islice])->GetSplitData())
  344. return Get(ix, iy, iz);
  345. // If the split voxel (sub-voxel 1) is not split, return the value of the sub-voxel 1.
  346. if (!((Voxel_SplitData*)((Voxel_SplitData*)((Voxel_SplitData**)myData)[islice])->GetSplitData())->GetSplitData())
  347. return Get(ix, iy, iz, ioct1);
  348. // Index of sub-voxel corresponding to ioct1: 8 voxels correspond to 64 sub-voxels.
  349. Standard_Integer ibyte1 = ibit - (islice << 3); // index of byte of 8-byte value (sub-voxel 1).
  350. Standard_Integer ibyte2 = (ibyte1 << 3) + ioct1; // index of byte of 64-byte value (sub-voxel 2)
  351. // Value
  352. Standard_Byte value = ((Standard_Byte*)((Voxel_SplitData*)((Voxel_SplitData*)((Voxel_SplitData*)((Voxel_SplitData**)myData)[islice])->GetSplitData())->GetSplitData())->GetValues())[ibyte2];
  353. return ((value & gbits[ioct2]) ? Standard_True : Standard_False);
  354. }
  355. Standard_Boolean Voxel_ROctBoolDS::IsSplit(const Standard_Integer ix, const Standard_Integer iy, const Standard_Integer iz) const
  356. {
  357. Standard_Integer ibit = ix + myNbX * iy + myNbXY * iz;
  358. Standard_Integer islice = ibit >> 3;
  359. // If the voxel has no value, it is not split.
  360. if (!((Voxel_SplitData**)myData)[islice])
  361. return Standard_False;
  362. // Check existence of sub-voxels
  363. if (((Voxel_SplitData*)((Voxel_SplitData**)myData)[islice])->GetSplitData())
  364. return Standard_True;
  365. return Standard_False;
  366. }
  367. Standard_Integer Voxel_ROctBoolDS::Deepness(const Standard_Integer ix, const Standard_Integer iy, const Standard_Integer iz) const
  368. {
  369. Standard_Integer ibit = ix + myNbX * iy + myNbXY * iz;
  370. Standard_Integer islice = ibit >> 3;
  371. // If the voxel has no value, it is not split.
  372. if (!((Voxel_SplitData**)myData)[islice])
  373. return 0;
  374. // Test deepness.
  375. if (((Voxel_SplitData*)((Voxel_SplitData**)myData)[islice])->GetSplitData())
  376. {
  377. if (((Voxel_SplitData*)((Voxel_SplitData*)((Voxel_SplitData**)myData)[islice])->GetSplitData())->GetSplitData())
  378. {
  379. return 2;
  380. }
  381. else
  382. {
  383. return 1;
  384. }
  385. }
  386. return 0;
  387. }
  388. void Voxel_ROctBoolDS::OptimizeMemory()
  389. {
  390. // Iterate the array of voxels checking coincidence of values of sub-voxels.
  391. Standard_Integer islice = 0, nb_slices = RealToInt(ceil(myNbXY * myNbZ / 8.0));
  392. for (; islice < nb_slices; islice++)
  393. {
  394. if (!((Voxel_SplitData**)myData)[islice])
  395. continue;
  396. if (((Voxel_SplitData*)((Voxel_SplitData**)myData)[islice])->GetSplitData())
  397. {
  398. Standard_Boolean suppress = Standard_False;
  399. // Second level of sub-voxels
  400. if (((Voxel_SplitData*)((Voxel_SplitData*)((Voxel_SplitData**)myData)[islice])->GetSplitData())->GetSplitData())
  401. {
  402. suppress = Standard_False;
  403. Standard_Byte value1 = ((Standard_Byte*)((Voxel_SplitData*)((Voxel_SplitData*)((Voxel_SplitData*)((Voxel_SplitData**)myData)[islice])->GetSplitData())->GetSplitData())->GetValues())[0];
  404. if (value1 == 0 || value1 == 255)
  405. {
  406. suppress = Standard_True;
  407. for (Standard_Integer ibyte2 = 1; ibyte2 < 64; ibyte2++)
  408. {
  409. Standard_Byte value2 = ((Standard_Byte*)((Voxel_SplitData*)((Voxel_SplitData*)((Voxel_SplitData*)((Voxel_SplitData**)myData)[islice])->GetSplitData())->GetSplitData())->GetValues())[ibyte2];
  410. if (value2 != value1)
  411. {
  412. suppress = Standard_False;
  413. break;
  414. }
  415. }
  416. }
  417. if (suppress)
  418. {
  419. SetZeroSplitData((Voxel_SplitData*)((Voxel_SplitData*)((Voxel_SplitData*)((Voxel_SplitData**)myData)[islice])->GetSplitData())->GetSplitData());
  420. ((Voxel_SplitData*)((Voxel_SplitData*)((Voxel_SplitData**)myData)[islice])->GetSplitData())->GetSplitData() = 0;
  421. // Set value to upper level
  422. for (Standard_Integer ibyte1 = 0; ibyte1 < 8; ibyte1++)
  423. {
  424. ((Standard_Byte*)((Voxel_SplitData*)((Voxel_SplitData*)((Voxel_SplitData**)myData)[islice])->GetSplitData())->GetValues())[ibyte1] = value1;
  425. }
  426. }
  427. else
  428. {
  429. // If we don't suppress sub-sub-voxels, we don't touch sub-voxels.
  430. continue;
  431. }
  432. }
  433. // First level of sub-voxels
  434. suppress = Standard_False;
  435. Standard_Byte value1 = ((Standard_Byte*)((Voxel_SplitData*)((Voxel_SplitData*)((Voxel_SplitData**)myData)[islice])->GetSplitData())->GetValues())[0];
  436. if (value1 == 0 || value1 == 255)
  437. {
  438. suppress = Standard_True;
  439. for (Standard_Integer ibyte1 = 1; ibyte1 < 8; ibyte1++)
  440. {
  441. Standard_Byte value2 = ((Standard_Byte*)((Voxel_SplitData*)((Voxel_SplitData*)((Voxel_SplitData**)myData)[islice])->GetSplitData())->GetValues())[ibyte1];
  442. if (value2 != value1)
  443. {
  444. suppress = Standard_False;
  445. break;
  446. }
  447. }
  448. }
  449. if (suppress)
  450. {
  451. SetZeroSplitData((Voxel_SplitData*)((Voxel_SplitData*)((Voxel_SplitData**)myData)[islice])->GetSplitData());
  452. ((Voxel_SplitData*)((Voxel_SplitData**)myData)[islice])->GetSplitData() = 0;
  453. // Set value to upper level
  454. *((Standard_Byte*)((Voxel_SplitData*)((Voxel_SplitData**)myData)[islice])->GetValues()) = value1;
  455. }
  456. }
  457. }
  458. }
  459. void Voxel_ROctBoolDS::GetCenter(const Standard_Integer ix, const Standard_Integer iy, const Standard_Integer iz,
  460. const Standard_Integer i,
  461. Standard_Real& xc, Standard_Real& yc, Standard_Real& zc) const
  462. {
  463. xc = myX + ix * myDX;
  464. yc = myY + iy * myDY;
  465. zc = myZ + iz * myDZ;
  466. switch (i)
  467. {
  468. case 0:
  469. {
  470. xc += 0.5 * myHalfDX;
  471. yc += 0.5 * myHalfDY;
  472. zc += 0.5 * myHalfDZ;
  473. break;
  474. }
  475. case 1:
  476. {
  477. xc += 1.5 * myHalfDX;
  478. yc += 0.5 * myHalfDY;
  479. zc += 0.5 * myHalfDZ;
  480. break;
  481. }
  482. case 2:
  483. {
  484. xc += 0.5 * myHalfDX;
  485. yc += 1.5 * myHalfDY;
  486. zc += 0.5 * myHalfDZ;
  487. break;
  488. }
  489. case 3:
  490. {
  491. xc += 1.5 * myHalfDX;
  492. yc += 1.5 * myHalfDY;
  493. zc += 0.5 * myHalfDZ;
  494. break;
  495. }
  496. case 4:
  497. {
  498. xc += 0.5 * myHalfDX;
  499. yc += 0.5 * myHalfDY;
  500. zc += 1.5 * myHalfDZ;
  501. break;
  502. }
  503. case 5:
  504. {
  505. xc += 1.5 * myHalfDX;
  506. yc += 0.5 * myHalfDY;
  507. zc += 1.5 * myHalfDZ;
  508. break;
  509. }
  510. case 6:
  511. {
  512. xc += 0.5 * myHalfDX;
  513. yc += 1.5 * myHalfDY;
  514. zc += 1.5 * myHalfDZ;
  515. break;
  516. }
  517. case 7:
  518. {
  519. xc += 1.5 * myHalfDX;
  520. yc += 1.5 * myHalfDY;
  521. zc += 1.5 * myHalfDZ;
  522. break;
  523. }
  524. }
  525. }
  526. void Voxel_ROctBoolDS::GetCenter(const Standard_Integer ix, const Standard_Integer iy, const Standard_Integer iz,
  527. const Standard_Integer i, const Standard_Integer j,
  528. Standard_Real& xc, Standard_Real& yc, Standard_Real& zc) const
  529. {
  530. xc = myX + ix * myDX;
  531. yc = myY + iy * myDY;
  532. zc = myZ + iz * myDZ;
  533. switch (i)
  534. {
  535. case 0:
  536. {
  537. break;
  538. }
  539. case 1:
  540. {
  541. xc += myHalfDX;
  542. break;
  543. }
  544. case 2:
  545. {
  546. yc += myHalfDY;
  547. break;
  548. }
  549. case 3:
  550. {
  551. xc += myHalfDX;
  552. yc += myHalfDY;
  553. break;
  554. }
  555. case 4:
  556. {
  557. zc += myHalfDZ;
  558. break;
  559. }
  560. case 5:
  561. {
  562. xc += myHalfDX;
  563. zc += myHalfDZ;
  564. break;
  565. }
  566. case 6:
  567. {
  568. yc += myHalfDY;
  569. zc += myHalfDZ;
  570. break;
  571. }
  572. case 7:
  573. {
  574. xc += myHalfDX;
  575. yc += myHalfDY;
  576. zc += myHalfDZ;
  577. break;
  578. }
  579. }
  580. switch (j)
  581. {
  582. case 0:
  583. {
  584. xc += 0.25 * myHalfDX;
  585. yc += 0.25 * myHalfDY;
  586. zc += 0.25 * myHalfDZ;
  587. break;
  588. }
  589. case 1:
  590. {
  591. xc += 0.75 * myHalfDX;
  592. yc += 0.25 * myHalfDY;
  593. zc += 0.25 * myHalfDZ;
  594. break;
  595. }
  596. case 2:
  597. {
  598. xc += 0.25 * myHalfDX;
  599. yc += 0.75 * myHalfDY;
  600. zc += 0.25 * myHalfDZ;
  601. break;
  602. }
  603. case 3:
  604. {
  605. xc += 0.75 * myHalfDX;
  606. yc += 0.75 * myHalfDY;
  607. zc += 0.25 * myHalfDZ;
  608. break;
  609. }
  610. case 4:
  611. {
  612. xc += 0.25 * myHalfDX;
  613. yc += 0.25 * myHalfDY;
  614. zc += 0.75 * myHalfDZ;
  615. break;
  616. }
  617. case 5:
  618. {
  619. xc += 0.75 * myHalfDX;
  620. yc += 0.25 * myHalfDY;
  621. zc += 0.75 * myHalfDZ;
  622. break;
  623. }
  624. case 6:
  625. {
  626. xc += 0.25 * myHalfDX;
  627. yc += 0.75 * myHalfDY;
  628. zc += 0.75 * myHalfDZ;
  629. break;
  630. }
  631. case 7:
  632. {
  633. xc += 0.75 * myHalfDX;
  634. yc += 0.75 * myHalfDY;
  635. zc += 0.75 * myHalfDZ;
  636. break;
  637. }
  638. }
  639. }