b72ac6545d8e50b4341862101d857aeeb349996c
[occt.git] / src / Voxel / Voxel_BooleanOperation.cxx
1 // Created on: 2008-05-21
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_BooleanOperation.ixx>
22 #include <Precision.hxx>
23
24 Voxel_BooleanOperation::Voxel_BooleanOperation()
25 {
26
27 }
28
29 Standard_Boolean Voxel_BooleanOperation::Fuse(      Voxel_BoolDS& theVoxels1,
30                                               const Voxel_BoolDS& theVoxels2) const
31 {
32   // Check the voxels
33   if (!Check(theVoxels1, theVoxels2))
34     return Standard_False;
35
36   // Take the values of the second cube and put them to the first one.
37   Standard_Integer ix, iy, iz;
38   for (iz = 0; iz < theVoxels2.GetNbZ(); iz++)
39   {
40     for (iy = 0; iy < theVoxels2.GetNbY(); iy++)
41     {
42       for (ix = 0; ix < theVoxels2.GetNbX(); ix++)
43       {
44         Standard_Boolean value2 = theVoxels2.Get(ix, iy, iz);
45         if (value2)
46           theVoxels1.Set(ix, iy, iz, value2);
47       }
48     }
49   }
50
51   return Standard_True;
52 }
53
54 Standard_Boolean Voxel_BooleanOperation::Fuse(      Voxel_ColorDS& theVoxels1,
55                                               const Voxel_ColorDS& theVoxels2) const
56 {
57   // Check the voxels
58   if (!Check(theVoxels1, theVoxels2))
59     return Standard_False;
60
61   // Take the values of the second cube and put them to the first one.
62   Standard_Integer ix, iy, iz;
63   for (iz = 0; iz < theVoxels2.GetNbZ(); iz++)
64   {
65     for (iy = 0; iy < theVoxels2.GetNbY(); iy++)
66     {
67       for (ix = 0; ix < theVoxels2.GetNbX(); ix++)
68       {
69         Standard_Byte value2 = theVoxels2.Get(ix, iy, iz);
70         if (value2)
71         {
72           Standard_Byte value1 = theVoxels1.Get(ix, iy, iz);
73           Standard_Byte value = value1 + value2;
74           if (value > 15)
75             value = 15;
76           theVoxels1.Set(ix, iy, iz, value);
77         }
78       }
79     }
80   }
81
82   return Standard_True;
83 }
84
85 Standard_Boolean Voxel_BooleanOperation::Fuse(      Voxel_FloatDS& theVoxels1,
86                                               const Voxel_FloatDS& theVoxels2) const
87 {
88   // Check the voxels
89   if (!Check(theVoxels1, theVoxels2))
90     return Standard_False;
91
92   // Take the values of the second cube and put them to the first one.
93   Standard_Integer ix, iy, iz;
94   for (iz = 0; iz < theVoxels2.GetNbZ(); iz++)
95   {
96     for (iy = 0; iy < theVoxels2.GetNbY(); iy++)
97     {
98       for (ix = 0; ix < theVoxels2.GetNbX(); ix++)
99       {
100         Standard_ShortReal value2 = theVoxels2.Get(ix, iy, iz);
101         if (value2)
102         {
103           Standard_ShortReal value1 = theVoxels1.Get(ix, iy, iz);
104           theVoxels1.Set(ix, iy, iz, value1 + value2);
105         }
106       }
107     }
108   }
109
110   return Standard_True;
111 }
112
113 Standard_Boolean Voxel_BooleanOperation::Cut(      Voxel_BoolDS& theVoxels1,
114                                              const Voxel_BoolDS& theVoxels2) const
115 {
116   // Check the voxels
117   if (!Check(theVoxels1, theVoxels2))
118     return Standard_False;
119
120   // Subtract the values.
121   Standard_Integer ix, iy, iz;
122   for (iz = 0; iz < theVoxels2.GetNbZ(); iz++)
123   {
124     for (iy = 0; iy < theVoxels2.GetNbY(); iy++)
125     {
126       for (ix = 0; ix < theVoxels2.GetNbX(); ix++)
127       {
128         Standard_Boolean value1 = theVoxels1.Get(ix, iy, iz);
129         if (value1)
130         {
131           Standard_Boolean value2 = theVoxels2.Get(ix, iy, iz);
132           if (value2)
133             theVoxels1.Set(ix, iy, iz, Standard_False);
134         }
135       }
136     }
137   }
138
139   return Standard_True;
140 }
141
142 Standard_Boolean Voxel_BooleanOperation::Cut(      Voxel_ColorDS& theVoxels1,
143                                              const Voxel_ColorDS& theVoxels2) const
144 {
145   // Check the voxels
146   if (!Check(theVoxels1, theVoxels2))
147     return Standard_False;
148
149   // Subtract the values.
150   Standard_Integer ix, iy, iz;
151   for (iz = 0; iz < theVoxels2.GetNbZ(); iz++)
152   {
153     for (iy = 0; iy < theVoxels2.GetNbY(); iy++)
154     {
155       for (ix = 0; ix < theVoxels2.GetNbX(); ix++)
156       {
157         Standard_Byte value2 = theVoxels2.Get(ix, iy, iz);
158         if (value2)
159         {
160           Standard_Byte value1 = theVoxels1.Get(ix, iy, iz);
161           if (value1)
162           {
163             Standard_Integer value = value1 - value2;
164             if (value < 0)
165               value = 0;
166             theVoxels1.Set(ix, iy, iz, value);
167           }
168         }
169       }
170     }
171   }
172
173   return Standard_True;
174 }
175
176 Standard_Boolean Voxel_BooleanOperation::Cut(      Voxel_FloatDS& theVoxels1,
177                                              const Voxel_FloatDS& theVoxels2) const
178 {
179   // Check the voxels
180   if (!Check(theVoxels1, theVoxels2))
181     return Standard_False;
182
183   // Subtract the values.
184   Standard_Integer ix, iy, iz;
185   for (iz = 0; iz < theVoxels2.GetNbZ(); iz++)
186   {
187     for (iy = 0; iy < theVoxels2.GetNbY(); iy++)
188     {
189       for (ix = 0; ix < theVoxels2.GetNbX(); ix++)
190       {
191         Standard_ShortReal value2 = theVoxels2.Get(ix, iy, iz);
192         if (value2)
193         {
194           Standard_ShortReal value1 = theVoxels1.Get(ix, iy, iz);
195           theVoxels1.Set(ix, iy, iz, value1 - value2);
196         }
197       }
198     }
199   }
200
201   return Standard_True;
202 }
203
204 Standard_Boolean Voxel_BooleanOperation::Check(const Voxel_DS& theVoxels1,
205                                                const Voxel_DS& theVoxels2) const
206 {
207   // Check the voxels
208   // Number of splits along X, Y and Z axes.
209   if (!theVoxels1.GetNbX() && theVoxels1.GetNbX() != theVoxels2.GetNbX())
210     return Standard_False;
211   if (!theVoxels1.GetNbY() && theVoxels1.GetNbY() != theVoxels2.GetNbY())
212     return Standard_False;
213   if (!theVoxels1.GetNbZ() && theVoxels1.GetNbZ() != theVoxels2.GetNbZ())
214     return Standard_False;
215   // Start point
216   if (fabs(theVoxels1.GetX() - theVoxels2.GetX()) > Precision::Confusion() ||
217       fabs(theVoxels1.GetY() - theVoxels2.GetY()) > Precision::Confusion() ||
218       fabs(theVoxels1.GetZ() - theVoxels2.GetZ()) > Precision::Confusion())
219   {
220     return Standard_False;
221   }
222   // Length along X, Y and Z axes.
223   if (fabs(theVoxels1.GetXLen() - theVoxels2.GetXLen()) > Precision::Confusion() ||
224       fabs(theVoxels1.GetYLen() - theVoxels2.GetYLen()) > Precision::Confusion() ||
225       fabs(theVoxels1.GetZLen() - theVoxels2.GetZLen()) > Precision::Confusion())
226   {
227     return Standard_False;
228   }
229   return Standard_True;
230 }