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