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