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