0026586: Eliminate compile warnings obtained by building occt with vc14: declaration...
[occt.git] / src / Voxel / Voxel_CollisionDetection.cxx
1 // Created on: 2008-07-16
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 <Bnd_Box.hxx>
18 #include <BRepBndLib.hxx>
19 #include <Precision.hxx>
20 #include <TopoDS_Shape.hxx>
21 #include <TopTools_ListIteratorOfListOfShape.hxx>
22 #include <Voxel_BoolDS.hxx>
23 #include <Voxel_CollisionDetection.hxx>
24 #include <Voxel_FastConverter.hxx>
25
26 Voxel_CollisionDetection::Voxel_CollisionDetection()
27 :myDeflection(0.1),
28  myNbX(100),
29  myNbY(100),
30  myNbZ(100),
31  myUsageOfVolume(Standard_False),
32  myKeepCollisions(Standard_False),
33  myXLen(-1.0),
34  myYLen(-1.0),
35  myZLen(-1.0),
36  myVoxels(0),
37  myHasCollisions(Standard_False)
38 {
39
40 }
41
42 Voxel_CollisionDetection::Voxel_CollisionDetection(const Standard_Real deflection,
43                                                    const Standard_Integer nbx,
44                                                    const Standard_Integer nby,
45                                                    const Standard_Integer nbz)
46 :myDeflection(deflection),
47  myNbX(nbx),
48  myNbY(nby),
49  myNbZ(nbz),
50  myUsageOfVolume(Standard_False),
51  myKeepCollisions(Standard_False),
52  myXLen(-1.0),
53  myYLen(-1.0),
54  myZLen(-1.0),
55  myVoxels(0),
56  myHasCollisions(Standard_False)
57 {
58
59 }
60
61 // Destructor
62 void Voxel_CollisionDetection::Destroy()
63 {
64   Clear();
65 }
66
67 Standard_Integer Voxel_CollisionDetection::AddShape(const TopoDS_Shape& shape)
68 {
69   Clear();
70   myShapes.Append(shape);
71   return myShapes.Extent();
72 }
73
74 Standard_Boolean Voxel_CollisionDetection::ReplaceShape(const Standard_Integer ishape,
75                                                         const TopoDS_Shape& shape)
76 {
77   if (ishape == 1)
78   {
79     myShapes.RemoveFirst();
80     myShapes.Prepend(shape);
81     return Standard_True;
82   }
83
84   Standard_Integer i = 1;
85   Standard_Boolean is_replaced = Standard_False;
86   TopTools_ListIteratorOfListOfShape itr(myShapes);
87   for (; itr.More(); itr.Next(), i++)
88   {
89     if (i == ishape)
90     {
91       myShapes.Remove(itr);
92       myShapes.InsertBefore(shape, itr);
93       is_replaced = Standard_True;
94       break;
95     }
96   }
97   return is_replaced;
98 }
99
100 void Voxel_CollisionDetection::SetDeflection(const Standard_Real deflection)
101 {
102   myDeflection = deflection;
103 }
104
105 void Voxel_CollisionDetection::SetNbVoxels(const Standard_Integer nbx,
106                                            const Standard_Integer nby,
107                                            const Standard_Integer nbz)
108 {
109   myNbX = nbx;
110   myNbY = nby;
111   myNbZ = nbz;
112 }
113
114 void Voxel_CollisionDetection::SetBoundaryBox(const Bnd_Box& box)
115 {
116   if (box.IsVoid())
117     return;
118
119   Standard_Real xmin, ymin, zmin, xmax, ymax, zmax;
120   box.Get(xmin, ymin, zmin, xmax, ymax, zmax);
121   
122   myX = xmin;
123   myY = ymin;
124   myZ = zmin;
125
126   myXLen = xmax - xmin;
127   myYLen = ymax - ymin;
128   myZLen = zmax - zmin;
129 }
130
131 void Voxel_CollisionDetection::SetUsageOfVolume(const Standard_Boolean usage)
132 {
133   myUsageOfVolume = usage;
134 }
135
136 void Voxel_CollisionDetection::KeepCollisions(const Standard_Boolean keep)
137 {
138   myKeepCollisions = keep;
139 }
140
141 Standard_Boolean Voxel_CollisionDetection::Voxelize(const Standard_Integer ishape)
142 {
143   // Check the arguments
144   if (myNbX <= 0 || myNbY <= 0 || myNbZ <= 0)
145     return Standard_False;
146
147   // Calculate the boundary box of the shapes to define the size of voxels.
148   // This code is called only if the user didn't define the boundary box himself.
149   if (myXLen < 0.0)
150   {
151     Bnd_Box B, b;
152     TopTools_ListIteratorOfListOfShape itrs(myShapes);
153     for (; itrs.More(); itrs.Next())
154     {
155       TopoDS_Shape S = itrs.Value();
156       BRepBndLib::Add(S, b);
157       B.Add(b);
158     }
159     SetBoundaryBox(B);
160   }
161
162   // Voxelize the shapes
163   Standard_Integer progress, ithread = 1, i = 1;
164   TopTools_ListIteratorOfListOfShape itrs(myShapes);
165   for (; itrs.More(); itrs.Next(), i++)
166   {
167     if (ishape != -1 && i != ishape)
168       continue;
169
170     if (!myVoxels)
171       myVoxels = (Standard_Address) new Voxel_BoolDS[myShapes.Extent()];
172     Voxel_BoolDS& voxels = ((Voxel_BoolDS*)myVoxels)[i - 1];
173     if (!CheckVoxels(voxels))
174     {
175       voxels.Init(myX, myY, myZ, myXLen, myYLen, myZLen, myNbX, myNbY, myNbZ);
176     }
177     else
178     {
179       voxels.SetZero();
180     }
181
182     TopoDS_Shape S = itrs.Value();
183     Voxel_FastConverter voxelizer(S, voxels, myDeflection, myNbX, myNbY, myNbZ, 1 /*number of threads */);
184     if (!voxelizer.Convert(progress, ithread))
185       return Standard_False;
186     if (myUsageOfVolume && !voxelizer.FillInVolume(1, ithread))
187       return Standard_False;
188   }
189
190   return Standard_True;
191 }
192
193 Standard_Boolean Voxel_CollisionDetection::Compute()
194 {
195   myHasCollisions = Standard_False;
196
197   // Check voxels of shapes
198   if (!myVoxels)
199     return Standard_False;
200   Standard_Integer ishape = 0, nb_shapes = myShapes.Extent();
201   for (; ishape < nb_shapes; ishape++)
202   {
203     Voxel_BoolDS& voxels = ((Voxel_BoolDS*)myVoxels)[ishape];
204     if (!CheckVoxels(voxels))
205     {
206       return Standard_False;
207     }
208   }
209
210   // Check the resulting voxels
211   Standard_Boolean created = Standard_False;
212   if (!CheckVoxels(myCollisions))
213   {
214     // Create 0-voxels for the result, if it is needed.
215     created = Standard_True;
216     myCollisions.Init(myX, myY, myZ, myXLen, myYLen, myZLen, myNbX, myNbY, myNbZ);
217   }
218
219   // Nullify the voxels of the result (it corresponds to the state of no collisions).
220   if (!myKeepCollisions && !created)
221   {
222     myCollisions.SetZero();
223   }
224   
225   // Check collisions
226   if (nb_shapes)
227   {
228     Standard_Integer ix, iy, iz;
229     Voxel_BoolDS& voxels = ((Voxel_BoolDS*)myVoxels)[0]; // 1st shape
230     for (ix = 0; ix < myNbX; ix++)
231     {
232       for (iy = 0; iy < myNbY; iy++)
233       {
234         for (iz = 0; iz < myNbZ; iz++)
235         {
236           if (voxels.Get(ix, iy, iz))
237           {
238             for (ishape = 1; ishape < nb_shapes; ishape++) // start with second shape
239             {
240               Voxel_BoolDS& anOtherVoxels = ((Voxel_BoolDS*)myVoxels)[ishape];
241               if (anOtherVoxels.Get(ix, iy, iz))
242               {
243                 myCollisions.Set(ix, iy, iz, Standard_True);
244                 if (!myHasCollisions)
245                 {
246                   myHasCollisions = Standard_True;
247                 }
248                 break;
249               }
250             }
251           }
252         }
253       }
254     }
255   }
256
257
258   return Standard_True;
259 }
260
261 Standard_Boolean Voxel_CollisionDetection::HasCollisions() const
262 {
263   return myHasCollisions;
264 }
265
266 const Voxel_BoolDS& Voxel_CollisionDetection::GetCollisions() const
267 {
268   return myCollisions;
269 }
270
271 void Voxel_CollisionDetection::Clear()
272 {
273   if (myVoxels)
274   {
275     delete[] ((Voxel_BoolDS*)myVoxels);
276     myVoxels = 0;
277   }
278 }
279
280 Standard_Boolean Voxel_CollisionDetection::CheckVoxels(const Voxel_BoolDS& voxels) const
281 {
282   if (fabs(voxels.GetX() - myX) > Precision::Confusion() ||
283       fabs(voxels.GetY() - myY) > Precision::Confusion() ||
284       fabs(voxels.GetZ() - myZ) > Precision::Confusion() ||
285       fabs(voxels.GetXLen() - myXLen) > Precision::Confusion() ||
286       fabs(voxels.GetYLen() - myYLen) > Precision::Confusion() ||
287       fabs(voxels.GetZLen() - myZLen) > Precision::Confusion() ||
288       voxels.GetNbX() != myNbX ||
289       voxels.GetNbY() != myNbY ||
290       voxels.GetNbZ() != myNbZ)
291   {
292     return Standard_False;
293   }
294   return Standard_True;
295 }