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