Commit | Line | Data |
---|---|---|
b311480e | 1 | // Created on: 2008-05-30 |
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_FastConverter.ixx> | |
22 | ||
23 | #include <Bnd_Box.hxx> | |
24 | #include <BRep_Tool.hxx> | |
25 | #include <BRepBndLib.hxx> | |
26 | #include <BRepMesh.hxx> | |
27 | ||
28 | #include <TopoDS.hxx> | |
29 | #include <TopoDS_Face.hxx> | |
30 | #include <TopExp_Explorer.hxx> | |
31 | ||
32 | #include <gp_Lin2d.hxx> | |
33 | #include <gce_MakePln.hxx> | |
34 | ||
35 | #include <ElSLib.hxx> | |
36 | #include <Poly_Triangulation.hxx> | |
37 | #include <IntAna2d_AnaIntersection.hxx> | |
38 | ||
39 | // Printing the progress in stdout. | |
40 | //#define CONV_DUMP | |
41 | ||
42 | Voxel_FastConverter::Voxel_FastConverter(const TopoDS_Shape& shape, | |
43 | Voxel_ROctBoolDS& voxels, | |
44 | const Standard_Real deflection, | |
45 | const Standard_Integer nbx, | |
46 | const Standard_Integer nby, | |
47 | const Standard_Integer nbz, | |
c5e9fb8b P |
48 | const Standard_Integer nbthreads, |
49 | const Standard_Boolean useExistingTriangulation) | |
7fd59977 | 50 | :myShape(shape),myVoxels(&voxels), |
51 | myDeflection(deflection), | |
52 | myNbX(nbx),myNbY(nby),myNbZ(nbz), | |
53 | myNbThreads(nbthreads),myIsBool(2), | |
c5e9fb8b P |
54 | myNbTriangles(0), |
55 | myUseExistingTriangulation(useExistingTriangulation) | |
7fd59977 | 56 | { |
57 | Init(); | |
58 | } | |
59 | ||
60 | Voxel_FastConverter::Voxel_FastConverter(const TopoDS_Shape& shape, | |
61 | Voxel_BoolDS& voxels, | |
62 | const Standard_Real deflection, | |
63 | const Standard_Integer nbx, | |
64 | const Standard_Integer nby, | |
65 | const Standard_Integer nbz, | |
c5e9fb8b P |
66 | const Standard_Integer nbthreads, |
67 | const Standard_Boolean useExistingTriangulation) | |
7fd59977 | 68 | :myShape(shape),myVoxels(&voxels), |
69 | myDeflection(deflection), | |
70 | myNbX(nbx),myNbY(nby),myNbZ(nbz), | |
71 | myNbThreads(nbthreads),myIsBool(1), | |
c5e9fb8b P |
72 | myNbTriangles(0), |
73 | myUseExistingTriangulation(useExistingTriangulation) | |
7fd59977 | 74 | { |
75 | Init(); | |
76 | } | |
77 | ||
78 | Voxel_FastConverter::Voxel_FastConverter(const TopoDS_Shape& shape, | |
79 | Voxel_ColorDS& voxels, | |
80 | const Standard_Real deflection, | |
81 | const Standard_Integer nbx, | |
82 | const Standard_Integer nby, | |
83 | const Standard_Integer nbz, | |
c5e9fb8b P |
84 | const Standard_Integer nbthreads, |
85 | const Standard_Boolean useExistingTriangulation) | |
7fd59977 | 86 | :myShape(shape),myVoxels(&voxels), |
87 | myDeflection(deflection), | |
88 | myNbX(nbx),myNbY(nby),myNbZ(nbz), | |
89 | myNbThreads(nbthreads),myIsBool(0), | |
c5e9fb8b P |
90 | myNbTriangles(0), |
91 | myUseExistingTriangulation(useExistingTriangulation) | |
7fd59977 | 92 | { |
93 | Init(); | |
94 | } | |
95 | ||
96 | void Voxel_FastConverter::Init() | |
97 | { | |
98 | if (myShape.IsNull()) | |
99 | return; | |
100 | if (myNbThreads < 1) | |
101 | return; | |
102 | ||
103 | // Check number of splits. | |
104 | Voxel_DS* voxels = (Voxel_DS*) myVoxels; | |
105 | if (voxels->GetNbX() != myNbX || voxels->GetNbY() != myNbY || voxels->GetNbZ() != myNbZ) | |
106 | { | |
107 | // Compute boundary box of the shape | |
108 | Bnd_Box box; | |
109 | BRepBndLib::Add(myShape, box); | |
110 | ||
111 | // Define the voxel model by means of the boundary box of shape | |
112 | Standard_Real xmin, ymin, zmin, xmax, ymax, zmax; | |
113 | box.Get(xmin, ymin, zmin, xmax, ymax, zmax); | |
114 | ||
115 | // Initialize the voxels. | |
116 | if (myIsBool == 2) | |
117 | ((Voxel_ROctBoolDS*) voxels)->Init(xmin, ymin, zmin, xmax - xmin, ymax - ymin, zmax - zmin, myNbX, myNbY, myNbZ); | |
118 | else if (myIsBool == 1) | |
119 | ((Voxel_BoolDS*) voxels)->Init(xmin, ymin, zmin, xmax - xmin, ymax - ymin, zmax - zmin, myNbX, myNbY, myNbZ); | |
120 | else if (myIsBool == 0) | |
121 | ((Voxel_ColorDS*) voxels)->Init(xmin, ymin, zmin, xmax - xmin, ymax - ymin, zmax - zmin, myNbX, myNbY, myNbZ); | |
122 | } | |
123 | ||
124 | // Check presence of triangulation. | |
125 | TopLoc_Location L; | |
126 | Standard_Boolean triangulate = Standard_False; | |
127 | TopExp_Explorer expl(myShape, TopAbs_FACE); | |
c5e9fb8b | 128 | if(myUseExistingTriangulation == Standard_False) |
7fd59977 | 129 | { |
c5e9fb8b | 130 | for (; expl.More(); expl.Next()) |
7fd59977 | 131 | { |
c5e9fb8b P |
132 | const TopoDS_Face & F = TopoDS::Face(expl.Current()); |
133 | Handle(Poly_Triangulation) T = BRep_Tool::Triangulation(F, L); | |
134 | if (T.IsNull() || (T->Deflection() > myDeflection)) | |
135 | { | |
136 | triangulate = Standard_True; | |
137 | break; | |
138 | } | |
7fd59977 | 139 | } |
140 | } | |
141 | ||
142 | // Re-create the triangulation. | |
143 | if (triangulate) | |
144 | { | |
145 | BRepMesh::Mesh(myShape, myDeflection); | |
146 | } | |
147 | ||
148 | // Compute the number of triangles. | |
149 | myNbTriangles = 0; | |
150 | expl.Init(myShape, TopAbs_FACE); | |
151 | for (; expl.More(); expl.Next()) | |
152 | { | |
034b4775 | 153 | const TopoDS_Face & F = TopoDS::Face(expl.Current()); |
7fd59977 | 154 | Handle(Poly_Triangulation) T = BRep_Tool::Triangulation(F, L); |
034b4775 P |
155 | if (T.IsNull() == Standard_False) |
156 | myNbTriangles += T->NbTriangles(); | |
7fd59977 | 157 | } |
158 | } | |
159 | ||
160 | // Destructor | |
161 | void Voxel_FastConverter::Destroy() | |
162 | { | |
163 | ||
164 | } | |
165 | ||
166 | Standard_Boolean Voxel_FastConverter::Convert(Standard_Integer& progress, | |
167 | const Standard_Integer ithread) | |
168 | { | |
169 | if (ithread == 1) | |
170 | progress = 0; | |
171 | #ifdef CONV_DUMP | |
172 | if (ithread == 1) | |
173 | printf("Progress = %d \r", progress); | |
174 | #endif | |
175 | ||
176 | if (myNbX <= 0 || myNbY <= 0 || myNbZ <= 0) | |
177 | return Standard_False; | |
178 | ||
c5e9fb8b P |
179 | if(myNbTriangles == 0) |
180 | return Standard_False; | |
181 | ||
7fd59977 | 182 | // Half of diagonal of a voxel |
183 | Voxel_DS* ds = (Voxel_DS*) myVoxels; | |
184 | Standard_Real dx = ds->GetXLen() / (Standard_Real) ds->GetNbX(), | |
185 | dy = ds->GetYLen() / (Standard_Real) ds->GetNbY(), | |
186 | dz = ds->GetZLen() / (Standard_Real) ds->GetNbZ(); | |
187 | Standard_Real hdiagonal = sqrt(dx * dx + dy * dy + dz * dz); | |
188 | hdiagonal /= 2.0; | |
189 | ||
190 | // Compute the scope of triangles for current thread | |
191 | Standard_Integer start_thread_triangle = 1, end_thread_triangle = myNbTriangles, ithread_triangle = 0; | |
192 | start_thread_triangle = (ithread - 1) * (myNbTriangles / myNbThreads) + 1; | |
193 | end_thread_triangle = (ithread - 0) * (myNbTriangles / myNbThreads); | |
194 | ||
195 | // Convert | |
196 | TopLoc_Location L; | |
197 | Standard_Integer iprogress = 0, prev_progress = 0; | |
198 | Standard_Integer n1, n2, n3; | |
199 | Standard_Integer ixmin, iymin, izmin, ixmax, iymax, izmax; | |
200 | Standard_Real xmin, ymin, zmin, xmax, ymax, zmax; | |
201 | TopExp_Explorer expl(myShape, TopAbs_FACE); | |
202 | for (; expl.More(); expl.Next()) | |
203 | { | |
034b4775 | 204 | const TopoDS_Face & F = TopoDS::Face(expl.Current()); |
7fd59977 | 205 | Handle(Poly_Triangulation) T = BRep_Tool::Triangulation(F, L); |
034b4775 P |
206 | if (T.IsNull()) |
207 | continue; | |
7fd59977 | 208 | |
209 | gp_Trsf trsf; | |
210 | Standard_Boolean transform = !L.IsIdentity(); | |
211 | if (transform) | |
212 | trsf = L.Transformation(); | |
213 | ||
214 | const TColgp_Array1OfPnt& nodes = T->Nodes(); | |
215 | const Poly_Array1OfTriangle& triangles = T->Triangles(); | |
216 | Standard_Integer itriangle = triangles.Lower(), nb_triangles = triangles.Upper(); | |
217 | for (; itriangle <= nb_triangles; itriangle++) | |
218 | { | |
219 | ithread_triangle++; | |
da8536ad P |
220 | if (ithread_triangle < start_thread_triangle ) |
221 | continue; | |
222 | if (ithread_triangle > end_thread_triangle) | |
223 | { | |
224 | if (ithread == 1) | |
225 | progress = 100; | |
226 | #ifdef CONV_DUMP | |
227 | if (ithread == 1) | |
228 | printf("Progress = %d \r", progress); | |
229 | #endif | |
230 | return Standard_True; | |
231 | } | |
7fd59977 | 232 | |
233 | const Poly_Triangle& t = triangles.Value(itriangle); | |
234 | t.Get(n1, n2, n3); | |
235 | gp_Pnt p1 = nodes.Value(n1); | |
236 | gp_Pnt p2 = nodes.Value(n2); | |
237 | gp_Pnt p3 = nodes.Value(n3); | |
238 | if (transform) | |
239 | { | |
da8536ad P |
240 | p1.Transform(trsf); |
241 | p2.Transform(trsf); | |
242 | p3.Transform(trsf); | |
7fd59977 | 243 | } |
244 | ||
245 | // Get boundary box of the triangle | |
246 | GetBndBox(p1, p2, p3, xmin, ymin, zmin, xmax, ymax, zmax); | |
247 | ||
248 | // Find the range of voxels inside the boudary box of the triangle. | |
249 | if (!ds->GetVoxel(xmin, ymin, zmin, ixmin, iymin, izmin)) | |
250 | continue; | |
251 | if (!ds->GetVoxel(xmax, ymax, zmax, ixmax, iymax, izmax)) | |
252 | continue; | |
253 | ||
254 | // Refuse voxels for whom distance from their center to plane of triangle is greater than half of diagonal. | |
255 | // Make a line from center of each voxel to the center of triangle and | |
256 | // compute intersection of the line with sides of triangle. | |
257 | // Refuse the voxel in case of intersection. | |
258 | gce_MakePln mkPlane(p1, p2, p3); | |
259 | if (!mkPlane.IsDone()) | |
260 | continue; | |
261 | gp_Pln plane = mkPlane.Value(); | |
262 | ComputeVoxelsNearTriangle(plane, p1, p2, p3, hdiagonal, ixmin, iymin, izmin, ixmax, iymax, izmax); | |
263 | ||
264 | // Progress | |
265 | if (ithread == 1) | |
266 | { | |
267 | iprogress++; | |
268 | progress = (Standard_Integer) ( (Standard_Real) iprogress / (Standard_Real) myNbTriangles * 100.0 ); | |
269 | } | |
270 | #ifdef CONV_DUMP | |
271 | if (ithread == 1 && prev_progress != progress) | |
272 | { | |
273 | printf("Progress = %d \r", progress); | |
274 | prev_progress = progress; | |
275 | } | |
276 | #endif | |
277 | ||
278 | } // iteration of triangles | |
279 | } // iteration of faces | |
280 | ||
281 | if (ithread == 1) | |
282 | progress = 100; | |
283 | #ifdef CONV_DUMP | |
284 | if (ithread == 1) | |
285 | printf("Progress = %d \r", progress); | |
286 | #endif | |
287 | return Standard_True; | |
288 | } | |
289 | ||
290 | Standard_Boolean Voxel_FastConverter::FillInVolume(const Standard_Byte inner, | |
291 | const Standard_Integer ithread) | |
292 | { | |
293 | Voxel_DS* ds = (Voxel_DS*) myVoxels; | |
294 | Standard_Integer ix, iy, iz, nbx = ds->GetNbX(), nby = ds->GetNbY(), nbz = ds->GetNbZ(); | |
295 | Standard_Boolean prev_surface, surface, volume; | |
296 | ||
297 | if (inner) | |
298 | { | |
299 | // Fill-in internal voxels by the value "inner" | |
300 | for (ix = 0; ix < nbx; ix++) | |
301 | { | |
302 | for (iy = 0; iy < nby; iy++) | |
303 | { | |
304 | // Check existence of volume. | |
305 | volume = Standard_False; | |
306 | surface = Standard_False; | |
307 | prev_surface = Standard_False; | |
308 | for (iz = 0; iz < nbz; iz++) | |
309 | { | |
310 | surface = (myIsBool == 1) ? | |
311 | ((Voxel_BoolDS*)myVoxels)->Get(ix, iy, iz) == Standard_True : | |
312 | ((Voxel_ColorDS*)myVoxels)->Get(ix, iy, iz) > 0; | |
313 | if (prev_surface && !surface) | |
314 | { | |
315 | volume = !volume; | |
316 | } | |
317 | prev_surface = surface; | |
318 | } | |
319 | if (volume) | |
320 | continue; | |
321 | ||
322 | // Fill-in the volume. | |
323 | volume = Standard_False; | |
324 | surface = Standard_False; | |
325 | prev_surface = Standard_False; | |
326 | for (iz = 0; iz < nbz; iz++) | |
327 | { | |
328 | surface = (myIsBool == 1) ? | |
329 | ((Voxel_BoolDS*)myVoxels)->Get(ix, iy, iz) == Standard_True : | |
330 | ((Voxel_ColorDS*)myVoxels)->Get(ix, iy, iz) > 0; | |
331 | if (prev_surface && !surface) | |
332 | { | |
333 | volume = !volume; | |
334 | } | |
335 | if (volume && !surface) | |
336 | { | |
337 | (myIsBool == 1) ? ((Voxel_BoolDS*)myVoxels)->Set(ix, iy, iz, inner) : | |
338 | ((Voxel_ColorDS*)myVoxels)->Set(ix, iy, iz, inner); | |
339 | } | |
340 | prev_surface = surface; | |
341 | } | |
342 | } | |
343 | } | |
344 | } | |
345 | else | |
346 | { | |
347 | // Set value of interbal voxels to 0 ("inner" = 0) | |
348 | Standard_Boolean next_surface; | |
349 | for (ix = 0; ix < nbx; ix++) | |
350 | { | |
351 | for (iy = 0; iy < nby; iy++) | |
352 | { | |
353 | volume = Standard_False; | |
354 | surface = Standard_False; | |
355 | prev_surface = Standard_False; | |
356 | next_surface = Standard_False; | |
357 | for (iz = 0; iz < nbz; iz++) | |
358 | { | |
359 | surface = (myIsBool == 1) ? | |
360 | ((Voxel_BoolDS*)myVoxels)->Get(ix, iy, iz) == Standard_True : | |
361 | ((Voxel_ColorDS*)myVoxels)->Get(ix, iy, iz) > 0; | |
362 | if (prev_surface != surface) | |
363 | { | |
364 | volume = !volume; | |
365 | } | |
366 | if (volume && iz + 1 < nbz) | |
367 | { | |
368 | next_surface = (myIsBool == 1) ? | |
369 | ((Voxel_BoolDS*)myVoxels)->Get(ix, iy, iz + 1) == Standard_True : | |
370 | ((Voxel_ColorDS*)myVoxels)->Get(ix, iy, iz + 1) > 0; | |
371 | } | |
372 | if (volume && prev_surface == surface && next_surface) | |
373 | { | |
374 | (myIsBool == 1) ? ((Voxel_BoolDS*)myVoxels)->Set(ix, iy, iz, inner) : | |
375 | ((Voxel_ColorDS*)myVoxels)->Set(ix, iy, iz, inner); | |
376 | } | |
377 | prev_surface = surface; | |
378 | } | |
379 | } | |
380 | } | |
381 | } | |
382 | ||
383 | return Standard_True; | |
384 | } | |
385 | ||
386 | void Voxel_FastConverter::GetBndBox(const gp_Pnt& p1, | |
387 | const gp_Pnt& p2, | |
388 | const gp_Pnt& p3, | |
389 | Standard_Real& xmin, | |
390 | Standard_Real& ymin, | |
391 | Standard_Real& zmin, | |
392 | Standard_Real& xmax, | |
393 | Standard_Real& ymax, | |
394 | Standard_Real& zmax) const | |
395 | { | |
396 | // P1: | |
397 | xmin = p1.X(); | |
398 | ymin = p1.Y(); | |
399 | zmin = p1.Z(); | |
400 | xmax = p1.X(); | |
401 | ymax = p1.Y(); | |
402 | zmax = p1.Z(); | |
403 | // P2: | |
404 | if (xmin > p2.X()) | |
405 | xmin = p2.X(); | |
406 | if (ymin > p2.Y()) | |
407 | ymin = p2.Y(); | |
408 | if (zmin > p2.Z()) | |
409 | zmin = p2.Z(); | |
410 | if (xmax < p2.X()) | |
411 | xmax = p2.X(); | |
412 | if (ymax < p2.Y()) | |
413 | ymax = p2.Y(); | |
414 | if (zmax < p2.Z()) | |
415 | zmax = p2.Z(); | |
416 | // P3: | |
417 | if (xmin > p3.X()) | |
418 | xmin = p3.X(); | |
419 | if (ymin > p3.Y()) | |
420 | ymin = p3.Y(); | |
421 | if (zmin > p3.Z()) | |
422 | zmin = p3.Z(); | |
423 | if (xmax < p3.X()) | |
424 | xmax = p3.X(); | |
425 | if (ymax < p3.Y()) | |
426 | ymax = p3.Y(); | |
427 | if (zmax < p3.Z()) | |
428 | zmax = p3.Z(); | |
429 | } | |
430 | ||
431 | // This method is copied from Voxel_ShapeIntersector.cxx | |
432 | static Standard_Boolean mayIntersect(const gp_Pnt2d& p11, const gp_Pnt2d& p12, | |
433 | const gp_Pnt2d& p21, const gp_Pnt2d& p22) | |
434 | { | |
435 | if (p11.X() > p21.X() && p11.X() > p22.X() && p12.X() > p21.X() && p12.X() > p22.X()) | |
436 | return Standard_False; | |
437 | if (p11.X() < p21.X() && p11.X() < p22.X() && p12.X() < p21.X() && p12.X() < p22.X()) | |
438 | return Standard_False; | |
439 | if (p11.Y() > p21.Y() && p11.Y() > p22.Y() && p12.Y() > p21.Y() && p12.Y() > p22.Y()) | |
440 | return Standard_False; | |
441 | if (p11.Y() < p21.Y() && p11.Y() < p22.Y() && p12.Y() < p21.Y() && p12.Y() < p22.Y()) | |
442 | return Standard_False; | |
443 | return Standard_True; | |
444 | } | |
445 | ||
446 | void Voxel_FastConverter::ComputeVoxelsNearTriangle(const gp_Pln& plane, | |
447 | const gp_Pnt& p1, | |
448 | const gp_Pnt& p2, | |
449 | const gp_Pnt& p3, | |
450 | const Standard_Real hdiagonal, | |
451 | const Standard_Integer ixmin, | |
452 | const Standard_Integer iymin, | |
453 | const Standard_Integer izmin, | |
454 | const Standard_Integer ixmax, | |
455 | const Standard_Integer iymax, | |
456 | const Standard_Integer izmax) const | |
457 | { | |
458 | gp_Pnt pc; | |
459 | Standard_Real xc, yc, zc, uc, vc, u1, v1, u2, v2, u3, v3; | |
460 | Standard_Integer ix, iy, iz; | |
461 | IntAna2d_AnaIntersection intersector2d; | |
462 | ||
463 | // Project points of triangle onto the plane | |
464 | ElSLib::Parameters(plane, p1, u1, v1); | |
465 | ElSLib::Parameters(plane, p2, u2, v2); | |
466 | ElSLib::Parameters(plane, p3, u3, v3); | |
467 | ||
468 | // Make lines of triangle | |
469 | gp_Pnt2d p2d1(u1, v1), p2d2(u2, v2), p2d3(u3, v3), p2dt((u1+u2+u3)/3.0,(v1+v2+v3)/3.0), p2dc; | |
470 | gp_Vec2d v2d12(p2d1, p2d2), v2d23(p2d2, p2d3), v2d31(p2d3, p2d1); | |
471 | gp_Lin2d L1(p2d1, v2d12), L2(p2d2, v2d23), L3(p2d3, v2d31), Lv; | |
472 | Standard_Real d1 = p2d1.Distance(p2d2) - Precision::Confusion(), | |
473 | d2 = p2d2.Distance(p2d3) - Precision::Confusion(), | |
474 | d3 = p2d3.Distance(p2d1) - Precision::Confusion(), dv; | |
475 | ||
476 | Voxel_DS* ds = (Voxel_DS*) myVoxels; | |
477 | for (ix = ixmin; ix <= ixmax; ix++) | |
478 | { | |
479 | for (iy = iymin; iy <= iymax; iy++) | |
480 | { | |
481 | for (iz = izmin; iz <= izmax; iz++) | |
482 | { | |
483 | ds->GetCenter(ix, iy, iz, xc, yc, zc); | |
484 | pc.SetCoord(xc, yc, zc); | |
485 | if (plane.Distance(pc) < hdiagonal) | |
486 | { | |
487 | ElSLib::Parameters(plane, pc, uc, vc); | |
488 | p2dc.SetCoord(uc, vc); | |
489 | ||
490 | gp_Vec2d v2dct(p2dc, p2dt); | |
491 | dv = v2dct.Magnitude() - Precision::Confusion(); | |
492 | Lv.SetLocation(p2dc); | |
493 | Lv.SetDirection(v2dct); | |
494 | ||
495 | // Side 1: | |
496 | if (mayIntersect(p2d1, p2d2, p2dc, p2dt)) | |
497 | { | |
498 | intersector2d.Perform(Lv, L1); | |
499 | if (intersector2d.IsDone() && !intersector2d.ParallelElements() && intersector2d.NbPoints()) | |
500 | { | |
501 | const IntAna2d_IntPoint& i2d = intersector2d.Point(1); | |
502 | Standard_Real param1 = i2d.ParamOnFirst(); | |
503 | Standard_Real param2 = i2d.ParamOnSecond(); | |
504 | if (param1 > Precision::Confusion() && param1 < dv && | |
505 | param2 > Precision::Confusion() && param2 < d1) | |
506 | { | |
507 | continue; | |
508 | } | |
509 | } | |
510 | } | |
511 | ||
512 | // Side 2: | |
513 | if (mayIntersect(p2d2, p2d3, p2dc, p2dt)) | |
514 | { | |
515 | intersector2d.Perform(Lv, L2); | |
516 | if (intersector2d.IsDone() && !intersector2d.ParallelElements() && intersector2d.NbPoints()) | |
517 | { | |
518 | const IntAna2d_IntPoint& i2d = intersector2d.Point(1); | |
519 | Standard_Real param1 = i2d.ParamOnFirst(); | |
520 | Standard_Real param2 = i2d.ParamOnSecond(); | |
521 | if (param1 > Precision::Confusion() && param1 < dv && | |
522 | param2 > Precision::Confusion() && param2 < d2) | |
523 | { | |
524 | continue; | |
525 | } | |
526 | } | |
527 | } | |
528 | ||
529 | // Side 3: | |
530 | if (mayIntersect(p2d3, p2d1, p2dc, p2dt)) | |
531 | { | |
532 | intersector2d.Perform(Lv, L3); | |
533 | if (intersector2d.IsDone() && !intersector2d.ParallelElements() && intersector2d.NbPoints()) | |
534 | { | |
535 | const IntAna2d_IntPoint& i2d = intersector2d.Point(1); | |
536 | Standard_Real param1 = i2d.ParamOnFirst(); | |
537 | Standard_Real param2 = i2d.ParamOnSecond(); | |
538 | if (param1 > Precision::Confusion() && param1 < dv && | |
539 | param2 > Precision::Confusion() && param2 < d3) | |
540 | { | |
541 | continue; | |
542 | } | |
543 | } | |
544 | } | |
545 | ||
546 | // Set positive value to this voxel: | |
547 | switch (myIsBool) | |
548 | { | |
549 | case 0: | |
550 | ((Voxel_ColorDS*) myVoxels)->Set(ix, iy, iz, 15); | |
551 | break; | |
552 | case 1: | |
553 | ((Voxel_BoolDS*) myVoxels)->Set(ix, iy, iz, Standard_True); | |
554 | break; | |
555 | case 2: | |
556 | { | |
557 | //((Voxel_ROctBoolDS*) myVoxels)->Set(ix, iy, iz, Standard_True); | |
558 | ||
559 | // Check intersection between the triangle & sub-voxels of the voxel. | |
560 | Standard_Real hdiagonal2 = hdiagonal / 2.0, hdiagonal4 = hdiagonal / 4.0; | |
561 | for (Standard_Integer i = 0; i < 8; i++) | |
562 | { | |
563 | ((Voxel_ROctBoolDS*) myVoxels)->GetCenter(ix, iy, iz, i, xc, yc, zc); | |
564 | pc.SetCoord(xc, yc, zc); | |
565 | if (plane.Distance(pc) < hdiagonal2) | |
566 | { | |
567 | ElSLib::Parameters(plane, pc, uc, vc); | |
568 | p2dc.SetCoord(uc, vc); | |
569 | ||
570 | gp_Vec2d v2dct(p2dc, p2dt); | |
571 | dv = v2dct.Magnitude() - Precision::Confusion(); | |
572 | Lv.SetLocation(p2dc); | |
573 | Lv.SetDirection(v2dct); | |
574 | ||
575 | // Side 1: | |
576 | if (mayIntersect(p2d1, p2d2, p2dc, p2dt)) | |
577 | { | |
578 | intersector2d.Perform(Lv, L1); | |
579 | if (intersector2d.IsDone() && !intersector2d.ParallelElements() && intersector2d.NbPoints()) | |
580 | { | |
581 | const IntAna2d_IntPoint& i2d = intersector2d.Point(1); | |
582 | Standard_Real param1 = i2d.ParamOnFirst(); | |
583 | Standard_Real param2 = i2d.ParamOnSecond(); | |
584 | if (param1 > Precision::Confusion() && param1 < dv && | |
585 | param2 > Precision::Confusion() && param2 < d1) | |
586 | { | |
587 | continue; | |
588 | } | |
589 | } | |
590 | } | |
591 | ||
592 | // Side 2: | |
593 | if (mayIntersect(p2d2, p2d3, p2dc, p2dt)) | |
594 | { | |
595 | intersector2d.Perform(Lv, L2); | |
596 | if (intersector2d.IsDone() && !intersector2d.ParallelElements() && intersector2d.NbPoints()) | |
597 | { | |
598 | const IntAna2d_IntPoint& i2d = intersector2d.Point(1); | |
599 | Standard_Real param1 = i2d.ParamOnFirst(); | |
600 | Standard_Real param2 = i2d.ParamOnSecond(); | |
601 | if (param1 > Precision::Confusion() && param1 < dv && | |
602 | param2 > Precision::Confusion() && param2 < d2) | |
603 | { | |
604 | continue; | |
605 | } | |
606 | } | |
607 | } | |
608 | ||
609 | // Side 3: | |
610 | if (mayIntersect(p2d3, p2d1, p2dc, p2dt)) | |
611 | { | |
612 | intersector2d.Perform(Lv, L3); | |
613 | if (intersector2d.IsDone() && !intersector2d.ParallelElements() && intersector2d.NbPoints()) | |
614 | { | |
615 | const IntAna2d_IntPoint& i2d = intersector2d.Point(1); | |
616 | Standard_Real param1 = i2d.ParamOnFirst(); | |
617 | Standard_Real param2 = i2d.ParamOnSecond(); | |
618 | if (param1 > Precision::Confusion() && param1 < dv && | |
619 | param2 > Precision::Confusion() && param2 < d3) | |
620 | { | |
621 | continue; | |
622 | } | |
623 | } | |
624 | } | |
625 | ||
626 | //((Voxel_ROctBoolDS*) myVoxels)->Set(ix, iy, iz, i, Standard_True); | |
627 | ||
628 | // Check intersection between the triangle & sub-voxels of the sub-voxel. | |
629 | for (Standard_Integer j = 0; j < 8; j++) | |
630 | { | |
631 | ((Voxel_ROctBoolDS*) myVoxels)->GetCenter(ix, iy, iz, i, j, xc, yc, zc); | |
632 | pc.SetCoord(xc, yc, zc); | |
633 | if (plane.Distance(pc) < hdiagonal4) | |
634 | { | |
635 | ElSLib::Parameters(plane, pc, uc, vc); | |
636 | p2dc.SetCoord(uc, vc); | |
637 | ||
638 | gp_Vec2d v2dct(p2dc, p2dt); | |
639 | dv = v2dct.Magnitude() - Precision::Confusion(); | |
640 | Lv.SetLocation(p2dc); | |
641 | Lv.SetDirection(v2dct); | |
642 | ||
643 | // Side 1: | |
644 | if (mayIntersect(p2d1, p2d2, p2dc, p2dt)) | |
645 | { | |
646 | intersector2d.Perform(Lv, L1); | |
647 | if (intersector2d.IsDone() && !intersector2d.ParallelElements() && intersector2d.NbPoints()) | |
648 | { | |
649 | const IntAna2d_IntPoint& i2d = intersector2d.Point(1); | |
650 | Standard_Real param1 = i2d.ParamOnFirst(); | |
651 | Standard_Real param2 = i2d.ParamOnSecond(); | |
652 | if (param1 > Precision::Confusion() && param1 < dv && | |
653 | param2 > Precision::Confusion() && param2 < d1) | |
654 | { | |
655 | continue; | |
656 | } | |
657 | } | |
658 | } | |
659 | ||
660 | // Side 2: | |
661 | if (mayIntersect(p2d2, p2d3, p2dc, p2dt)) | |
662 | { | |
663 | intersector2d.Perform(Lv, L2); | |
664 | if (intersector2d.IsDone() && !intersector2d.ParallelElements() && intersector2d.NbPoints()) | |
665 | { | |
666 | const IntAna2d_IntPoint& i2d = intersector2d.Point(1); | |
667 | Standard_Real param1 = i2d.ParamOnFirst(); | |
668 | Standard_Real param2 = i2d.ParamOnSecond(); | |
669 | if (param1 > Precision::Confusion() && param1 < dv && | |
670 | param2 > Precision::Confusion() && param2 < d2) | |
671 | { | |
672 | continue; | |
673 | } | |
674 | } | |
675 | } | |
676 | ||
677 | // Side 3: | |
678 | if (mayIntersect(p2d3, p2d1, p2dc, p2dt)) | |
679 | { | |
680 | intersector2d.Perform(Lv, L3); | |
681 | if (intersector2d.IsDone() && !intersector2d.ParallelElements() && intersector2d.NbPoints()) | |
682 | { | |
683 | const IntAna2d_IntPoint& i2d = intersector2d.Point(1); | |
684 | Standard_Real param1 = i2d.ParamOnFirst(); | |
685 | Standard_Real param2 = i2d.ParamOnSecond(); | |
686 | if (param1 > Precision::Confusion() && param1 < dv && | |
687 | param2 > Precision::Confusion() && param2 < d3) | |
688 | { | |
689 | continue; | |
690 | } | |
691 | } | |
692 | } | |
693 | ||
694 | ((Voxel_ROctBoolDS*) myVoxels)->Set(ix, iy, iz, i, j, Standard_True); | |
695 | } | |
696 | } // End of "Check level 2". | |
697 | ||
698 | } | |
699 | } // End of "Check level 1". | |
700 | ||
701 | break; | |
702 | } | |
703 | } | |
704 | } | |
705 | } | |
706 | } | |
707 | } | |
708 | } |