0023889: Assignment of function parameter has no effect outside the function.
[occt.git] / src / Voxel / Voxel_ROctBoolDS.cxx
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
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   }
90   delete data;
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       {
102         SetZeroSplitData((Voxel_SplitData*)((Voxel_SplitData**)myData)[ix]);
103         ((Voxel_SplitData**)myData)[ix] = 0;
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 }