1 // Created on: 2008-07-16
2 // Created by: Vladislav ROMASHKO
3 // Copyright (c) 2008-2014 OPEN CASCADE SAS
5 // This file is part of Open CASCADE Technology software library.
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.
13 // Alternatively, this file may be used under the terms of Open CASCADE
14 // commercial license or contractual agreement.
16 #include <Voxel_CollisionDetection.ixx>
17 #include <Voxel_FastConverter.hxx>
19 #include <Precision.hxx>
20 #include <BRepBndLib.hxx>
21 #include <TopTools_ListIteratorOfListOfShape.hxx>
25 Voxel_CollisionDetection::Voxel_CollisionDetection()
30 myUsageOfVolume(Standard_False),
31 myKeepCollisions(Standard_False),
36 myHasCollisions(Standard_False)
41 Voxel_CollisionDetection::Voxel_CollisionDetection(const Standard_Real deflection,
42 const Standard_Integer nbx,
43 const Standard_Integer nby,
44 const Standard_Integer nbz)
45 :myDeflection(deflection),
49 myUsageOfVolume(Standard_False),
50 myKeepCollisions(Standard_False),
55 myHasCollisions(Standard_False)
61 void Voxel_CollisionDetection::Destroy()
66 Standard_Integer Voxel_CollisionDetection::AddShape(const TopoDS_Shape& shape)
69 myShapes.Append(shape);
70 return myShapes.Extent();
73 Standard_Boolean Voxel_CollisionDetection::ReplaceShape(const Standard_Integer ishape,
74 const TopoDS_Shape& shape)
78 myShapes.RemoveFirst();
79 myShapes.Prepend(shape);
83 Standard_Integer i = 1;
84 Standard_Boolean is_replaced = Standard_False;
85 TopTools_ListIteratorOfListOfShape itr(myShapes);
86 for (; itr.More(); itr.Next(), i++)
91 myShapes.InsertBefore(shape, itr);
92 is_replaced = Standard_True;
99 void Voxel_CollisionDetection::SetDeflection(const Standard_Real deflection)
101 myDeflection = deflection;
104 void Voxel_CollisionDetection::SetNbVoxels(const Standard_Integer nbx,
105 const Standard_Integer nby,
106 const Standard_Integer nbz)
113 void Voxel_CollisionDetection::SetBoundaryBox(const Bnd_Box& box)
118 Standard_Real xmin, ymin, zmin, xmax, ymax, zmax;
119 box.Get(xmin, ymin, zmin, xmax, ymax, zmax);
125 myXLen = xmax - xmin;
126 myYLen = ymax - ymin;
127 myZLen = zmax - zmin;
130 void Voxel_CollisionDetection::SetUsageOfVolume(const Standard_Boolean usage)
132 myUsageOfVolume = usage;
135 void Voxel_CollisionDetection::KeepCollisions(const Standard_Boolean keep)
137 myKeepCollisions = keep;
140 Standard_Boolean Voxel_CollisionDetection::Voxelize(const Standard_Integer ishape)
142 // Check the arguments
143 if (myNbX <= 0 || myNbY <= 0 || myNbZ <= 0)
144 return Standard_False;
146 // Calculate the boundary box of the shapes to define the size of voxels.
147 // This code is called only if the user didn't define the boundary box himself.
151 TopTools_ListIteratorOfListOfShape itrs(myShapes);
152 for (; itrs.More(); itrs.Next())
154 TopoDS_Shape S = itrs.Value();
155 BRepBndLib::Add(S, b);
161 // Voxelize the shapes
162 Standard_Integer progress, ithread = 1, i = 1;
163 TopTools_ListIteratorOfListOfShape itrs(myShapes);
164 for (; itrs.More(); itrs.Next(), i++)
166 if (ishape != -1 && i != ishape)
170 myVoxels = (Standard_Address) new Voxel_BoolDS[myShapes.Extent()];
171 Voxel_BoolDS& voxels = ((Voxel_BoolDS*)myVoxels)[i - 1];
172 if (!CheckVoxels(voxels))
174 voxels.Init(myX, myY, myZ, myXLen, myYLen, myZLen, myNbX, myNbY, myNbZ);
181 TopoDS_Shape S = itrs.Value();
182 Voxel_FastConverter voxelizer(S, voxels, myDeflection, myNbX, myNbY, myNbZ, 1 /*number of threads */);
183 if (!voxelizer.Convert(progress, ithread))
184 return Standard_False;
185 if (myUsageOfVolume && !voxelizer.FillInVolume(1, ithread))
186 return Standard_False;
189 return Standard_True;
192 Standard_Boolean Voxel_CollisionDetection::Compute()
194 myHasCollisions = Standard_False;
196 // Check voxels of shapes
198 return Standard_False;
199 Standard_Integer ishape = 0, nb_shapes = myShapes.Extent();
200 for (; ishape < nb_shapes; ishape++)
202 Voxel_BoolDS& voxels = ((Voxel_BoolDS*)myVoxels)[ishape];
203 if (!CheckVoxels(voxels))
205 return Standard_False;
209 // Check the resulting voxels
210 Standard_Boolean created = Standard_False;
211 if (!CheckVoxels(myCollisions))
213 // Create 0-voxels for the result, if it is needed.
214 created = Standard_True;
215 myCollisions.Init(myX, myY, myZ, myXLen, myYLen, myZLen, myNbX, myNbY, myNbZ);
218 // Nullify the voxels of the result (it corresponds to the state of no collisions).
219 if (!myKeepCollisions && !created)
221 myCollisions.SetZero();
227 Standard_Integer ix, iy, iz;
228 Voxel_BoolDS& voxels = ((Voxel_BoolDS*)myVoxels)[0]; // 1st shape
229 for (ix = 0; ix < myNbX; ix++)
231 for (iy = 0; iy < myNbY; iy++)
233 for (iz = 0; iz < myNbZ; iz++)
235 if (voxels.Get(ix, iy, iz))
237 for (ishape = 1; ishape < nb_shapes; ishape++) // start with second shape
239 Voxel_BoolDS& voxels = ((Voxel_BoolDS*)myVoxels)[ishape];
240 if (voxels.Get(ix, iy, iz))
242 myCollisions.Set(ix, iy, iz, Standard_True);
243 if (!myHasCollisions)
245 myHasCollisions = Standard_True;
257 return Standard_True;
260 Standard_Boolean Voxel_CollisionDetection::HasCollisions() const
262 return myHasCollisions;
265 const Voxel_BoolDS& Voxel_CollisionDetection::GetCollisions() const
270 void Voxel_CollisionDetection::Clear()
274 delete ((Voxel_BoolDS*)myVoxels);
279 Standard_Boolean Voxel_CollisionDetection::CheckVoxels(const Voxel_BoolDS& voxels) const
281 if (fabs(voxels.GetX() - myX) > Precision::Confusion() ||
282 fabs(voxels.GetY() - myY) > Precision::Confusion() ||
283 fabs(voxels.GetZ() - myZ) > Precision::Confusion() ||
284 fabs(voxels.GetXLen() - myXLen) > Precision::Confusion() ||
285 fabs(voxels.GetYLen() - myYLen) > Precision::Confusion() ||
286 fabs(voxels.GetZLen() - myZLen) > Precision::Confusion() ||
287 voxels.GetNbX() != myNbX ||
288 voxels.GetNbY() != myNbY ||
289 voxels.GetNbZ() != myNbZ)
291 return Standard_False;
293 return Standard_True;